From 343b658c32a6473c545187c1e276ee5d06c2686a Mon Sep 17 00:00:00 2001 From: Kevin Rushforth Date: Wed, 9 Jun 2004 04:25:41 +0000 Subject: Initial creation of j3d-core-utils sources in CVS repository git-svn-id: https://svn.java.net/svn/j3d-core~svn/trunk@7 ba19aa83-45c5-6ac9-afd3-db810772062c --- src/native/build.xml | 367 + src/native/d3d/Attributes.cpp | 3014 ++++++ src/native/d3d/Canvas3D.cpp | 1029 ++ src/native/d3d/CompressedGeometryRetained.cpp | 39 + src/native/d3d/D3dCtx.cpp | 1793 ++++ src/native/d3d/D3dCtx.hpp | 325 + src/native/d3d/D3dDeviceInfo.cpp | 204 + src/native/d3d/D3dDeviceInfo.hpp | 85 + src/native/d3d/D3dDisplayList.cpp | 330 + src/native/d3d/D3dDisplayList.hpp | 38 + src/native/d3d/D3dDriverInfo.cpp | 320 + src/native/d3d/D3dDriverInfo.hpp | 61 + src/native/d3d/D3dImageComponent.cpp | 171 + src/native/d3d/D3dImageComponent.hpp | 52 + src/native/d3d/D3dUtil.cpp | 11666 +++++++++++++++++++++++ src/native/d3d/D3dUtil.hpp | 310 + src/native/d3d/D3dVertexBuffer.cpp | 259 + src/native/d3d/D3dVertexBuffer.hpp | 127 + src/native/d3d/GeometryArrayRetained.cpp | 5254 ++++++++++ src/native/d3d/GraphicsContext3D.cpp | 150 + src/native/d3d/Lights.cpp | 155 + src/native/d3d/NativeAPIInfo.c | 23 + src/native/d3d/NativeConfigTemplate3D.cpp | 140 + src/native/d3d/NativeWSInfo.cpp | 92 + src/native/d3d/RasterRetained.cpp | 255 + src/native/d3d/StdAfx.h | 54 + src/native/d3d/build-windows-i586-gcc.xml | 17 + src/native/d3d/build-windows-i586-vc.xml | 63 + src/native/ogl/Attributes.c | 3505 +++++++ src/native/ogl/Canvas3D.c | 3388 +++++++ src/native/ogl/CompressedGeometryRetained.c | 70 + src/native/ogl/DrawingSurfaceObjectAWT.c | 268 + src/native/ogl/GeometryArrayRetained.c | 3599 +++++++ src/native/ogl/GraphicsContext3D.c | 171 + src/native/ogl/Lights.c | 168 + src/native/ogl/MasterControl.c | 261 + src/native/ogl/NativeAPIInfo.c | 38 + src/native/ogl/NativeConfigTemplate3D.c | 1277 +++ src/native/ogl/NativeScreenInfo.c | 65 + src/native/ogl/NativeWSInfo.c | 78 + src/native/ogl/RasterRetained.c | 392 + src/native/ogl/build-linux-i586.xml | 56 + src/native/ogl/build-solaris-sparc-forte.xml | 81 + src/native/ogl/build-solaris-sparc-gcc.xml | 81 + src/native/ogl/build-windows-i586-gcc.xml | 64 + src/native/ogl/build-windows-i586-vc.xml | 62 + src/native/ogl/gl_1_2.h | 191 + src/native/ogl/gldefs.h | 645 ++ src/native/ogl/glext.h | 3063 ++++++ src/native/ogl/panoramiXext.h | 102 + src/native/share/build-linux-i586.xml | 54 + src/native/share/build-solaris-sparc-forte.xml | 79 + src/native/share/build-solaris-sparc-gcc.xml | 79 + src/native/share/build-windows-i586-gcc.xml | 63 + src/native/share/build-windows-i586-vc.xml | 62 + 55 files changed, 44355 insertions(+) create mode 100644 src/native/build.xml create mode 100644 src/native/d3d/Attributes.cpp create mode 100644 src/native/d3d/Canvas3D.cpp create mode 100644 src/native/d3d/CompressedGeometryRetained.cpp create mode 100644 src/native/d3d/D3dCtx.cpp create mode 100644 src/native/d3d/D3dCtx.hpp create mode 100644 src/native/d3d/D3dDeviceInfo.cpp create mode 100644 src/native/d3d/D3dDeviceInfo.hpp create mode 100644 src/native/d3d/D3dDisplayList.cpp create mode 100644 src/native/d3d/D3dDisplayList.hpp create mode 100644 src/native/d3d/D3dDriverInfo.cpp create mode 100644 src/native/d3d/D3dDriverInfo.hpp create mode 100644 src/native/d3d/D3dImageComponent.cpp create mode 100644 src/native/d3d/D3dImageComponent.hpp create mode 100644 src/native/d3d/D3dUtil.cpp create mode 100644 src/native/d3d/D3dUtil.hpp create mode 100644 src/native/d3d/D3dVertexBuffer.cpp create mode 100644 src/native/d3d/D3dVertexBuffer.hpp create mode 100644 src/native/d3d/GeometryArrayRetained.cpp create mode 100644 src/native/d3d/GraphicsContext3D.cpp create mode 100644 src/native/d3d/Lights.cpp create mode 100644 src/native/d3d/NativeAPIInfo.c create mode 100644 src/native/d3d/NativeConfigTemplate3D.cpp create mode 100644 src/native/d3d/NativeWSInfo.cpp create mode 100644 src/native/d3d/RasterRetained.cpp create mode 100644 src/native/d3d/StdAfx.h create mode 100644 src/native/d3d/build-windows-i586-gcc.xml create mode 100644 src/native/d3d/build-windows-i586-vc.xml create mode 100644 src/native/ogl/Attributes.c create mode 100644 src/native/ogl/Canvas3D.c create mode 100644 src/native/ogl/CompressedGeometryRetained.c create mode 100644 src/native/ogl/DrawingSurfaceObjectAWT.c create mode 100644 src/native/ogl/GeometryArrayRetained.c create mode 100644 src/native/ogl/GraphicsContext3D.c create mode 100644 src/native/ogl/Lights.c create mode 100644 src/native/ogl/MasterControl.c create mode 100644 src/native/ogl/NativeAPIInfo.c create mode 100644 src/native/ogl/NativeConfigTemplate3D.c create mode 100644 src/native/ogl/NativeScreenInfo.c create mode 100644 src/native/ogl/NativeWSInfo.c create mode 100644 src/native/ogl/RasterRetained.c create mode 100644 src/native/ogl/build-linux-i586.xml create mode 100644 src/native/ogl/build-solaris-sparc-forte.xml create mode 100644 src/native/ogl/build-solaris-sparc-gcc.xml create mode 100644 src/native/ogl/build-windows-i586-gcc.xml create mode 100644 src/native/ogl/build-windows-i586-vc.xml create mode 100644 src/native/ogl/gl_1_2.h create mode 100644 src/native/ogl/gldefs.h create mode 100644 src/native/ogl/glext.h create mode 100644 src/native/ogl/panoramiXext.h create mode 100644 src/native/share/build-linux-i586.xml create mode 100644 src/native/share/build-solaris-sparc-forte.xml create mode 100644 src/native/share/build-solaris-sparc-gcc.xml create mode 100644 src/native/share/build-windows-i586-gcc.xml create mode 100644 src/native/share/build-windows-i586-vc.xml (limited to 'src/native') diff --git a/src/native/build.xml b/src/native/build.xml new file mode 100644 index 0000000..f2ca9a1 --- /dev/null +++ b/src/native/build.xml @@ -0,0 +1,367 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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( + env->GetPrimitiveArrayCritical(modelMatrix, NULL)); + + CopyTranspose(d3dMatrix, matrix); + + env->ReleasePrimitiveArrayCritical(modelMatrix, matrix, 0); + + + device->SetTransform(D3DTS_WORLD,&d3dMatrix); + + matrix = reinterpret_cast( + 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( + 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<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( + env->GetPrimitiveArrayCritical(transform, NULL)); + CopyTranspose((*m), mx_ptr); + + env->ReleasePrimitiveArrayCritical(transform, mx_ptr, 0); + /* + printf("set Tex Transform \n"); + printf("%f, %f, %f, %f\n", (*m)._11, (*m)._12, (*m)._13, (*m)._14); + printf("%f, %f, %f, %f\n", (*m)._21, (*m)._22, (*m)._23, (*m)._24); + printf("%f, %f, %f, %f\n", (*m)._31, (*m)._23, (*m)._33, (*m)._34); + printf("%f, %f, %f, %f\n", (*m)._41, (*m)._42, (*m)._43, (*m)._44); + */ + d3dCtx->texTransformSet[tus] = true; + d3dCtx->texTranslateSet[tus] = false; + device->SetTransform((D3DTRANSFORMSTATETYPE) + (D3DTS_TEXTURE0 + tus), m); + } + + /* set texture environment mode */ + + switch (textureMode) { + case javax_media_j3d_TextureAttributes_MODULATE: + switch (format) { + case J3D_RGBA: + case INTENSITY: + case LUMINANCE_ALPHA: + device->SetTextureStageState(tus, + D3DTSS_COLOROP, D3DTOP_MODULATE); + device->SetTextureStageState(tus, + D3DTSS_COLORARG1, D3DTA_TEXTURE); + device->SetTextureStageState(tus, + D3DTSS_COLORARG2, D3DTA_CURRENT); + device->SetTextureStageState(tus, + D3DTSS_ALPHAOP, D3DTOP_MODULATE); + device->SetTextureStageState(tus, + D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + device->SetTextureStageState(tus, + D3DTSS_ALPHAARG2, D3DTA_CURRENT); + break; + case J3D_RGB: + case LUMINANCE: + device->SetTextureStageState(tus, + D3DTSS_COLOROP, D3DTOP_MODULATE); + device->SetTextureStageState(tus, + D3DTSS_COLORARG1, D3DTA_TEXTURE); + device->SetTextureStageState(tus, + D3DTSS_COLORARG2, D3DTA_CURRENT); + device->SetTextureStageState(tus, + D3DTSS_ALPHAOP, D3DTOP_DISABLE); + break; + case ALPHA: + device->SetTextureStageState(tus, + D3DTSS_COLOROP, D3DTOP_SELECTARG1); + device->SetTextureStageState(tus, + D3DTSS_COLORARG1, D3DTA_CURRENT); + device->SetTextureStageState(tus, + D3DTSS_ALPHAOP, D3DTOP_MODULATE); + device->SetTextureStageState(tus, + D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + device->SetTextureStageState(tus, + D3DTSS_ALPHAARG2, D3DTA_CURRENT); + break; + default: + printf("Format %d not support\n", format); + } + break; + case javax_media_j3d_TextureAttributes_DECAL: + switch (format) { + case J3D_RGBA: + case INTENSITY: + case LUMINANCE_ALPHA: + device->SetTextureStageState(tus, + D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA); + device->SetTextureStageState(tus, + D3DTSS_COLORARG1, D3DTA_TEXTURE); + device->SetTextureStageState(tus, + D3DTSS_COLORARG2, D3DTA_CURRENT); + device->SetTextureStageState(tus, + D3DTSS_ALPHAOP, D3DTOP_DISABLE); + break; + case J3D_RGB: + case LUMINANCE: + device->SetTextureStageState(tus, + D3DTSS_COLOROP, D3DTOP_SELECTARG1); + device->SetTextureStageState(tus, + D3DTSS_COLORARG1, D3DTA_TEXTURE); + device->SetTextureStageState(tus, + D3DTSS_ALPHAOP, D3DTOP_DISABLE); + break; + case ALPHA: + device->SetTextureStageState(tus, + D3DTSS_COLOROP, D3DTOP_SELECTARG1); + device->SetTextureStageState(tus, + D3DTSS_COLORARG1, D3DTA_CURRENT); + device->SetTextureStageState(tus, + D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + device->SetTextureStageState(tus, + D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + break; + default: + printf("Format %d not support\n", format); + } + break; + case javax_media_j3d_TextureAttributes_BLEND: + // Two pass is needed for this mode, the first pass + // will + + textureBlendColor = D3DCOLOR_COLORVALUE(textureBlendColorRed, + textureBlendColorGreen, + textureBlendColorBlue, + textureBlendColorAlpha); + + device->SetRenderState(D3DRS_TEXTUREFACTOR, + *((LPDWORD) &textureBlendColor)); + + switch (format) { + case ALPHA: + device->SetTextureStageState(tus, + D3DTSS_COLOROP, D3DTOP_SELECTARG1); + device->SetTextureStageState(tus, + D3DTSS_COLORARG1, D3DTA_CURRENT); + device->SetTextureStageState(tus, + D3DTSS_ALPHAOP, D3DTOP_MODULATE); + device->SetTextureStageState(tus, + D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + device->SetTextureStageState(tus, + D3DTSS_ALPHAARG2, D3DTA_CURRENT); + break; + case INTENSITY: + device->SetTextureStageState(tus, + D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA); + device->SetTextureStageState(tus, + D3DTSS_COLORARG1, D3DTA_CURRENT); + device->SetTextureStageState(tus, + D3DTSS_COLORARG2, D3DTA_TFACTOR); + device->SetTextureStageState(tus, + D3DTSS_ALPHAOP, D3DTOP_BLENDTEXTUREALPHA); + device->SetTextureStageState(tus, + D3DTSS_ALPHAARG1, D3DTA_CURRENT); + device->SetTextureStageState(tus, + D3DTSS_ALPHAARG2, D3DTA_TFACTOR); + break; + case J3D_RGB: + case LUMINANCE: + device->SetTextureStageState(0, + D3DTSS_ALPHAOP, + D3DTOP_DISABLE); + alphaDisable = TRUE; + // fallthrough + case J3D_RGBA: + case LUMINANCE_ALPHA: + + if (!d3dCtx->deviceInfo->texLerpSupport) { + // Use two pass, first pass will enable specular and + // compute Cf*(1 - Ct), second pass will disable specular and + // comptue Cc*Ct. Note that multi-texturing is disable + // in this case, so stage 0 is always use. + device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + device->SetTextureStageState(0, D3DTSS_COLORARG1, + D3DTA_TEXTURE|D3DTA_COMPLEMENT); + device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + + if (!alphaDisable) { + device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT); + } + } else { + device->SetTextureStageState(tus, D3DTSS_COLOROP, D3DTOP_LERP); + device->SetTextureStageState(tus, D3DTSS_COLORARG0, D3DTA_TEXTURE); + device->SetTextureStageState(tus, D3DTSS_COLORARG1, D3DTA_TFACTOR); + device->SetTextureStageState(tus, D3DTSS_COLORARG2, D3DTA_CURRENT); + + if (!alphaDisable) { + device->SetTextureStageState(tus, D3DTSS_ALPHAOP, D3DTOP_LERP); + device->SetTextureStageState(tus, D3DTSS_ALPHAARG0, D3DTA_TEXTURE); + device->SetTextureStageState(tus, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); + device->SetTextureStageState(tus, D3DTSS_ALPHAARG2, D3DTA_CURRENT); + } + } + break; + default: + printf("Format %d not support\n", format); + } + + + break; + case javax_media_j3d_TextureAttributes_REPLACE: + switch (format) { + case J3D_RGBA: + case INTENSITY: + case LUMINANCE_ALPHA: + device->SetTextureStageState(tus, + D3DTSS_COLOROP, D3DTOP_SELECTARG1); + device->SetTextureStageState(tus, + D3DTSS_COLORARG1, D3DTA_TEXTURE); + device->SetTextureStageState(tus, + D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + device->SetTextureStageState(tus, + D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + break; + case J3D_RGB: + case LUMINANCE: + device->SetTextureStageState(tus, + D3DTSS_COLOROP, D3DTOP_SELECTARG1); + device->SetTextureStageState(tus, + D3DTSS_COLORARG1, D3DTA_TEXTURE); + device->SetTextureStageState(tus, + D3DTSS_ALPHAOP, D3DTOP_DISABLE); + break; + case ALPHA: + device->SetTextureStageState(tus, + D3DTSS_COLOROP, D3DTOP_SELECTARG1); + device->SetTextureStageState(tus, + D3DTSS_COLORARG1, D3DTA_CURRENT); + device->SetTextureStageState(tus, + D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + device->SetTextureStageState(tus, + D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + break; + default: + printf("Format %d not support\n", format); + } + break; + default: + // TEXTURE COMBINER case + break; + } +} + + +// This procedure is invoked after Blend2Pass to restore the original value +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureAttributesRetained_restoreBlend1Pass( + JNIEnv *env, + jobject obj, + jlong ctx) +{ + GetDevice(); + + device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + device->SetTextureStageState(0, D3DTSS_COLORARG1, + D3DTA_TEXTURE|D3DTA_COMPLEMENT); + device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); + + device->SetRenderState(D3DRS_SRCBLEND, + d3dCtx->srcBlendFunc); + device->SetRenderState(D3DRS_DESTBLEND, + d3dCtx->dstBlendFunc); + device->SetRenderState(D3DRS_ALPHABLENDENABLE, + d3dCtx->blendEnable); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureAttributesRetained_updateBlend2Pass( + JNIEnv *env, + jobject obj, + jlong ctx) +{ + GetDevice(); + device->GetRenderState(D3DRS_SRCBLEND, + &d3dCtx->srcBlendFunc); + device->GetRenderState(D3DRS_DESTBLEND, + &d3dCtx->dstBlendFunc); + device->GetRenderState(D3DRS_ALPHABLENDENABLE, + &d3dCtx->blendEnable); + + device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); + device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); + device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureAttributesRetained_updateCombinerNative( + JNIEnv *env, + jobject obj, + jlong ctx, + jint combineRgbMode, + jint combineAlphaMode, + jintArray combineRgbSrc, + jintArray combineAlphaSrc, + jintArray combineRgbFcn, + jintArray combineAlphaFcn, + jint combineRgbScale, + jint combineAlphaScale) +{ + + GetDevice(); + + DWORD ts = d3dCtx->texUnitStage; + + jint *rgbSrc = (jint *) env->GetPrimitiveArrayCritical(combineRgbSrc, NULL); + jint *alphaSrc = (jint *) env->GetPrimitiveArrayCritical(combineAlphaSrc, NULL); + jint *rgbFcn = (jint *) env->GetPrimitiveArrayCritical(combineRgbFcn, NULL); + jint *alphaFcn = (jint *) env->GetPrimitiveArrayCritical(combineAlphaFcn, NULL); + + + device->SetTextureStageState(ts, D3DTSS_COLOROP, + combineFunctionTable[(combineRgbMode << 2) + combineRgbScale]); + + if (combineRgbMode != javax_media_j3d_TextureAttributes_COMBINE_INTERPOLATE) { + device->SetTextureStageState(ts, D3DTSS_COLORARG1, + combineSourceTable[(rgbSrc[0] << 2) + rgbFcn[0]]); + if (combineRgbMode != javax_media_j3d_TextureAttributes_COMBINE_REPLACE) { + device->SetTextureStageState(ts, D3DTSS_COLORARG2, + combineSourceTable[(rgbSrc[1] << 2) + rgbFcn[1]]); + } + } else { + device->SetTextureStageState(ts, D3DTSS_COLORARG1, + combineSourceTable[(rgbSrc[2] << 2) + rgbFcn[2]]); + device->SetTextureStageState(ts, D3DTSS_COLORARG2, + combineSourceTable[(rgbSrc[0] << 2) + rgbFcn[0]]); + device->SetTextureStageState(ts, D3DTSS_COLORARG0, + combineSourceTable[(rgbSrc[1] << 2) + rgbFcn[1]]); + } + + device->SetTextureStageState(ts, D3DTSS_ALPHAOP, + combineFunctionTable[(combineAlphaMode << 2) + combineAlphaScale]); + + if (combineAlphaMode != javax_media_j3d_TextureAttributes_COMBINE_INTERPOLATE) { + device->SetTextureStageState(ts, D3DTSS_ALPHAARG1, + combineSourceTable[(alphaSrc[0] << 2) + alphaFcn[0]]); + if (combineAlphaMode != javax_media_j3d_TextureAttributes_COMBINE_REPLACE) { + device->SetTextureStageState(ts, D3DTSS_ALPHAARG2, + combineSourceTable[(alphaSrc[1] << 2) + alphaFcn[1]]); + } + } else { + device->SetTextureStageState(ts, D3DTSS_ALPHAARG0, + combineSourceTable[(alphaSrc[2] << 2) + alphaFcn[2]]); + device->SetTextureStageState(ts, D3DTSS_ALPHAARG1, + combineSourceTable[(alphaSrc[0] << 2) + alphaFcn[0]]); + device->SetTextureStageState(ts, D3DTSS_ALPHAARG2, + combineSourceTable[(alphaSrc[1] << 2) + alphaFcn[1]]); + } + + env->ReleasePrimitiveArrayCritical(combineRgbSrc, rgbSrc, 0); + env->ReleasePrimitiveArrayCritical(combineAlphaSrc, alphaSrc, 0); + env->ReleasePrimitiveArrayCritical(combineRgbFcn, rgbFcn, 0); + env->ReleasePrimitiveArrayCritical(combineAlphaFcn, alphaFcn, 0); +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureAttributesRetained_updateTextureColorTableNative( + JNIEnv *env, + jobject obj, + jlong ctx, + jint numComponents, + jint colorTableSize, + jintArray textureColorTable) +{ + // Not support by D3D +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_updateMaterial( + JNIEnv *env, + jobject obj, + jlong ctx, + jfloat colorRed, + jfloat colorGreen, + jfloat colorBlue, + jfloat transparency) +{ + GetDevice(); + + d3dCtx->currentColor_r = colorRed; + d3dCtx->currentColor_g = colorGreen; + d3dCtx->currentColor_b = colorBlue; + d3dCtx->currentColor_a = transparency; + + d3dCtx->isLightEnable = false; + device->SetRenderState(D3DRS_LIGHTING, false); + if (d3dCtx->resetColorTarget) { + device->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, + D3DMCS_COLOR1); + device->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, + D3DMCS_MATERIAL); + device->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, + D3DMCS_MATERIAL); + device->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, + D3DMCS_MATERIAL); + d3dCtx->resetColorTarget = false; + } +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_MaterialRetained_updateNative( + JNIEnv *env, + jobject obj, + jlong ctx, + jfloat colorRed, + jfloat colorGreen, + jfloat colorBlue, + jfloat transparency, + jfloat aRed, + jfloat aGreen, + jfloat aBlue, + jfloat eRed, + jfloat eGreen, + jfloat eBlue, + jfloat dRed, + jfloat dGreen, + jfloat dBlue, + jfloat sRed, + jfloat sGreen, + jfloat sBlue, + jfloat shininess, + jint colorTarget, + jboolean lightEnable) +{ + D3DMATERIAL8 material; + + GetDevice(); + + switch (colorTarget) { + case javax_media_j3d_Material_DIFFUSE: + device->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, + D3DMCS_COLOR1); + break; + case javax_media_j3d_Material_SPECULAR: + device->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, + D3DMCS_COLOR1); + d3dCtx->resetColorTarget = true; + break; + case javax_media_j3d_Material_AMBIENT: + device->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, + D3DMCS_COLOR1); + d3dCtx->resetColorTarget = true; + break; + case javax_media_j3d_Material_AMBIENT_AND_DIFFUSE: + device->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, + D3DMCS_COLOR1); + device->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, + D3DMCS_COLOR1); + d3dCtx->resetColorTarget = true; + break; + case javax_media_j3d_Material_EMISSIVE: + device->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, + D3DMCS_COLOR1); + d3dCtx->resetColorTarget = true; + break; + default: + printf("Material updateNative: Uknown colorTarget %d\n", colorTarget); + } + + material.Power = shininess; + + CopyColor(material.Emissive, eRed, eGreen, eBlue, 1.0f); + CopyColor(material.Ambient, aRed, aGreen, aBlue, 1.0f); + CopyColor(material.Specular, sRed, sGreen, sBlue, 1.0f); + + d3dCtx->currentColor_a = transparency; + + if (lightEnable) { + d3dCtx->currentColor_r = dRed; + d3dCtx->currentColor_g = dGreen; + d3dCtx->currentColor_b = dBlue; + + CopyColor(material.Diffuse, dRed, dGreen, dBlue, + transparency); + + } else { + d3dCtx->currentColor_r = colorRed; + d3dCtx->currentColor_g = colorGreen; + d3dCtx->currentColor_b = colorBlue; + + CopyColor(material.Diffuse, colorRed, colorGreen, + colorBlue, transparency); + } + + + d3dCtx->isLightEnable = lightEnable; + device->SetRenderState(D3DRS_LIGHTING, lightEnable); + device->SetMaterial(&material); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_resetTransparency( + JNIEnv *env, + jobject obj, + jlong ctx, + jint geometryType, + jint polygonMode, + jboolean lineAA, + jboolean pointAA) +{ + GetDevice(); + + // Line/Point Antialiasing not support + + /* + if (((((geometryType & LINE) != 0) || polygonMode == POLYGON_LINE) + && lineAA == JNI_TRUE) || + ((((geometryType & _POINT) != 0) || polygonMode == POLYGON_POINT) + && pointAA == JNI_TRUE)) { + device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + } else { + */ + device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + // } +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TransparencyAttributesRetained_updateNative( + JNIEnv *env, + jobject tr, + jlong ctx, + jfloat transparency, + jint geometryType, + jint polygonMode, + jboolean lineAA, + jboolean pointAA, + jint transparencyMode, + jint srcBlendFunction, + jint dstBlendFunction) +{ + + GetDevice(); + + // No screen door transparency in D3D, use BLENDED + // Don't know how to use STIPPLEDALPHA either. + /* + if (transparencyMode != TRANS_SCREEN_DOOR) { + device->SetRenderState(D3DRS_STIPPLEDALPHA, FALSE); + } else { + device->SetRenderState(D3DRS_STIPPLEDALPHA, TRUE); + } + */ + + if (transparencyMode < javax_media_j3d_TransparencyAttributes_NONE) { + /* + ((((geometryType & LINE) != 0) || polygonMode == POLYGON_LINE) + && lineAA == JNI_TRUE) || + ((((geometryType & _POINT) != 0) || polygonMode == POLYGON_POINT) + && pointAA == JNI_TRUE)) { + */ + device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + device->SetRenderState(D3DRS_SRCBLEND, + blendFunctionTable[srcBlendFunction]); + device->SetRenderState(D3DRS_DESTBLEND, + blendFunctionTable[dstBlendFunction]); + } else { + device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } +} + + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_resetColoringAttributes( + JNIEnv *env, + jobject obj, + jlong ctx, + jfloat colorRed, + jfloat colorGreen, + jfloat colorBlue, + jfloat transparency, + jboolean lightEnable) +{ + + GetDevice(); + + if (!lightEnable) { + d3dCtx->currentColor_r = colorRed; + d3dCtx->currentColor_g = colorGreen; + d3dCtx->currentColor_b = colorBlue; + d3dCtx->currentColor_a = transparency; + } + device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); + // No line smooth in D3D +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_ColoringAttributesRetained_updateNative( + JNIEnv *env, + jobject obj, + jlong ctx, + jfloat dRed, + jfloat dGreen, + jfloat dBlue, + jfloat colorRed, + jfloat colorGreen, + jfloat colorBlue, + jfloat transparency, + jboolean lightEnable, + jint shadeModel) +{ + + GetDevice(); + + d3dCtx->currentColor_a = transparency; + if (lightEnable) { + d3dCtx->currentColor_r = dRed; + d3dCtx->currentColor_g = dGreen; + d3dCtx->currentColor_b = dBlue; + } else { + d3dCtx->currentColor_r = colorRed; + d3dCtx->currentColor_g = colorGreen; + d3dCtx->currentColor_b = colorBlue; + } + + + if (shadeModel == javax_media_j3d_ColoringAttributes_SHADE_FLAT) { + device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); + } else { + device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); + } +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_resetTextureNative( + JNIEnv *env, + jobject texture, + jlong ctx, + jint texUnitIndex) +{ + GetDevice(); + + if (texUnitIndex < 0) { + texUnitIndex = 0; + } + + d3dCtx->texUnitStage = texUnitIndex; + + if (texUnitIndex >= d3dCtx->bindTextureIdLen) { + return; + } + device->SetTexture(texUnitIndex, NULL); + d3dCtx->bindTextureId[texUnitIndex] = -1; + + if (d3dCtx->texTransformSet[texUnitIndex]) { + d3dCtx->texTransformSet[texUnitIndex] = false; + device->SetTransform((D3DTRANSFORMSTATETYPE) + (D3DTS_TEXTURE0 + texUnitIndex), + &identityMatrix); + } + d3dCtx->texGenMode[texUnitIndex] = TEX_GEN_NONE; + device->SetTextureStageState(texUnitIndex, + D3DTSS_TEXCOORDINDEX, + D3DTSS_TCI_PASSTHRU); + device->SetTextureStageState(texUnitIndex, + D3DTSS_COLOROP, D3DTOP_SELECTARG1); + device->SetTextureStageState(texUnitIndex, + D3DTSS_COLORARG1, D3DTA_TEXTURE); + device->SetTextureStageState(texUnitIndex, + D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + device->SetTextureStageState(texUnitIndex, + D3DTSS_ALPHAARG1, D3DTA_TEXTURE); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_bindTexture( + JNIEnv *env, + jobject texture, + jlong ctx, + jint objectId, + jboolean enable) +{ + GetDevice(); + + if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) { + return; + } + + if (!enable) { + device->SetTexture(d3dCtx->texUnitStage, NULL); + d3dCtx->bindTextureId[d3dCtx->texUnitStage] = -1; + } else { + if (d3dCtx->bindTextureId[d3dCtx->texUnitStage] == objectId) { + return; + } + + if (objectId >= d3dCtx->textureTableLen) { + DWORD i; + DWORD len = max(objectId+1, d3dCtx->textureTableLen << 1); + LPDIRECT3DTEXTURE8 *newTable = (LPDIRECT3DTEXTURE8 *) + malloc(sizeof(LPDIRECT3DTEXTURE8) * len); + + if (newTable == NULL) { + printf("Not enough memory to alloc texture table of size %d.\n", len); + return; + } + for (i=0; i < d3dCtx->textureTableLen; i++) { + newTable[i] = d3dCtx->textureTable[i]; + } + for (i=d3dCtx->textureTableLen; i < len; i++) { + newTable[i] = NULL; + } + d3dCtx->textureTableLen = len; + SafeFree(d3dCtx->textureTable); + d3dCtx->textureTable = newTable; + } + + d3dCtx->bindTextureId[d3dCtx->texUnitStage] = objectId; + if (d3dCtx->textureTable[objectId] != NULL) { + device->SetTexture(d3dCtx->texUnitStage, + d3dCtx->textureTable[objectId]); + } + // else we will bind this in updateTextureImage + } +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureFilterModes( + JNIEnv *env, + jobject texture, + jlong ctx, + jint minFilter, + jint magFilter) +{ + GetDevice(); + + + if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) { + return; + } + + d3dCtx->texLinearMode = false; + + /* set texture min filter */ + switch (minFilter) { + case javax_media_j3d_Texture_FASTEST: + case javax_media_j3d_Texture_BASE_LEVEL_POINT: + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_MINFILTER, D3DTEXF_POINT); + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_MIPFILTER, D3DTEXF_POINT); + break; + case javax_media_j3d_Texture_BASE_LEVEL_LINEAR: + d3dCtx->texLinearMode = true; + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_MINFILTER, D3DTEXF_LINEAR); + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_MIPFILTER, D3DTEXF_POINT); + break; + case javax_media_j3d_Texture_MULTI_LEVEL_POINT: + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_MINFILTER, D3DTEXF_POINT); + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + break; + case javax_media_j3d_Texture_NICEST: + case javax_media_j3d_Texture_MULTI_LEVEL_LINEAR: + d3dCtx->texLinearMode = true; + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_MINFILTER, D3DTEXF_LINEAR); + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + break; + } + + /* set texture mag filter */ + switch (magFilter) { + case javax_media_j3d_Texture_FASTEST: + case javax_media_j3d_Texture_BASE_LEVEL_POINT: + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_MAGFILTER, D3DTEXF_POINT); + break; + case javax_media_j3d_Texture_NICEST: + case javax_media_j3d_Texture_BASE_LEVEL_LINEAR: + d3dCtx->texLinearMode = true; + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + break; + } + + return; +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureLodRange( + JNIEnv *env, + jobject texture, + jlong ctx, + jint baseLevel, + jint maximumLevel, + jfloat minimumLod, + jfloat maximumLod) +{ +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureLodOffset( + JNIEnv *env, + jobject texture, + jlong ctx, + jfloat lodOffsetS, + jfloat lodOffsetT, + jfloat lodOffsetR) +{ + /* not supported */ +} + +void updateTextureBoundary(JNIEnv *env, + jobject texture, + jlong ctx, + jint boundaryModeS, + jint boundaryModeT, + jint boundaryModeR, + jfloat boundaryRed, + jfloat boundaryGreen, + jfloat boundaryBlue, + jfloat boundaryAlpha) +{ + GetDevice(); + + + if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) { + return; + } + + /* set texture wrap parameter */ + BOOL useBorderMode = FALSE; + + // D3D ignored border color in CLAMP mode. + // Instead D3D use Border color in D3DTADDRESS_BORDER only. + // So we approximate the effect by using D3DTADDRESS_BORDER + // mode if linear filtering mode is used. + + switch (boundaryModeS) { + case javax_media_j3d_Texture_WRAP: + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_ADDRESSU, + D3DTADDRESS_WRAP); + break; + case javax_media_j3d_Texture_CLAMP: + if (!d3dCtx->texLinearMode || !d3dCtx->deviceInfo->texBorderModeSupport) { + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_ADDRESSU, + D3DTADDRESS_CLAMP); + } else { + useBorderMode = TRUE; + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_ADDRESSU, + D3DTADDRESS_BORDER); + } + break; + } + + switch (boundaryModeT) { + case javax_media_j3d_Texture_WRAP: + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_ADDRESSV, + D3DTADDRESS_WRAP); + break; + case javax_media_j3d_Texture_CLAMP: + if (!d3dCtx->texLinearMode || !d3dCtx->deviceInfo->texBorderModeSupport) { + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_ADDRESSV, + D3DTADDRESS_CLAMP); + } else { + useBorderMode = TRUE; + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_ADDRESSV, + D3DTADDRESS_BORDER); + } + break; + } + + if (boundaryModeR >= 0) { + switch (boundaryModeR) { + case javax_media_j3d_Texture_WRAP: + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_ADDRESSW, + D3DTADDRESS_WRAP); + break; + case javax_media_j3d_Texture_CLAMP: + if (!d3dCtx->texLinearMode || !d3dCtx->deviceInfo->texBorderModeSupport) { + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_ADDRESSW, + D3DTADDRESS_CLAMP); + } else { + useBorderMode = TRUE; + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_ADDRESSW, + D3DTADDRESS_BORDER); + } + break; + } + } + + if (useBorderMode) { + D3DCOLOR color = D3DCOLOR_COLORVALUE(boundaryRed, boundaryGreen, + boundaryBlue, boundaryAlpha); + + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_BORDERCOLOR, + *((DWORD *) &color)); + } +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureBoundary( + JNIEnv *env, + jobject texture, + jlong ctx, + jint boundaryModeS, + jint boundaryModeT, + jfloat boundaryRed, + jfloat boundaryGreen, + jfloat boundaryBlue, + jfloat boundaryAlpha) +{ + updateTextureBoundary(env, texture, ctx, boundaryModeS, + boundaryModeT, -1, + boundaryRed, boundaryGreen, + boundaryBlue, boundaryAlpha); + +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureSharpenFunc( + JNIEnv *env, + jobject texture, + jlong ctx, + jint numPts, + jfloatArray pts) +{ +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureFilter4Func( + JNIEnv *env, + jobject texture, + jlong ctx, + jint numPts, + jfloatArray pts) +{ +} + + +void updateTextureAnisotropicFilter( + jlong ctx, + jfloat degree) +{ + GetDevice(); + + if (degree > 1) { + DWORD deg = degree + 0.5f; // round float to int + // This will overwrite the previous setting in + // updateTextureFilterModes() + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_MINFILTER, + D3DTEXF_ANISOTROPIC); + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_MAGFILTER, + D3DTEXF_ANISOTROPIC); + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_MIPFILTER, + D3DTEXF_ANISOTROPIC); + + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_MAXANISOTROPY, deg); + } else { + // updateTextureFilterModes() will always invoke before + // updateTextureAnisotropicFilter() to set Filter mode + // correctly. + device->SetTextureStageState(d3dCtx->texUnitStage, + D3DTSS_MAXANISOTROPY, 1); + } + +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureAnisotropicFilter( + JNIEnv *env, + jobject texture, + jlong ctx, + jfloat degree) +{ + updateTextureAnisotropicFilter(ctx, degree); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureAnisotropicFilter( + JNIEnv *env, + jobject texture, + jlong ctx, + jfloat degree) +{ + GetCtx(); + + if (d3dCtx->deviceInfo->maxTextureDepth > 0) { + updateTextureAnisotropicFilter(ctx, degree); + } + +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureAnisotropicFilter( + JNIEnv *env, + jobject texture, + jlong ctx, + jfloat degree) +{ + updateTextureAnisotropicFilter(ctx, degree); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureSubImage( + JNIEnv *env, + jobject texture, + jlong ctx, + jint level, + jint xoffset, + jint yoffset, + jint internalFormat, + jint storedFormat, + jint imgXOffset, + jint imgYOffset, + jint tilew, + jint width, + jint height, + jbyteArray image) +{ + GetDevice(); + + if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) { + return; + } + + INT currBindTex = d3dCtx->bindTextureId[d3dCtx->texUnitStage]; + + if ((currBindTex < 1) || + (currBindTex >= d3dCtx->textureTableLen)) { + if (debug) { + printf("Internal Error : UpdateTextureSubImage bind texture ID %d, textureTableLen %d, texUnitStage = %d \n", currBindTex, d3dCtx->textureTableLen, d3dCtx->texUnitStage); + } + return; + } + + LPDIRECT3DTEXTURE8 surf = d3dCtx->textureTable[currBindTex]; + + if ((surf == NULL) || + ((level > 0) && (!d3dCtx->deviceInfo->supportMipmap))) { + return; + } + + // update Image data + if (storedFormat != FORMAT_USHORT_GRAY) { + jbyte *byteData = (jbyte *) env->GetPrimitiveArrayCritical(image, NULL); + copyDataToSurface(storedFormat, internalFormat, xoffset, yoffset, + imgXOffset, imgYOffset, + width, height, tilew, byteData, + surf, level); + env->ReleasePrimitiveArrayCritical(image, byteData, 0); + + } else { + jshort *shortData = (jshort *) env->GetPrimitiveArrayCritical(image, NULL); + copyDataToSurface(storedFormat, internalFormat, xoffset, yoffset, + imgXOffset, imgYOffset, + width, height, tilew, shortData, + surf, level); + env->ReleasePrimitiveArrayCritical(image, shortData, 0); + } + +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureImage( + JNIEnv *env, + jobject texture, + jlong ctx, + jint numLevels, + jint level, + jint internalFormat, + jint format, + jint width, + jint height, + jint boundaryWidth, + jbyteArray imageYup) +{ + GetDevice(); + + + + if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) { + if (debug) { + printf("Internal Error: texUnitState %d, bindTextureIDLen %d\n", + d3dCtx->texUnitStage, d3dCtx->bindTextureIdLen); + } + return; + } + + + INT currBindTex = d3dCtx->bindTextureId[d3dCtx->texUnitStage]; + + if ((currBindTex < 1) || + (currBindTex >= d3dCtx->textureTableLen)) { + if (debug) { + printf("Internal Error : UpdateTextureImage bind texture ID %d, textureTableLen %d, texUnitStage = %d \n", currBindTex, d3dCtx->textureTableLen, d3dCtx->texUnitStage); + } + return; + } + + LPDIRECT3DTEXTURE8 surf = d3dCtx->textureTable[currBindTex]; + + if (level == 0) { + if (surf != NULL) { + // see if no. of mipmap level change + + if (surf->GetLevelCount() != numLevels) { + d3dCtx->freeResource(surf); + d3dCtx->textureTable[currBindTex] = NULL; + surf = NULL; + } + } + + if (surf == NULL) { + // Need to create surface + surf = createTextureSurface(d3dCtx, numLevels, internalFormat, + width, height); + + if (surf == NULL) { + return; + } + + d3dCtx->textureTable[currBindTex] = surf; + } + } else { + if (surf == NULL) { + return; + } + } + + if ((level > 0) && (!d3dCtx->deviceInfo->supportMipmap)) { + if (debug) { + printf("mipmap not support\n"); + } + return; + } + + // update Image data + if (imageYup != NULL) { + if (format != FORMAT_USHORT_GRAY) { + jbyte *byteData = (jbyte *) env->GetPrimitiveArrayCritical(imageYup, NULL); + copyDataToSurface(format, internalFormat, 0, 0, 0, 0, + width, height, width, byteData, + surf, level); + env->ReleasePrimitiveArrayCritical(imageYup, byteData, 0); + + } else { + jshort *shortData = (jshort *) env->GetPrimitiveArrayCritical(imageYup, NULL); + copyDataToSurface(format, internalFormat, 0, 0, 0, 0, + width, height, width, shortData, + surf, level); + env->ReleasePrimitiveArrayCritical(imageYup, shortData, 0); + } + } + + + device->SetTexture(d3dCtx->texUnitStage, surf); +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture2DRetained_bindTexture( + JNIEnv *env, + jobject texture, + jlong ctx, + jint objectId, + jboolean enable) +{ + Java_javax_media_j3d_TextureRetained_bindTexture(env, texture, + ctx, objectId, enable); +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture2DRetained_updateTextureSubImage( + JNIEnv *env, + jobject texture, + jlong ctx, + jint level, + jint xoffset, + jint yoffset, + jint internalFormat, + jint storedFormat, + jint imgXOffset, + jint imgYOffset, + jint tilew, + jint width, + jint height, + jbyteArray image) +{ + Java_javax_media_j3d_TextureRetained_updateTextureSubImage( + env, texture, ctx, level, xoffset, yoffset, internalFormat, + storedFormat, imgXOffset, imgYOffset, tilew, width, height, image); +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture2DRetained_updateTextureImage( + JNIEnv *env, + jobject texture, + jlong ctx, + jint numLevels, + jint level, + jint internalFormat, + jint format, + jint width, + jint height, + jint boundaryWidth, + jbyteArray imageYup) +{ + Java_javax_media_j3d_TextureRetained_updateTextureImage(env, texture, + ctx, numLevels, level, internalFormat, format, + width, height, boundaryWidth, imageYup); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture2DRetained_updateDetailTextureParameters( + JNIEnv *env, + jobject texture, + jlong ctx, + jint detailTextureMode, + jint detailTextureLevel, + jint numPts, + jfloatArray funcPts) +{ + // Not support +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_bindTexture( + JNIEnv *env, + jobject texture, + jlong ctx, + jint objectId, + jboolean enable) +{ + GetDevice(); + + if ((d3dCtx->deviceInfo->maxTextureDepth <= 0) || + (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen)) { + return; + } + + if (!enable) { + device->SetTexture(d3dCtx->texUnitStage, NULL); + d3dCtx->bindTextureId[d3dCtx->texUnitStage] = -1; + } else { + if (d3dCtx->bindTextureId[d3dCtx->texUnitStage] == objectId) { + return; + } + if (objectId >= d3dCtx->volumeTableLen) { + DWORD i; + DWORD len = max(objectId+1, d3dCtx->volumeTableLen << 1); + LPDIRECT3DVOLUMETEXTURE8 *newTable = (LPDIRECT3DVOLUMETEXTURE8 *) + malloc(sizeof(LPDIRECT3DVOLUMETEXTURE8) * len); + + if (newTable == NULL) { + printf("Not enough memory to alloc volume texture table of size %d.\n", len); + return; + } + for (i=0; i < d3dCtx->volumeTableLen; i++) { + newTable[i] = d3dCtx->volumeTable[i]; + } + for (i=d3dCtx->volumeTableLen; i < len; i++) { + newTable[i] = NULL; + } + d3dCtx->volumeTableLen = len; + SafeFree(d3dCtx->volumeTable); + d3dCtx->volumeTable = newTable; + } + + d3dCtx->bindTextureId[d3dCtx->texUnitStage] = objectId; + if (d3dCtx->volumeTable[objectId] != NULL) { + device->SetTexture(d3dCtx->texUnitStage, + d3dCtx->volumeTable[objectId]); + } + // else we will bind this in updateTextureImage + } + +} + + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureFilterModes( + JNIEnv *env, + jobject texture, + jlong ctx, + jint minFilter, + jint magFilter) +{ + GetCtx(); + + if (d3dCtx->deviceInfo->maxTextureDepth > 0) { + Java_javax_media_j3d_TextureRetained_updateTextureFilterModes( + env, texture, ctx, minFilter, magFilter); + } +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureLodRange( + JNIEnv *env, + jobject texture, + jlong ctx, + jint baseLevel, + jint maximumLevel, + jfloat minimumLod, + jfloat maximumLod) +{ + // Not support +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureLodOffset( + JNIEnv *env, + jobject texture, + jlong ctx, + jfloat lodOffsetS, + jfloat lodOffsetT, + jfloat lodOffsetR) +{ + /* not supported */ +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureBoundary( + JNIEnv *env, + jobject texture, + jlong ctx, + jint boundaryModeS, + jint boundaryModeT, + jint boundaryModeR, + jfloat boundaryRed, + jfloat boundaryGreen, + jfloat boundaryBlue, + jfloat boundaryAlpha) +{ + + GetCtx(); + + if (d3dCtx->deviceInfo->maxTextureDepth > 0) { + + updateTextureBoundary( + env, texture, ctx, + boundaryModeS, + boundaryModeT, + boundaryModeR, + boundaryRed, + boundaryGreen, + boundaryBlue, + boundaryAlpha); + } +} + + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureImage( + JNIEnv *env, + jobject texture, + jlong ctx, + jint numLevels, + jint level, + jint internalFormat, + jint format, + jint width, + jint height, + jint depth, + jint boundaryWidth, + jbyteArray imageYup) +{ + + GetDevice(); + + if (d3dCtx->deviceInfo->maxTextureDepth <= 0) { + return; + } + + if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) { + if (debug) { + printf("Internal Error: texUnitState %d, bindTextureIDLen %d\n", + d3dCtx->texUnitStage, d3dCtx->bindTextureIdLen); + } + return; + } + + + INT currBindTex = d3dCtx->bindTextureId[d3dCtx->texUnitStage]; + + if ((currBindTex < 1) || + (currBindTex >= d3dCtx->volumeTableLen)) { + if (debug) { + printf("Internal Error : UpdateTexture3DImage bind texture ID %d, volumeTableLen %d, texUnitStage = %d \n", currBindTex, d3dCtx->volumeTableLen, d3dCtx->texUnitStage); + } + return; + } + + LPDIRECT3DVOLUMETEXTURE8 surf = d3dCtx->volumeTable[currBindTex]; + + if (level == 0) { + if (surf != NULL) { + // see if no. of mipmap level change + + if (surf->GetLevelCount() != numLevels) { + d3dCtx->freeResource(surf); + d3dCtx->volumeTable[currBindTex] = NULL; + surf = NULL; + } + } + + if (surf == NULL) { + surf = createVolumeTexture(d3dCtx, numLevels, internalFormat, + width, height, depth); + if (surf == NULL) { + return; + } + + d3dCtx->volumeTable[currBindTex] = surf; + } + } else { + if (surf == NULL) { + return; + } + } + + if ((level > 0) && (!d3dCtx->deviceInfo->supportMipmap)) { + if (debug) { + printf("mipmap not support\n"); + } + return; + } + + // update Image data + if (imageYup != NULL) { + if (format != FORMAT_USHORT_GRAY) { + jbyte *byteData = (jbyte *) env->GetPrimitiveArrayCritical(imageYup, NULL); + copyDataToVolume(format, internalFormat, 0, 0, 0, 0, 0, 0, + width, height, depth, width, height, byteData, + surf, level); + env->ReleasePrimitiveArrayCritical(imageYup, byteData, 0); + + } else { + jshort *shortData = (jshort *) env->GetPrimitiveArrayCritical(imageYup, NULL); + copyDataToVolume(format, internalFormat, 0, 0, 0, 0, 0, 0, + width, height, depth, width, height, shortData, + surf, level); + env->ReleasePrimitiveArrayCritical(imageYup, shortData, 0); + } + } + device->SetTexture(d3dCtx->texUnitStage, surf); + +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureSubImage( + JNIEnv *env, + jobject texture, + jlong ctx, + jint level, + jint xoffset, + jint yoffset, + jint zoffset, + jint internalFormat, + jint storedFormat, + jint imgXOffset, + jint imgYOffset, + jint imgZOffset, + jint tilew, + jint tileh, + jint width, + jint height, + jint depth, + jbyteArray image) +{ + GetDevice(); + + if ((d3dCtx->deviceInfo->maxTextureDepth <= 0) || + (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen)) { + return; + } + + INT currBindTex = d3dCtx->bindTextureId[d3dCtx->texUnitStage]; + + if ((currBindTex < 1) || + (currBindTex >= d3dCtx->volumeTableLen)) { + if (debug) { + printf("Internal Error : UpdateTexture3DSubImage bind texture ID %d, volumeableLen %d, texUnitStage = %d \n", currBindTex, d3dCtx->volumeTableLen, d3dCtx->texUnitStage); + } + return; + } + + LPDIRECT3DVOLUMETEXTURE8 surf = d3dCtx->volumeTable[currBindTex]; + + if ((surf == NULL) || + ((level > 0) && (!d3dCtx->deviceInfo->supportMipmap))) { + return; + } + + // update Image data + if (storedFormat != FORMAT_USHORT_GRAY) { + jbyte *byteData = (jbyte *) env->GetPrimitiveArrayCritical(image, NULL); + copyDataToVolume(storedFormat, internalFormat, xoffset, + yoffset, zoffset, imgXOffset, imgYOffset, + imgZOffset, width, height, depth, + tilew, tileh, byteData, + surf, level); + env->ReleasePrimitiveArrayCritical(image, byteData, 0); + + } else { + jshort *shortData = (jshort *) env->GetPrimitiveArrayCritical(image, NULL); + copyDataToVolume(storedFormat, internalFormat, xoffset, + yoffset, zoffset, + imgXOffset, imgYOffset, imgZOffset, + width, height, depth, tilew, tileh, shortData, + surf, level); + env->ReleasePrimitiveArrayCritical(image, shortData, 0); + } + +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_bindTexture( + JNIEnv *env, + jobject texture, + jlong ctx, + jint objectId, + jboolean enable) +{ + GetDevice(); + + if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) { + return; + } + + if (!enable) { + device->SetTexture(d3dCtx->texUnitStage, NULL); + d3dCtx->bindTextureId[d3dCtx->texUnitStage] = -1; + } else { + + if (d3dCtx->bindTextureId[d3dCtx->texUnitStage] == objectId) { + return; + } + + if (objectId >= d3dCtx->cubeMapTableLen) { + DWORD i; + DWORD len = max(objectId+1, d3dCtx->cubeMapTableLen << 1); + LPDIRECT3DCUBETEXTURE8 *newTable = (LPDIRECT3DCUBETEXTURE8 *) + malloc(sizeof(LPDIRECT3DCUBETEXTURE8) * len); + + if (newTable == NULL) { + printf("Not enough memory to alloc cubeMap table of size %d.\n", len); + return; + } + for (i=0; i < d3dCtx->cubeMapTableLen; i++) { + newTable[i] = d3dCtx->cubeMapTable[i]; + } + for (i=d3dCtx->cubeMapTableLen; i < len; i++) { + newTable[i] = NULL; + } + d3dCtx->cubeMapTableLen = len; + SafeFree(d3dCtx->cubeMapTable); + d3dCtx->cubeMapTable = newTable; + } + + d3dCtx->bindTextureId[d3dCtx->texUnitStage] = objectId; + if (d3dCtx->cubeMapTable[objectId] != NULL) { + device->SetTexture(d3dCtx->texUnitStage, + d3dCtx->cubeMapTable[objectId]); + } + // else we will bind this in updateTextureImage + } +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureFilterModes( + JNIEnv *env, + jobject texture, + jlong ctx, + jint minFilter, + jint magFilter) +{ + Java_javax_media_j3d_TextureRetained_updateTextureFilterModes(env, + texture, ctx, minFilter, magFilter); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureLodRange( + JNIEnv *env, + jobject texture, + jlong ctx, + jint baseLevel, + jint maximumLevel, + jfloat minimumLod, + jfloat maximumLod) +{ + // not support +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureLodOffset( + JNIEnv *env, + jobject texture, + jlong ctx, + jfloat lodOffsetS, + jfloat lodOffsetT, + jfloat lodOffsetR) +{ + /* not supported */ +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureBoundary( + JNIEnv *env, + jobject texture, + jlong ctx, + jint boundaryModeS, + jint boundaryModeT, + jfloat boundaryRed, + jfloat boundaryGreen, + jfloat boundaryBlue, + jfloat boundaryAlpha) +{ + updateTextureBoundary(env, texture, ctx, boundaryModeS, + boundaryModeT, -1, boundaryRed, + boundaryGreen, boundaryBlue, + boundaryAlpha); + +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureSubImage( + JNIEnv *env, + jobject texture, + jlong ctx, + jint face, + jint level, + jint xoffset, + jint yoffset, + jint internalFormat, + jint storedFormat, + jint imgXOffset, + jint imgYOffset, + jint tilew, + jint width, + jint height, + jbyteArray image) +{ + GetDevice(); + + if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) { + return; + } + + INT currBindTex = d3dCtx->bindTextureId[d3dCtx->texUnitStage]; + + if ((currBindTex < 1) || + (currBindTex >= d3dCtx->cubeMapTableLen)) { + if (debug) { + printf("Internal Error : UpdateCubeMapSubImage bind texture ID %d, cubeMapTableLen %d, texUnitStage = %d \n", currBindTex, d3dCtx->cubeMapTableLen, d3dCtx->texUnitStage); + } + return; + } + + LPDIRECT3DCUBETEXTURE8 surf = d3dCtx->cubeMapTable[currBindTex]; + + if ((surf == NULL) || + ((level > 0) && (!d3dCtx->deviceInfo->supportMipmap))) { + return; + } + + // update Image data + if (storedFormat != FORMAT_USHORT_GRAY) { + jbyte *byteData = (jbyte *) env->GetPrimitiveArrayCritical(image, NULL); + copyDataToCubeMap(storedFormat, internalFormat, + xoffset, yoffset, + imgXOffset, imgYOffset, + width, height, + tilew, byteData, + surf, level, face); + env->ReleasePrimitiveArrayCritical(image, byteData, 0); + + } else { + jshort *shortData = (jshort *) env->GetPrimitiveArrayCritical(image, NULL); + copyDataToCubeMap(storedFormat, internalFormat, + xoffset, yoffset, + imgXOffset, imgYOffset, + width, height, + tilew, shortData, + surf, level, face); + env->ReleasePrimitiveArrayCritical(image, shortData, 0); + } +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureImage( + JNIEnv *env, + jobject texture, + jlong ctx, + jint face, + jint numLevels, + jint level, + jint internalFormat, + jint format, + jint width, + jint height, + jint boundaryWidth, + jbyteArray imageYup) +{ + GetDevice(); + + if (d3dCtx->texUnitStage >= d3dCtx->bindTextureIdLen) { + if (debug) { + printf("Internal Error: texUnitState %d, bindTextureIDLen %d\n", + d3dCtx->texUnitStage, d3dCtx->bindTextureIdLen); + } + return; + } + + + INT currBindTex = d3dCtx->bindTextureId[d3dCtx->texUnitStage]; + + if ((currBindTex < 1) || + (currBindTex >= d3dCtx->cubeMapTableLen)) { + if (debug) { + printf("Internal Error : UpdateCubeMapImage bind texture ID %d, cubeMapTableLen %d, texUnitStage = %d \n", currBindTex, d3dCtx->cubeMapTableLen, d3dCtx->texUnitStage); + } + return; + } + + LPDIRECT3DCUBETEXTURE8 surf = d3dCtx->cubeMapTable[currBindTex]; + + if (level == 0) { + if (surf != NULL) { + // see if no. of mipmap level change + + if (surf->GetLevelCount() != numLevels) { + d3dCtx->freeResource(surf); + d3dCtx->cubeMapTable[currBindTex] = NULL; + surf = NULL; + } + } + + if (surf == NULL) { + // Need to create surface + surf = createCubeMapTexture(d3dCtx, numLevels, internalFormat, + width, height); + if (surf == NULL) { + return; + } + + d3dCtx->cubeMapTable[currBindTex] = surf; + } + } else { + if (surf == NULL) { + return; + } + } + + if ((level > 0) && (!d3dCtx->deviceInfo->supportMipmap)) { + if (debug) { + printf("mipmap not support\n"); + } + return; + } + + // update Image data + if (imageYup != NULL) { + if (format != FORMAT_USHORT_GRAY) { + jbyte *byteData = (jbyte *) env->GetPrimitiveArrayCritical(imageYup, NULL); + copyDataToCubeMap(format, internalFormat, 0, 0, 0, 0, + width, height, width, byteData, + surf, level, face); + env->ReleasePrimitiveArrayCritical(imageYup, byteData, 0); + + } else { + jshort *shortData = (jshort *) env->GetPrimitiveArrayCritical(imageYup, NULL); + copyDataToCubeMap(format, internalFormat, 0, 0, 0, 0, + width, height, width, shortData, + surf, level, face); + env->ReleasePrimitiveArrayCritical(imageYup, shortData, 0); + } + } + + device->SetTexture(d3dCtx->texUnitStage, surf); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_DetailTextureImage_bindTexture( + JNIEnv *env, + jobject texture, + jlong ctx, + jint objectId) +{ + // NOT SUPPORTED +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_DetailTextureImage_updateTextureImage( + JNIEnv *env, + jobject texture, + jlong ctx, + jint numLevels, + jint level, + jint internalFormat, + jint format, + jint width, + jint height, + jint boundaryWidth, + jbyteArray imageYup) +{ + // NOT SUPPORTED +} + +extern "C" JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_Canvas3D_decal1stChildSetup( + JNIEnv *env, + jobject obj, + jlong ctx) +{ + GetDevice2(); + + device->SetRenderState(D3DRS_STENCILENABLE, TRUE); + device->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 1.0, 0); + device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); + device->SetRenderState(D3DRS_STENCILREF, 0x1); + device->SetRenderState(D3DRS_STENCILMASK, 0x1); + device->SetRenderState(D3DRS_STENCILFAIL, + D3DSTENCILOP_KEEP); + device->SetRenderState(D3DRS_STENCILZFAIL, + D3DSTENCILOP_KEEP); + device->SetRenderState(D3DRS_STENCILPASS, + D3DSTENCILOP_REPLACE); + return d3dCtx->zEnable; +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_decalNthChildSetup( + JNIEnv *env, + jobject obj, + jlong ctx) + +{ + GetDevice(); + + d3dCtx->zEnable = FALSE; + device->SetRenderState(D3DRS_ZENABLE, FALSE); + device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL); + device->SetRenderState(D3DRS_STENCILREF, 0x1); + device->SetRenderState(D3DRS_STENCILMASK, 0x1); + device->SetRenderState(D3DRS_STENCILFAIL, + D3DSTENCILOP_KEEP); + device->SetRenderState(D3DRS_STENCILZFAIL, + D3DSTENCILOP_KEEP); + device->SetRenderState(D3DRS_STENCILPASS, + D3DSTENCILOP_KEEP); +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_decalReset( + JNIEnv *env, + jobject obj, + jlong ctx, + jboolean depthBufferEnable) +{ + GetDevice(); + + device->SetRenderState(D3DRS_STENCILENABLE, FALSE); + + if (depthBufferEnable) { + d3dCtx->zEnable = TRUE; + device->SetRenderState(D3DRS_ZENABLE, TRUE); + } +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_ctxUpdateEyeLightingEnable( + JNIEnv *env, + jobject obj, + jlong ctx, + jboolean localEyeLightingEnable) +{ + GetDevice(); + device->SetRenderState(D3DRS_LOCALVIEWER, localEyeLightingEnable); +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_activeTextureUnit( + JNIEnv *env, + jobject obj, + jlong ctx, + jint index) +{ + GetDevice(); + // If this index is greater than max support stage, + // then subsequence texture operation will ignore. + if (index < 0) { + index = 0; + } + + d3dCtx->texUnitStage = index; +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureUnitStateRetained_updateTextureUnitState( + JNIEnv *env, + jobject obj, + jlong ctx, + jint index, + jboolean enable) +{ + GetDevice(); + // If this index is greater than max support stage, + // then subsequence texture operation will ignore. + if (index <= 0) { + index = 0; + } + + d3dCtx->texUnitStage = index; + + if (!enable && (index < d3dCtx->bindTextureIdLen)) { + device->SetTexture(index, NULL); + d3dCtx->bindTextureId[index] = -1; + } +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setDepthFunc( + JNIEnv * env, + jobject obj, + jlong ctx, + jint func) +{ + GetDevice(); + + if (func == javax_media_j3d_RenderingAttributesRetained_LESS) { + device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); + } else if (func == + javax_media_j3d_RenderingAttributesRetained_LEQUAL) { + device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + } + +} + + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setBlendColor( + JNIEnv *env, + jobject obj, + jlong ctx, + jfloat colorRed, + jfloat colorGreen, + jfloat colorBlue, + jfloat colorAlpha) +{ + // Not support in D3D +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setBlendFunc( + JNIEnv * env, + jobject obj, + jlong ctx, + jint srcBlendFunction, + jint dstBlendFunction) +{ + GetDevice(); + + device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + device->SetRenderState(D3DRS_SRCBLEND, + blendFunctionTable[srcBlendFunction]); + device->SetRenderState(D3DRS_DESTBLEND, + blendFunctionTable[dstBlendFunction]); +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setFogEnableFlag( + JNIEnv * env, + jobject obj, + jlong ctx, + jboolean enable) +{ + GetDevice(); + + device->SetRenderState(D3DRS_FOGENABLE, enable); +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_updateSeparateSpecularColorEnable( + JNIEnv *env, + jobject obj, + jlong ctx, + jboolean enable) +{ +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_updateTexUnitStateMap( + JNIEnv *env, + jobject obj, + jlong ctx, + jint numActiveTexUnit, + jintArray texUnitStateMapArray) +{ + if ((texUnitStateMapArray != NULL) && (numActiveTexUnit > 0)) { + GetDevice(); + + jint* texUnitStateMap = (jint *) env->GetPrimitiveArrayCritical( + texUnitStateMapArray, NULL); + int genMode; + int ts; + for (int i = 0; i < numActiveTexUnit; i++) { + genMode = setTextureStage(d3dCtx, device, i, texUnitStateMap[i]); + if (genMode != TEX_GEN_AUTO) { + ts = d3dCtx->texStride[i]; + if (ts == 0) { + /* + In multiTexture case when no tex defined in non object + linear mode. + */ + ts = d3dCtx->texCoordFormat[i]; + } + } else { + ts = d3dCtx->texCoordFormat[i]; + } + setTexTransformStageFlag(d3dCtx, device, i, ts, genMode); + } + + env->ReleasePrimitiveArrayCritical(texUnitStateMapArray, + texUnitStateMap, 0); + } +} diff --git a/src/native/d3d/Canvas3D.cpp b/src/native/d3d/Canvas3D.cpp new file mode 100644 index 0000000..c262335 --- /dev/null +++ b/src/native/d3d/Canvas3D.cpp @@ -0,0 +1,1029 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include "StdAfx.h" + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setDrawActive( + JNIEnv *env, + jobject obj, + jint fd) +{ + // This function is only used for Solaris OpenGL +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_widSync( + JNIEnv *env, + jobject obj, + jint fd, + jint numWindows) +{ + // This function is only used for Solaris OpenGL +} + + + +extern "C" JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_Canvas3D_useSharedCtx( + JNIEnv *env, + jobject obj) +{ + return JNI_FALSE; +} + + + +extern "C" JNIEXPORT +jlong JNICALL Java_javax_media_j3d_Canvas3D_createContext( + JNIEnv *env, + jobject obj, + jlong display, + jint window, + jint vid, + jlong visInfo, + jlong sharedCtx, + jboolean isSharedCtx, + jboolean offScreen) +{ + HWND hwnd = WindowFromDC(reinterpret_cast(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(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(window)); + + lock(); + // always use offscreen for property since it + // makes no difference in D3D and this will also + // instruct initialize() to use offScreenWidth/Height + // instead of current window width/height to create + // context. + + D3dCtx* ctx = new D3dCtx(env, obj, hwnd, true, vid); + if (ctx == NULL) { + printf("%s", getErrorMessage(OUTOFMEMORY)); + unlock(); + return; + } + + ctx->offScreenWidth = width; + ctx->offScreenHeight = height; + + ctx->initialize(env, obj); + delete ctx; + unlock(); +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_useCtx( + JNIEnv *env, + jclass cl, + jlong ctx, + jlong display, + jint window) +{ + // D3D doesn't have notation of current context +} + + +extern "C" JNIEXPORT +jint JNICALL Java_javax_media_j3d_Canvas3D_getNumCtxLights( + JNIEnv *env, + jobject obj, + jlong ctx) +{ + GetDevice2(); + + int nlight = d3dCtx->deviceInfo->maxActiveLights; + if (nlight <= 0) { + // In emulation & referene mode, D3D return -1 + // work around by setting 8. + nlight = 8; + } + return nlight; +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_composite( + JNIEnv *env, + jobject obj, + jlong ctx, + jint px, + jint py, + jint minX, + jint minY, + jint maxX, + jint maxY, + jint rasWidth, + jbyteArray imageYdown, + jint winWidth, + jint winHeight) + +{ + GetDevice(); + + // However we use the following texturemapping function instead + // so this will not invoke. + if (d3dCtx->backSurface == NULL) { + device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, + &d3dCtx->backSurface); + } + jbyte *byteData = (jbyte *) (env->GetPrimitiveArrayCritical( + imageYdown, NULL)); + compositeDataToSurface(px, py, + minX, minY, maxX-minX, maxY-minY, + rasWidth, + byteData, d3dCtx->backSurface); + env->ReleasePrimitiveArrayCritical(imageYdown, byteData, 0); +} + +extern "C" JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_Canvas3D_initTexturemapping( + JNIEnv *env, + jobject texture, + jlong ctx, + jint texWidth, + jint texHeight, + jint objectId) +{ + GetCtx2(); + + + if ((objectId >= 0) && + (objectId < d3dCtx->textureTableLen) && + (d3dCtx->textureTable[objectId] != NULL)) { + // delete the previous texture reference + // when canvas resize + Java_javax_media_j3d_Canvas3D_freeTexture(env, + NULL, + ctx, + objectId); + } + + Java_javax_media_j3d_TextureRetained_bindTexture( + env, texture, ctx, objectId, TRUE); + + Java_javax_media_j3d_TextureRetained_updateTextureImage( + env, texture, ctx, 1, 0, J3D_RGBA, 0, texWidth, texHeight, 0, NULL); + + return (d3dCtx->textureTable[objectId] != NULL); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_texturemapping( + JNIEnv *env, + jobject texture, + jlong ctx, + jint px, + jint py, + jint minX, + jint minY, + jint maxX, + jint maxY, + jint texWidth, + jint texHeight, + jint rasWidth, + jint format, + jint objectId, + jbyteArray imageYdown, + jint winWidth, + jint winHeight) +{ + GetDevice(); + + Java_javax_media_j3d_TextureRetained_bindTexture( + env, texture, ctx, objectId, TRUE); + + + Java_javax_media_j3d_Texture2DRetained_updateTextureSubImage( + env, texture, ctx, 0, minX, minY, J3D_RGBA, format, + minX, minY, rasWidth, maxX-minX, maxY-minY, imageYdown); + + LPDIRECT3DTEXTURE8 surf = d3dCtx->textureTable[objectId]; + + if (surf == NULL) { + if (debug) { + printf("[Java 3D] Fail to apply texture in J3DGraphics2D !\n"); + } + return; + } + + D3DTLVERTEX screenCoord; + DWORD zcmpfunc; + + screenCoord.sx = (px + minX) - 0.5f; + screenCoord.sy = (py + minY) - 0.5f; + + // sz can be any number since we will disable z buffer + // However rhw can't be 0, otherwise texture will not shown + screenCoord.sz = 0.999f; + screenCoord.rhw = 1; + + DWORD blendEnable; + DWORD srcBlend; + DWORD dstBlend; + + // disable z buffer + device->GetRenderState(D3DRS_ZFUNC, &zcmpfunc); + device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); + + device->GetRenderState(D3DRS_ALPHABLENDENABLE, &blendEnable); + device->GetRenderState(D3DRS_SRCBLEND, &srcBlend); + device->GetRenderState(D3DRS_DESTBLEND, &dstBlend); + + device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + + drawTextureRect(d3dCtx, device, surf, screenCoord, + minX, minY, maxX, maxY, + maxX - minX, maxY - minY, false); + + Java_javax_media_j3d_TextureRetained_bindTexture( + env, texture, ctx, objectId, FALSE); + + device->SetRenderState(D3DRS_ALPHABLENDENABLE, blendEnable); + device->SetRenderState(D3DRS_SRCBLEND, srcBlend); + device->SetRenderState(D3DRS_DESTBLEND, dstBlend); + device->SetRenderState(D3DRS_ZFUNC, zcmpfunc); + device->SetRenderState(D3DRS_ZWRITEENABLE, + d3dCtx->zWriteEnable); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_clear( + JNIEnv *env, + jobject obj, + jlong ctx, + jfloat r, + jfloat g, + jfloat b, + jint winWidth, + jint winHeight, + jobject pa2d, + jint imageScaleMode, + jbyteArray pixels_obj) +{ + + GetDevice(); + + /* Java 3D always clears the Z-buffer */ + + if (!d3dCtx->zWriteEnable) { + device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); + } + + device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, + D3DCOLOR_COLORVALUE(r, g, b, 1.0f), 1.0, 0); + + if (pa2d) { + jclass pa2d_class = env->GetObjectClass(pa2d); + /* + jfieldID id = env->GetFieldID(pa2d_class, "surfaceDirty", "I"); + if (env->GetIntField(pa2d, id) == NOTLIVE) { + return; + } + */ + // It is possible that (1) Another user thread will free this + // image. (2) Another Renderer thread in case of multiple screen + // will invoke clear() at the same time. + lockBackground(); + + + jfieldID id = env->GetFieldID(pa2d_class, "hashId", "I"); + int hashCode = env->GetIntField(pa2d, id); + + D3dImageComponent *d3dImage = + D3dImageComponent::find(&BackgroundImageList, d3dCtx, hashCode); + + id = env->GetFieldID(pa2d_class, "width", "I"); + int width = env->GetIntField(pa2d, id); + id = env->GetFieldID(pa2d_class, "height", "I"); + int height = env->GetIntField(pa2d, id); + + LPDIRECT3DTEXTURE8 surf; + + if ((d3dImage == NULL) || (d3dImage->surf == NULL)) { + surf = createSurfaceFromImage(env, pa2d, ctx, + width, height, pixels_obj); + if (surf == NULL) { + if (d3dImage != NULL) { + D3dImageComponent::remove(&BackgroundImageList, d3dImage); + } + unlockBackground(); + return; + } + + if (d3dImage == NULL) { + d3dImage = + D3dImageComponent::add(&BackgroundImageList, d3dCtx, hashCode, surf); + } else { + // need to add this one because the new imageDirtyFlag may + // cause d3dImage->surf set to NULL + d3dImage->surf = surf; + } + } + + + D3DTLVERTEX screenCoord; + DWORD zcmpfunc; + boolean texModeRepeat; + int scaleWidth, scaleHeight; + float sw, sh; + + // sz can be any number since we already disable z buffer + // However rhw can't be 0, otherwise texture will not shown + screenCoord.sz = 0.999f; + screenCoord.rhw = 1; + + // disable z buffer + device->GetRenderState(D3DRS_ZFUNC, &zcmpfunc); + device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); + + switch (imageScaleMode){ + case javax_media_j3d_Background_SCALE_NONE: + screenCoord.sx = -0.5f; + screenCoord.sy = -0.5f; + scaleWidth = width; + scaleHeight = height; + texModeRepeat = FALSE; + break; + case javax_media_j3d_Background_SCALE_FIT_MIN: + screenCoord.sx = -0.5f; + screenCoord.sy = -0.5f; + sw = winWidth/(float) width; + sh = winHeight/(float) height; + if (sw >= sh) { + scaleWidth = width*sh; + scaleHeight = winHeight; + } else { + scaleWidth = winWidth; + scaleHeight = height*sw; + } + texModeRepeat = FALSE; + break; + case javax_media_j3d_Background_SCALE_FIT_MAX: + screenCoord.sx = -0.5f; + screenCoord.sy = -0.5f; + sw = winWidth/(float) width; + sh = winHeight/(float) height; + if (sw >= sh) { + scaleWidth = winWidth; + scaleHeight = height*sw; + } else { + scaleWidth = width*sh; + scaleHeight = winHeight; + } + texModeRepeat = FALSE; + break; + case javax_media_j3d_Background_SCALE_FIT_ALL: + screenCoord.sx = -0.5f; + screenCoord.sy = -0.5f; + scaleWidth = winWidth; + scaleHeight = winHeight; + texModeRepeat = FALSE; + break; + case javax_media_j3d_Background_SCALE_REPEAT: + screenCoord.sx = -0.5f; + screenCoord.sy = -0.5f; + scaleWidth = winWidth; + scaleHeight = winHeight; + texModeRepeat = TRUE; + break; + case javax_media_j3d_Background_SCALE_NONE_CENTER: + screenCoord.sx = (winWidth - width)/2.0f - 0.5f; + screenCoord.sy = (winHeight - height)/2.0f -0.5f; + scaleWidth = width; + scaleHeight = height; + texModeRepeat = FALSE; + break; + default: + printf("Unknown Background scale mode %d\n", imageScaleMode); + } + + drawTextureRect(d3dCtx, device, d3dImage->surf, + screenCoord, 0, 0, width, height, + scaleWidth, scaleHeight, texModeRepeat); + + device->SetRenderState(D3DRS_ZFUNC, zcmpfunc); + device->SetRenderState(D3DRS_ZWRITEENABLE, + d3dCtx->zWriteEnable); + unlockBackground(); + } else { + if (!d3dCtx->zWriteEnable) { + device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + } + } + + +} + + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setRenderMode( + JNIEnv *env, + jobject obj, + jlong ctx, + jint mode, + jboolean dbEnable) +{ + // D3D v8.0 doesn't support stereo +} + + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_clearAccum( + JNIEnv *env, + jobject obj, + jlong ctx) +{ + // D3D use full-scene antialiasing capbilities in device + // instead of accumulation buffer (which it didn't support) +} + + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_accum( + JNIEnv *env, + jobject obj, + jlong ctx, + jfloat value) +{ + // D3D use full-scene antialiasing capbilities in device + // instead of accumulation buffer (which didn't support) +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_accumReturn( + JNIEnv *env, + jobject obj, + jlong ctx) +{ + // D3D use full-scene antialiasing capbilities in device + // instead of accumulation buffer (which it didn't support) +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setDepthBufferWriteEnable( + JNIEnv *env, + jobject obj, + jlong ctx, + jboolean mode) +{ + GetDevice(); + + d3dCtx->zWriteEnable = mode; + device->SetRenderState(D3DRS_ZWRITEENABLE, mode); +} + + +VOID freePointerList() +{ + if (useFreePointerList0) { + if (freePointerList1.size() > 0) { + lockSurfaceList(); + for (void **p = freePointerList1.begin(); + p != freePointerList1.end(); ++p) { + delete (*p); + } + + freePointerList1.clear(); + unlockSurfaceList(); + } + useFreePointerList0 = false; + } else { + if (freePointerList0.size() > 0) { + lockSurfaceList(); + for (void **p = freePointerList0.begin(); + p != freePointerList0.end(); ++p) { + delete (*p); + } + + freePointerList0.clear(); + unlockSurfaceList(); + } + useFreePointerList0 = true; + + } +} + + +extern "C" JNIEXPORT +jint JNICALL Java_javax_media_j3d_Canvas3D_swapBuffers( + JNIEnv *env, + jobject obj, + jlong ctx, + jlong display, + jint win) +{ + GetDevice2(); + + int retCode = NOCHANGE; + + HRESULT hr = device->Present(NULL, NULL, NULL, NULL); + + if (FAILED(hr)) { + hr = device->TestCooperativeLevel(); + if (D3DERR_DEVICELOST == hr) { + return NOCHANGE; + } + if (D3DERR_DEVICENOTRESET == hr) { + if (debug) { + printf("Buffer swap error %s, try Reset() the surface... \n", + DXGetErrorString8(hr)); + } + retCode = d3dCtx->resetSurface(env, obj); + GetDevice2(); + hr = device->Present(NULL, NULL, NULL, NULL); + if (FAILED(hr)) { + if (debug) { + printf("Buffer swap error %s \n", + DXGetErrorString8(hr)); + } + } + } + + } + + d3dCtx->freeList(); + freePointerList(); + return retCode; +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_syncRender( + JNIEnv *env, + jobject obj, + jlong ctx, + jboolean waitFlag) +{ + // do nothing since D3D always wait in Blt +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_newDisplayList( + JNIEnv *env, + jobject obj, + jlong ctx, + jint id) +{ + GetCtx(); + + if (id <= 0) { + if (debug) { + printf("In Canvas3D.newDisplayList id pass in = %d !\n", id); + } + return; + } + + if (id >= d3dCtx->dlTableSize) { + int newSize = d3dCtx->dlTableSize << 1; + if (id >= newSize) { + newSize = id+1; + } + int i=0; + LPD3DDISPLAYLIST *newTable = new LPD3DDISPLAYLIST[newSize]; + + if (newTable == NULL) { + printf("%s", getErrorMessage(OUTOFMEMORY)); + exit(1); + } + // entry 0 is not used + newTable[0] = NULL; + while (++i < d3dCtx->dlTableSize) { + newTable[i] = d3dCtx->displayListTable[i]; + } + while (i < newSize) { + newTable[i++] = NULL; + } + d3dCtx->dlTableSize = newSize; + SafeDelete(d3dCtx->displayListTable); + d3dCtx->displayListTable = newTable; + } + + if (d3dCtx->displayListTable[id] != NULL) { + SafeDelete(d3dCtx->displayListTable[id]); + } + d3dCtx->displayListTable[id] = new D3dDisplayList(); + if (d3dCtx->displayListTable[id] == NULL) { + printf("%s", getErrorMessage(OUTOFMEMORY)); + exit(1); + } + d3dCtx->currDisplayListID = id; +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_endDisplayList( + JNIEnv *env, + jobject obj, + jlong ctx) +{ + GetDevice(); + d3dCtx->displayListTable[d3dCtx->currDisplayListID]->optimize(d3dCtx); + d3dCtx->currDisplayListID = 0; +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_callDisplayList( + JNIEnv *env, + jobject obj, + jlong ctx, + jint id, + jboolean isNonUniformScale) +{ + GetDevice(); + + // TODO: Remove this two safe checks when release + // d3dCtx->displayListTable[id]->render(d3dCtx); + + + if ((id <= 0) || (id >= d3dCtx->dlTableSize)) { + if (debug) { + if (id <= 0) { + printf("[Java 3D] Invalid Display List ID %d is invoked !\n", id); + } else { + printf("[Java 3D] Display List ID %d not yet initialize !\n", id); + } + } + return; + } + + LPD3DDISPLAYLIST dl = d3dCtx->displayListTable[id]; + + if (dl == NULL) { + if (debug) { + printf("[Java 3D] Display List ID %d not yet initialize !\n", id); + } + return; + } + dl->render(d3dCtx); + +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_freeDisplayList( + JNIEnv *env, + jclass cl, + jlong ctx, + jint id) +{ + GetCtx(); + + if ((id < 0) || (id >= d3dCtx->dlTableSize)) { + if (debug) { + printf("[Java 3D] FreeDisplayList, id %d not within table range %d!\n", id, + d3dCtx->dlTableSize); + } + return; + } + + SafeDelete(d3dCtx->displayListTable[id]); +} + + +/* + Native function to delete OGL texture object after j3d texture object + has been deleted by java garbage collector. + */ +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_freeTexture( + JNIEnv *env, + jclass cls, + jlong ctx, + jint id) +{ + GetDevice(); + + for (int i=0; i < d3dCtx->bindTextureIdLen; i++) { + if (d3dCtx->bindTextureId[i] == id) { + device->SetTexture(i, NULL); + d3dCtx->bindTextureId[i] = -1; + } + } + + if ((id >= d3dCtx->textureTableLen) || (id < 1)) { + if (debug) { + printf("Internal Error : freeTexture ID %d, textureTableLen %d \n", + id, d3dCtx->textureTableLen); + } + return; + } + + d3dCtx->freeResource(d3dCtx->textureTable[id]); + d3dCtx->textureTable[id] = NULL; +} + + +extern "C" JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_Canvas3D_isTexture3DAvailable( + JNIEnv *env, + jobject obj, + jlong ctx) +{ + return JNI_FALSE; +} + + +extern "C" JNIEXPORT +jint JNICALL Java_javax_media_j3d_Canvas3D_getTextureColorTableSize( + JNIEnv *env, + jobject obj, + jlong ctx) +{ + // Not support by D3D + return 0; +} + + +extern "C" JNIEXPORT +jint JNICALL Java_javax_media_j3d_Canvas3D_getTextureUnitCount( + JNIEnv *env, + jobject obj, + jlong ctx) +{ + GetCtx2(); + return d3dCtx->deviceInfo->maxTextureUnitStageSupport; +} + + +extern "C" JNIEXPORT +jint JNICALL Java_javax_media_j3d_Canvas3D_createOffScreenBuffer( + JNIEnv *env, + jobject obj, + jlong ctx, + jlong display, + jint vid, + jint width, + jint height) +{ + + + if (ctx == 0) { + // createContext() will be invoked later in Renderer + return 1; + } else { + GetCtx2(); + d3dCtx->d3dPresent.BackBufferWidth = width; + d3dCtx->d3dPresent.BackBufferHeight = height; + return SUCCEEDED(d3dCtx->resetSurface(env, obj)); + } +} + + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_destroyContext( + JNIEnv *env, + jclass cl, + jlong display, + jint window, + jlong ctx) +{ + GetDevice(); + + lock(); + d3dCtxList.erase(find(d3dCtxList.begin(), d3dCtxList.end(), d3dCtx)); + delete d3dCtx; + unlock(); + + Java_javax_media_j3d_Renderer_D3DCleanUp(env, cl); +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_destroyOffScreenBuffer( + JNIEnv *env, + jobject obj, + jlong ctx, + jlong display, + jint window) +{ + // do nothing, since the old buffer will destory + // in createOffScreenBuffer +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_readOffScreenBuffer( + JNIEnv *env, + jobject obj, + jlong ctx, + jint format, + jint width, + jint height) +{ + GetDevice(); + + if (format == FORMAT_USHORT_GRAY) { + printf("[Java 3D] readOffScreenBuffer not support FORMAT_USHORT_GRAY\n"); + return; + } + + if (d3dCtx->backSurface == NULL) { + HRESULT hr = device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, + &d3dCtx->backSurface); + if (FAILED(hr)) { + printf("[Java 3D] GetBackBuffer fail %s\n", + DXGetErrorString8(hr)); + return; + } + } + + jclass cv_class = env->GetObjectClass(obj); + + jfieldID byteData_field = env->GetFieldID(cv_class, "byteBuffer", "[B"); + jbyteArray byteData_array = (jbyteArray) env->GetObjectField(obj, byteData_field); + jbyte *byteData = (jbyte *) env->GetPrimitiveArrayCritical( + byteData_array, NULL); + + copyDataFromSurface(format, 0, 0, width, height, byteData, + d3dCtx->backSurface); + + env->ReleasePrimitiveArrayCritical(byteData_array, byteData, 0); + return; +} + + +extern "C" JNIEXPORT +jint JNICALL Java_javax_media_j3d_Canvas3D_resizeD3DCanvas( + JNIEnv *env, + jobject obj, + jlong ctx) +{ + int status; + + GetCtx2(); + lock(); + status = d3dCtx->resize(env, obj); + unlock(); + + return status; +} + + +extern "C" JNIEXPORT +jint JNICALL Java_javax_media_j3d_Canvas3D_toggleFullScreenMode( + JNIEnv *env, + jobject obj, + jlong ctx) +{ + int status; + + GetCtx2(); + lock(); + status = d3dCtx->toggleMode(!d3dCtx->bFullScreen, env, obj); + unlock(); + if (status == RECREATEDFAIL) { + return RECREATEDDRAW; + } + return status; +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setFullSceneAntialiasing( + JNIEnv *env, + jobject obj, + jlong ctx, + jboolean enable) +{ + GetDevice(); + + if (!implicitMultisample) { + device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, enable); + } +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Renderer_D3DCleanUp( + JNIEnv *env, + jobject obj) +{ + lock(); + if (d3dCtxList.empty()) { + D3dDriverInfo::release(); + } + unlock(); + + // Need to call it two times to free both list0 and list1 + freePointerList(); + freePointerList(); +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_ImageComponent2DRetained_freeD3DSurface( + JNIEnv *env, + jobject image, + jint hashCode) + +{ + + lockImage(); + D3dImageComponent::remove(&RasterList, hashCode); + unlockImage(); + lockBackground(); + D3dImageComponent::remove(&BackgroundImageList, hashCode); + unlockBackground(); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_beginScene( + JNIEnv *env, + jobject obj, + jlong ctx) +{ + GetDevice(); + device->BeginScene(); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_endScene( + JNIEnv *env, + jobject obj, + jlong ctx) +{ + GetDevice(); + device->EndScene(); +} + + +extern "C" JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_Canvas3D_validGraphicsMode( + JNIEnv *env, + jobject obj) +{ + DEVMODE devMode; + + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode); + return (devMode.dmBitsPerPel > 8); +} + diff --git a/src/native/d3d/CompressedGeometryRetained.cpp b/src/native/d3d/CompressedGeometryRetained.cpp new file mode 100644 index 0000000..413b33d --- /dev/null +++ b/src/native/d3d/CompressedGeometryRetained.cpp @@ -0,0 +1,39 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include "StdAfx.h" + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_CompressedGeometryRetained_execute + (JNIEnv *env, jobject obj, jlong ctx, jint version, jint bufferType, + jint bufferContents, jint renderFlags, jint offset, jint size, + jbyteArray geometry) +{ + // Not support by D3D, problem should not call this. + printf("Error: CompressedGeometryRetained execute should not invoke by D3D"); +} + +extern "C" JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_CompressedGeometryRetained_decompressByRef + (JNIEnv *env, jobject obj, jlong ctx) +{ + // Not support by D3D + return JNI_FALSE ; +} + +extern "C" JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_CompressedGeometryRetained_decompressHW + (JNIEnv *env, jobject obj, jlong ctx, jint majorVersion, jint minorVersion) +{ + // Not support by D3D + return JNI_FALSE ; +} diff --git a/src/native/d3d/D3dCtx.cpp b/src/native/d3d/D3dCtx.cpp new file mode 100644 index 0000000..9072a3f --- /dev/null +++ b/src/native/d3d/D3dCtx.cpp @@ -0,0 +1,1793 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include "Stdafx.h" + +D3dCtxVector d3dCtxList; + +/* + * Use the following code to initialize ctx property : + * + * D3dCtx ctx* = new D3dCtx(env, obj, hwnd, offScreen, vid); + * if (ctx->initialize(env, obj)) { + * delete ctx; + * } + * d3dCtxList.push_back(ctx); + * + * + * When ctx remove : + * + * d3dCtxList.erase(find(d3dCtxList.begin(), d3dCtxList.end(), ctx); + * delete ctx; + * + */ + +const D3DXMATRIX identityMatrix = D3DXMATRIX(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + +D3dCtx::D3dCtx(JNIEnv* env, jobject obj, HWND _hwnd, BOOL _offScreen, + jint vid) +{ + int i; + + monitor = NULL; + hwnd = _hwnd; + pD3D = NULL; + pDevice = NULL; + offScreen = _offScreen; + offScreenWidth = 0; + offScreenHeight = 0; + + driverInfo = NULL; + deviceInfo = NULL; + + depthStencilSurface = NULL; + frontSurface = NULL; + backSurface = NULL; + resetColorTarget = false; + forceResize = false; + inToggle = false; + useFreeList0 = true; + reIndexifyTable = NULL; + + // set default RenderingState variable + cullMode = D3DCULL_CW; + fillMode = D3DFILL_SOLID; + zWriteEnable = TRUE; + zEnable = TRUE; + + // this is the pixelFormat return from NativeConfigTemplate. + minZDepth = vid & 0x3fffffff; + if (vid & 0x80000000) { + antialiasing = REQUIRED; + } else if (vid & 0x40000000) { + antialiasing = PREFERRED; + } else { + antialiasing = UNNECESSARY; + } + + setFullScreenFromProperty(env); + + if (offScreen) { + // disable fullscreen mode for offscreen + bFullScreen = false; + bFullScreenRequired = false; + } + + dlTableSize = DISPLAYLIST_INITSIZE; + displayListTable = new LPD3DDISPLAYLIST[dlTableSize]; + if (displayListTable == NULL) { + error(OUTOFMEMORY); + exit(1); + } + for (i=0; i < dlTableSize; i++) { + displayListTable[i] = NULL; + } + + currDisplayListID = 0; + quadIndexBuffer = NULL; + quadIndexBufferSize = 0; + lineModeIndexBuffer = NULL; + + srcVertexBuffer = NULL; + dstVertexBuffer = NULL; + + + multiTextureSupport = false; + texUnitStage = 0; + twoSideLightingEnable = false; + bindTextureId = NULL; + bindTextureIdLen = 0; + + textureTable = (LPDIRECT3DTEXTURE8 *) malloc( + sizeof(LPDIRECT3DTEXTURE8) * TEXTURETABLESIZE); + + if (textureTable == NULL) { + error(OUTOFMEMORY); + exit(1); + } + ZeroMemory(textureTable, sizeof(LPDIRECT3DTEXTURE8)*TEXTURETABLESIZE); + textureTableLen = TEXTURETABLESIZE; + + bindTextureId = NULL; + + volumeTable = (LPDIRECT3DVOLUMETEXTURE8 *) malloc( + sizeof(LPDIRECT3DVOLUMETEXTURE8) * TEXTURETABLESIZE); + + if (volumeTable == NULL) { + error(OUTOFMEMORY); + exit(1); + } + ZeroMemory(volumeTable, sizeof(LPDIRECT3DVOLUMETEXTURE8)*TEXTURETABLESIZE); + volumeTableLen = TEXTURETABLESIZE; + + + cubeMapTable = (LPDIRECT3DCUBETEXTURE8 *) malloc( + sizeof(LPDIRECT3DCUBETEXTURE8) * TEXTURETABLESIZE); + + if (cubeMapTable == NULL) { + error(OUTOFMEMORY); + exit(1); + } + ZeroMemory(cubeMapTable, sizeof(LPDIRECT3DCUBETEXTURE8)*TEXTURETABLESIZE); + cubeMapTableLen = TEXTURETABLESIZE; + + + if (hwnd == 0) { + // Offscreen rendering + hwnd = GetDesktopWindow(); + topHwnd = hwnd; + } else { + topHwnd = getTopWindow(hwnd); + } + + if (d3dDriverList == NULL) { + + // keep trying to initialize even though + // last time it fail. + D3dDriverInfo::initialize(env); + } + + if (d3dDriverList == NULL) { + /* + * This happen when either + * (1) D3D v8.0 not install or + * (2) Not enough memory or + * (3) No adapter found in the system. + */ + SafeRelease(pD3D); + return; + } + + pD3D = Direct3DCreate8( D3D_SDK_VERSION ); + + if (pD3D == NULL) { + error(D3DNOTFOUND); + return; + } + // find current monitor handle before + // get current display mode + monitor = findMonitor(); + + // check current display mode + enumDisplayMode(&devmode); + + if (devmode.dmBitsPerPel < 16) { + // tell user switch to at least 16 bit color next time + warning(NEEDSWITCHMODE); + } + + // find the adapter for this + setDriverInfo(); + + GetWindowRect(topHwnd, &savedTopRect); + winStyle = GetWindowLong(topHwnd, GWL_STYLE); + + for (i=0; i < 4; i++) { + rasterRect[i].sx = 0; + rasterRect[i].sy = 0; + rasterRect[i].sz = 0; + rasterRect[i].rhw = 0; + } + + rasterRect[0].tu = 0; + rasterRect[0].tv = 1; + rasterRect[1].tu = 0; + rasterRect[1].tv = 0; + rasterRect[2].tu = 1; + rasterRect[2].tv = 1; + rasterRect[3].tu = 1; + rasterRect[3].tv = 0; + + // initialize Ambient Material + ambientMaterial.Power = 0; + CopyColor(ambientMaterial.Emissive, 0, 0, 0, 1.0f); + CopyColor(ambientMaterial.Diffuse, 0, 0, 0, 1.0f); + CopyColor(ambientMaterial.Ambient, 1.0f, 1.0f, 1.0f, 1.0f); + CopyColor(ambientMaterial.Specular, 0, 0, 0, 1.0f); + GetWindowRect(hwnd, &windowRect); +} + +D3dCtx::~D3dCtx() +{ + release(); + SafeRelease(pD3D); +} + +VOID D3dCtx::releaseTexture() +{ + + for (int i=0; i < bindTextureIdLen; i++) { + if (bindTextureId[i] > 0) { + pDevice->SetTexture(i, NULL); + } + } + + lockSurfaceList(); + if (textureTable != NULL) { + // free all textures + for (int i=0; i < textureTableLen; i++) { + SafeRelease(textureTable[i]); + } + SafeFree(textureTable); + } + + if (volumeTable != NULL) { + for (int i=0; i < volumeTableLen; i++) { + SafeRelease(volumeTable[i]); + } + SafeFree(volumeTable); + + } + + + if (cubeMapTable != NULL) { + for (int i=0; i < cubeMapTableLen; i++) { + SafeRelease(cubeMapTable[i]); + } + SafeFree(cubeMapTable); + + } + + textureTableLen = 0; + volumeTableLen = 0; + cubeMapTableLen = 0; + unlockSurfaceList(); + + lockImage(); + D3dImageComponent::remove(&RasterList, this); + unlockImage(); + + lockBackground(); + D3dImageComponent::remove(&BackgroundImageList, this); + unlockBackground(); + + // free list0 + freeList(); + // free list1 + freeList(); +} + +VOID D3dCtx::setViewport() +{ + int renderWidth = getWidth(); + int renderHeight = getHeight(); + HRESULT hr; + D3DVIEWPORT8 vp = {0, 0, renderWidth, renderHeight, 0.0f, 1.0f}; + + hr = pDevice->SetViewport( &vp ); + + if (FAILED(hr)) { + // Use the previous Viewport if fail + error(VIEWPORTFAIL, hr); + } +} + +VOID D3dCtx::releaseVB() +{ + + if (displayListTable != NULL) { + // entry 0 is not used + for (int i=1; i < dlTableSize; i++) { + SafeDelete(displayListTable[i]); + } + SafeFree(displayListTable); + dlTableSize = 0; + } + + + lockGeometry(); + + D3dVertexBuffer *p = vertexBufferTable.next; + D3dVertexBuffer *q, **r; + D3dVertexBufferVector *vbVector; + boolean found = false; + + while (p != NULL) { + vbVector = p->vbVector; + if (vbVector != NULL) { + for (r = vbVector->begin(); r != vbVector->end(); ++r) { + if (*r == p) { + vbVector->erase(r); + found = true; + break; + } + } + } + q = p; + p = p->next; + delete q; + } + + vertexBufferTable.next = NULL; + + freeVBList0.clear(); + freeVBList1.clear(); + + unlockGeometry(); + +} + +VOID D3dCtx::release() +{ + D3dImageComponent::removeAll(&BackgroundImageList); + D3dImageComponent::removeAll(&RasterList); + releaseTexture(); + SafeFree(bindTextureId); + bindTextureIdLen = 0; + + + SafeRelease(srcVertexBuffer); + SafeRelease(dstVertexBuffer); + SafeRelease(quadIndexBuffer); + SafeRelease(lineModeIndexBuffer); + quadIndexBufferSize = 0; + releaseVB(); + + // trying to free VertexBuffer + // This will crash the driver if Indices/StreamSource + // Not set before. + // pDevice->SetIndices(NULL, 0); + // pDevice->SetStreamSource(0, NULL, 0); + SafeRelease(depthStencilSurface); + SafeRelease(frontSurface); + SafeRelease(backSurface); + + SafeRelease(pDevice); + currDisplayListID = 0; + multiTextureSupport = false; + texUnitStage = 0; + twoSideLightingEnable = false; + freePointerList(); + freePointerList(); +} + + + +/* + * Application should delete ctx when this function return false. + */ +BOOL D3dCtx::initialize(JNIEnv *env, jobject obj) +{ + HRESULT hr; + // int oldWidth, oldHeight; + // BOOL needBiggerRenderSurface = false; + + // It is possible that last time Emulation mode is used. + // If this is the case we will try Hardware mode first. + deviceInfo = setDeviceInfo(driverInfo, &bFullScreen, minZDepth); + + if ((pD3D == NULL) || (driverInfo == NULL)) { + return false; + } + /* + if (offScreenWidth > driverInfo->desktopMode.Width) { + if (debug) { + printf("OffScreen width cannot greater than %d\n", + driverInfo->desktopMode.Width); + } + oldWidth = offScreenWidth; + offScreenWidth = driverInfo->desktopMode.Width; + needBiggerRenderSurface = true; + + } + + if (offScreenHeight > driverInfo->desktopMode.Height) { + if (debug) { + printf("OffScreen Height cannot greater than %d\n", + driverInfo->desktopMode.Height); + } + oldHeight = offScreenHeight; + offScreenHeight = driverInfo->desktopMode.Height; + needBiggerRenderSurface = true; + } + */ + + if (!bFullScreen) { + getScreenRect(hwnd, &savedClientRect); + CopyMemory(&screenRect, &savedClientRect, sizeof (RECT)); + } + + dwBehavior = findBehavior(); + + if (debug) { + printf("Use %s, ", driverInfo->adapterIdentifier.Description); + + if (deviceInfo->isHardwareTnL && + (dwBehavior == D3DCREATE_SOFTWARE_VERTEXPROCESSING)) { + // user select non-TnL device + printf("Hardware Rasterizer\n"); + } else { + printf("%s \n", deviceInfo->deviceName); + } + } + + setPresentParams(env, obj); + + if (debug) { + printf("\nCreate device :\n"); + printInfo(&d3dPresent); + } + + + if ((d3dPresent.BackBufferWidth <= 0) || + (d3dPresent.BackBufferHeight <= 0)) { + if (debug) { + printf("D3D: Can't create device of buffer size %dx%d\n", + d3dPresent.BackBufferWidth, + d3dPresent.BackBufferHeight); + } + return false; + } + + hr = pD3D->CreateDevice(driverInfo->iAdapter, + deviceInfo->deviceType, + topHwnd, + dwBehavior, + &d3dPresent, + &pDevice); + + if (FAILED(hr) && (requiredDeviceID < 0)) { + if (deviceInfo->deviceType != D3DDEVTYPE_REF) { + // switch to reference mode + warning(CREATEDEVICEFAIL, hr); + deviceInfo = driverInfo->d3dDeviceList[DEVICE_REF]; + dwBehavior = findBehavior(); + deviceInfo->findDepthStencilFormat(minZDepth); + d3dPresent.AutoDepthStencilFormat = + deviceInfo->depthStencilFormat; + if (deviceInfo->depthStencilFormat == D3DFMT_UNKNOWN) { + // should not happen since reference mode will + // support all depth stencil format + error(DEPTHSTENCILNOTFOUND); + return false; + } + if (debug) { + printf("Fallback to create reference device :\n"); + printInfo(&d3dPresent); + } + + hr = pD3D->CreateDevice(driverInfo->iAdapter, + deviceInfo->deviceType, + topHwnd, + dwBehavior, + &d3dPresent, + &pDevice); + } + } + + /* + if (offScreen && needBiggerRenderSurface) { + IDirect3DSurface8 *pRenderTarget; + IDirect3DSurface8 *pStencilDepthTarget; + + hr = pDevice->CreateRenderTarget(oldWidth, + oldHeight, + driverInfo->desktopMode.Format, + D3DMULTISAMPLE_NONE, + true, + &pRenderTarget); + + if (FAILED(hr)) { + printf("Fail to CreateRenderTarget %s\n", DXGetErrorString8(hr)); + } else { + hr = pDevice->CreateDepthStencilSurface(oldWidth, + oldHeight, + deviceInfo->depthStencilFormat, + D3DMULTISAMPLE_NONE, + &pStencilDepthTarget); + if (FAILED(hr)) { + printf("Fail to CreateDepthStencilSurface %s\n", DXGetErrorString8(hr)); + pRenderTarget->Release(); + } else { + hr = pDevice->SetRenderTarget(pRenderTarget, + pStencilDepthTarget); + if (FAILED(hr)) { + printf("Fail to SetRenderTarget %s\n", DXGetErrorString8(hr)); + pRenderTarget->Release(); + pStencilDepthTarget->Release(); + } else { + printf("Successfully set bigger buffer\n"); + } + } + } + } + */ + + + setWindowMode(); + + if (FAILED(hr)) { + release(); + if (!inToggle) { + error(CREATEREFDEVICEFAIL, hr); + } else { + warning(CREATEREFDEVICEFAIL, hr); + } + return false; + } + + if (deviceInfo != NULL) { + bindTextureIdLen = deviceInfo->maxTextureUnitStageSupport; + } else { + bindTextureIdLen = 1; + } + + jclass canvasCls = env->GetObjectClass(obj); + jfieldID id = env->GetFieldID(canvasCls, "numTexCoordSupported", "I"); + env->SetIntField(obj, id, TEXSTAGESUPPORT); + + if (bindTextureIdLen > 1) { + if (bindTextureIdLen > TEXSTAGESUPPORT) { + // D3D only support max. 8 stages. + bindTextureIdLen = TEXSTAGESUPPORT; + } + multiTextureSupport = true; + id = env->GetFieldID(canvasCls, "multiTexAccelerated", "Z"); + env->SetBooleanField(obj, id, JNI_TRUE); + id = env->GetFieldID(canvasCls, "numTexUnitSupported", "I"); + env->SetIntField(obj, id, bindTextureIdLen); + } else { + bindTextureIdLen = 1; + } + + bindTextureId = (INT *) malloc(sizeof(INT) * bindTextureIdLen); + if (bindTextureId == NULL) { + release(); + error(OUTOFMEMORY); + return false; + } + + setViewport(); + setDefaultAttributes(); + + createVertexBuffer(); + + if (debug && (deviceInfo != NULL)) { + if (multiTextureSupport) { + printf("Max Texture Unit Stage support : %d \n", + deviceInfo->maxTextureBlendStages); + + printf("Max Simultaneous Texture unit support : %d \n", + deviceInfo->maxSimultaneousTextures); + } else { + printf("MultiTexture support : false\n"); + } + } + return true; +} + +// canvas size change, get new back buffer +INT D3dCtx::resize(JNIEnv *env, jobject obj) +{ + int retValue; + + if ((pDevice == NULL) || bFullScreen) { + return false; // not yet ready when startup + } + + if (forceResize) { + // ignore first resize request after screen toggle + forceResize = false; + return NOCHANGE; + } + // we don't want resize to do twice but when window toggle + // between fullscreen and window mode, the move event will got + // first. Thus it will get size correctly without doing resize. + + BOOL moveRequest; + + + GetWindowRect(hwnd, &windowRect); + + if ((windowRect.right == screenRect.right) && + (windowRect.left == screenRect.left) && + (windowRect.bottom == screenRect.bottom) && + (windowRect.top == screenRect.top)) { + return NOCHANGE; + } + + if (((windowRect.left - windowRect.right) + == (screenRect.left - screenRect.right)) && + ((windowRect.bottom - windowRect.top) + == (screenRect.bottom - screenRect.top))) { + moveRequest = true; + } else { + moveRequest = false; + } + + + HMONITOR oldMonitor = monitor; + monitor = findMonitor(); + + getScreenRect(hwnd, &screenRect); + + if (monitor != oldMonitor) { + enumDisplayMode(&devmode); + setDriverInfo(); + release(); + initialize(env, obj); + return RECREATEDDRAW; + } + + if (!moveRequest) { + + retValue = resetSurface(env, obj); + if (retValue != RECREATEDFAIL) { + return retValue; + } else { + return RECREATEDDRAW; + } + } + return NOCHANGE; +} + + +INT D3dCtx::toggleMode(BOOL _bFullScreen, JNIEnv *env, jobject obj) +{ + INT retValue; + + if ((pDevice == NULL) || + (!_bFullScreen && + !deviceInfo->canRenderWindowed)) { + // driver did not support window mode + return NOCHANGE; + } + + int onScreenCount = 0; + + for (D3dCtx **p = d3dCtxList.begin(); p != d3dCtxList.end(); p++) { + if (!(*p)->offScreen && + // (monitor == (*p)->monitor) && + (++onScreenCount > 1)) { + // don't toggle if there are more than one onScreen ctx exists + // in the same screen + return false; + } + } + + + inToggle = true; + bFullScreen = _bFullScreen; + + retValue = resetSurface(env, obj); + + if (retValue != RECREATEDFAIL) { + forceResize = true; + } else { + // Switch back to window mode if fall to toggle fullscreen + // and vice versa + bFullScreen = !bFullScreen; + release(); + if (initialize(env, obj)) { + retValue = RECREATEDDRAW; + forceResize = true; + } else { + retValue = RECREATEDFAIL; + } + } + if (retValue != RECREATEDFAIL) { + setViewport(); + } + + inToggle = false; + return retValue; +} + +VOID D3dCtx::setPresentParams(JNIEnv *env, jobject obj) +{ + setCanvasProperty(env, obj); + + d3dPresent.AutoDepthStencilFormat = deviceInfo->depthStencilFormat; + d3dPresent.EnableAutoDepthStencil = true; + + if ((antialiasing != UNNECESSARY) && + deviceInfo->supportAntialiasing()) { + d3dPresent.MultiSampleType = deviceInfo->getBestMultiSampleType(); + } else { + d3dPresent.MultiSampleType = D3DMULTISAMPLE_NONE; + } + d3dPresent.BackBufferCount = 1; + d3dPresent.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; + + // We can't use Discard, otherwise readRaster will fail as + // content of backbuffer will discard after swap unless + // we always call readRaster() just before swap. + // However in this way we can't use multisample effect + + + if (bFullScreen) { + GetWindowRect(topHwnd, &savedTopRect); + GetWindowRect(hwnd, &savedClientRect); + + d3dPresent.Windowed = false; + d3dPresent.hDeviceWindow = topHwnd; + + if ((antialiasing != UNNECESSARY) && + deviceInfo->supportAntialiasing()) { + d3dPresent.SwapEffect = D3DSWAPEFFECT_DISCARD; + } else { + d3dPresent.SwapEffect = D3DSWAPEFFECT_FLIP; + } + d3dPresent.BackBufferWidth = driverInfo->desktopMode.Width; + d3dPresent.BackBufferHeight = driverInfo->desktopMode.Height; + d3dPresent.BackBufferFormat = driverInfo->desktopMode.Format; + d3dPresent.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + d3dPresent.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE; + + } else { + d3dPresent.Windowed = true; + d3dPresent.hDeviceWindow = hwnd; + + if ((antialiasing != UNNECESSARY) && + deviceInfo->supportAntialiasing()) { + d3dPresent.SwapEffect = D3DSWAPEFFECT_DISCARD; + } else { + d3dPresent.SwapEffect = D3DSWAPEFFECT_COPY; + } + d3dPresent.BackBufferWidth = getWidth(); + d3dPresent.BackBufferHeight = getHeight(); + d3dPresent.BackBufferFormat = driverInfo->desktopMode.Format; + d3dPresent.FullScreen_RefreshRateInHz = 0; + d3dPresent.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + + } + +} + +INT D3dCtx::resetSurface(JNIEnv *env, jobject obj) +{ + D3dDeviceInfo* oldDevice = deviceInfo; + HRESULT hr; + + + deviceInfo = setDeviceInfo(driverInfo, &bFullScreen, minZDepth); + + if (deviceInfo == NULL) { + return NOCHANGE; + } + if (deviceInfo != oldDevice) { + // we fall back to Reference mode last time, + // try to see if we can run in hardware mode after + // the surface size change. + release(); + if (initialize(env, obj)) { + return RECREATEDDRAW; + } else { + return RECREATEDFAIL; + } + } else { + setPresentParams(env, obj); + if (debug) { + printf("\nReset Device :\n"); + printInfo(&d3dPresent); + } + + // Must release any non default pool surface, otherwise + // Reset() will fail + SafeRelease(depthStencilSurface); + SafeRelease(frontSurface); + SafeRelease(backSurface); + + releaseVB(); + SafeRelease(lineModeIndexBuffer); + quadIndexBufferSize = 0; + + hr = pDevice->Reset(&d3dPresent); + if (FAILED(hr)) { + warning(RESETFAIL, hr); + // try to recreate Surface, if still fail, try Reference mode + release(); + if (initialize(env, obj)) { + return RECREATEDDRAW; + } else { + return RECREATEDFAIL; + } + } else { + setWindowMode(); + setDefaultAttributes(); + return RESETSURFACE; + } + } + + return NOCHANGE; +} + + +VOID D3dCtx::error(int idx) +{ + error(getErrorMessage(idx)); +} + +VOID D3dCtx::error(int idx, HRESULT hr) +{ + error(getErrorMessage(idx), hr); +} + + +VOID D3dCtx::warning(int idx) +{ + printf("%s\n", getErrorMessage(idx)); +} + +VOID D3dCtx::warning(int idx, HRESULT hr) +{ + printf("%s - %s\n", getErrorMessage(idx), DXGetErrorString8(hr)); +} + + +VOID D3dCtx::error(char *s) +{ + showError(hwnd, s, bFullScreen); +} + +VOID D3dCtx::error(char *s, HRESULT hr) +{ + char message[400]; + sprintf(message, "%s - %s", s, DXGetErrorString8(hr)); + showError(hwnd, message, bFullScreen); +} + + +VOID D3dCtx::d3dWarning(int idx) +{ + printf("%s\n", getErrorMessage(idx)); +} + +VOID D3dCtx::d3dWarning(int idx, HRESULT hr) +{ + printf("%s - %s\n", + getErrorMessage(idx), DXGetErrorString8(hr)); + +} + +VOID D3dCtx::d3dError(char *s) +{ + showError(GetDesktopWindow(), s, false); +} + + +VOID D3dCtx::d3dError(int idx) +{ + d3dError(getErrorMessage(idx)); +} + + +// Only display message box for the first error, since +// Java3D will continue to invoke createContext() when it fail +VOID D3dCtx::showError(HWND hwnd, char *s, BOOL bFullScreen) +{ + if (firstError) { + firstError = false; + if (bFullScreen) { + // In full screen mode, we can't see message box + printf("[Java 3D] %s\n", s); + exit(1); + } else { + MessageBox(hwnd, s, "Java 3D", MB_OK|MB_ICONERROR); + } + } +} + + +DWORD D3dCtx::getWidth() +{ + if (!offScreen) { + return screenRect.right - screenRect.left; + } else { + return offScreenWidth; + } + +} + + +DWORD D3dCtx::getHeight() +{ + if (!offScreen) { + return screenRect.bottom - screenRect.top; + } else { + return offScreenHeight; + } + +} + +D3dDeviceInfo* D3dCtx::selectDevice(int deviceID, + D3dDriverInfo *driverInfo, + BOOL *bFullScreen, + int minZDepth) +{ + D3dDeviceInfo *pDevice; + + for (int i=0; i < numDeviceTypes; i++) { + pDevice = driverInfo->d3dDeviceList[i]; + if ((((deviceID == DEVICE_HAL) || (deviceID == DEVICE_HAL_TnL)) && + (pDevice->deviceType == D3DDEVTYPE_HAL)) || + (deviceID == DEVICE_REF) && + (pDevice->deviceType == D3DDEVTYPE_REF)) { + if ((*bFullScreen && !pDevice->fullscreenCompatible) || + (!*bFullScreen && !pDevice->desktopCompatible)) { + if (pDevice->deviceType == D3DDEVTYPE_HAL) { + d3dError(HALDEVICENOTFOUND); + } else { + // should not happen, REF device always support + d3dError(DEVICENOTFOUND); + } + exit(1); + } + if (pDevice->maxZBufferDepthSize == 0) { + if (pDevice->deviceType == D3DDEVTYPE_HAL) { + d3dError(HALNOTCOMPATIBLE); + } else { + // should not happen, REF device always support + d3dError(DEVICENOTFOUND); + } + exit(1); + } + if (pDevice->deviceType == D3DDEVTYPE_HAL) { + if ((deviceID == DEVICE_HAL_TnL) && + !pDevice->isHardwareTnL) { + d3dError(TNLHALDEVICENOTFOUND); + exit(1); + } + } + pDevice->findDepthStencilFormat(minZDepth); + if (pDevice->depthStencilFormat == D3DFMT_UNKNOWN) { + d3dError(DEPTHSTENCILNOTFOUND); + exit(1); + } + return pDevice; + } + } + + + // should not happen + d3dError(DEVICENOTFOUND); + exit(1); +} + + + +D3dDeviceInfo* D3dCtx::selectBestDevice(D3dDriverInfo *driverInfo, + BOOL *bFullScreen, int minZDepth) +{ + D3dDeviceInfo *pDevice; + D3dDeviceInfo *bestDevice = NULL; + int i; + + for (i=0; i < numDeviceTypes; i++) { + pDevice = driverInfo->d3dDeviceList[i]; + if (pDevice->maxZBufferDepthSize > 0) { + pDevice->findDepthStencilFormat(minZDepth); + + if (pDevice->depthStencilFormat == D3DFMT_UNKNOWN) { + if (pDevice->deviceType == D3DDEVTYPE_REF) { + d3dError(DEPTHSTENCILNOTFOUND); + return NULL; + } else { + continue; + } + } + if (*bFullScreen) { + if (pDevice->fullscreenCompatible) { + bestDevice = pDevice; + break; + } + } else { + if (pDevice->canRenderWindowed) { + if (pDevice->desktopCompatible) { + bestDevice = pDevice; + break; + } + } else { + if (pDevice->fullscreenCompatible) { + // switch to fullscreen mode + *bFullScreen = true; + bestDevice = pDevice; + break; + } + } + } + } + } + + if (bestDevice == NULL) { + // should not happen + d3dError(DEVICENOTFOUND); + return NULL; + } + + // TODO: suggest another display mode for user + /* + if (bestDevice->deviceType == D3DDEVTYPE_REF) { + // Recomend other display mode that support + // hardware accerated rendering if any. + int numModes = pD3D->GetAdapterModeCount(driverInfo->iAdapter); + D3DDISPLAYMODE dmode; + + for (i=0; i < numModes; i++) { + pD3D->EnumAdapterModes(pDriverInfo->iAdapter, i, &dmode); + if ((dmode.Width < 640) || (dmode.Height < 400)) { + // filter out low resolution modes + continue; + } + } + .... + } + */ + return bestDevice; +} + + +VOID D3dCtx::setDeviceFromProperty(JNIEnv *env) +{ + + jclass systemClass = env->FindClass( "javax/media/j3d/MasterControl" ); + + if ( systemClass != NULL ) + { + jmethodID method = env->GetStaticMethodID( + systemClass, "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;" ); + if ( method != NULL ) + { + jstring name = env->NewStringUTF( "j3d.d3ddevice" ); + jstring property = reinterpret_cast( + env->CallStaticObjectMethod( + systemClass, method, name )); + jboolean isCopy; + + if ( property != NULL ) + { + const char* chars = env->GetStringUTFChars( + property, &isCopy ); + if ( chars != 0 ) + { + if (stricmp(chars, "reference") == 0) { + // There is no emulation device anymore in v8.0 + requiredDeviceID = DEVICE_REF; + } else if (stricmp(chars, "hardware") == 0) { + requiredDeviceID = DEVICE_HAL; + } else if (stricmp(chars, "TnLhardware") == 0) { + requiredDeviceID = DEVICE_HAL_TnL; + } else { + d3dError(UNKNOWNDEVICE); + exit(1); + } + env->ReleaseStringUTFChars( property, chars ); + } + } + name = env->NewStringUTF( "j3d.d3ddriver" ); + property = reinterpret_cast( + env->CallStaticObjectMethod( + systemClass, method, name )); + if ( property != NULL ) + { + const char* chars = env->GetStringUTFChars( + property, &isCopy); + if ( chars != 0 ) + { + // atoi() return 0, our default value, on error. + requiredDriverID = atoi(chars); + } + } + } + } +} + +VOID D3dCtx::setFullScreenFromProperty(JNIEnv *env) +{ + + jclass systemClass = env->FindClass( "javax/media/j3d/MasterControl" ); + + bFullScreenRequired = false; + bFullScreen = false; + + if ( systemClass != NULL ) + { + jmethodID method = env->GetStaticMethodID( + systemClass, "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;" ); + if ( method != NULL ) + { + jstring name = env->NewStringUTF( "j3d.fullscreen" ); + jstring property = reinterpret_cast( + env->CallStaticObjectMethod( + systemClass, method, name )); + if ( property != NULL ) + { + jboolean isCopy; + const char * chars = env->GetStringUTFChars( + property, &isCopy ); + if ( chars != 0 ) + { + if ( stricmp( chars, "required" ) == 0 ) { + bFullScreenRequired = true; + bFullScreen = true; + } else if ( stricmp( chars, "preferred" ) == 0 ) { + bFullScreen = true; + } + // "UNNECESSARY" is the default + env->ReleaseStringUTFChars( property, chars ); + } + } + } + } + +} + +VOID D3dCtx::setVBLimitProperty(JNIEnv *env) +{ + jclass systemClass = env->FindClass( "javax/media/j3d/MasterControl" ); + + if ( systemClass != NULL ) + { + jmethodID method = env->GetStaticMethodID( + systemClass, "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;" ); + if ( method != NULL ) + { + jstring name = env->NewStringUTF( "j3d.vertexbufferlimit" ); + jstring property = reinterpret_cast( + env->CallStaticObjectMethod( + systemClass, method, name )); + if ( property != NULL ) + { + jboolean isCopy; + const char * chars = env->GetStringUTFChars( + property, &isCopy ); + if ( chars != 0 ) + { + long vbLimit = atol(chars); + env->ReleaseStringUTFChars( property, chars ); + if (vbLimit >= 6) { + // Has to be at least 6 since for Quad the + // limit reset to 2*vbLimit/3 >= 4 + printf("Java 3D: VertexBuffer limit set to %ld\n", vbLimit); + vertexBufferMaxVertexLimit = vbLimit; + } else { + printf("Java 3D: VertexBuffer limit should be an integer >= 6 !\n"); + } + + } + } + } + } +} + +VOID D3dCtx::setDebugProperty(JNIEnv *env) +{ + jclass systemClass = env->FindClass( "javax/media/j3d/MasterControl" ); + + debug = false; + + if ( systemClass != NULL ) + { + jmethodID method = env->GetStaticMethodID( + systemClass, "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;" ); + if ( method != NULL ) + { + jstring name = env->NewStringUTF( "j3d.debug" ); + jstring property = reinterpret_cast( + env->CallStaticObjectMethod( + systemClass, method, name )); + if ( property != NULL ) + { + jboolean isCopy; + const char * chars = env->GetStringUTFChars( + property, &isCopy ); + if ( chars != 0 ) + { + if ( stricmp( chars, "true" ) == 0 ) { + debug = true; + } else { + debug = false; + } + // "UNNECESSARY" is the default + env->ReleaseStringUTFChars( property, chars ); + } + } + } + } +} + +VOID D3dCtx::setImplicitMultisamplingProperty(JNIEnv *env) +{ + jclass cls = env->FindClass("javax/media/j3d/VirtualUniverse"); + + if (cls == NULL) { + implicitMultisample = false; + return; + } + + jfieldID fieldID = env->GetStaticFieldID(cls, "mc", "Ljavax/media/j3d/MasterControl;"); + + if (fieldID == NULL) { + implicitMultisample = false; + return; + } + + jobject obj = env->GetStaticObjectField(cls, fieldID); + + if (obj == NULL) { + implicitMultisample = false; + return; + } + + cls = env->FindClass("javax/media/j3d/MasterControl"); + + if (cls == NULL) { + implicitMultisample = false; + return; + } + + fieldID = env->GetFieldID(cls, "implicitAntialiasing", "Z"); + + if (fieldID == NULL ) { + implicitMultisample = false; + return; + } + + implicitMultisample = env->GetBooleanField(obj, fieldID); + return; +} + + +// Callback to notify Canvas3D which mode it is currently running +VOID D3dCtx::setCanvasProperty(JNIEnv *env, jobject obj) +{ + int mask = javax_media_j3d_Canvas3D_EXT_ABGR | + javax_media_j3d_Canvas3D_EXT_BGR; + + if ((deviceInfo->depthStencilFormat == D3DFMT_D24S8) || + (deviceInfo->depthStencilFormat == D3DFMT_D24X4S4)) { + // The other format D3DFMT_D15S1 with 1 bit + // stencil buffer has no use for Decal group so it + // is ignored. + mask |= javax_media_j3d_Canvas3D_STENCIL_BUFFER; + } + + jclass canvasCls = env->GetObjectClass(obj); + jfieldID id = env->GetFieldID(canvasCls, "fullScreenMode", "Z"); + env->SetBooleanField(obj, id, bFullScreen); + id = env->GetFieldID(canvasCls, "fullscreenWidth", "I"); + env->SetIntField(obj, id, driverInfo->desktopMode.Width); + id = env->GetFieldID(canvasCls, "fullscreenHeight", "I"); + env->SetIntField(obj, id, driverInfo->desktopMode.Height); + + id = env->GetFieldID(canvasCls, "textureExtendedFeatures", "I"); + env->SetIntField(obj, id, deviceInfo->getTextureFeaturesMask()); + + id = env->GetFieldID(canvasCls, "extensionsSupported", "I"); + env->SetIntField(obj, id, mask); + + + id = env->GetFieldID(canvasCls, "nativeGraphicsVersion", "Ljava/lang/String;"); + char *version = "DirectX 8.0 or above"; + env->SetObjectField(obj, id, env->NewStringUTF(version)); + + float degree = deviceInfo->maxAnisotropy; + id = env->GetFieldID(canvasCls, "anisotropicDegreeMax", "F"); + env->SetFloatField(obj, id, degree); + + id = env->GetFieldID(canvasCls, "textureWidthMax", "I"); + env->SetIntField(obj, id, deviceInfo->maxTextureWidth); + + id = env->GetFieldID(canvasCls, "textureHeightMax", "I"); + env->SetIntField(obj, id, deviceInfo->maxTextureHeight); +} + +VOID D3dCtx::createVertexBuffer() +{ + if (srcVertexBuffer != NULL) { + // Each pDevice has its own vertex buffer, + // so if different pDevice create vertex buffer has to + // recreate again. + srcVertexBuffer->Release(); + } + + if (dstVertexBuffer != NULL) { + dstVertexBuffer->Release(); + } + + HRESULT hr = + pDevice->CreateVertexBuffer(sizeof(D3DVERTEX), + D3DUSAGE_DONOTCLIP| + D3DUSAGE_WRITEONLY| + D3DUSAGE_SOFTWAREPROCESSING, + D3DFVF_XYZ, + D3DPOOL_MANAGED, + &srcVertexBuffer); + + if (FAILED(hr)) { + error(CREATEVERTEXBUFFER, hr); + } + + hr = pDevice->CreateVertexBuffer(sizeof(D3DTLVERTEX), + D3DUSAGE_DONOTCLIP| + D3DUSAGE_SOFTWAREPROCESSING, + D3DFVF_XYZRHW|D3DFVF_TEX1, + D3DPOOL_MANAGED, + &dstVertexBuffer); + if (FAILED(hr)) { + error(CREATEVERTEXBUFFER, hr); + } +} + + +VOID D3dCtx::transform(D3DVERTEX *worldCoord, D3DTLVERTEX *screenCoord) { + D3DVERTEX *pv; + D3DTLVERTEX *tlpv; + HRESULT hr; + + if (srcVertexBuffer != NULL) { + // Need to disable Texture state, otherwise + // ProcessVertices() will fail with debug message : + // + // "Number of output texture coordintes and their format should + // be the same in the destination vertex buffer and as + // computed for current D3D settings." + // + // when multiple texture is used. + DWORD texState; + // save original texture state + pDevice->GetTextureStageState(0, D3DTSS_COLOROP, &texState); + // disable texture processing + pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); + + if (!softwareVertexProcessing) { + // ProcessVertices() only work in software vertex + // processing mode + pDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, + TRUE); + } + + pDevice->SetRenderState(D3DRS_CLIPPING, FALSE); + hr = srcVertexBuffer->Lock(0, 0, (BYTE **)&pv, 0); + if (FAILED(hr)) { + if (debug) { + printf("Fail to lock buffer %s\n", DXGetErrorString8(hr)); + } + } else { + pv[0].x = worldCoord->x; + pv[0].y = worldCoord->y; + pv[0].z = worldCoord->z; + + srcVertexBuffer->Unlock(); + pDevice->SetStreamSource(0, srcVertexBuffer, + sizeof(D3DVERTEX)); + pDevice->SetVertexShader(D3DFVF_XYZ); + hr = pDevice->ProcessVertices(0, 0, 1, + dstVertexBuffer, 0); + + if (FAILED(hr)) { + if (debug) { + printf("Fail to processVertices %s\n", DXGetErrorString8(hr)); + } + } else { + hr = dstVertexBuffer->Lock(0, 0, (BYTE **)&tlpv, D3DLOCK_READONLY); + if (SUCCEEDED(hr)) { + screenCoord->sx = tlpv[0].sx; + screenCoord->sy = tlpv[0].sy; + screenCoord->sz = tlpv[0].sz; + screenCoord->rhw = tlpv[0].rhw; + dstVertexBuffer->Unlock(); + } else { + if (debug) { + error("Fail to lock surface in transform", hr); + } + } + } + } + pDevice->SetRenderState(D3DRS_CLIPPING, TRUE); + if (!softwareVertexProcessing) { + pDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, + FALSE); + } + // restore original texture state + pDevice->SetTextureStageState(0, D3DTSS_COLOROP, texState); + } +} + + + +VOID D3dCtx::getScreenRect(HWND hwnd, RECT *rect) { + + GetWindowRect(hwnd, rect); + + if ((deviceInfo->isHardware) && + (numDriver > 1)) { + + MONITORINFO info; + HMONITOR hMonitor = driverInfo->hMonitor; + + info.cbSize = sizeof(MONITORINFO); + if (hMonitor == NULL) { + hMonitor = MonitorFromWindow(hwnd, + MONITOR_DEFAULTTONEAREST); + } + GetMonitorInfo(hMonitor, &info); + monitorLeft = info.rcMonitor.left; + monitorTop = info.rcMonitor.top; + rect->left -= monitorLeft; + rect->right -= monitorLeft; + rect->top -= monitorTop; + rect->bottom -= monitorTop; + } else { + monitorLeft = 0; + monitorTop = 0; + } +} + +/* + * Search the monitor that this window competely enclosed. + * Return NULL if this window intersect several monitor + */ + +HMONITOR D3dCtx::findMonitor() +{ + + if ((osvi.dwMajorVersion < 4) || + (numDriver < 2)) { + return NULL; + } + + RECT rect; + MONITORINFO info; + HMONITOR hmonitor = MonitorFromWindow(hwnd, + MONITOR_DEFAULTTONEAREST); + info.cbSize = sizeof(MONITORINFO); + GetMonitorInfo(hmonitor, &info); + GetWindowRect(hwnd, &rect); + + if ((info.rcMonitor.left <= rect.left) && + (info.rcMonitor.right >= rect.right) && + (info.rcMonitor.top <= rect.top) && + (info.rcMonitor.bottom >= rect.bottom)) { + if (info.dwFlags & MONITORINFOF_PRIMARY) { + // Pass NULL is same as passing the guid of the + // first monitor. This can avoid recreate when + // window drag between screen borders from first + // screen. + return NULL; + } else { + return hmonitor; + } + } + return NULL; +} + + +D3dDeviceInfo* D3dCtx::setDeviceInfo(D3dDriverInfo *driverInfo, + BOOL *bFullScreen, + int minZDepth) +{ + if (requiredDeviceID >= 0) { + return selectDevice(requiredDeviceID, driverInfo, + bFullScreen, minZDepth); + } else { + return selectBestDevice(driverInfo, bFullScreen, + minZDepth); + } +} + +// Find the adapter that this window belongs to +// and set driverInfo to this +VOID D3dCtx::setDriverInfo() +{ + D3dDriverInfo *newDriver = NULL; + + if (requiredDriverID <= 0) { + if ((numDriver < 2) || + (monitor == NULL) || + (osvi.dwMajorVersion < 4)) { + // windows 95 don't support multiple monitors + // Use Primary display driver + newDriver = d3dDriverList[0]; + } else { + for (int i=0; i < numDriver; i++) { + if (d3dDriverList[i]->hMonitor == monitor) { + newDriver = d3dDriverList[i]; + break; + } + } + } + } else { + if (requiredDriverID > numDriver) { + requiredDriverID = numDriver; + } + newDriver = d3dDriverList[requiredDriverID-1]; + } + + driverInfo = newDriver; +} + + +VOID D3dCtx::setDefaultAttributes() +{ + + pDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, + softwareVertexProcessing); + + pDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, + D3DMCS_MATERIAL); + pDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, + D3DMCS_MATERIAL); + pDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE); + // Default specular is FALSE + pDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE); + // Texture & CULL mode default value for D3D is different from OGL + + pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); + + // Default in D3D is D3DCMP_LESSEQUAL, OGL is D3DCMP_LESS + + // Set Range based fog + pDevice->SetRenderState(D3DRS_RANGEFOGENABLE, + deviceInfo->rangeFogEnable); + + // disable antialiasing (default is true in D3D) + if (!implicitMultisample) { + pDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE); + } + + pointSize = 1; + cullMode = D3DCULL_CW; + fillMode = D3DFILL_SOLID; + zWriteEnable = TRUE; + zEnable = TRUE; + + if ((pDevice != NULL) && (bindTextureId != NULL)) { + for (int i=0; i < bindTextureIdLen; i++) { + pDevice->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + pDevice->SetTextureStageState(i, D3DTSS_COLORARG1, D3DTA_TEXTURE); + pDevice->SetTextureStageState(i, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + pDevice->SetTextureStageState(i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + pDevice->SetTextureStageState(i, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + pDevice->SetTextureStageState(i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + bindTextureId[i] = -1; + } + } + + + for (int i=0; i < TEXSTAGESUPPORT; i++) { + texGenMode[i] = TEX_GEN_NONE; + texTransformSet[i] = false; + texCoordFormat[i] = 2; + texTransform[i] = identityMatrix; + texStride[i] = 0; + texTranslateSet[i] = false; + } +} + +VOID D3dCtx::enumDisplayMode(DEVMODE* dmode) +{ + + MONITORINFOEX mi; + + if (monitor == NULL) { + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, dmode ); + } else { + mi.cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(monitor, (MONITORINFOEX *) &mi); + dmode->dmSize = sizeof(DEVMODE); + EnumDisplaySettings( mi.szDevice, ENUM_CURRENT_SETTINGS, dmode); + } +} + +DWORD D3dCtx::findBehavior() +{ + if (deviceInfo->isHardwareTnL && + ((requiredDeviceID < 0) || (requiredDeviceID == DEVICE_HAL_TnL))) { + softwareVertexProcessing = FALSE; + return D3DCREATE_MIXED_VERTEXPROCESSING; + } else { + softwareVertexProcessing = TRUE; + return D3DCREATE_SOFTWARE_VERTEXPROCESSING; + } +} + +VOID D3dCtx::printInfo(D3DPRESENT_PARAMETERS *d3dPresent) +{ + + if (d3dPresent->Windowed) { + printf("Window "); + } else { + printf("FullScreen "); + } + + printf("%dx%d %s, handle=%x, %s, %s, %s\n", + d3dPresent->BackBufferWidth, + d3dPresent->BackBufferHeight, + getPixelFormatName(d3dPresent->BackBufferFormat), + d3dPresent->hDeviceWindow, + getMultiSampleName(d3dPresent->MultiSampleType), + getSwapEffectName(d3dPresent->SwapEffect), + getPixelFormatName(d3dPresent->AutoDepthStencilFormat)); +} + +VOID D3dCtx::setWindowMode() +{ + if (inToggle) { + if (!bFullScreen) { + SetWindowLong(topHwnd, GWL_STYLE, winStyle); + SetWindowPos(topHwnd, HWND_NOTOPMOST, savedTopRect.left, savedTopRect.top, + savedTopRect.right - savedTopRect.left, + savedTopRect.bottom - savedTopRect.top, + SWP_SHOWWINDOW); + } else { + SetWindowLong(topHwnd, GWL_STYLE, + WS_POPUP|WS_SYSMENU|WS_VISIBLE); + } + } + +} + +VOID D3dCtx::setAmbientLightMaterial() +{ + // We need to set a constant per vertex color + // There is no way in D3D to do this. It is workaround + // by adding Ambient light and set Ambient Material + // color temporary + pDevice->GetLight(0, &savedLight); + pDevice->GetMaterial(&savedMaterial); + pDevice->GetLightEnable(0, &savedLightEnable); + + CopyColor(ambientMaterial.Ambient, + currentColor_r, + currentColor_g, + currentColor_b, + currentColor_a); + + + // This is what the specification say it should set + ambientMaterial.Specular.a = currentColor_a; + + // This is what we found after testing - spec. is not correct + ambientMaterial.Diffuse.a = currentColor_a; + + pDevice->SetLight(0, &ambientLight); + pDevice->SetMaterial(&ambientMaterial); + pDevice->SetRenderState(D3DRS_LIGHTING, TRUE); + pDevice->LightEnable(0, TRUE); +} + +VOID D3dCtx::restoreDefaultLightMaterial() +{ + // restore original values after setAmbientLightMaterial() + pDevice->SetLight(0, &savedLight); + pDevice->SetMaterial(&savedMaterial); + pDevice->SetRenderState(D3DRS_LIGHTING, FALSE); + pDevice->LightEnable(0, savedLightEnable); +} + +VOID D3dCtx::freeVBList(D3dVertexBufferVector *v) +{ + LPD3DVERTEXBUFFER *p, r; + + lockGeometry(); + + for (p = v->begin(); p != v->end(); ++p) { + // Remove itself from current ctx vertexBufferTable list + r = (*p)->next; + if (r != NULL) { + r->previous = (*p)->previous; + } + (*p)->previous->next = r; + // Now we can free current VB + delete (*p); + } + v->clear(); + unlockGeometry(); +} + + +VOID D3dCtx::freeResourceList(LPDIRECT3DRESOURCE8Vector *v) +{ + LPDIRECT3DRESOURCE8 *s; + + lockSurfaceList(); + for (s = v->begin(); s != v->end(); ++s) { + (*s)->Release(); + } + v->clear(); + unlockSurfaceList(); +} + +VOID D3dCtx::freeList() +{ + if (useFreeList0) { + if (freeResourceList1.size() > 0) { + freeResourceList(&freeResourceList1); + } + if (freeVBList1.size() > 0) { + freeVBList(&freeVBList1); + } + useFreeList0 = false; + } else { + if (freeResourceList0.size() > 0) { + freeResourceList(&freeResourceList0); + } + if (freeVBList0.size() > 0) { + freeVBList(&freeVBList0); + } + useFreeList0 = true; + } +} + +VOID D3dCtx::freeVB(LPD3DVERTEXBUFFER vb) +{ + if (vb != NULL) { + lockSurfaceList(); + if (useFreeList0) { + freeVBList0.push_back(vb); + } else { + freeVBList1.push_back(vb); + } + unlockSurfaceList(); + } +} + + +VOID D3dCtx::freeResource(LPDIRECT3DRESOURCE8 res) +{ + if (res != NULL) { + lockSurfaceList(); + if (useFreeList0) { + freeResourceList0.push_back(res); + } else { + freeResourceList1.push_back(res); + } + unlockSurfaceList(); + } +} + +BOOL D3dCtx::createFrontBuffer() +{ + HRESULT hr; + + hr = pDevice->CreateImageSurface(driverInfo->desktopMode.Width, + driverInfo->desktopMode.Height, + D3DFMT_A8R8G8B8, + &frontSurface); + if (FAILED(hr)) { + if (debug) { + printf("[Java3D] Fail to CreateImageSurface %s\n", + DXGetErrorString8(hr)); + } + frontSurface = NULL; + return false; + } + return true; +} + + + diff --git a/src/native/d3d/D3dCtx.hpp b/src/native/d3d/D3dCtx.hpp new file mode 100644 index 0000000..83added --- /dev/null +++ b/src/native/d3d/D3dCtx.hpp @@ -0,0 +1,325 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#if !defined(D3DCTX_H) +#define D3DCTX_H + + +#include "StdAfx.h" +#include "D3dVertexBuffer.hpp" +#include "D3dDisplayList.hpp" + +#define TEXTURETABLESIZE 8 +#define TEXSTAGESUPPORT 8 +#define DISPLAYLIST_INITSIZE 8 +#define NOCHANGE 0 +#define RESETSURFACE 1 +#define RECREATEDDRAW 2 +#define RECREATEDFAIL -1 + + +// Use in texCoordPosition[] +// Must be negative number +#define TEX_GEN_NONE 0 +#define TEX_EYE_LINEAR -1 +#define TEX_SPHERE_MAP -2 +#define TEX_NORMAL_MAP -3 +#define TEX_REFLECT_MAP -4 +#define TEX_OBJ_LINEAR -5 +#define TEX_GEN_INVALID -6 +#define TEX_GEN_AUTO -7 + +typedef struct _D3DVERTEX { + float x, y, z; +} D3DVERTEX; + +typedef struct _D3DTLVERTEX { + float sx, sy, sz, rhw; + float tu, tv; +} D3DTLVERTEX; + +typedef vector LPDIRECT3DRESOURCE8Vector; +typedef vector LPDIRECT3DVERTEXBUFFER8Vector; + +class D3dCtx { +public: + + HWND hwnd; // window handle + HWND topHwnd; // Top window handle + D3dDriverInfo *driverInfo; // Driver use + D3dDeviceInfo *deviceInfo; // Device use + + LPDIRECT3D8 pD3D; // Direct3D interface + LPDIRECT3DDEVICE8 pDevice; // Instance of D3D Device + + LPDIRECT3DSURFACE8 depthStencilSurface; + + // This is used for readRaster and offscreen rendering + // Only allocate the memory area if necessary + LPDIRECT3DSURFACE8 frontSurface; + + LPDIRECT3DSURFACE8 backSurface; + + // Parameters use for CreateDevice() + D3DPRESENT_PARAMETERS d3dPresent; + DWORD dwBehavior; + + BOOL offScreen; // true if it is offScreen rendering + // in this case only backSurface is used + DWORD offScreenWidth; + DWORD offScreenHeight; + + BOOL bFullScreen; // true if in full screen mode + BOOL bFullScreenRequired; // true if must run in full + // screen mode or die + BOOL inToggle; // in toggle fullscreen/window mode + RECT screenRect; // coordinate of window relative to + // the whole desktop in multiple monitor + RECT windowRect; // coordinate of window relative to + // the current monitor desktop only + INT minZDepth; // min Z depth set in NativeConfigTemplate + + DEVMODE devmode; // current display mode + DWORD antialiasing; // PREFERRED, REQUIRED or UNNECESSARY + + + // Store current color as in OGL glColor() + float currentColor_r; + float currentColor_g; + float currentColor_b; + float currentColor_a; + + // Two side light is used. Note that D3D don't support two side + // lighting. + BOOL twoSideLightingEnable; + + // True if lighting is currently enable + // Save the current RenderingState to avoid GetRenderState() + // call during Rendering. + BOOL isLightEnable; + DWORD cullMode; + DWORD fillMode; + DWORD softwareVertexProcessing; + DWORD zWriteEnable; + DWORD zEnable; + + // Ambient material used when coloring Attributes + D3DMATERIAL8 ambientMaterial; + + // temporary variables for ambient light setting + D3DLIGHT8 savedLight; + D3DMATERIAL8 savedMaterial; + BOOL savedLightEnable; + + // temporary variables used for building VertexBuffer + LPD3DVERTEXBUFFER pVB; // point to the current VB being update + DWORD texSetUsed; + DWORD texStride[TEXSTAGESUPPORT]; + + // true when in toggle mode + BOOL forceResize; + + // Texture related variables + INT *bindTextureId; + DWORD bindTextureIdLen; + + LPDIRECT3DTEXTURE8 *textureTable; + DWORD textureTableLen; + + // Volume Texture related variables + // Since 2d & 3d texture ID can't be the same from Java3D. + // We don't need bindVolumeId + LPDIRECT3DVOLUMETEXTURE8 *volumeTable; + DWORD volumeTableLen; + + // Texture Cube Mapping related variables + LPDIRECT3DCUBETEXTURE8 *cubeMapTable; + DWORD cubeMapTableLen; + + // true if hardware support MultiTexture + BOOL multiTextureSupport; + + // handle to monitor that this ctx belongs to. This is equal to + // NULL if this window is a primary display screen or it covers + // more than one screen. + HMONITOR monitor; + + // D3D don't have concept of current texture unit stage, + // instead, the texture unit stage is pass in as argument + // for all texture call. + INT texUnitStage; + + // true if linear filtering is to be used + BOOL texLinearMode; + + + // This is used temporary to store the blend function + // when two pass texture is used to simulate BLEND mode + DWORD srcBlendFunc; + DWORD dstBlendFunc; + DWORD blendEnable; + + + // This is used for to transform vertex + // from world to screen coordinate + LPDIRECT3DVERTEXBUFFER8 srcVertexBuffer; + LPDIRECT3DVERTEXBUFFER8 dstVertexBuffer; + + // For Rect of texture map in Raster write + D3DTLVERTEX rasterRect[4]; + + // Set automatic Texture coordinate generation type + // TEX_xxx_xxx as defined in GeometryArrayRetained.cpp + INT texGenMode[TEXSTAGESUPPORT]; + + // Whether TEXTURE_COORDINATE_2/3/4 is used in this state + INT texCoordFormat[TEXSTAGESUPPORT]; + + // Whether texture transform matrix is set in this state or not + BOOL texTransformSet[TEXSTAGESUPPORT]; + + // Remember the last Texture Transform pass down, since + // TexCoordGen may destroy it in some mode so we have to + // restore it later manually. + D3DXMATRIX texTransform[TEXSTAGESUPPORT]; + + // True if we copy m._41, m._42 elment to m._31, m._32 + // as a workaround that 2D texture translation did not work. + BOOL texTranslateSet[TEXSTAGESUPPORT]; + + float planeS[TEXSTAGESUPPORT][4]; + float planeT[TEXSTAGESUPPORT][4]; + float planeR[TEXSTAGESUPPORT][4]; + float planeQ[TEXSTAGESUPPORT][4]; + + // Display List ID (start from 1) => VertexBuffer pointer table + LPD3DDISPLAYLIST *displayListTable; + int dlTableSize; + + // For immediate mode rendering, we save the vertexBuffer pointer + // in variable pVertexBuffer of GeometryArrayRetained to reuse it. + D3dVertexBuffer vertexBufferTable; + + int currDisplayListID; + + // True if colorTarget need to reset + BOOL resetColorTarget; + + // Use for QuadArray + LPDIRECT3DINDEXBUFFER8 quadIndexBuffer; + DWORD quadIndexBufferSize; + + // Use for Quad Polygon Line mode + LPDIRECT3DINDEXBUFFER8 lineModeIndexBuffer; + + // Use temporary for reindexing + DWORD *reIndexifyTable; + + // True if Direcct Draw context is being destroy and recreate + // again during resize/toggle + BOOL recreateDDraw; + + // Screen coordinate of current monitor in use + // When hardware accleerated mode is used. For Emulation mode + // they are always zero; + INT monitorLeft; + INT monitorTop; + float pointSize; + + // Use to free resource surface in swap() + BOOL useFreeList0; + LPDIRECT3DRESOURCE8Vector freeResourceList0; + LPDIRECT3DRESOURCE8Vector freeResourceList1; + D3dVertexBufferVector freeVBList0; + D3dVertexBufferVector freeVBList1; + + D3dCtx(JNIEnv *env, jobject obj, HWND hwnd, BOOL offScreen, jint vid); + ~D3dCtx(); + + BOOL initialize(JNIEnv *env, jobject obj); + INT resize(JNIEnv *env, jobject obj); + VOID error(char *s, HRESULT hr); + VOID error(int idx, HRESULT hr); + VOID error(int idx); + VOID error(char *s); + VOID warning(int idx, HRESULT hr); + VOID warning(int idx); + + static VOID d3dError(int idx); + static VOID d3dError(char *s); + static VOID d3dWarning(int idx, HRESULT hr); + static VOID d3dWarning(int idx); + + INT toggleMode(BOOL fullScreen, JNIEnv *env, jobject obj); + DWORD getWidth(); + DWORD getHeight(); + + VOID release(); + VOID releaseTexture(); + VOID releaseVB(); + VOID setViewport(); + VOID transform(D3DVERTEX *worldCoord, D3DTLVERTEX *screenCoord); + VOID getScreenRect(HWND hwnd, RECT *rect); + HMONITOR findMonitor(); + VOID setDriverInfo(); + static D3dDeviceInfo* setDeviceInfo(D3dDriverInfo *driverInfo, + BOOL *bFullScreen, + int minZDepth); + DWORD findBehavior(); + VOID setPresentParams(); + INT resetSurface(JNIEnv *env, jobject obj); + VOID setPresentParams(JNIEnv *env, jobject obj); + VOID setAmbientLightMaterial(); + VOID restoreDefaultLightMaterial(); + VOID freeResource(LPDIRECT3DRESOURCE8 surf); + VOID freeVB(LPD3DVERTEXBUFFER vb); + + VOID freeList(); + VOID freeResourceList(LPDIRECT3DRESOURCE8Vector *v); + VOID freeVBList(D3dVertexBufferVector *v); + BOOL createFrontBuffer(); + + static D3dDeviceInfo* selectDevice(int deviceID, + D3dDriverInfo *driverInfo, + BOOL *bFullScreen, + int minZDepth); + static D3dDeviceInfo* selectBestDevice(D3dDriverInfo *driverInfo, + BOOL *bFullScreen, + int minZDepth); + static VOID setDeviceFromProperty(JNIEnv *env); + static VOID setDebugProperty(JNIEnv *env); + static VOID setVBLimitProperty(JNIEnv *env); + static VOID setImplicitMultisamplingProperty(JNIEnv *env); + +private: + + RECT savedTopRect; // for toggle between fullscreen mode + RECT savedClientRect; + DWORD winStyle; + + VOID createVertexBuffer(); + + VOID setCanvasProperty(JNIEnv *env, jobject obj); + VOID setFullScreenFromProperty(JNIEnv *env); + VOID enumDisplayMode(DEVMODE *devmode); + + static VOID printWarningMessage(D3dDeviceInfo *deviceInfo); + static VOID showError(HWND hwnd, char *s, BOOL bFullScreen); + VOID setDefaultAttributes(); + VOID printInfo(D3DPRESENT_PARAMETERS *d3dPresent); + VOID setWindowMode(); +}; + +typedef vector D3dCtxVector; +extern D3dCtxVector d3dCtxList; +const extern D3DXMATRIX identityMatrix; +#endif diff --git a/src/native/d3d/D3dDeviceInfo.cpp b/src/native/d3d/D3dDeviceInfo.cpp new file mode 100644 index 0000000..4a12167 --- /dev/null +++ b/src/native/d3d/D3dDeviceInfo.cpp @@ -0,0 +1,204 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include "Stdafx.h" + +// return true if device is capable of hardware accelerated + +D3dDeviceInfo::D3dDeviceInfo() +{ +} + +D3dDeviceInfo::~D3dDeviceInfo() +{ +} + +VOID D3dDeviceInfo::setCaps(D3DCAPS8 *d3dCaps) { + + if (deviceType == D3DDEVTYPE_HAL) { + isHardware = true; + isHardwareTnL = (d3dCaps->DevCaps & + D3DDEVCAPS_HWTRANSFORMANDLIGHT); + } else { + isHardware = false; + isHardwareTnL = false; + } + maxTextureBlendStages = d3dCaps->MaxTextureBlendStages; + maxSimultaneousTextures = d3dCaps->MaxSimultaneousTextures; + maxTextureUnitStageSupport = min(maxTextureBlendStages, + maxSimultaneousTextures); + supportMipmap = ((d3dCaps->TextureCaps & + D3DPTEXTURECAPS_MIPMAP) != 0); + texturePow2Only = ((d3dCaps->TextureCaps & + D3DPTEXTURECAPS_POW2) != 0); + textureSquareOnly = ((d3dCaps->TextureCaps & + D3DPTEXTURECAPS_SQUAREONLY) != 0); + linePatternSupport = ((d3dCaps->PrimitiveMiscCaps & + D3DPMISCCAPS_LINEPATTERNREP) != 0); + texBorderModeSupport = ((d3dCaps->TextureAddressCaps & + D3DPTADDRESSCAPS_BORDER) != 0); + texLerpSupport = ((d3dCaps->TextureOpCaps & + D3DTEXOPCAPS_LERP) != 0); + canRenderWindowed = ((d3dCaps->Caps2 & + D3DCAPS2_CANRENDERWINDOWED) != 0); + maxPrimitiveCount = d3dCaps->MaxPrimitiveCount; + maxVertexIndex = min(vertexBufferMaxVertexLimit, + d3dCaps->MaxVertexIndex); + maxTextureHeight = d3dCaps->MaxTextureHeight; + maxTextureWidth = d3dCaps->MaxTextureWidth; + maxTextureDepth = d3dCaps->MaxVolumeExtent; + + maxActiveLights = d3dCaps->MaxActiveLights; + maxPointSize = d3dCaps->MaxPointSize; + maxAnisotropy = d3dCaps->MaxAnisotropy; + + maxVertexCount[GEO_TYPE_QUAD_SET] = min(vertexBufferMaxVertexLimit, + maxPrimitiveCount << 1); + + // Since index is used, we need to make sure than index range + // is also support. + maxVertexCount[GEO_TYPE_QUAD_SET] = min(maxVertexCount[GEO_TYPE_QUAD_SET], + maxVertexIndex); + + maxVertexCount[GEO_TYPE_TRI_SET] = min(vertexBufferMaxVertexLimit, + maxPrimitiveCount*3); + maxVertexCount[GEO_TYPE_POINT_SET] = min(vertexBufferMaxVertexLimit, + maxPrimitiveCount); + maxVertexCount[GEO_TYPE_LINE_SET] = min(vertexBufferMaxVertexLimit, + maxPrimitiveCount << 1); + maxVertexCount[GEO_TYPE_TRI_STRIP_SET] = min(vertexBufferMaxVertexLimit, + maxPrimitiveCount + 2); + maxVertexCount[GEO_TYPE_TRI_FAN_SET] = min(vertexBufferMaxVertexLimit, + maxPrimitiveCount + 2); + maxVertexCount[GEO_TYPE_LINE_STRIP_SET] = min(vertexBufferMaxVertexLimit, + maxPrimitiveCount +1); + maxVertexCount[GEO_TYPE_INDEXED_QUAD_SET] = maxVertexCount[GEO_TYPE_QUAD_SET]; + maxVertexCount[GEO_TYPE_INDEXED_TRI_SET] = maxVertexCount[GEO_TYPE_TRI_SET]; + maxVertexCount[GEO_TYPE_INDEXED_POINT_SET] = maxVertexCount[GEO_TYPE_POINT_SET]; + maxVertexCount[GEO_TYPE_INDEXED_LINE_SET] = maxVertexCount[GEO_TYPE_LINE_SET]; + maxVertexCount[GEO_TYPE_INDEXED_TRI_STRIP_SET] = maxVertexCount[GEO_TYPE_TRI_STRIP_SET]; + maxVertexCount[GEO_TYPE_INDEXED_TRI_FAN_SET] = maxVertexCount[GEO_TYPE_TRI_FAN_SET]; + maxVertexCount[GEO_TYPE_INDEXED_LINE_STRIP_SET] = maxVertexCount[GEO_TYPE_LINE_STRIP_SET]; + + + if (((d3dCaps->RasterCaps & D3DPRASTERCAPS_FOGTABLE) != 0) && + ((d3dCaps->RasterCaps & D3DPRASTERCAPS_WFOG) != 0)) { + // use pixel w-fog + fogMode = D3DRS_FOGTABLEMODE; + rangeFogEnable = false; + } else if (((d3dCaps->RasterCaps & D3DPRASTERCAPS_FOGVERTEX) != 0) && + ((d3dCaps->RasterCaps & D3DPRASTERCAPS_FOGRANGE) != 0)) { + // use vertex range based fog + fogMode = D3DRS_FOGVERTEXMODE; + rangeFogEnable = true; + } else if ((d3dCaps->RasterCaps & D3DPRASTERCAPS_FOGTABLE) != 0) { + // use pixel z-fog + fogMode = D3DRS_FOGTABLEMODE; + rangeFogEnable = false; + } else if (D3DPRASTERCAPS_FOGVERTEX) { + // use vertex z-fog + fogMode = D3DRS_FOGVERTEXMODE; + rangeFogEnable = false; + } else { + if (debug) { + printf("[Java 3D] Fog not support in this device !\n"); + } + } + + + texMask = 0; + + if ((d3dCaps->TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) && + (maxTextureDepth > 0)) { + texMask |= javax_media_j3d_Canvas3D_TEXTURE_3D; + } + + if (d3dCaps->TextureCaps & D3DPTEXTURECAPS_CUBEMAP) { + texMask |= javax_media_j3d_Canvas3D_TEXTURE_CUBE_MAP; + } + + if (maxTextureUnitStageSupport > 1) { + texMask |= javax_media_j3d_Canvas3D_TEXTURE_MULTI_TEXTURE; + } + + if (d3dCaps->TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) { + texMask |= javax_media_j3d_Canvas3D_TEXTURE_COMBINE_DOT3; + } + + if (d3dCaps->TextureOpCaps & D3DTEXOPCAPS_SUBTRACT) { + texMask |= javax_media_j3d_Canvas3D_TEXTURE_COMBINE_SUBTRACT; + } + + if (d3dCaps->TextureOpCaps & D3DTEXOPCAPS_LERP) { + texMask |= (javax_media_j3d_Canvas3D_TEXTURE_LERP| + javax_media_j3d_Canvas3D_TEXTURE_COMBINE); + } else if (d3dCaps->TextureOpCaps & + (D3DTEXOPCAPS_DOTPRODUCT3|D3DTEXOPCAPS_SUBTRACT| + D3DTEXOPCAPS_MODULATE|D3DTEXOPCAPS_ADD| + D3DTEXOPCAPS_ADDSIGNED)) { + texMask |= javax_media_j3d_Canvas3D_TEXTURE_COMBINE; + } + + + if (maxAnisotropy > 1) { + texMask |= javax_media_j3d_Canvas3D_TEXTURE_ANISOTROPIC_FILTER; + } +} + +BOOL D3dDeviceInfo::supportAntialiasing() { + return (multiSampleSupport != 0); +} + + +void D3dDeviceInfo::findDepthStencilFormat(int minZDepth) +{ + depthStencilFormat = D3DFMT_UNKNOWN; + for (int i=0; i < D3DDEPTHFORMATSIZE; i++) { + if (depthFormatSupport[i]) { + // prefer one with stencil buffer, follow by D3DFMT_D16_LOCKABLE, + if (d3dDepthTable[i] >= minZDepth) { + depthStencilFormat = (D3DFORMAT) d3dDepthFormat[i]; + break; + } + } + } +} + + +D3DMULTISAMPLE_TYPE D3dDeviceInfo::getBestMultiSampleType() +{ + DWORD bitmask = 0; + UINT i; + + // start with 4, if none found, try 3 and 2 + for (i=4; i < 16; i++) { + bitmask = (1 << i); + if (multiSampleSupport & bitmask) { + return (D3DMULTISAMPLE_TYPE) i; + } + } + + for (i=3; i >= 2; i--) { + bitmask = (1 << i); + if (multiSampleSupport & bitmask) { + return (D3DMULTISAMPLE_TYPE) i; + } + } + + // Should not happen + return D3DMULTISAMPLE_NONE; +} + +int D3dDeviceInfo::getTextureFeaturesMask() +{ + return texMask; +} diff --git a/src/native/d3d/D3dDeviceInfo.hpp b/src/native/d3d/D3dDeviceInfo.hpp new file mode 100644 index 0000000..7701261 --- /dev/null +++ b/src/native/d3d/D3dDeviceInfo.hpp @@ -0,0 +1,85 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#if !defined(D3DDEVICEINFO_H) +#define D3DDEVICEINFO_H + +#include "StdAfx.h" + +extern UINT vertexBufferMaxVertexLimit; + +#define D3DDEPTHFORMATSIZE 6 + +class D3dDeviceInfo { +public: + // Hardware Rasterizer + // Transform & Light Hardware Rasterizer + // Reference Rasterizer + char deviceName[40]; // One of above name + D3DDEVTYPE deviceType; // D3DDEVTYPE_HAL or D3DDEVTYPE_REF + BOOL desktopCompatible; // Can render in desktop mode + BOOL fullscreenCompatible; // Can render in fullscreen mode + // using current desktop mode setting + + // each bitmask correspond to the support of + // D3DMULTISAMPLE_i_SAMPLES type, i = 2...16 + DWORD multiSampleSupport; + + // TRUE when d3dDepthFormat[i] support + BOOL depthFormatSupport[D3DDEPTHFORMATSIZE]; + + // depth format select + D3DFORMAT depthStencilFormat; + + // max z buffer depth support + UINT maxZBufferDepthSize; + + // Max vetex count support for each primitive + DWORD maxVertexCount[GEO_TYPE_INDEXED_LINE_STRIP_SET+1]; + + BOOL isHardware; + BOOL isHardwareTnL; + BOOL canRenderWindowed; + BOOL supportMipmap; + BOOL texturePow2Only; + BOOL textureSquareOnly; + BOOL linePatternSupport; + BOOL texBorderModeSupport; + BOOL texLerpSupport; + DWORD maxTextureUnitStageSupport; + DWORD maxTextureBlendStages; + DWORD maxSimultaneousTextures; + DWORD maxTextureWidth; + DWORD maxTextureHeight; + DWORD maxTextureDepth; + DWORD maxPrimitiveCount; + DWORD maxVertexIndex; + DWORD maxActiveLights; + DWORD maxPointSize; + DWORD rangeFogEnable; + D3DRENDERSTATETYPE fogMode; + int texMask; + int maxAnisotropy; + + D3dDeviceInfo(); + ~D3dDeviceInfo(); + + // set capabilities of this device + VOID setCaps(D3DCAPS8 *d3dCaps); + BOOL supportAntialiasing(); + D3DMULTISAMPLE_TYPE getBestMultiSampleType(); + int getTextureFeaturesMask(); + void findDepthStencilFormat(int minZDepth); +}; + +#endif + diff --git a/src/native/d3d/D3dDisplayList.cpp b/src/native/d3d/D3dDisplayList.cpp new file mode 100644 index 0000000..f2de71e --- /dev/null +++ b/src/native/d3d/D3dDisplayList.cpp @@ -0,0 +1,330 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include "StdAfx.h" +#include "D3dDisplayList.hpp" + +D3dDisplayList::D3dDisplayList() +{ +} + +D3dDisplayList::~D3dDisplayList() +{ + for (D3dVertexBuffer **p = vBufferVec.begin(); + p != vBufferVec.end(); p++) { + SafeDelete(*p); + } + vBufferVec.empty(); +} + +VOID D3dDisplayList::render(D3dCtx *d3dCtx) +{ + for (D3dVertexBuffer **p = vBufferVec.begin(); + p != vBufferVec.end(); p++) { + (*p)->render(d3dCtx); + } +} + +VOID D3dDisplayList::add(LPD3DVERTEXBUFFER vbuffer) +{ + vBufferVec.push_back(vbuffer); +} + + +BOOL D3dDisplayList::isQuad(LPD3DVERTEXBUFFER p) +{ + return (!p->isIndexPrimitive && (p->indexBuffer != NULL)); +} + +VOID D3dDisplayList::optimize(D3dCtx *d3dCtx) +{ + + D3dVertexBufferVector vCloneBufferVec; + D3dVertexBuffer **r = vBufferVec.begin(); + + for (; r != vBufferVec.end(); r++) { + vCloneBufferVec.push_back(*r); + + } + + vBufferVec.erase(vBufferVec.begin(), vBufferVec.end()); + + D3dVertexBuffer **vbegin = vCloneBufferVec.begin(); + D3dVertexBuffer **vend = vCloneBufferVec.end(); + D3dVertexBuffer **q = vbegin; + D3dVertexBuffer **p; + int primitiveType, vcounts, climit; + int indexCounts = 0; + BOOL merge; + LPD3DVERTEXBUFFER mergedVB; + BOOL isPointFlagUsed; + DWORD vertexFormat; + BOOL isIndexPrimitive; + BOOL quadFlag; + + while (q != vend) { + primitiveType = (*q)->primitiveType; + climit = (*q)->maxVertexLimit; + vcounts = (*q)->vcount; + isPointFlagUsed = (*q)->isPointFlagUsed; + vertexFormat = (*q)->vertexFormat; + isIndexPrimitive = (*q)->isIndexPrimitive; + quadFlag = isQuad(*q); + + if ((*q)->indexBuffer != NULL) { + indexCounts = (*q)->indexCount; + } + merge = false; + p = q + 1; + + while (p != vend) { + if (((*p)->primitiveType == primitiveType) && + ((*p)->vertexFormat == vertexFormat) && + ((*p)->isIndexPrimitive == isIndexPrimitive) && + (isQuad(*p) == quadFlag) && + ((*p)->isPointFlagUsed == isPointFlagUsed) && + // This means Mutliple VBs already use + ((*p)->totalVertexCount == (*p)->vcount)) { + vcounts += (*p)->totalVertexCount; + if ((*p)->indexBuffer != NULL) { + indexCounts += (*p)->totalIndexCount; + } + if ((vcounts > climit) || (indexCounts > climit)) { + break; + } + p++; + merge = true; + } else { + break; + } + } + + if (merge) { + mergedVB = createMergedVB(d3dCtx, q, p, vcounts, indexCounts); + if (mergedVB != NULL) { + for (r = q; r != p; r++) { + SafeDelete(*r); + } + vBufferVec.push_back(mergedVB); + } else { + for (r = q; r != p; r++) { + vBufferVec.push_back(*r); + } + } + } else { + vBufferVec.push_back(*q); + } + q = p; + } + + vCloneBufferVec.erase(vCloneBufferVec.begin(), vCloneBufferVec.end()); +} + + + +LPD3DVERTEXBUFFER D3dDisplayList::createMergedVB(D3dCtx *d3dCtx, + D3dVertexBuffer **vstart, + D3dVertexBuffer **vend, + DWORD vcount, + DWORD indexCount) +{ + LPDIRECT3DDEVICE8 device = d3dCtx->pDevice; + D3dVertexBuffer **r; + UINT i; + HRESULT hr; + LPD3DVERTEXBUFFER vb = new D3dVertexBuffer(); + + vb->primitiveType = (*vstart)->primitiveType; + vb->isIndexPrimitive = (*vstart)->isIndexPrimitive; + vb->isPointFlagUsed = (*vstart)->isPointFlagUsed; + vb->vertexFormat = (*vstart)->vertexFormat; + vb->stride = (*vstart)->stride; + vb->ctx = (*vstart)->ctx; + vb->vcount = vb->totalVertexCount = vcount; + vb->indexCount = vb->totalIndexCount = indexCount; + vb->maxVertexLimit = (*vstart)->maxVertexLimit; + + if (!vb->isPointFlagUsed) { + hr = device->CreateVertexBuffer(vb->stride*vcount, + D3DUSAGE_WRITEONLY, + vb->vertexFormat, + D3DPOOL_DEFAULT, + &vb->buffer); + } else { + hr = device->CreateVertexBuffer(vb->stride*vcount, + D3DUSAGE_WRITEONLY|D3DUSAGE_POINTS, + vb->vertexFormat, + D3DPOOL_DEFAULT, + &vb->buffer); + } + + if (FAILED(hr)) { + return NULL; + } + + BYTE *bdst = NULL; + WORD *wdst = NULL; + UINT *idst = NULL; + + hr = vb->buffer->Lock(0, 0, (BYTE**) &bdst, 0); + if (FAILED(hr)) { + SafeRelease(vb->buffer); + return NULL; + } + + if (indexCount > 0) { + if (indexCount <= 0xffff) { + hr = device->CreateIndexBuffer(indexCount*sizeof(WORD), + D3DUSAGE_WRITEONLY, + D3DFMT_INDEX16, + D3DPOOL_DEFAULT, + &vb->indexBuffer); + + } else { + hr = device->CreateIndexBuffer(indexCount*sizeof(UINT), + D3DUSAGE_WRITEONLY, + D3DFMT_INDEX32, + D3DPOOL_DEFAULT, + &vb->indexBuffer); + } + if (FAILED(hr)) { + vb->buffer->Unlock(); + SafeRelease(vb->buffer); + return NULL; + } + if (indexCount <= 0xffff) { + hr = vb->indexBuffer->Lock(0, 0, (BYTE**) &wdst, 0); + } else { + hr = vb->indexBuffer->Lock(0, 0, (BYTE**) &idst, 0); + } + if (FAILED(hr)) { + vb->buffer->Unlock(); + SafeRelease(vb->buffer); + SafeRelease(vb->indexBuffer); + return NULL; + } + } + + BYTE *bsrc = NULL; + WORD *wsrc = NULL; + UINT *isrc = NULL; + UINT offset = 0; + DWORD len; + BOOL stripType = true; + + if ((vb->primitiveType == D3DPT_POINTLIST) || + (vb->primitiveType == D3DPT_LINELIST) || + (vb->primitiveType == D3DPT_TRIANGLELIST)) { + vb->numVertices = new USHORT[1]; + if (indexCount <= 0) { + vb->numVertices[0] = vcount; + } else { + vb->numVertices[0] = indexCount; + } + vb->numVerticesLen = 1; + vb->stripLen = 1; + stripType = false; + } + + for (r = vstart; r != vend; r++) { + hr = (*r)->buffer->Lock(0, 0, (BYTE **) &bsrc, 0); + + if (FAILED(hr)) { + vb->buffer->Unlock(); + if (indexCount > 0) { + vb->indexBuffer->Unlock(); + } + SafeRelease(vb->buffer); + SafeRelease(vb->indexBuffer); + return NULL; + } + + if (indexCount > 0) { + if (indexCount <= 0xffff) { + hr = (*r)->indexBuffer->Lock(0, 0, (BYTE**) &wsrc, 0); + } else { + hr = (*r)->indexBuffer->Lock(0, 0, (BYTE**) &isrc, 0); + } + if (FAILED(hr)) { + (*r)->buffer->Unlock(); + vb->buffer->Unlock(); + SafeRelease(vb->buffer); + SafeRelease(vb->indexBuffer); + return NULL; + } + } + len = (*r)->vcount*(*r)->stride; + CopyMemory(bdst, bsrc, len); + if (stripType) { + vb->appendStrides((*r)->stripLen, (*r)->numVertices); + } + if (indexCount > 0) { + if (wdst != NULL) { + if (wsrc != NULL) { + for (i=0; i < (*r)->indexCount; i++) { + *wdst++ = offset + *wsrc++; + } + } else { + // should not happen + printf("[Java3D] Error in merging index vertex buffer\n"); + } + + } else { + if (wsrc != NULL) { + for (i=0; i < (*r)->indexCount; i++) { + *idst++ = offset + *wsrc++; + } + } else { + for (i=0; i < (*r)->indexCount; i++) { + *idst++ = offset + *isrc++; + } + } + } + offset += (*r)->vcount; + } + bdst += len; + (*r)->buffer->Unlock(); + if (indexCount > 0) { + (*r)->indexBuffer->Unlock(); + wsrc = NULL; + isrc = NULL; + } + } + + + vb->buffer->Unlock(); + if (indexCount > 0) { + vb->indexBuffer->Unlock(); + } + + if (vb->isIndexPrimitive && (indexCount <= 0)) { + // QUAD is used, adjust size of index + createQuadIndices(d3dCtx, vcount); + } + + for (i=0; i < D3DDP_MAXTEXCOORD; i++) { + vb->texCoordPosition[i] = -9999; + } + + + if (debug) { + int n = 0; + for (r = vstart; r != vend; r++) { + n++; + } + printf("Merge %d VB with primitiveType %d, vcount %d, indexCount %d\n", + n, vb->primitiveType, vcount, indexCount); + } + return vb; + +} + diff --git a/src/native/d3d/D3dDisplayList.hpp b/src/native/d3d/D3dDisplayList.hpp new file mode 100644 index 0000000..f8323c6 --- /dev/null +++ b/src/native/d3d/D3dDisplayList.hpp @@ -0,0 +1,38 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#if !defined(D3DDISPLAYLIST_H) +#define D3DDISPLAYLIST_H + +#include "StdAfx.h" +#include "D3dVertexBuffer.hpp" + + +class D3dDisplayList { +public: + D3dDisplayList(); + ~D3dDisplayList(); + VOID add(LPD3DVERTEXBUFFER vBuffer); + VOID render(D3dCtx *d3dCtx); + VOID optimize(D3dCtx *d3dCtx); + BOOL isQuad(LPD3DVERTEXBUFFER p); + LPD3DVERTEXBUFFER createMergedVB(D3dCtx *d3dCtx, + D3dVertexBuffer **p, + D3dVertexBuffer **q, + DWORD vcount, + DWORD indexCount); + +private: + D3dVertexBufferVector vBufferVec; +}; +typedef D3dDisplayList* LPD3DDISPLAYLIST; +#endif diff --git a/src/native/d3d/D3dDriverInfo.cpp b/src/native/d3d/D3dDriverInfo.cpp new file mode 100644 index 0000000..81acdf7 --- /dev/null +++ b/src/native/d3d/D3dDriverInfo.cpp @@ -0,0 +1,320 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include "Stdafx.h" + + +const DWORD numDeviceTypes = 2; +const D3DDEVTYPE deviceTypes[2] = { D3DDEVTYPE_HAL, D3DDEVTYPE_REF }; +D3dDriverInfo **d3dDriverList = NULL; +int numDriver = 0; // size of above array list + +int requiredDeviceID = -1; // must use this Device or die + +// If this number is greater than zero, J3D must use the +// adapter index in the order of GetAdapterIdentifier() starting from one. +// Otherwise, the first driver found with monitor matching the display +// driver is used. +int requiredDriverID = -1; +OSVERSIONINFO osvi; + +// There is bug in Nvidia driver which prevent VB too big +// in TnL hardware vertex processing mode. +// When the index is greater than 65535, the nvidia driver will +// consider it to be N % 65535. However it works fine in +// hardware vertex processing mode. +UINT vertexBufferMaxVertexLimit = 65535; + +// True to disable setting D3DRS_MULTISAMPLEANTIALIAS +// Rendering state. +BOOL implicitMultisample; + +D3DFORMAT d3dDepthFormat[D3DDEPTHFORMATSIZE] = {D3DFMT_D15S1, + D3DFMT_D24S8, + D3DFMT_D24X4S4, + D3DFMT_D16_LOCKABLE, + D3DFMT_D16, + D3DFMT_D32}; + +// This should match the depth bit in the above array +int d3dDepthTable[D3DDEPTHFORMATSIZE] = {15, 24, 24, 16, 16, 32}; +D3DLIGHT8 ambientLight; + +D3dDriverInfo::D3dDriverInfo() +{ + for (int i=0; i < numDeviceTypes; i++) { + d3dDeviceList[i] = new D3dDeviceInfo(); + } +} + +D3dDriverInfo::~D3dDriverInfo() +{ + for (int i=0; i < numDeviceTypes; i++) { + SafeDelete(d3dDeviceList[i]); + } +} + +VOID computeRGBDepth(D3dDriverInfo *pDriver) +{ + switch (pDriver->desktopMode.Format) { + case D3DFMT_R8G8B8: + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + pDriver->redDepth = pDriver->greenDepth = + pDriver->blueDepth = 8; + break; + case D3DFMT_R5G6B5: + pDriver->redDepth = pDriver->blueDepth = 5; + pDriver->greenDepth = 6; + break; + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: + pDriver->redDepth = pDriver->blueDepth = + pDriver->greenDepth = 5; + break; + case D3DFMT_A4R4G4B4: + case D3DFMT_X4R4G4B4: + pDriver->redDepth = pDriver->blueDepth = + pDriver->greenDepth = 4; + break; + case D3DFMT_R3G3B2: + case D3DFMT_A8R3G3B2: + pDriver->redDepth = pDriver->greenDepth = 3; + pDriver->blueDepth = 2; + default: // 8 color indexed or less + pDriver->redDepth = pDriver->blueDepth = + pDriver->greenDepth = 0; + } + +} + +VOID buildDriverList(LPDIRECT3D8 pD3D) +{ + numDriver = pD3D->GetAdapterCount(); + + if (numDriver <= 0) { + // keep d3dDriverList = NULL for checking later + D3dCtx::d3dError(DRIVERNOTFOUND); + return; + } + + d3dDriverList = new LPD3dDriverInfo[numDriver]; + + if (d3dDriverList == NULL) { + D3dCtx::d3dError(OUTOFMEMORY); + return; + } + + D3dDriverInfo *pDriver; + + for (int i = 0; i < numDriver; i++ ) + { + pDriver = new D3dDriverInfo(); + d3dDriverList[i] = pDriver; + pD3D->GetAdapterIdentifier(i, D3DENUM_NO_WHQL_LEVEL, + &pDriver->adapterIdentifier); + pD3D->GetAdapterDisplayMode(i, &pDriver->desktopMode); + computeRGBDepth(pDriver); + pDriver->hMonitor = pD3D->GetAdapterMonitor(i); + pDriver->iAdapter = i; + + for (int j = 0; j < numDeviceTypes; j++ ) + { + D3DCAPS8 d3dCaps; + D3dDeviceInfo* pDevice = pDriver->d3dDeviceList[j]; + pDevice->deviceType = deviceTypes[j]; + pD3D->GetDeviceCaps(i, deviceTypes[j], &d3dCaps); + pDevice->setCaps(&d3dCaps); + pDevice->desktopCompatible = + SUCCEEDED(pD3D->CheckDeviceType(i, deviceTypes[j], + pDriver->desktopMode.Format, + pDriver->desktopMode.Format, + TRUE)); + pDevice->fullscreenCompatible = + SUCCEEDED(pD3D->CheckDeviceType(i,deviceTypes[j], + pDriver->desktopMode.Format, + pDriver->desktopMode.Format, + FALSE)); + pDevice->maxZBufferDepthSize = 0; + + if (pDevice->isHardwareTnL) { + strcpy(pDevice->deviceName, "Transform & Light Hardware Rasterizer"); + } else if (pDevice->isHardware) { + strcpy(pDevice->deviceName, "Hardware Rasterizer"); + } else { + strcpy(pDevice->deviceName, "Reference Rasterizer"); + } + + for (int k=0; k < D3DDEPTHFORMATSIZE; k++) { + pDevice->depthFormatSupport[k] = + SUCCEEDED(pD3D->CheckDeviceFormat(i, deviceTypes[j], + pDriver->desktopMode.Format, + D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, + d3dDepthFormat[k])) + && + SUCCEEDED(pD3D->CheckDepthStencilMatch(i, deviceTypes[j], + pDriver->desktopMode.Format, + pDriver->desktopMode.Format, + d3dDepthFormat[k])); + if (pDevice->depthFormatSupport[k]) { + if (d3dDepthTable[k] > pDevice->maxZBufferDepthSize) { + pDevice->maxZBufferDepthSize = d3dDepthTable[k]; + } + } + } + + DWORD bitmask = 1 << 2; + pDevice->multiSampleSupport = 0; + for (int mtype = D3DMULTISAMPLE_2_SAMPLES; + mtype <= D3DMULTISAMPLE_16_SAMPLES; mtype++) { + // consider desktop mode only for multisampling + if (SUCCEEDED(pD3D->CheckDeviceMultiSampleType(i, deviceTypes[j], + pDriver->desktopMode.Format, + TRUE, + (D3DMULTISAMPLE_TYPE) mtype))) { + pDevice->multiSampleSupport |= bitmask; + } + bitmask <<= 1; + } + } + } +} + + + +// Cleanup when no more ctx exists +VOID D3dDriverInfo::release() +{ + for (int i = 0; i < numDriver; i++ ) { + SafeDelete(d3dDriverList[i]); + } + SafeDelete(d3dDriverList); + numDriver = 0; +} + +VOID printInfo() +{ + printf("Java 3D 1.3.2, Windows version is %d.%d ", + osvi.dwMajorVersion, osvi.dwMinorVersion); + + printf("Build: %d, ", LOWORD(osvi.dwBuildNumber)); + + switch(osvi.dwPlatformId) { + case VER_PLATFORM_WIN32s: + printf("Windows3.1"); + break; + case VER_PLATFORM_WIN32_WINDOWS: + printf("Windows 95/98"); + break; + case VER_PLATFORM_WIN32_NT: + printf("Windows NT"); + break; + } + + printf(" %s", osvi.szCSDVersion); + + D3dDriverInfo *pDriver; + for (int i=0; i < numDriver; i++) { + pDriver = d3dDriverList[i]; + D3DADAPTER_IDENTIFIER8 *id = &pDriver->adapterIdentifier; + D3DDISPLAYMODE *dm = &pDriver->desktopMode; + printf("\n[Display Driver] %s, %s, Product %d\n", + id->Driver, id->Description, + HIWORD(id->DriverVersion.HighPart)); + printf(" Version %d.%d, Build %d, VendorId %d\n", + LOWORD(id->DriverVersion.HighPart), + HIWORD(id->DriverVersion.LowPart), + LOWORD(id->DriverVersion.LowPart)); + printf(" DeviceId 0x%x, SubSysId 0x%x, Revision 0x%d\n", + id->VendorId, id->DeviceId, + id->SubSysId, id->Revision); + printf(" [Desktop Mode] %dx%d ", + dm->Width, dm->Height); + + if (dm->RefreshRate != 0) { + printf("%d MHz", dm->RefreshRate); + } + printf(", %s\n", getPixelFormatName(dm->Format)); + + for (int j=0; j < numDeviceTypes; j++) { + D3dDeviceInfo *pDevice = pDriver->d3dDeviceList[j]; + printf("\t[Device] %s ", pDevice->deviceName); + if (pDevice->multiSampleSupport) { + printf("(AA)"); + } + printf("\n"); + } + } + printf("\n"); +} + + +// Construct the D3dDriverList by enumerate all the drivers +VOID D3dDriverInfo::initialize(JNIEnv *env) +{ + HINSTANCE hD3D8DLL = LoadLibrary( "D3D8.DLL" ); + + // Simply see if D3D8.dll exists. + if ( hD3D8DLL == NULL ) + { + D3dCtx::d3dError(D3DNOTFOUND); + return; + } + FreeLibrary(hD3D8DLL); + + + LPDIRECT3D8 pD3D = Direct3DCreate8( D3D_SDK_VERSION ); + + if (pD3D == NULL) { + D3dCtx::d3dError(D3DNOTFOUND); + return; + } + + // must appear before buildDriverList in order to + // set VertexBufferLimit correctly in D3dDeviceInfo + D3dCtx::setVBLimitProperty(env); + + buildDriverList(pD3D); + + SafeRelease(pD3D); + + D3dCtx::setDebugProperty(env); + + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); + + if (debug) { + printInfo(); + } + + // compute requiredGUID + D3dCtx::setDeviceFromProperty(env); + + D3dCtx::setImplicitMultisamplingProperty(env); + + RasterList.init(); + BackgroundImageList.init(); + + // Setup Global constant Ambient light + ambientLight.Type = D3DLIGHT_DIRECTIONAL; + ambientLight.Direction.x = 0; + ambientLight.Direction.y = 0; + ambientLight.Direction.z = 1; + CopyColor(ambientLight.Diffuse, 0, 0, 0, 1.0f); + CopyColor(ambientLight.Ambient, 1.0f, 1.0f, 1.0f, 1.0f); + CopyColor(ambientLight.Specular, 0, 0, 0, 1.0f); +} + + + + diff --git a/src/native/d3d/D3dDriverInfo.hpp b/src/native/d3d/D3dDriverInfo.hpp new file mode 100644 index 0000000..f907a99 --- /dev/null +++ b/src/native/d3d/D3dDriverInfo.hpp @@ -0,0 +1,61 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#if !defined(D3DDRIVERINFO_H) +#define D3DDRIVERINFO_H + +#include "StdAfx.h" + + +#define DEVICE_HAL 0 +#define DEVICE_REF 1 +#define DEVICE_HAL_TnL 2 + +extern D3DFORMAT d3dDepthFormat[D3DDEPTHFORMATSIZE]; +extern int d3dDepthTable[D3DDEPTHFORMATSIZE]; + +class D3dDriverInfo { +public: + // DDraw Driver info + D3DADAPTER_IDENTIFIER8 adapterIdentifier; + // Desktop display mode for this adapter + D3DDISPLAYMODE desktopMode; + // monitor handle for this adapter + HMONITOR hMonitor; + + // Index position in the adapter list + UINT iAdapter; + + // Support devices : HAL or REF + D3dDeviceInfo* d3dDeviceList[2]; + + // Use for NativeConfigTemplate to + // determine the min. config support + UINT redDepth, greenDepth, blueDepth; + + D3dDriverInfo(); + ~D3dDriverInfo(); + + static VOID initialize(JNIEnv *env); + static VOID release(); +}; + +typedef D3dDriverInfo* LPD3dDriverInfo; +extern int numDriver; // size of above array list +extern D3dDriverInfo **d3dDriverList; +extern const DWORD numDeviceTypes; +extern const D3DDEVTYPE deviceTypes[2]; +extern int requiredDeviceID; // force to use HAL/REF or exit +extern int requiredDriverID; // force to use specific adapte +extern D3DLIGHT8 ambientLight; // constant ambient light +extern BOOL implicitMultisample; +#endif diff --git a/src/native/d3d/D3dImageComponent.cpp b/src/native/d3d/D3dImageComponent.cpp new file mode 100644 index 0000000..e857f5f --- /dev/null +++ b/src/native/d3d/D3dImageComponent.cpp @@ -0,0 +1,171 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include "StdAfx.h" + +D3dImageComponent::D3dImageComponent() +{ + init(); +} + + +D3dImageComponent::D3dImageComponent(D3dCtx *_ctx, + int _hashCode, + LPDIRECT3DTEXTURE8 _surf) +{ + ctx = _ctx; + hashCode = _hashCode; + surf = _surf; + next = NULL; +} + +D3dImageComponent::~D3dImageComponent() +{ + if ((ctx != NULL) && (surf != NULL)) { + ctx->freeResource(surf); + } +} + +VOID D3dImageComponent::init() +{ + next = NULL; + surf = NULL; + hashCode = 0; + ctx = NULL; +} + +D3dImageComponent* D3dImageComponent::add(D3dImageComponent *list, + D3dCtx *ctx, + int hashCode, + LPDIRECT3DTEXTURE8 surf) +{ + D3dImageComponent *p = list->next; + + D3dImageComponent *ic = new D3dImageComponent(ctx, hashCode, surf); + + if (ic == NULL) { + return NULL; + } + list->next = ic; + ic->next = p; + return ic; +} + +D3dImageComponent* D3dImageComponent::find(D3dImageComponent *list, + D3dCtx *ctx, + int hashCode) +{ + // skip the first dummy node + D3dImageComponent *p = list->next; + while (p != NULL) { + if ((p->ctx == ctx) && + (p->hashCode == hashCode)) { + return p; + } + p = p->next; + } + return NULL; +} + + +VOID D3dImageComponent::remove(D3dImageComponent *list, + D3dCtx *ctx, int hashCode) +{ + // skip the first dummy node + D3dImageComponent *p = list->next; + D3dImageComponent *q = list; + + while (p != NULL) { + if ((p->ctx == ctx) && + (p->hashCode == hashCode)) { + q->next = p->next; + delete p; + break; + } + q = p; + p = p->next; + + } +} + + +VOID D3dImageComponent::remove(D3dImageComponent *list, + int hashCode) +{ + // skip the first dummy node + D3dImageComponent *p = list->next; + D3dImageComponent *q = list; + + while (p != NULL) { + if (p->hashCode == hashCode) { + q->next = p->next; + delete p; + // continue for image in another ctx + p = q->next; + } else { + q = p; + p = p->next; + } + } +} + +VOID D3dImageComponent::remove(D3dImageComponent *list, + D3dCtx *ctx) +{ + // skip the first dummy node + D3dImageComponent *p = list->next; + D3dImageComponent *q = list; + + while (p != NULL) { + if (p->ctx == ctx) { + q->next = p->next; + delete p; + p = q->next; + // continue for other images + } else { + q = p; + p = p->next; + } + } +} + +VOID D3dImageComponent::remove(D3dImageComponent *list, + D3dImageComponent *ic) +{ + // skip the first dummy node + D3dImageComponent *p = list->next; + D3dImageComponent *q = list; + + while (p != NULL) { + if (p == ic) { + q->next = p->next; + delete p; + break; + } + q = p; + p = p->next; + } +} + +VOID D3dImageComponent::removeAll(D3dImageComponent *list) +{ + // skip the first dummy node + D3dImageComponent *q, *p = list->next; + + list->next = NULL; + + while (p != NULL) { + q = p->next; + delete p; + p = q; + } +} diff --git a/src/native/d3d/D3dImageComponent.hpp b/src/native/d3d/D3dImageComponent.hpp new file mode 100644 index 0000000..659f907 --- /dev/null +++ b/src/native/d3d/D3dImageComponent.hpp @@ -0,0 +1,52 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#if !defined(D3DIMAGECOMPONENT_H) +#define D3DIMAGECOMPONENT_H + +#include "StdAfx.h" + +class D3dImageComponent { +public: + + LPDIRECT3DTEXTURE8 surf; + D3dCtx *ctx; + int hashCode; + D3dImageComponent *next; + + D3dImageComponent(); + + D3dImageComponent(D3dCtx *ctx, int hashCode, + LPDIRECT3DTEXTURE8 surf); + + ~D3dImageComponent(); + + VOID init(); + + static D3dImageComponent* find(D3dImageComponent *list, + D3dCtx *ctx, int hashCode); + + static D3dImageComponent* add(D3dImageComponent *list, + D3dCtx *ctx, int hashCode, + LPDIRECT3DTEXTURE8 surf); + + static VOID remove(D3dImageComponent *list, D3dCtx *ctx, int hashCode); + static VOID remove(D3dImageComponent *list, D3dCtx *ctx); + static VOID remove(D3dImageComponent *list, int hashCode); + static VOID remove(D3dImageComponent *list, D3dImageComponent *ic); + static VOID removeAll(D3dImageComponent *list); +}; + +extern D3dImageComponent RasterList; +extern D3dImageComponent BackgroundImageList; + +#endif diff --git a/src/native/d3d/D3dUtil.cpp b/src/native/d3d/D3dUtil.cpp new file mode 100644 index 0000000..643b809 --- /dev/null +++ b/src/native/d3d/D3dUtil.cpp @@ -0,0 +1,11666 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include "StdAfx.h" + +HANDLE hSema = CreateSemaphore(NULL, 1, 1, "Java3d_Ctx"); +HANDLE imageSema = CreateSemaphore(NULL, 1, 1, + "Java3d_ImageComponent2DLock"); +HANDLE backgroundSema = CreateSemaphore(NULL, 1, 1, + "Java3d_ImageBackgroundLock"); +HANDLE geometrySema = CreateSemaphore(NULL, 1, 1, + "Java3d_GeometryArrayLock"); +HANDLE surfaceListSema = CreateSemaphore(NULL, 1, 1, "Java3d_SurfaceListLock"); + +BOOL firstError = true; +BOOL firstWarning = true; +BOOL debug; + + +vector freePointerList0; +vector freePointerList1; +BOOL useFreePointerList0 = true; + +char *D3dErrorMessage[] = { + "Can't found 3D Driver !", + "Current display driver did not support renderer inside window. Now switch to full screen mode...", + "DirectX 8.0 or above is required for this version of Java3D.", + "Your graphics card did not support >= 16 bit color mode which Java 3D required.", + "Please switch your display mode to at least 16 bit color depth.", + "No compatible device found, please switch to other display mode and try again !", + "Fail to create hardware D3D Device, switch to use reference rasterizer.", + "Fail to create reference rasterizer 3D Device.", + "Fail to set Viewport", + "Fail to get attach back buffer", + "256 color mode not support !", + "Out of memory !", + "Unknown 3D device specified in property j3d.d3ddevice, please use either \"reference\" or \"hardware\".", + "Graphics card did not support Hardware acceleration", + "Graphics card did not support Transform and light hardware acceleration", + "No Stencil buffer found in current display mode. DecalGroup may not work correctly.", + "Can't found a valid texture format, please try to use reference mode", + "Fail to create offscreen image for background", + "Fail to create Vertex Buffer", + "Fail to Reset() D3D device, try Recreate device again.", + "No compatible depth buffer found in your system, please switch to other display mode or try reference rasterizer.", + "Depth buffer with the required bit depth is not support, please try the default.", + "Fail to lock Vertex Buffer", + "Fail to create Vertex Buffer", + "Fail to create Index Buffer", + "Fail to lock Index Buffer" +}; + +D3DTRANSFORMSTATETYPE transformState[] = { + D3DTS_TEXTURE0, + D3DTS_TEXTURE1, + D3DTS_TEXTURE2, + D3DTS_TEXTURE3, + D3DTS_TEXTURE4, + D3DTS_TEXTURE5, + D3DTS_TEXTURE6, + D3DTS_TEXTURE7}; + +#define D3DFORMATTABLESIZE 40 + +D3DFORMAT d3dFormatTable[] = { + D3DFMT_UNKNOWN, + D3DFMT_R8G8B8, + D3DFMT_A8R8G8B8, + D3DFMT_X8R8G8B8, + D3DFMT_R5G6B5, + D3DFMT_X1R5G5B5, + D3DFMT_A1R5G5B5, + D3DFMT_A4R4G4B4, + D3DFMT_R3G3B2, + D3DFMT_A8, + D3DFMT_A8R3G3B2, + D3DFMT_X4R4G4B4, + D3DFMT_A8P8, + D3DFMT_P8, + D3DFMT_L8, + D3DFMT_A8L8, + D3DFMT_A4L4, + D3DFMT_V8U8, + D3DFMT_L6V5U5, + D3DFMT_X8L8V8U8, + D3DFMT_Q8W8V8U8, + D3DFMT_V16U16, + D3DFMT_W11V11U10, + D3DFMT_UYVY, + D3DFMT_YUY2, + D3DFMT_DXT1, + D3DFMT_DXT2, + D3DFMT_DXT3, + D3DFMT_DXT4, + D3DFMT_DXT5, + D3DFMT_D16_LOCKABLE, + D3DFMT_D32, + D3DFMT_D15S1, + D3DFMT_D24S8, + D3DFMT_D16, + D3DFMT_D24X8, + D3DFMT_D24X4S4, + D3DFMT_VERTEXDATA, + D3DFMT_INDEX16, + D3DFMT_INDEX32 +}; + +char *d3dFormatTableChar[] = { + "D3DFMT_UNKNOWN", + "D3DFMT_R8G8B8", + "D3DFMT_A8R8G8B8", + "D3DFMT_X8R8G8B8", + "D3DFMT_R5G6B5", + "D3DFMT_X1R5G5B5", + "D3DFMT_A1R5G5B5", + "D3DFMT_A4R4G4B4", + "D3DFMT_R3G3B2", + "D3DFMT_A8", + "D3DFMT_A8R3G3B2", + "D3DFMT_X4R4G4B4", + "D3DFMT_A8P8", + "D3DFMT_P8", + "D3DFMT_L8", + "D3DFMT_A8L8", + "D3DFMT_A4L4", + "D3DFMT_V8U8", + "D3DFMT_L6V5U5", + "D3DFMT_X8L8V8U8", + "D3DFMT_Q8W8V8U8", + "D3DFMT_V16U16", + "D3DFMT_W11V11U10", + "D3DFMT_UYVY", + "D3DFMT_YUY2", + "D3DFMT_DXT1", + "D3DFMT_DXT2", + "D3DFMT_DXT3", + "D3DFMT_DXT4", + "D3DFMT_DXT5", + "D3DFMT_D16_LOCKABLE", + "D3DFMT_D32", + "D3DFMT_D15S1", + "D3DFMT_D24S8", + "D3DFMT_D16", + "D3DFMT_D24X8", + "D3DFMT_D24X4S4", + "D3DFMT_VERTEXDATA", + "D3DFMT_INDEX16", + "D3DFMT_INDEX32" +}; + +char* multipleSampleTypeTable[] = { + "D3DMULTISAMPLE_NONE", + "D3DMULTISAMPLE_UNKNOWN" + "D3DMULTISAMPLE_2_SAMPLES", + "D3DMULTISAMPLE_3_SAMPLES", + "D3DMULTISAMPLE_4_SAMPLES", + "D3DMULTISAMPLE_5_SAMPLES", + "D3DMULTISAMPLE_6_SAMPLES", + "D3DMULTISAMPLE_7_SAMPLES", + "D3DMULTISAMPLE_8_SAMPLES", + "D3DMULTISAMPLE_9_SAMPLES", + "D3DMULTISAMPLE_10_SAMPLES", + "D3DMULTISAMPLE_11_SAMPLES", + "D3DMULTISAMPLE_12_SAMPLES", + "D3DMULTISAMPLE_13_SAMPLES", + "D3DMULTISAMPLE_14_SAMPLES", + "D3DMULTISAMPLE_15_SAMPLES", + "D3DMULTISAMPLE_16_SAMPLES", +}; + +char* swapEffectTable[] = { + "D3DSWAPEFFECT_UNKNOWN", + "D3DSWAPEFFECT_DISCARD", + "D3DSWAPEFFECT_FLIP", + "D3DSWAPEFFECT_COPY", + "D3DSWAPEFFECT_COPY_VSYNC" +}; + + +// mapping from java enum to d3d enum + +D3DCUBEMAP_FACES textureCubeMapFace[] = { + D3DCUBEMAP_FACE_POSITIVE_X, + D3DCUBEMAP_FACE_NEGATIVE_X, + D3DCUBEMAP_FACE_POSITIVE_Y, + D3DCUBEMAP_FACE_NEGATIVE_Y, + D3DCUBEMAP_FACE_NEGATIVE_Z, + D3DCUBEMAP_FACE_POSITIVE_Z, +}; + +typedef struct _PIXELFORMAT { + DWORD dwRGBBitCount; + DWORD dwRBitMask; + DWORD dwGBitMask; + DWORD dwBBitMask; + DWORD dwRGBAlphaBitMask; + BOOL noAlpha; +} PIXELFORMAT; + + +typedef struct _DEPTHPIXELFORMAT { + DWORD dwZBufferBitDepth; + DWORD dwZBitMask; +} DEPTHPIXELFORMAT; + + +char *getSwapEffectName(D3DSWAPEFFECT swapEffect) +{ + int t = (int) swapEffect; + if ((t < 0) || (t > 4)) { + return swapEffectTable[0]; + } + return swapEffectTable[t]; +} + +char *getMultiSampleName(D3DMULTISAMPLE_TYPE mtype) +{ + int t = (int) mtype; + if ((t < 0) || (t > 16)) { + // UNKNOWN + return multipleSampleTypeTable[1]; + } + return multipleSampleTypeTable[t]; +} + +char* getPixelFormatName(D3DFORMAT f) +{ + for (int i=0; i < D3DFORMATTABLESIZE; i++) { + if (f == d3dFormatTable[i]) { + return d3dFormatTableChar[i]; + } + } + // should not happen + return d3dFormatTableChar[0]; +} + +// If there is a new D3DFORMAT, just add it here and +// our copy procedures can handle any format specific +// as bit mask. +VOID computePixelFormat(PIXELFORMAT *ddpf, D3DFORMAT format) +{ + switch (format) { + case D3DFMT_R8G8B8: + ddpf->dwRGBBitCount = 24; + ddpf->dwRGBAlphaBitMask = 0; + ddpf->dwRBitMask = 0x00ff0000; + ddpf->dwGBitMask = 0x0000ff00; + ddpf->dwBBitMask = 0x000000ff; + ddpf->noAlpha = true; + break; + case D3DFMT_A8R8G8B8: + ddpf->dwRGBBitCount = 32; + ddpf->dwRGBAlphaBitMask = 0xff000000; + ddpf->dwRBitMask = 0x00ff0000; + ddpf->dwGBitMask = 0x0000ff00; + ddpf->dwBBitMask = 0x000000ff; + ddpf->noAlpha = false; + break; + case D3DFMT_X8R8G8B8: + ddpf->dwRGBBitCount = 32; + ddpf->dwRGBAlphaBitMask = 0; + ddpf->dwRBitMask = 0x00ff0000; + ddpf->dwGBitMask = 0x0000ff00; + ddpf->dwBBitMask = 0x000000ff; + ddpf->noAlpha = true; + break; + case D3DFMT_R5G6B5: + ddpf->dwRGBBitCount = 16; + ddpf->dwRGBAlphaBitMask = 0; + ddpf->dwRBitMask = 0xf800; + ddpf->dwGBitMask = 0x07e0; + ddpf->dwBBitMask = 0x001f; + ddpf->noAlpha = true; + break; + case D3DFMT_X1R5G5B5: + ddpf->dwRGBBitCount = 16; + ddpf->dwRGBAlphaBitMask = 0; + ddpf->dwRBitMask = 0x7c00; + ddpf->dwGBitMask = 0x03e0; + ddpf->dwBBitMask = 0x001f; + ddpf->noAlpha = true; + break; + case D3DFMT_A1R5G5B5: + ddpf->dwRGBBitCount = 16; + ddpf->dwRGBAlphaBitMask = 0x8000; + ddpf->dwRBitMask = 0x7c00; + ddpf->dwGBitMask = 0x03e0; + ddpf->dwBBitMask = 0x001f; + ddpf->noAlpha = false; + break; + case D3DFMT_A4R4G4B4: + ddpf->dwRGBBitCount = 16; + ddpf->dwRGBAlphaBitMask = 0xf000; + ddpf->dwRBitMask = 0x0f00; + ddpf->dwGBitMask = 0x00f0; + ddpf->dwBBitMask = 0x000f; + ddpf->noAlpha = false; + break; + case D3DFMT_X4R4G4B4: + ddpf->dwRGBBitCount = 16; + ddpf->dwRGBAlphaBitMask = 0; + ddpf->dwRBitMask = 0x0f00; + ddpf->dwGBitMask = 0x00f0; + ddpf->dwBBitMask = 0x000f; + ddpf->noAlpha = true; + break; + case D3DFMT_R3G3B2: + ddpf->dwRGBBitCount = 8; + ddpf->dwRGBAlphaBitMask = 0; + ddpf->dwRBitMask = 0xe0; + ddpf->dwGBitMask = 0x1c; + ddpf->dwBBitMask = 0x03; + ddpf->noAlpha = true; + break; + case D3DFMT_A8R3G3B2: + ddpf->dwRGBBitCount = 16; + ddpf->dwRGBAlphaBitMask = 0xff00; + ddpf->dwRBitMask = 0x00e0; + ddpf->dwGBitMask = 0x001c; + ddpf->dwBBitMask = 0x0003; + ddpf->noAlpha = false; + break; + case D3DFMT_A8: + ddpf->dwRGBBitCount = 8; + ddpf->dwRGBAlphaBitMask = 0xff; + ddpf->dwRBitMask = 0; + ddpf->dwGBitMask = 0; + ddpf->dwBBitMask = 0; + ddpf->noAlpha = false; + break; + case D3DFMT_L8: + ddpf->dwRGBBitCount = 8; + ddpf->dwRGBAlphaBitMask = 0; + ddpf->dwRBitMask = 0xff; + ddpf->dwGBitMask = 0; + ddpf->dwBBitMask = 0; + ddpf->noAlpha = true; + break; + case D3DFMT_A8L8: + ddpf->dwRGBBitCount = 16; + ddpf->dwRGBAlphaBitMask = 0xff00; + ddpf->dwRBitMask = 0x00ff; + ddpf->dwGBitMask = 0; + ddpf->dwBBitMask = 0; + ddpf->noAlpha = false; + break; + case D3DFMT_A4L4: + ddpf->dwRGBBitCount = 8; + ddpf->dwRGBAlphaBitMask = 0xf0; + ddpf->dwRBitMask = 0x0f; + ddpf->dwGBitMask = 0; + ddpf->dwBBitMask = 0; + ddpf->noAlpha = false; + break; + default: + printf("Unsupport format %d\n ", format); + ddpf->dwRGBBitCount = 8; + ddpf->dwRGBAlphaBitMask = 0; + ddpf->dwRBitMask = 0; + ddpf->dwGBitMask = 0; + ddpf->dwBBitMask = 0; + ddpf->noAlpha = true; + break; + } + +} + + +/* + * Right now only format D3DFMT_D16_LOCKABLE + * is lockable by application. So can't use + * with stencil buffer (in DecalGroup) together + */ +VOID computeDepthPixelFormat(DEPTHPIXELFORMAT *ddpf, + D3DFORMAT format) +{ + switch (format) { + case D3DFMT_D16_LOCKABLE: + case D3DFMT_D16: + ddpf->dwZBufferBitDepth = 16; + ddpf->dwZBitMask = 0xffff; + break; + case D3DFMT_D15S1: + ddpf->dwZBufferBitDepth = 16; + ddpf->dwZBitMask = 0xfffe; + break; + case D3DFMT_D32: + ddpf->dwZBufferBitDepth = 32; + ddpf->dwZBitMask = 0xffffffff; + break; + case D3DFMT_D24S8: + case D3DFMT_D24X8: + case D3DFMT_D24X4S4: + ddpf->dwZBufferBitDepth = 32; + ddpf->dwZBitMask = 0xffffff00; + break; + default: + printf("Unknown depth buffer format %d\n", format); + } +} + + +/* + * Set the correct D3DTSS_TEXTURETRANSFORMFLAGS + */ +void setTexTransformStageFlag(D3dCtx* d3dCtx, + LPDIRECT3DDEVICE8 device, + int tus, int ts, int genMode) +{ + /* + * In case of automatic texture generation, disable + * texture unit transform stage will cause crash in + * reference device mode. + */ + if ((!d3dCtx->texTransformSet[tus]) && + (d3dCtx->texGenMode == TEX_GEN_NONE)) { + device->SetTextureStageState(tus, + D3DTSS_TEXTURETRANSFORMFLAGS, + D3DTTFF_DISABLE); + } else { + D3DXMATRIX *m; + + switch (ts) { + case 2: + // Adjust for 2D texture transform in D3D + // 1 0 0 0 + // 0 1 0 0 + // du dv 0 0 + // 0 0 0 0 + // + + /* + * From DIRECTXDEV@DISCUSS.MICROSOFT.COM: + * + * The texture transform matrix is funky. With COUNT=2 + * and texture coordinates coming from the vertices, you + * can't use the stock transformation matrix functions to + * generate the matrix without adjusting it before setting + * the transform. Basically in the case of COUNT=2 with + * texcoords coming from the vertices, the pipeline uses + * the upper 3x3 submatrix of the 4x4 matrix as the + * transformation. So if you were expecting the (u,v) + * translation elements to be on the 4th row, these won't + * be applied properly in this case. + * + * What's funky is that if you were using COUNT=2 and + * texture coordinates coming in automatically, then it + * wants the translation in the 4th row. I can't decide + * yet if this is a poor specification that results in + * this matrix weirdness, or if its a bug in the runtime. + */ + if ((genMode != TEX_GEN_AUTO) && + !d3dCtx->texTranslateSet[tus]) { + m = &d3dCtx->texTransform[tus]; + (*m)._31 = (*m)._41; + (*m)._32 = (*m)._42; + device->SetTransform((D3DTRANSFORMSTATETYPE) + (D3DTS_TEXTURE0 + tus), m); + d3dCtx->texTranslateSet[tus] = true; + } + + device->SetTextureStageState(tus, + D3DTSS_TEXTURETRANSFORMFLAGS, + D3DTTFF_COUNT2); + break; + case 3: + device->SetTextureStageState(tus, + D3DTSS_TEXTURETRANSFORMFLAGS, + D3DTTFF_COUNT3); + break; + case 4: + if (d3dCtx->texGenMode[tus] == TEX_OBJ_LINEAR) { + // The texture transform matrix is funky that only the + // upper 3x3 matrix is used if we are not using + // automatic texture generation. In case of Object + // Linear we are need to workaround by doing our + // own texture transform when generate texture + // coordinate. + device->SetTextureStageState(tus, + D3DTSS_TEXTURETRANSFORMFLAGS, + D3DTTFF_DISABLE); + } else { + device->SetTextureStageState(tus, + D3DTSS_TEXTURETRANSFORMFLAGS, + D3DTTFF_COUNT4|D3DTTFF_PROJECTED); + } + break; + default: + printf("ERROR texCoordFormat, stage %d, format %d\n", + tus, ts); + } + } + +} + +/* + * Set the corresponding D3D texture coordinate + * mapping mode. + */ +inline int setTextureStage(D3dCtx *d3dCtx, + LPDIRECT3DDEVICE8 device, + int mapTexStage, + jint texStage) +{ + DWORD mode = 0; + int genMode = d3dCtx->texGenMode[mapTexStage]; + + // printf("Set TexStage mapTexStage = %d, texStage = %d, genMode = %d\n", + // mapTexStage, texStage, genMode); + + switch (genMode) { + case TEX_GEN_NONE: + case TEX_OBJ_LINEAR: + case TEX_GEN_INVALID: + // optimize for general case + device->SetTextureStageState(mapTexStage, + D3DTSS_TEXCOORDINDEX, + texStage); + return genMode; + case TEX_EYE_LINEAR: + mode = D3DTSS_TCI_CAMERASPACEPOSITION; + break; + case TEX_SPHERE_MAP: + mode = D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR; + break; + case TEX_NORMAL_MAP: + mode = D3DTSS_TCI_CAMERASPACENORMAL; + break; + case TEX_REFLECT_MAP: + mode = D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR; + break; + default: + // should not happen + printf("Unknown TexCoordGenMode %d\n", genMode); + break; + } + // Need to OR texStage for Wrapping mode even though + // there is no texture coordinate defined in that texStage in VB. + // This also clear the texStage previously set. + device->SetTextureStageState(mapTexStage, + D3DTSS_TEXCOORDINDEX, + mode | texStage); + + return TEX_GEN_AUTO; +} + + +void getTexWidthHeight(D3dDeviceInfo *deviceInfo, + jint* width, jint *height) +{ + int texWidth, texHeight; + + texWidth = *width; + texHeight = *height; + + + // Found a texture bigger than width/height + if (deviceInfo->texturePow2Only) { + for (texWidth=1; *width > texWidth; texWidth <<= 1); + for (texHeight=1; *height > texHeight; texHeight <<= 1); + } + + + if (deviceInfo->textureSquareOnly) { + if (texWidth >= texHeight) { + texHeight = texWidth; + } else { + texWidth = texHeight; + } + } + + // Check for maximum texture size support by hardware + if (texWidth > deviceInfo->maxTextureWidth) { + if (debug) { + printf("[Java 3D] Warning: Input texture width %d > maximum texture width %d hardware can support.\n", texWidth, deviceInfo->maxTextureWidth); + if (*width != texWidth) { + printf("Note that width is adjust from %d to %d to reflect texture limitation e.g. POW2, SQAUREONLY in hardware.\n", *width, texWidth); + } + } + texWidth = deviceInfo->maxTextureWidth; + } + + if (texHeight > deviceInfo->maxTextureHeight) { + if (debug) { + printf("[Java 3D] Warning: Input texture height %d > maximum texture height %d hardware can support.\n", texHeight, deviceInfo->maxTextureHeight); + if (*height != texHeight) { + printf("Note that height is adjust from %d to %d to reflect texture limitation e.g. POW2, SQAUREONLY in hardware.\n", *height, texHeight); + } + } + texHeight = deviceInfo->maxTextureHeight; + } + + *width = texWidth; + *height = texHeight; +} + +D3DFORMAT getTexFormat(jint internalFormat) { + + switch (internalFormat) { + case J3D_RGBA: + case INTENSITY: + return D3DFMT_A8R8G8B8; + case J3D_RGB: + return D3DFMT_R8G8B8; + case LUMINANCE_ALPHA: + return D3DFMT_A8L8; + case ALPHA: + return D3DFMT_A8; + case LUMINANCE: + return D3DFMT_L8; + default: + printf("CreateTextureSurface: Unknown internal Format %d \n", internalFormat); + return D3DFMT_UNKNOWN; + } + +} + +D3dCtx* findCtx(HWND hwnd) +{ + D3dCtx *ctx = NULL; + + for (D3dCtx **p = d3dCtxList.begin(); p != d3dCtxList.end(); p++) { + if ((*p)->hwnd == hwnd) { + ctx = *p; + break; + } + } + return ctx; +} + + +inline VOID lock() +{ + if (hSema != NULL) { + WaitForSingleObject(hSema, INFINITE); + } +} + +inline VOID unlock() +{ + if (hSema != NULL) { + ReleaseSemaphore(hSema, 1, NULL); + } +} + + +inline VOID lockSurfaceList() +{ + if (surfaceListSema != NULL) { + WaitForSingleObject(surfaceListSema, INFINITE); + } +} + +inline VOID unlockSurfaceList() +{ + if (surfaceListSema != NULL) { + ReleaseSemaphore(surfaceListSema, 1, NULL); + } +} + +inline VOID lockBackground() +{ + if (backgroundSema != NULL) { + WaitForSingleObject(backgroundSema, INFINITE); + } +} + +inline VOID unlockBackground() +{ + if (backgroundSema != NULL) { + ReleaseSemaphore(backgroundSema, 1, NULL); + } +} + +inline VOID lockImage() +{ + if (imageSema != NULL) { + WaitForSingleObject(imageSema, INFINITE); + } +} + +inline VOID unlockImage() +{ + if (imageSema != NULL) { + ReleaseSemaphore(imageSema, 1, NULL); + } +} + + + +inline VOID lockGeometry() +{ + if (geometrySema != NULL) { + WaitForSingleObject(geometrySema, INFINITE); + } +} + +inline VOID unlockGeometry() +{ + if (geometrySema != NULL) { + ReleaseSemaphore(geometrySema, 1, NULL); + } +} + +VOID freePointer(void * ptr) +{ + if (ptr != NULL) { + lockSurfaceList(); + if (useFreePointerList0) { + freePointerList0.push_back(ptr); + } else { + freePointerList1.push_back(ptr); + } + unlockSurfaceList(); + } +} + + +char *getErrorMessage(int idx) +{ + return D3dErrorMessage[idx]; +} + + + +HWND getTopWindow(HWND hwnd) +{ + HWND desktop = GetDesktopWindow(); + HWND parent = GetParent(hwnd); + + while ((parent != NULL) && (parent != desktop)) { + hwnd = parent; + parent = GetParent(hwnd); + } + return hwnd; +} + + +DWORD firstBit(DWORD mask) +{ + int i; + + for (i=0; i < sizeof(DWORD)*8-1; i++) { + if ((mask & 0x01) > 0) { + return i; + } + mask >>= 1; + } + + return i; +} + +// create a DirectDraw Texture surface of specific width and height +LPDIRECT3DTEXTURE8 createTextureSurface(D3dCtx *d3dCtx, + jint numLevels, + jint internalFormat, + jint width, jint height) +{ + LPDIRECT3DTEXTURE8 pTexture; + D3DFORMAT format; + HRESULT hr; + + LPDIRECT3DDEVICE8 pDevice = d3dCtx->pDevice; + D3dDeviceInfo *deviceInfo = d3dCtx->deviceInfo; + + if (!deviceInfo->supportMipmap) { + numLevels = 1; + } + + getTexWidthHeight(deviceInfo, &width, &height); + format = getTexFormat(internalFormat); + + // If format not support, the utility function will adjust the + // calling parameters automatically + hr = D3DXCreateTexture(d3dCtx->pDevice, width, height, + numLevels, 0, format, D3DPOOL_MANAGED, + &pTexture); + + if (FAILED(hr)) { + printf("Fail to create texture surface %dx%d, format %d, level %d : %s\n", + width, height, format, numLevels, DXGetErrorString8(hr)); + return NULL; + } + + return pTexture; +} + + + +// create a DirectDraw Texture surface of specific width and height +LPDIRECT3DVOLUMETEXTURE8 createVolumeTexture(D3dCtx *d3dCtx, + jint numLevels, + jint internalFormat, + jint width, + jint height, + jint depth) +{ + LPDIRECT3DVOLUMETEXTURE8 pTexture; + int texWidth, texHeight, texDepth; + D3DFORMAT format; + HRESULT hr; + + LPDIRECT3DDEVICE8 pDevice = d3dCtx->pDevice; + D3dDeviceInfo *deviceInfo = d3dCtx->deviceInfo; + + texWidth = width; + texHeight = height; + texDepth = depth; + + + if (!deviceInfo->supportMipmap) { + numLevels = 1; + } + + + // Found a texture bigger than width/height + if (deviceInfo->texturePow2Only) { + for (texWidth=1; width > texWidth; texWidth <<= 1); + for (texHeight=1; height > texHeight; texHeight <<= 1); + for (texDepth=1; depth > texDepth; texDepth <<= 1); + } + + + if (deviceInfo->textureSquareOnly) { + if (texWidth >= texHeight) { + texHeight = texWidth; + } else { + texWidth = texHeight; + } + if (texDepth <= texWidth) { + texDepth = texWidth; + } else { + texWidth = texHeight = texDepth; + } + } + + // Check for maximum texture size support by hardware + if (texWidth > deviceInfo->maxTextureWidth) { + if (debug) { + printf("[Java 3D] Warning: Input texture width %d > maximum texture width %d hardware can support.\n", texWidth, deviceInfo->maxTextureWidth); + if (width != texWidth) { + printf("Note that width is adjust from %d to %d to reflect texture limitation e.g. POW2, SQAUREONLY in hardware.\n", width, texWidth); + } + } + texWidth = deviceInfo->maxTextureWidth; + } + + if (texHeight > deviceInfo->maxTextureHeight) { + if (debug) { + printf("[Java 3D] Warning: Input texture height %d > maximum texture height %d hardware can support.\n", texHeight, deviceInfo->maxTextureHeight); + if (height != texHeight) { + printf("Note that height is adjust from %d to %d to reflect texture limitation e.g. POW2, SQAUREONLY in hardware.\n", height, texHeight); + } + } + texHeight = deviceInfo->maxTextureHeight; + } + + if (texDepth > deviceInfo->maxTextureDepth) { + if (debug) { + printf("[Java 3D] Warning: Input texture depth %d > maximum texture depth %d hardware can support.\n", texDepth, deviceInfo->maxTextureDepth); + if (depth != texDepth) { + printf("Note that depth is adjust from %d to %d to reflect texture limitation e.g. POW2, SQAUREONLY in hardware.\n", depth, texDepth); + } + } + texDepth = deviceInfo->maxTextureDepth; + } + + + format = getTexFormat(internalFormat); + + // If format not support, the utility function will adjust the + // calling parameters automatically + hr = D3DXCreateVolumeTexture(d3dCtx->pDevice, texWidth, texHeight, + texDepth, numLevels, 0, format, D3DPOOL_MANAGED, + &pTexture); + + if (FAILED(hr)) { + if (debug) { + printf("Fail to create volume texture %dx%dx%d, format %d, level %d : %s\n", + texWidth, texHeight, texDepth, format, numLevels, + DXGetErrorString8(hr)); + } + return NULL; + } + + return pTexture; +} + + +// copy data from DirectDraw surface to memory +// and reverse the Y axis +void copyDataFromSurface(jint internalFormat, + jint xoffset, jint yoffset, + jint subWidth, jint subHeight, + jbyte *data, + LPDIRECT3DSURFACE8 surf) +{ + D3DSURFACE_DESC ddsd; + D3DLOCKED_RECT lockedRect; + PIXELFORMAT ddpf; + HRESULT hr; + + if (surf == NULL) { + return; + } + + surf->GetDesc(&ddsd); + DWORD width = ddsd.Width; + DWORD height = ddsd.Height; + computePixelFormat(&ddpf, ddsd.Format); + + if ((xoffset >= width) || (yoffset >= height)) { + return; + } + + DWORD xlimit = min(xoffset + subWidth, width); + DWORD ylimit = min(yoffset + subHeight, height); + + hr = surf->LockRect(&lockedRect, NULL, D3DLOCK_NOSYSLOCK| + D3DLOCK_READONLY); + + if (FAILED(hr)) { + printf("Fail to lock surface: %s\n", DXGetErrorString8(hr)); + return; + } + + unsigned char *src; + unsigned char *dst; + byte b1, b2, b3, b4; + DWORD mask, t; + DWORD dstPitch; + + unsigned char *destRow = (unsigned char *) data; + unsigned char *srcRow = ((unsigned char *) lockedRect.pBits) + + xoffset*((int) ceil((float) ddpf.dwRGBBitCount/8.0)) + + (yoffset*lockedRect.Pitch); + + + if ((internalFormat == FORMAT_BYTE_RGBA) || + (internalFormat == FORMAT_BYTE_RGB)) { + dstPitch = subWidth << 2; + destRow += (subHeight-1)*dstPitch; + + if ((ddpf.dwRGBBitCount == 32) && + (ddpf.dwRBitMask == 0xff0000) && + (ddpf.dwGBitMask == 0xff00) && + (ddpf.dwBBitMask == 0xff)) { + // Optimize for the most common case + if (ddpf.noAlpha) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + b3 = *src++; + *dst++ = b3; + *dst++ = b2; + *dst++ = b1; + *src++; + *dst++ = (byte) 0xff; + } + srcRow += lockedRect.Pitch; + destRow -= dstPitch; + } + } else { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + b3 = *src++; + *dst++ = b3; + *dst++ = b2; + *dst++ = b1; + *dst++ = *src++; + } + srcRow += lockedRect.Pitch; + destRow -= dstPitch; + } + } + } else { // handle less common format + int rshift = firstBit(ddpf.dwRBitMask) + + countBits(ddpf.dwRBitMask) - 8; + int gshift = firstBit(ddpf.dwGBitMask) + + countBits(ddpf.dwGBitMask) - 8; + int bshift = firstBit(ddpf.dwBBitMask) + + countBits(ddpf.dwBBitMask) - 8; + int ashift = firstBit(ddpf.dwRGBAlphaBitMask) + + countBits(ddpf.dwRGBAlphaBitMask) - 8; + + if ((ddpf.dwRGBBitCount <= 32) && + (ddpf.dwRGBBitCount > 24)) { + + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + b3 = *src++; + b4 = *src++; + mask = ((b4 << 24) | (b3 << 16)| (b2 << 8) | b1); + if (rshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwRBitMask) >> + rshift); + } else { + t = (mask & ddpf.dwRBitMask) << -rshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + + if (gshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwGBitMask) >> + gshift); + } else { + t = (mask & ddpf.dwGBitMask) << -gshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + if (bshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwBBitMask) >> + bshift); + } else { + t = (mask & ddpf.dwBBitMask) << -bshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + if (ddpf.noAlpha) { + *dst++ = (byte) 0xff; + } else { + if (ashift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwRGBAlphaBitMask) >> + ashift); + } else { + t = (mask & ddpf.dwRGBAlphaBitMask) <<-ashift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + } + } + srcRow += lockedRect.Pitch; + destRow -= dstPitch; + } + } else if ((ddpf.dwRGBBitCount <= 24) && + (ddpf.dwRGBBitCount > 16)) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + b3 = *src++; + mask = ((b3 << 16) | (b2 << 8) | b1); + if (rshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwRBitMask) >> + rshift); + } else { + t = (mask & ddpf.dwRBitMask) << -rshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + if (gshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwGBitMask) >> + gshift); + } else { + t = (mask & ddpf.dwGBitMask) <<-gshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + if (bshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwBBitMask) >> + bshift); + } else { + t = (mask & ddpf.dwBBitMask) << -bshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + if (ddpf.noAlpha) { + *dst++ = (byte) 0xff; + } else { + if (ashift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwRGBAlphaBitMask) >> + ashift); + } else { + t = (mask & ddpf.dwRGBAlphaBitMask) <<-ashift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + } + } + srcRow += lockedRect.Pitch; + destRow -= dstPitch; + } + } else if ((ddpf.dwRGBBitCount <= 16) && + (ddpf.dwRGBBitCount > 8)) { + + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + mask = ((b2 << 8) | b1); + if (rshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwRBitMask) >> + rshift); + } else { + t = (mask & ddpf.dwRBitMask) << -rshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + + if (gshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwGBitMask) >> + gshift); + } else { + t = (mask & ddpf.dwGBitMask) << -gshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + if (bshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwBBitMask) >> + bshift); + } else { + t = (mask & ddpf.dwBBitMask) << -bshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + + if (ddpf.noAlpha) { + *dst++ = (byte) 0xff; + } else { + if (ashift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwRGBAlphaBitMask) >> + ashift); + } else { + t = (mask & ddpf.dwRGBAlphaBitMask) <<-ashift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + } + } + srcRow += lockedRect.Pitch; + destRow -= dstPitch; + } + } else if (ddpf.dwRGBBitCount <= 8) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + mask = *src++; + if (rshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwRBitMask) >> + rshift); + } else { + t = (mask & ddpf.dwRBitMask) << -rshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + + if (gshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwGBitMask) >> + gshift); + } else { + t = (mask & ddpf.dwGBitMask) << -gshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + if (bshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwBBitMask) >> + bshift); + } else { + t = (mask & ddpf.dwBBitMask) << -bshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + if (ddpf.noAlpha) { + *dst++ = (byte) 0xff; + } else { + if (ashift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwRGBAlphaBitMask) >> + ashift); + } else { + t = (mask & ddpf.dwRGBAlphaBitMask) <<-ashift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + } + } + srcRow += lockedRect.Pitch; + destRow -= dstPitch; + } + } + } + } else if (internalFormat == FORMAT_BYTE_LA) { + int gshift = firstBit(ddpf.dwGBitMask) + + countBits(ddpf.dwGBitMask) - 8; + int ashift = firstBit(ddpf.dwRGBAlphaBitMask) + + countBits(ddpf.dwRGBAlphaBitMask) - 8; + dstPitch = subWidth << 1; + destRow += (subHeight-1)*dstPitch; + + if ((ddpf.dwRGBBitCount == 32) && + (ddpf.dwRBitMask == 0xff0000) && + (ddpf.dwGBitMask == 0xff00) && + (ddpf.dwBBitMask == 0xff)) { + // Optimize for the most common case + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + b3 = *src++; + *dst++ = b2; + if (ddpf.noAlpha) { + *dst++ = (byte) 0xff; + *src++; + } else { + *dst++ = *src++; + } + } + srcRow += lockedRect.Pitch; + destRow -= dstPitch; + } + } else { // handle less common format + int gshift = firstBit(ddpf.dwGBitMask) + + countBits(ddpf.dwGBitMask) - 8; + if ((ddpf.dwRGBBitCount <= 32) && + (ddpf.dwRGBBitCount > 24)) { + + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + b3 = *src++; + b4 = *src++; + mask = ((b4 << 24) | (b3 << 16)| (b2 << 8) | b1); + if (gshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwGBitMask) >> + gshift); + } else { + t = (mask & ddpf.dwGBitMask) << -gshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + if (ddpf.noAlpha) { + *dst++ = (byte) 0xff; + } else { + if (ashift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwRGBAlphaBitMask) >> + ashift); + } else { + t = (mask & ddpf.dwRGBAlphaBitMask) <<-ashift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + } + } + srcRow += lockedRect.Pitch; + destRow -= dstPitch; + } + } else if ((ddpf.dwRGBBitCount <= 24) && + (ddpf.dwRGBBitCount > 16)) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + b3 = *src++; + mask = ((b3 << 16) | (b2 << 8) | b1); + if (gshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwGBitMask) >> + gshift); + } else { + t = (mask & ddpf.dwGBitMask) << -gshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + if (ddpf.noAlpha) { + *dst++ = (byte) 0xff; + } else { + if (ashift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwRGBAlphaBitMask) >> + ashift); + } else { + t = (mask & ddpf.dwRGBAlphaBitMask) <<-ashift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + } + } + srcRow += lockedRect.Pitch; + destRow -= dstPitch; + } + } else if ((ddpf.dwRGBBitCount <= 16) && + (ddpf.dwRGBBitCount > 8)) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + mask = ((b2 << 8) | b1); + if (gshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwGBitMask) >> + gshift); + } else { + t = (mask & ddpf.dwGBitMask) << -gshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + if (ddpf.noAlpha) { + *dst++ = (byte) 0xff; + } else { + if (ashift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwRGBAlphaBitMask) >> + ashift); + } else { + t = (mask & ddpf.dwRGBAlphaBitMask) <<-ashift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + } + } + srcRow += lockedRect.Pitch; + destRow -= dstPitch; + } + } else if (ddpf.dwRGBBitCount <= 8) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + mask = *src++; + if (gshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwGBitMask) >> + gshift); + } else { + t = (mask & ddpf.dwGBitMask) << -gshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + if (ddpf.noAlpha) { + *dst++ = (byte) 0xff; + } else { + if (ashift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwRGBAlphaBitMask) >> + ashift); + } else { + t = (mask & ddpf.dwRGBAlphaBitMask) <<-ashift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + } + } + srcRow += lockedRect.Pitch; + destRow -= dstPitch; + } + } + } + + } else if (internalFormat == FORMAT_BYTE_GRAY) { + int gshift = firstBit(ddpf.dwGBitMask) + + countBits(ddpf.dwGBitMask) - 8; + dstPitch = subWidth; + destRow += (subHeight-1)*dstPitch; + + if ((ddpf.dwRGBBitCount == 32) && + (ddpf.dwRBitMask == 0xff0000) && + (ddpf.dwGBitMask == 0xff00) && + (ddpf.dwBBitMask == 0xff)) { + // Optimize for the most common case + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + b3 = *src++; + *dst++ = b2; + *src++; + } + srcRow += lockedRect.Pitch; + destRow -= dstPitch; + } + } else { // handle less common format + int gshift = firstBit(ddpf.dwGBitMask) + + countBits(ddpf.dwGBitMask) - 8; + if ((ddpf.dwRGBBitCount <= 32) && + (ddpf.dwRGBBitCount > 24)) { + + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + b3 = *src++; + b4 = *src++; + mask = ((b4 << 24) | (b3 << 16)| (b2 << 8) | b1); + if (gshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwGBitMask) >> + gshift); + } else { + t = (mask & ddpf.dwGBitMask) << -gshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + } + srcRow += lockedRect.Pitch; + destRow -= dstPitch; + } + } else if ((ddpf.dwRGBBitCount <= 24) && + (ddpf.dwRGBBitCount > 16)) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + b3 = *src++; + mask = ((b3 << 16) | (b2 << 8) | b1); + if (gshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwGBitMask) >> + gshift); + } else { + t = (mask & ddpf.dwGBitMask) << -gshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + } + srcRow += lockedRect.Pitch; + destRow -= dstPitch; + } + } else if ((ddpf.dwRGBBitCount <= 16) && + (ddpf.dwRGBBitCount > 8)) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + mask = ((b2 << 8) | b1); + if (gshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwGBitMask) >> + gshift); + } else { + t = (mask & ddpf.dwGBitMask) << -gshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + } + srcRow += lockedRect.Pitch; + destRow -= dstPitch; + } + } else if (ddpf.dwRGBBitCount <= 8) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + mask = *src++; + if (gshift >= 0) { + *dst++ = (byte) ((mask & ddpf.dwGBitMask) >> + gshift); + } else { + t = (mask & ddpf.dwGBitMask) << -gshift; + *dst++ = (t <= 0xff ? (byte) t : 0xff); + } + } + srcRow += lockedRect.Pitch; + destRow -= dstPitch; + } + } + } + + } else { + // FORMAT_USHORT_GRAY + printf("[Java 3D] copyDataFromSurface: Format not support %d\n", internalFormat); + } + + + hr = surf->UnlockRect(); + if (FAILED(hr)) { + printf("Fail to unlock surface: %s\n", DXGetErrorString8(hr)); + return; + } + +} + + +void copyDataToSurfaceABGR(jint internalFormat, + PIXELFORMAT *ddpf, + unsigned char* pRect, + DWORD rectPitch, + jbyte *data, + jint xoffset, jint yoffset, + DWORD xlimit, DWORD ylimit, + jint subWidth) +{ + unsigned char *src; + unsigned char *dst; + DWORD r, g, b, a, l; + const DWORD srcPitch = subWidth*4; + unsigned char *srcRow = (unsigned char *) data; + unsigned char *destRow = pRect + rectPitch*yoffset; + + if ((internalFormat == J3D_RGBA) || + (internalFormat == J3D_RGB)) { + if ((ddpf->dwRGBBitCount == 32) && + (ddpf->dwRBitMask == 0xff0000) && + (ddpf->dwGBitMask == 0xff00) && + (ddpf->dwBBitMask == 0xff)) { + // Optimize for most common case + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + a = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst++ = a; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount == 16) && + (ddpf->dwRBitMask == 0xf00) && + (ddpf->dwGBitMask == 0xf0) && + (ddpf->dwBBitMask == 0xf)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + a = (*src++) >> 4; // discard the lower 4 bit + b = (*src++) >> 4; + g = (*src++) >> 4; + r = (*src++) >> 4; + *dst++ = (g << 4) | b; + *dst++ = (a << 4) | r; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { // handle less common (even weird) format + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + *dst++ = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + // should not happen, RGBBitCount > 32. Even DirectX + // RGB mask can't address it. + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } + } else if (internalFormat == LUMINANCE_ALPHA) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + src++; + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + src++; + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + src++; + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + src++; + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + *dst++ = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if (internalFormat == ALPHA) { + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + src += 3; + mask = a << ashift; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + src += 3; + mask = a << ashift; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + src += 3; + mask = (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + src += 3; + *dst++ = (byte) (a << ashift); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if ((internalFormat == LUMINANCE) || + (internalFormat == INTENSITY)) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src += 3; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src += 3; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src += 3; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src += 3; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + *dst++ = (byte) ((r << rshift) | + (g << gshift) | + (b << bshift) | + (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else { + printf("Texture format %d not support.\n", internalFormat); + } +} + + +void copyDataToSurfaceBGR(jint internalFormat, + PIXELFORMAT *ddpf, + unsigned char* pRect, + DWORD rectPitch, + jbyte *data, + jint xoffset, jint yoffset, + DWORD xlimit, DWORD ylimit, + jint subWidth) +{ + unsigned char *src; + unsigned char *dst; + DWORD r, g, b, l; + const DWORD srcPitch = subWidth*3; + unsigned char *srcRow = (unsigned char *) data; + unsigned char *destRow = pRect + rectPitch*yoffset; + + + if ((internalFormat == J3D_RGBA) || + (internalFormat == J3D_RGB)) { + if ((ddpf->dwRGBBitCount == 32) && + (ddpf->dwRBitMask == 0xff0000) && + (ddpf->dwGBitMask == 0xff00) && + (ddpf->dwBBitMask == 0xff)) { + // Optimize for most common case + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst++ = 0xff; + } + srcRow += srcPitch; + destRow += rectPitch; + } + + } else if ((ddpf->dwRGBBitCount == 16) && + (ddpf->dwRBitMask == 0xf00) && + (ddpf->dwGBitMask == 0xf0) && + (ddpf->dwBBitMask == 0xf)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b = (*src++) >> 4; + g = (*src++) >> 4; + r = (*src++) >> 4; + *dst++ = (g << 4) | b; + *dst++ = 0xf0 | r; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { // handle less common (even weird) format + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + *dst++ = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + // should not happen, RGBBitCount > 32. Even DirectX + // RGB mask can't address it. + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } + } else if (internalFormat == LUMINANCE_ALPHA) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + *dst++ = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) |ddpf->dwRGBAlphaBitMask); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if (internalFormat == ALPHA) { + byte m1 = (byte) (ddpf->dwRGBAlphaBitMask & 0xff); + byte m2 = (byte) ((ddpf->dwRGBAlphaBitMask >> 8) & 0xff); + byte m3 = (byte) ((ddpf->dwRGBAlphaBitMask >> 16) & 0xff); + byte m4 = (byte) ((ddpf->dwRGBAlphaBitMask >> 24) & 0xff); + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + *dst++ = m1; + *dst++ = m2; + *dst++ = m3; + *dst++ = m4; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + *dst++ = m1; + *dst++ = m2; + *dst++ = m3; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + *dst++ = m1; + *dst++ = m2; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + *dst++ = m1; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if ((internalFormat == LUMINANCE) || + (internalFormat == INTENSITY)) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src += 3; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src += 3; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src += 3; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src += 3; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + *dst++ = (byte) ((r << rshift) | + (g << gshift) | + (b << bshift) | + ddpf->dwRGBAlphaBitMask); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else { + printf("Texture format %d not support.\n", internalFormat); + } +} + +/* + * Same as copyDataToSurfaceRGBA() + * but the pixel is written in the destination buffer + * from right to left. This is used for CubeMapping. + */ +void copyDataToSurfaceRGBARev(jint internalFormat, + PIXELFORMAT *ddpf, + unsigned char* pRect, + DWORD rectPitch, + jbyte *data, + jint xoffset, jint yoffset, + DWORD xlimit, DWORD ylimit, + jint subWidth) +{ + unsigned char *src; + unsigned char *dst; + DWORD r, g, b, a, l; + unsigned char *srcRow = (unsigned char *) data; + unsigned char *destRow = pRect + rectPitch*yoffset; + const DWORD srcPitch = subWidth*4; + + if ((internalFormat == J3D_RGBA) || + (internalFormat == J3D_RGB)) { + if ((ddpf->dwRGBBitCount == 32) && + (ddpf->dwRBitMask == 0xff0000) && + (ddpf->dwGBitMask == 0xff00) && + (ddpf->dwBBitMask == 0xff)) { + // Most common case + // Note that format of destination is ARGB, which + // in PC format are BGRA, so we can't directly + // copy a row using CopyMemory() + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + r = *src++; + g = *src++; + b = *src++; + *dst-- = *src++; + *dst-- = r; + *dst-- = g; + *dst-- = b; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount == 16) && + (ddpf->dwRBitMask == 0xf00) && + (ddpf->dwGBitMask == 0xf0) && + (ddpf->dwBBitMask == 0xf)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + r = (*src++) >> 4; // discard the lower 4 bit + g = (*src++) >> 4; + b = (*src++) >> 4; + a = (*src++) >> 4; + *dst-- = (a << 4) | r; + *dst-- = (g << 4) | b; + + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { // handle less common (even weird) format + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit-1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + *dst-- = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + // should not happen, RGBBitCount > 32. Even DirectX + // RGB mask can't address it. + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } + } else if (internalFormat == LUMINANCE_ALPHA) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) -1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += ((xlimit*3) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + *dst-- = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if (internalFormat == ALPHA) { + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = a << ashift; + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += ((xlimit*3) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = a << ashift; + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit-1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + *dst-- = (byte) (a << ashift); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if ((internalFormat == LUMINANCE) || + (internalFormat == INTENSITY)) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += ((xlimit*3)-1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit-1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + *dst-- = (byte) ((r << rshift) | + (g << gshift) | + (b << bshift) | + (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else { + printf("Texture format %d not support.\n", internalFormat); + } +} + + + +void copyDataToSurfaceABGRRev(jint internalFormat, + PIXELFORMAT *ddpf, + unsigned char* pRect, + DWORD rectPitch, + jbyte *data, + jint xoffset, jint yoffset, + DWORD xlimit, DWORD ylimit, + jint subWidth) +{ + unsigned char *src; + unsigned char *dst; + DWORD r, g, b, a, l; + const DWORD srcPitch = subWidth*4; + unsigned char *srcRow = (unsigned char *) data; + unsigned char *destRow = pRect + rectPitch*yoffset; + + if ((internalFormat == J3D_RGBA) || + (internalFormat == J3D_RGB)) { + if ((ddpf->dwRGBBitCount == 32) && + (ddpf->dwRBitMask == 0xff0000) && + (ddpf->dwGBitMask == 0xff00) && + (ddpf->dwBBitMask == 0xff)) { + // Optimize for most common case + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + a = *src++; + b = *src++; + g = *src++; + r = *src++; + *dst-- = a; + *dst-- = r; + *dst-- = g; + *dst-- = b; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount == 16) && + (ddpf->dwRBitMask == 0xf00) && + (ddpf->dwGBitMask == 0xf0) && + (ddpf->dwBBitMask == 0xf)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + a = (*src++) >> 4; // discard the lower 4 bit + b = (*src++) >> 4; + g = (*src++) >> 4; + r = (*src++) >> 4; + *dst-- = (a << 4) | r; + *dst-- = (g << 4) | b; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { // handle less common (even weird) format + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3-1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit-1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + *dst-- = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + // should not happen, RGBBitCount > 32. Even DirectX + // RGB mask can't address it. + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } + } else if (internalFormat == LUMINANCE_ALPHA) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + src++; + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3-1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + src++; + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + src++; + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + src++; + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + *dst-- = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if (internalFormat == ALPHA) { + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + src += 3; + mask = a << ashift; + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3-1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + src += 3; + mask = a << ashift; + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + src += 3; + mask = (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xlimit; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + src += 3; + *dst-- = (byte) (a << ashift); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if ((internalFormat == LUMINANCE) || + (internalFormat == INTENSITY)) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src += 3; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3-1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src += 3; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src += 3; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src += 3; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + *dst-- = (byte) ((r << rshift) | + (g << gshift) | + (b << bshift) | + (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else { + printf("Texture format %d not support.\n", internalFormat); + } + +} + + +void copyDataToSurfaceBGRRev(jint internalFormat, + PIXELFORMAT *ddpf, + unsigned char* pRect, + DWORD rectPitch, + jbyte *data, + jint xoffset, jint yoffset, + DWORD xlimit, DWORD ylimit, + jint subWidth) +{ + unsigned char *src; + unsigned char *dst; + DWORD r, g, b, l; + const DWORD srcPitch = subWidth*3; + unsigned char *srcRow = (unsigned char *) data; + unsigned char *destRow = pRect + rectPitch*yoffset; + + + if ((internalFormat == J3D_RGBA) || + (internalFormat == J3D_RGB)) { + if ((ddpf->dwRGBBitCount == 32) && + (ddpf->dwRBitMask == 0xff0000) && + (ddpf->dwGBitMask == 0xff00) && + (ddpf->dwBBitMask == 0xff)) { + // Optimize for most common case + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b = *src++; + g = *src++; + r = *src++; + *dst-- = 0xff; + *dst-- = r; + *dst-- = g; + *dst-- = b; + } + srcRow += srcPitch; + destRow += rectPitch; + } + + } else if ((ddpf->dwRGBBitCount == 16) && + (ddpf->dwRBitMask == 0xf00) && + (ddpf->dwGBitMask == 0xf0) && + (ddpf->dwBBitMask == 0xf)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b = (*src++) >> 4; + g = (*src++) >> 4; + r = (*src++) >> 4; + *dst-- = 0xf0 | r; + *dst-- = (g << 4) | b; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { // handle less common (even weird) format + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3-1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + *dst-- = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + // should not happen, RGBBitCount > 32. Even DirectX + // RGB mask can't address it. + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } + } else if (internalFormat == LUMINANCE_ALPHA) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + *dst-- = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) |ddpf->dwRGBAlphaBitMask); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if (internalFormat == ALPHA) { + byte m1 = (byte) (ddpf->dwRGBAlphaBitMask & 0xff); + byte m2 = (byte) ((ddpf->dwRGBAlphaBitMask >> 8) & 0xff); + byte m3 = (byte) ((ddpf->dwRGBAlphaBitMask >> 16) & 0xff); + byte m4 = (byte) ((ddpf->dwRGBAlphaBitMask >> 24) & 0xff); + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + *dst-- = m4; + *dst-- = m3; + *dst-- = m2; + *dst-- = m1; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + *dst-- = m3; + *dst-- = m2; + *dst-- = m1; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + *dst-- = m2; + *dst-- = m1; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + *dst-- = m1; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if ((internalFormat == LUMINANCE) || + (internalFormat == INTENSITY)) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src += 3; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src += 3; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src += 3; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src += 3; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + *dst-- = (byte) ((r << rshift) | + (g << gshift) | + (b << bshift) | + ddpf->dwRGBAlphaBitMask); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else { + printf("Texture format %d not support.\n", internalFormat); + } +} + + +void copyDataToSurfaceRGBRev(jint internalFormat, + PIXELFORMAT *ddpf, + unsigned char* pRect, + DWORD rectPitch, + jbyte *data, + jint xoffset, jint yoffset, + DWORD xlimit, DWORD ylimit, + jint subWidth) +{ + unsigned char *src; + unsigned char *dst; + DWORD r, g, b, l; + const DWORD srcPitch = subWidth*3; + unsigned char *srcRow = (unsigned char *) data; + unsigned char *destRow = pRect + rectPitch*yoffset; + + if ((internalFormat == J3D_RGBA) || + (internalFormat == J3D_RGB)) { + destRow += ((xlimit << 2) - 1); + if ((ddpf->dwRGBBitCount == 32) && + (ddpf->dwRBitMask == 0xff0000) && + (ddpf->dwGBitMask == 0xff00) && + (ddpf->dwBBitMask == 0xff)) { + // Most common case + // Note that format of destination is ARGB, which + // in PC format are BGRA, so we can't directly + // copy a row using CopyMemory() + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + r = *src++; + g = *src++; + b = *src++; + *dst-- = (byte) 0xff; + *dst-- = r; + *dst-- = g; + *dst-- = b; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount == 16) && + (ddpf->dwRBitMask == 0xf00) && + (ddpf->dwGBitMask == 0xf0) && + (ddpf->dwBBitMask == 0xf)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + r = (*src++) >> 4; // discard the lower 4 bit + g = (*src++) >> 4; + b = (*src++) >> 4; + *dst-- = 0xf0 | r; + *dst-- = (g << 4) | b; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { // handle less common (even weird) format + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + *dst-- = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + // should not happen, RGBBitCount > 32. Even DirectX + // RGB mask can't address it. + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } + } else if (internalFormat == LUMINANCE_ALPHA) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + *dst-- = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if (internalFormat == ALPHA) { + byte m1 = (byte) (ddpf->dwRGBAlphaBitMask & 0xff); + byte m2 = (byte) ((ddpf->dwRGBAlphaBitMask >> 8) & 0xff); + byte m3 = (byte) ((ddpf->dwRGBAlphaBitMask >> 16) & 0xff); + byte m4 = (byte) ((ddpf->dwRGBAlphaBitMask >> 24) & 0xff); + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + *dst-- = m4; + *dst-- = m3; + *dst-- = m2; + *dst-- = m1; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3- 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + *dst-- = m3; + *dst-- = m2; + *dst-- = m1; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + *dst-- = m2; + *dst-- = m1; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + *dst-- = m1; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if ((internalFormat == LUMINANCE) || + (internalFormat == INTENSITY)) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + *dst-- = (byte) ((r << rshift) | + (g << gshift) | + (b << bshift) | + ddpf->dwRGBAlphaBitMask); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else { + printf("Texture format %d not support.\n", internalFormat); + } +} + +void copyDataToSurfaceLARev(jint internalFormat, + PIXELFORMAT *ddpf, + unsigned char* pRect, + DWORD rectPitch, + jbyte *data, + jint xoffset, jint yoffset, + DWORD xlimit, DWORD ylimit, + jint subWidth) +{ + unsigned char *src; + unsigned char *dst; + DWORD a, r, g, b, l; + unsigned char *srcRow = (unsigned char *) data; + unsigned char *destRow = pRect + rectPitch*yoffset; + const DWORD srcPitch = subWidth*2; + + if ((internalFormat == J3D_RGBA) || + (internalFormat == J3D_RGB)) { + if ((ddpf->dwRGBBitCount == 32) && + (ddpf->dwRBitMask == 0xff0000) && + (ddpf->dwGBitMask == 0xff00) && + (ddpf->dwBBitMask == 0xff)) { + // Most common case + // Note that format of destination is ARGB, which + // in PC format are BGRA, so we can't directly + // copy a row using CopyMemory() + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + *dst-- = *src++; + *dst-- = l; + *dst-- = l; + *dst-- = l; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount == 16) && + (ddpf->dwRBitMask == 0xf00) && + (ddpf->dwGBitMask == 0xf0) && + (ddpf->dwBBitMask == 0xf)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = (*src++) >> 4; // discard the lower 4 bit + a = (*src++) >> 4; + *dst-- = (a << 4) | l; + *dst-- = (l << 4) | l; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { // handle less common (even weird) format + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + l = (*src++) >> rDiscard; + } else { + l = (*src++) << -rDiscard; + } + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + mask = (l << rshift) | (l << gshift) | + (l << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + l = (*src++) >> rDiscard; + } else { + l = (*src++) << -rDiscard; + } + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + mask = (l << rshift) | (l << gshift) | + (l << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + l = (*src++) >> rDiscard; + } else { + l = (*src++) << -rDiscard; + } + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + mask = (l << rshift) | (l << gshift) | + (l << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + l = (*src++) >> rDiscard; + } else { + l = (*src++) << -rDiscard; + } + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + *dst-- = (byte) ((l << rshift) | (l << gshift) | + (l << bshift) | (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + // should not happen, RGBBitCount > 32. Even DirectX + // RGB mask can't address it. + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } + } else if (internalFormat == LUMINANCE_ALPHA) { + + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + *dst-- = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if (internalFormat == ALPHA) { + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = a << ashift; + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = a << ashift; + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + *dst-- = (byte) (a << ashift); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if ((internalFormat == LUMINANCE) || + (internalFormat == INTENSITY)) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + *dst-- = (byte) ((r << rshift) | + (g << gshift) | + (b << bshift) | + (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else { + printf("Texture format %d not support.\n", internalFormat); + } +} + +void copyDataToSurfaceGrayRev(jint internalFormat, + PIXELFORMAT *ddpf, + unsigned char* pRect, + DWORD rectPitch, + jbyte *data, + jint xoffset, jint yoffset, + DWORD xlimit, DWORD ylimit, + jint subWidth) +{ + unsigned char *src; + unsigned char *dst; + DWORD a, r, g, b, l; + unsigned char *srcRow = (unsigned char *) data; + unsigned char *destRow = pRect + rectPitch*yoffset; + const DWORD srcPitch = subWidth; + + if ((internalFormat == J3D_RGBA) || + (internalFormat == J3D_RGB)) { + if ((ddpf->dwRGBBitCount == 32) && + (ddpf->dwRBitMask == 0xff0000) && + (ddpf->dwGBitMask == 0xff00) && + (ddpf->dwBBitMask == 0xff)) { + // Most common case + // Note that format of destination is ARGB, which + // in PC format are BGRA, so we can't directly + // copy a row using CopyMemory() + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + *dst-- = 0xff; + *dst-- = l; + *dst-- = l; + *dst-- = l; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount == 16) && + (ddpf->dwRBitMask == 0xf00) && + (ddpf->dwGBitMask == 0xf0) && + (ddpf->dwBBitMask == 0xf)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = (*src++) >> 4; // discard the lower 4 bit + *dst-- = 0xf0 | l; + *dst-- = (l << 4) | l; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { // handle less common (even weird) format + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + l = (*src++) >> rDiscard; + } else { + l = (*src++) << -rDiscard; + } + mask = (l << rshift) | (l << gshift) | + (l << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + l = (*src++) >> rDiscard; + } else { + l = (*src++) << -rDiscard; + } + mask = (l << rshift) | (l << gshift) | + (l << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + l = (*src++) >> rDiscard; + } else { + l = (*src++) << -rDiscard; + } + mask = (l << rshift) | (l << gshift) | + (l << bshift) | ddpf->dwRGBAlphaBitMask; + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + l = (*src++) >> rDiscard; + } else { + l = (*src++) << -rDiscard; + } + *dst-- = (byte) ((l << rshift) | (l << gshift) | + (l << bshift) | ddpf->dwRGBAlphaBitMask); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + // should not happen, RGBBitCount > 32. Even DirectX + // RGB mask can't address it. + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } + } else if (internalFormat == LUMINANCE_ALPHA) { + + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + *dst-- = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if (internalFormat == ALPHA) { + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = a << ashift; + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = a << ashift; + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + *dst-- = (byte) (a << ashift); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if ((internalFormat == LUMINANCE) || + (internalFormat == INTENSITY)) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + *dst-- = (byte) ((r << rshift) | + (g << gshift) | + (b << bshift) | + (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else { + printf("Texture format %d not support.\n", internalFormat); + } +} + + +void copyDataToSurfaceGrayRev(jint internalFormat, + PIXELFORMAT *ddpf, + unsigned char* pRect, + DWORD rectPitch, + jshort *data, + jint xoffset, jint yoffset, + DWORD xlimit, DWORD ylimit, + jint subWidth) +{ + unsigned char *src; + unsigned char *dst; + DWORD a, r, g, b, l; + DWORD srcPitch = subWidth << 1; + unsigned char *srcRow = (unsigned char *) data; + unsigned char *destRow = pRect + rectPitch*yoffset; + + + if (internalFormat == ALPHA) { + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *src++; // discard lower order byte + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = a << ashift; + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *src++; // discard lower order byte + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = a << ashift; + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *src++; // discard lower order byte + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *src++; // discard lower order byte + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + *dst-- = (byte) (a << ashift); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if ((internalFormat == LUMINANCE) || + (internalFormat == INTENSITY)) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += ((xlimit << 2) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *src++; // discard lower order byte + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 24) & 0xff); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xlimit*3 - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *src++; // discard lower order byte + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 16) & 0xff); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += ((xlimit << 1) - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *src++; // discard lower order byte + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst-- = (byte) ((mask >> 8) & 0xff); + *dst-- = (byte) (mask & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += (xlimit - 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *src++; // discard lower order byte + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + *dst-- = (byte) ((r << rshift) | + (g << gshift) | + (b << bshift) | + (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else { + printf("Texture format %d not support.\n", internalFormat); + } +} + + + +/* + * Copy data to Texture memory surface *pRect + * with pitch = rectPitch + * Note that rectPitch >= surface width since + * D3D may allocate extra width in texture memory + * for other purpose or for alignment. Addional + * offset = (xoffset, yoffset) is added to copy + * data in texture memory. + * + * The source image has width = subWidth and + * pointer *data. + * + * + */ +void copyDataToSurfaceRGBA(jint internalFormat, + PIXELFORMAT *ddpf, + unsigned char* pRect, + DWORD rectPitch, + jbyte *data, + jint xoffset, jint yoffset, + DWORD xlimit, DWORD ylimit, + jint subWidth) +{ + unsigned char *src; + unsigned char *dst; + DWORD r, g, b, a, l; + unsigned char *srcRow = (unsigned char *) data; + unsigned char *destRow = pRect + rectPitch*yoffset; + const DWORD srcPitch = subWidth*4; + + if ((internalFormat == J3D_RGBA) || + (internalFormat == J3D_RGB)) { + if ((ddpf->dwRGBBitCount == 32) && + (ddpf->dwRBitMask == 0xff0000) && + (ddpf->dwGBitMask == 0xff00) && + (ddpf->dwBBitMask == 0xff)) { + // Most common case + // Note that format of destination is ARGB, which + // in PC format are BGRA, so we can't directly + // copy a row using CopyMemory() + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + r = *src++; + g = *src++; + b = *src++; + *dst++ = b; + *dst++ = g; + *dst++ = r; + *dst++ = *src++; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount == 16) && + (ddpf->dwRBitMask == 0xf00) && + (ddpf->dwGBitMask == 0xf0) && + (ddpf->dwBBitMask == 0xf)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + r = (*src++) >> 4; // discard the lower 4 bit + g = (*src++) >> 4; + b = (*src++) >> 4; + a = (*src++) >> 4; + *dst++ = (g << 4) | b; + *dst++ = (a << 4) | r; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { // handle less common (even weird) format + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + *dst++ = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + // should not happen, RGBBitCount > 32. Even DirectX + // RGB mask can't address it. + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } + } else if (internalFormat == LUMINANCE_ALPHA) { + + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + *dst++ = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if (internalFormat == ALPHA) { + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = a << ashift; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = a << ashift; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + *dst++ = (byte) (a << ashift); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if ((internalFormat == LUMINANCE) || + (internalFormat == INTENSITY)) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + *dst++ = (byte) ((r << rshift) | + (g << gshift) | + (b << bshift) | + (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else { + printf("Texture format %d not support.\n", internalFormat); + } +} + + +void copyDataToSurfaceRGB(jint internalFormat, + PIXELFORMAT *ddpf, + unsigned char* pRect, + DWORD rectPitch, + jbyte *data, + jint xoffset, jint yoffset, + DWORD xlimit, DWORD ylimit, + jint subWidth) +{ + unsigned char *src; + unsigned char *dst; + DWORD r, g, b, l; + const DWORD srcPitch = subWidth*3; + unsigned char *srcRow = (unsigned char *) data; + unsigned char *destRow = pRect + rectPitch*yoffset; + + if ((internalFormat == J3D_RGBA) || + (internalFormat == J3D_RGB)) { + destRow += (xoffset << 2); + if ((ddpf->dwRGBBitCount == 32) && + (ddpf->dwRBitMask == 0xff0000) && + (ddpf->dwGBitMask == 0xff00) && + (ddpf->dwBBitMask == 0xff)) { + // Most common case + // Note that format of destination is ARGB, which + // in PC format are BGRA, so we can't directly + // copy a row using CopyMemory() + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + r = *src++; + g = *src++; + b = *src++; + *dst++ = b; + *dst++ = g; + *dst++ = r; + *dst++ = (byte) 0xff; + + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount == 16) && + (ddpf->dwRBitMask == 0xf00) && + (ddpf->dwGBitMask == 0xf0) && + (ddpf->dwBBitMask == 0xf)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + r = (*src++) >> 4; // discard the lower 4 bit + g = (*src++) >> 4; + b = (*src++) >> 4; + *dst++ = (g << 4) | b; + *dst++ = 0xf0 | r; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { // handle less common (even weird) format + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + r = (*src++) >> rDiscard; + } else { + r = (*src++) << -rDiscard; + } + if (gDiscard >= 0) { + g = (*src++) >> gDiscard; + } else { + g = (*src++) >> -gDiscard; + } + if (bDiscard >= 0) { + b = (*src++) >> bDiscard; + } else { + b = (*src++) >> -bDiscard; + } + *dst++ = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + // should not happen, RGBBitCount > 32. Even DirectX + // RGB mask can't address it. + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } + } else if (internalFormat == LUMINANCE_ALPHA) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + *dst++ = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if (internalFormat == ALPHA) { + byte m1 = (byte) (ddpf->dwRGBAlphaBitMask & 0xff); + byte m2 = (byte) ((ddpf->dwRGBAlphaBitMask >> 8) & 0xff); + byte m3 = (byte) ((ddpf->dwRGBAlphaBitMask >> 16) & 0xff); + byte m4 = (byte) ((ddpf->dwRGBAlphaBitMask >> 24) & 0xff); + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + *dst++ = m1; + *dst++ = m2; + *dst++ = m3; + *dst++ = m4; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + *dst++ = m1; + *dst++ = m2; + *dst++ = m3; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + *dst++ = m1; + *dst++ = m2; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src += 3; + *dst++ = m1; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if ((internalFormat == LUMINANCE) || + (internalFormat == INTENSITY)) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + src++; + src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + *dst++ = (byte) ((r << rshift) | + (g << gshift) | + (b << bshift) | + ddpf->dwRGBAlphaBitMask); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else { + printf("Texture format %d not support.\n", internalFormat); + } +} + + +void copyDataToSurfaceLA(jint internalFormat, + PIXELFORMAT *ddpf, + unsigned char* pRect, + DWORD rectPitch, + jbyte *data, + jint xoffset, jint yoffset, + DWORD xlimit, DWORD ylimit, + jint subWidth) +{ + unsigned char *src; + unsigned char *dst; + DWORD a, r, g, b, l; + unsigned char *srcRow = (unsigned char *) data; + unsigned char *destRow = pRect + rectPitch*yoffset; + const DWORD srcPitch = subWidth*2; + + if ((internalFormat == J3D_RGBA) || + (internalFormat == J3D_RGB)) { + if ((ddpf->dwRGBBitCount == 32) && + (ddpf->dwRBitMask == 0xff0000) && + (ddpf->dwGBitMask == 0xff00) && + (ddpf->dwBBitMask == 0xff)) { + // Most common case + // Note that format of destination is ARGB, which + // in PC format are BGRA, so we can't directly + // copy a row using CopyMemory() + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + *dst++ = l; + *dst++ = l; + *dst++ = l; + *dst++ = *src++; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount == 16) && + (ddpf->dwRBitMask == 0xf00) && + (ddpf->dwGBitMask == 0xf0) && + (ddpf->dwBBitMask == 0xf)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = (*src++) >> 4; // discard the lower 4 bit + a = (*src++) >> 4; + *dst++ = (l << 4) | l; + *dst++ = (a << 4) | l; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { // handle less common (even weird) format + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + l = (*src++) >> rDiscard; + } else { + l = (*src++) << -rDiscard; + } + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + mask = (l << rshift) | (l << gshift) | + (l << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + l = (*src++) >> rDiscard; + } else { + l = (*src++) << -rDiscard; + } + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + mask = (l << rshift) | (l << gshift) | + (l << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + l = (*src++) >> rDiscard; + } else { + l = (*src++) << -rDiscard; + } + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + mask = (l << rshift) | (l << gshift) | + (l << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + l = (*src++) >> rDiscard; + } else { + l = (*src++) << -rDiscard; + } + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) >> -aDiscard; + } + *dst++ = (byte) ((l << rshift) | (l << gshift) | + (l << bshift) | (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + // should not happen, RGBBitCount > 32. Even DirectX + // RGB mask can't address it. + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } + } else if (internalFormat == LUMINANCE_ALPHA) { + + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + *dst++ = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if (internalFormat == ALPHA) { + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = a << ashift; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = a << ashift; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + *dst++ = (byte) (a << ashift); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if ((internalFormat == LUMINANCE) || + (internalFormat == INTENSITY)) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + src++; + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + *dst++ = (byte) ((r << rshift) | + (g << gshift) | + (b << bshift) | + (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else { + printf("Texture format %d not support.\n", internalFormat); + } +} + +void copyDataToSurfaceGray(jint internalFormat, + PIXELFORMAT *ddpf, + unsigned char* pRect, + DWORD rectPitch, + jbyte *data, + jint xoffset, jint yoffset, + DWORD xlimit, DWORD ylimit, + jint subWidth) +{ + unsigned char *src; + unsigned char *dst; + DWORD a, r, g, b, l; + unsigned char *srcRow = (unsigned char *) data; + unsigned char *destRow = pRect + rectPitch*yoffset; + const DWORD srcPitch = subWidth; + + + if ((internalFormat == J3D_RGBA) || + (internalFormat == J3D_RGB)) { + if ((ddpf->dwRGBBitCount == 32) && + (ddpf->dwRBitMask == 0xff0000) && + (ddpf->dwGBitMask == 0xff00) && + (ddpf->dwBBitMask == 0xff)) { + // Most common case + // Note that format of destination is ARGB, which + // in PC format are BGRA, so we can't directly + // copy a row using CopyMemory() + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + *dst++ = l; + *dst++ = l; + *dst++ = l; + *dst++ = 0xff; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount == 16) && + (ddpf->dwRBitMask == 0xf00) && + (ddpf->dwGBitMask == 0xf0) && + (ddpf->dwBBitMask == 0xf)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = (*src++) >> 4; // discard the lower 4 bit + *dst++ = (l << 4) | l; + *dst++ = 0xf0 | l; + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { // handle less common (even weird) format + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + l = (*src++) >> rDiscard; + } else { + l = (*src++) << -rDiscard; + } + mask = (l << rshift) | (l << gshift) | + (l << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + l = (*src++) >> rDiscard; + } else { + l = (*src++) << -rDiscard; + } + mask = (l << rshift) | (l << gshift) | + (l << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + l = (*src++) >> rDiscard; + } else { + l = (*src++) << -rDiscard; + } + mask = (l << rshift) | (l << gshift) | + (l << bshift) | ddpf->dwRGBAlphaBitMask; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (rDiscard >= 0) { + l = (*src++) >> rDiscard; + } else { + l = (*src++) << -rDiscard; + } + *dst++ = (byte) ((l << rshift) | (l << gshift) | + (l << bshift) | ddpf->dwRGBAlphaBitMask); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + // should not happen, RGBBitCount > 32. Even DirectX + // RGB mask can't address it. + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } + } else if (internalFormat == LUMINANCE_ALPHA) { + + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + *dst++ = (byte) ((r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if (internalFormat == ALPHA) { + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = a << ashift; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = a << ashift; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + *dst++ = (byte) (a << ashift); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if ((internalFormat == LUMINANCE) || + (internalFormat == INTENSITY)) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + *dst++ = (byte) ((r << rshift) | + (g << gshift) | + (b << bshift) | + (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else { + printf("Texture format %d not support.\n", internalFormat); + } +} + + + +/* + * Copy data from memory to DirectDraw surface + * + * Source image with WIDTH = tilew, the subimage with + * dimension (subWidth, subHeight) is copy with + * offset = (imgXOffset, imgYOffset) from the start + * pointer *data. + * + * Destination frame buffer is copy with + * offset = (xoffset, yoffset) + * + */ +void copyDataToSurface(jint storedFormat, + jint internalFormat, + jint xoffset, jint yoffset, + jint imgXOffset, jint imgYOffset, + jint subWidth, jint subHeight, + jint tilew, jbyte *data, + LPDIRECT3DTEXTURE8 surf, + jint level) +{ + D3DSURFACE_DESC ddsd; + D3DLOCKED_RECT lockedRect; + PIXELFORMAT ddpf; + HRESULT hr; + + if (surf == NULL) { + return; + } + surf->GetLevelDesc(level, &ddsd); + DWORD width = ddsd.Width; + DWORD height = ddsd.Height; + computePixelFormat(&ddpf, ddsd.Format); + + // It is possible when texture is not a power of 2 or + // square only texture is required in hardware. In these + // case the hardware memory buffer may smaller than the + // texture pass in. + + if ((xoffset >= width) || (yoffset >= height)) { + return; + } + + DWORD xlimit = min(xoffset + subWidth, width); + DWORD ylimit = min(yoffset + subHeight, height); + + hr = surf->LockRect(level, &lockedRect, NULL, 0); + + + if (FAILED(hr)) { + printf("Fail to lock surface: %s\n", DXGetErrorString8(hr)); + return; + } + int offset = tilew*imgYOffset + imgXOffset; + switch (storedFormat) { + case FORMAT_BYTE_RGBA : + // This is the one we use when byReference = false + copyDataToSurfaceRGBA(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + (offset << 2), + xoffset, yoffset, + xlimit, ylimit, tilew); + break; + case FORMAT_BYTE_RGB: + copyDataToSurfaceRGB(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + 3*offset, + xoffset, yoffset, + xlimit, ylimit, tilew); + break; + case FORMAT_BYTE_ABGR: + copyDataToSurfaceABGR(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + (offset << 2), + xoffset, yoffset, + xlimit, ylimit, tilew); + break; + case FORMAT_BYTE_BGR: + copyDataToSurfaceBGR(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + 3*offset, + xoffset, yoffset, + xlimit, ylimit, tilew); + break; + case FORMAT_BYTE_LA: + copyDataToSurfaceLA(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + (offset << 1), + xoffset, yoffset, + xlimit, ylimit, tilew); + break; + case FORMAT_BYTE_GRAY: + copyDataToSurfaceGray(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + offset, + xoffset, yoffset, + xlimit, ylimit, tilew); + break; + default: // should not happen + printf("[Java 3D] StoredFormat %d, internalFormat %d not support !\n", + storedFormat, internalFormat); + } + + hr = surf->UnlockRect(level); + if (FAILED(hr)) { + printf("Fail to unlock surface: %s\n", DXGetErrorString8(hr)); + return; + } +} + + + +void copyDataToSurfaceGray(jint internalFormat, + PIXELFORMAT *ddpf, + unsigned char* pRect, + DWORD rectPitch, + jshort *data, + jint xoffset, jint yoffset, + DWORD xlimit, DWORD ylimit, + jint subWidth) +{ + unsigned char *src; + unsigned char *dst; + DWORD a, r, g, b, l; + DWORD srcPitch = subWidth << 1; + unsigned char *srcRow = (unsigned char *) data; + unsigned char *destRow = pRect + rectPitch*yoffset; + + + if (internalFormat == ALPHA) { + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *src++; // discard lower order byte + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = a << ashift; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *src++; // discard lower order byte + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = a << ashift; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *src++; // discard lower order byte + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + mask = (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *src++; // discard lower order byte + if (aDiscard >= 0) { + a = (*src++) >> aDiscard; + } else { + a = (*src++) << -aDiscard; + } + *dst++ = (byte) (a << ashift); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else if ((internalFormat == LUMINANCE) || + (internalFormat == INTENSITY)) { + int rDiscard = 8-countBits(ddpf->dwRBitMask); + int gDiscard = 8-countBits(ddpf->dwGBitMask); + int bDiscard = 8-countBits(ddpf->dwBBitMask); + int aDiscard = 8-countBits(ddpf->dwRGBAlphaBitMask); + int rshift = firstBit(ddpf->dwRBitMask); + int gshift = firstBit(ddpf->dwGBitMask); + int bshift = firstBit(ddpf->dwBBitMask); + int ashift = firstBit(ddpf->dwRGBAlphaBitMask); + DWORD mask; + + + if ((ddpf->dwRGBBitCount <= 32) && + (ddpf->dwRGBBitCount > 24)) { + destRow += (xoffset << 2); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *src++; // discard lower order byte + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 24) && + (ddpf->dwRGBBitCount > 16)) { + destRow += (xoffset*3); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *src++; // discard lower order byte + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if ((ddpf->dwRGBBitCount <= 16) && + (ddpf->dwRGBBitCount > 8)) { + destRow += (xoffset << 1); + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *src++; // discard lower order byte + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + mask = (r << rshift) | (g << gshift) | + (b << bshift) | (a << ashift); + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else if (ddpf->dwRGBBitCount <= 8) { + destRow += xoffset; + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *src++; // discard lower order byte + l = *src++; + if (rDiscard >= 0) { + r = l >> rDiscard; + } else { + r = l << -rDiscard; + } + if (gDiscard >= 0) { + g = l >> gDiscard; + } else { + g = l << -gDiscard; + } + if (bDiscard >= 0) { + b = l >> bDiscard; + } else { + b = l << -bDiscard; + } + if (aDiscard >= 0) { + a = l >> aDiscard; + } else { + a = l << -aDiscard; + } + *dst++ = (byte) ((r << rshift) | + (g << gshift) | + (b << bshift) | + (a << ashift)); + } + srcRow += srcPitch; + destRow += rectPitch; + } + } else { + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf->dwRGBBitCount); + } + } else { + printf("Texture format %d not support.\n", internalFormat); + } +} + + +// copy the texture data to DirectDraw surface +void copyDataToSurface(jint storedFormat, + jint internalFormat, + jint xoffset, jint yoffset, + jint imgXOffset, jint imgYOffset, + jint subWidth, jint subHeight, + jint tilew, jshort *data, + LPDIRECT3DTEXTURE8 surf, + jint level) +{ + D3DSURFACE_DESC ddsd; + D3DLOCKED_RECT lockedRect; + PIXELFORMAT ddpf; + HRESULT hr; + + if (surf == NULL) { + return; + } + + surf->GetLevelDesc(level, &ddsd); + DWORD width = ddsd.Width; + DWORD height = ddsd.Height; + computePixelFormat(&ddpf, ddsd.Format); + + if ((xoffset >= width) || (yoffset >= height)) { + return; + } + DWORD xlimit = min(xoffset + subWidth, width); + DWORD ylimit = min(yoffset + subHeight, height); + + hr = surf->LockRect(level, &lockedRect, NULL, 0); + + if (FAILED(hr)) { + printf("Fail to lock surface: %s\n", DXGetErrorString8(hr)); + return; + } + + int offset = tilew*imgYOffset + imgXOffset; + + copyDataToSurfaceGray(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + (offset << 1), + xoffset, yoffset, + xlimit, ylimit, tilew); + + hr = surf->UnlockRect(level); + if (FAILED(hr)) { + printf("Fail to unlock surface: %s\n", DXGetErrorString8(hr)); + return; + } +} + + +// copy data from DirectDraw depth surface to memory +// and reverse the Y axis +void copyDepthFromSurface(jint xoffset, jint yoffset, + jint subWidth, jint subHeight, + jint *data, + LPDIRECT3DSURFACE8 surf) +{ + D3DSURFACE_DESC ddsd; + DEPTHPIXELFORMAT ddpf; + D3DLOCKED_RECT lockedRect; + HRESULT hr; + + if (surf == NULL) { + return; + } + surf->GetDesc(&ddsd); + DWORD width = ddsd.Width; + DWORD height = ddsd.Height; + computeDepthPixelFormat(&ddpf, ddsd.Format); + + if ((xoffset >= width) || (yoffset >= height)) { + return; + } + + DWORD xlimit = min(xoffset + subWidth, width); + DWORD ylimit = min(yoffset + subHeight, height); + + hr = surf->LockRect(&lockedRect, NULL, D3DLOCK_READONLY); + + if (FAILED(hr)) { + if (debug) { + printf("Fail to lock depth surface: %s\n", DXGetErrorString8(hr)); + } + return; + } + + DWORD b1, b2, b3, b4; + DWORD mask; + jint *destRow = data; + jint *dst; + unsigned char *src; + unsigned char *srcRow = ((unsigned char *) lockedRect.pBits) + + xoffset*((int) ceil((float) ddpf.dwZBufferBitDepth/8.0)) + + (yoffset*lockedRect.Pitch); + + int zshift = firstBit(ddpf.dwZBitMask); + + destRow += (subHeight-1)*subWidth; + + if ((ddpf.dwZBufferBitDepth <= 32) && + (ddpf.dwZBufferBitDepth > 24)) { + + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + b3 = *src++; + b4 = *src++; + mask = (b4 << 24) | (b3 << 16) | + (b2 << 8) | b1; + *dst++ = (mask & ddpf.dwZBitMask) >> zshift; + } + srcRow += lockedRect.Pitch; + destRow -= subWidth; + } + } else if ((ddpf.dwZBufferBitDepth <= 24) && + (ddpf.dwZBufferBitDepth > 16)) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + b3 = *src++; + mask = (b3 << 16) | (b2 << 8) | b1; + *dst++ = (mask & ddpf.dwZBitMask) >> zshift; + } + srcRow += lockedRect.Pitch; + destRow -= subWidth; + } + } else if ((ddpf.dwZBufferBitDepth <= 16) && + (ddpf.dwZBufferBitDepth > 8)) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + mask = (b2 << 8) | b1; + *dst++ = (mask & ddpf.dwZBitMask) >> zshift; + } + srcRow += lockedRect.Pitch; + destRow -= subWidth; + } + } else if (ddpf.dwZBufferBitDepth <= 8) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *dst++ = (*src++ & ddpf.dwZBitMask) >> zshift; + } + srcRow += lockedRect.Pitch; + destRow -= subWidth; + } + } else { + // This is not support by D3D 8 either + printf("[Java 3D] %d bit Z buffer not support !\n", + ddpf.dwZBufferBitDepth); + } + + hr = surf->UnlockRect(); + if (FAILED(hr)) { + printf("Fail to unlock depth surface: %s\n", DXGetErrorString8(hr)); + return; + } +} + + +// copy data from DirectDraw depth surface to memory +// and reverse the Y axis +void copyDepthFromSurface(jint xoffset, jint yoffset, + jint subWidth, jint subHeight, + jfloat *data, + LPDIRECT3DSURFACE8 surf) +{ + D3DSURFACE_DESC ddsd; + DEPTHPIXELFORMAT ddpf; + D3DLOCKED_RECT lockedRect; + HRESULT hr; + + if (surf == NULL) { + return; + } + + surf->GetDesc(&ddsd); + DWORD width = ddsd.Width; + DWORD height = ddsd.Height; + computeDepthPixelFormat(&ddpf, ddsd.Format); + + if ((xoffset >= width) || (yoffset >= height)) { + return; + } + + DWORD xlimit = min(xoffset + subWidth, width); + DWORD ylimit = min(yoffset + subHeight, height); + + hr = surf->LockRect(&lockedRect, NULL, D3DLOCK_READONLY); + + if (FAILED(hr)) { + if (debug) { + printf("Fail to lock depth surface: %s\n", DXGetErrorString8(hr)); + } + return; + } + + DWORD b1, b2, b3, b4; + DWORD mask; + jfloat *destRow = data; + jfloat *dst; + unsigned char *src; + unsigned char *srcRow = ((unsigned char *) lockedRect.pBits) + + xoffset*((int) ceil((float) ddpf.dwZBufferBitDepth/8.0)) + + (yoffset*lockedRect.Pitch); + + int zshift = firstBit(ddpf.dwZBitMask); + float maxdepth = 1 << ddpf.dwZBufferBitDepth; + + destRow += (subHeight-1)*subWidth; + + if ((ddpf.dwZBufferBitDepth <= 32) && + (ddpf.dwZBufferBitDepth > 24)) { + + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + b3 = *src++; + b4 = *src++; + mask = (b4 << 24) | (b3 << 16) | + (b2 << 8) | b1; + *dst++ = (((mask & ddpf.dwZBitMask) >> + zshift))/ maxdepth; + } + srcRow += lockedRect.Pitch; + destRow -= subWidth; + } + } else if ((ddpf.dwZBufferBitDepth <= 24) && + (ddpf.dwZBufferBitDepth > 16)) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + b3 = *src++; + mask = (b3 << 16) | (b2 << 8) | b1; + *dst++ = ((mask & ddpf.dwZBitMask) >> + zshift)/ maxdepth; + } + srcRow += lockedRect.Pitch; + destRow -= subWidth; + } + } else if ((ddpf.dwZBufferBitDepth <= 16) && + (ddpf.dwZBufferBitDepth > 8)) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + b1 = *src++; + b2 = *src++; + mask = (b2 << 8) | b1; + *dst++ = ((mask & ddpf.dwZBitMask) >> + zshift)/ maxdepth; + } + srcRow += lockedRect.Pitch; + destRow -= subWidth; + } + } else if (ddpf.dwZBufferBitDepth <= 8) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + *dst++ = ((*src++ & ddpf.dwZBitMask) >> + zshift)/ maxdepth; + } + srcRow += lockedRect.Pitch; + destRow -= subWidth; + } + } else { + // This is not support by D3D 8 either + printf("[Java 3D] %d bit Z buffer not support !\n", + ddpf.dwZBufferBitDepth); + } + + hr = surf->UnlockRect(); + if (FAILED(hr)) { + printf("Fail to unlock depth surface: %s\n", DXGetErrorString8(hr)); + return; + } +} + + +// copy data to DirectDraw depth surface from memory +// and reverse the Y axis +void copyDepthToSurfaceAlways(jint dst_xoffset, jint dst_yoffset, + jint src_xoffset, jint src_yoffset, + jint subWidth, jint subHeight, + jint src_width, jint src_height, + jint *data, + LPDIRECT3DSURFACE8 surf) +{ + D3DSURFACE_DESC ddsd; + DEPTHPIXELFORMAT ddpf; + D3DLOCKED_RECT lockedRect; + HRESULT hr; + + if (surf == NULL) { + return; + } + + surf->GetDesc(&ddsd); + DWORD width = ddsd.Width; + DWORD height = ddsd.Height; + computeDepthPixelFormat(&ddpf, ddsd.Format); + + if ((dst_xoffset >= width) || (dst_yoffset >= height)) { + return; + } + + DWORD xlimit = min(dst_xoffset + subWidth, width); + DWORD ylimit = min(dst_yoffset + subHeight, height); + + hr = surf->LockRect(&lockedRect, NULL, 0); + + if (FAILED(hr)) { + if (debug) { + printf("Fail to lock depth surface: %s\n", DXGetErrorString8(hr)); + } + return; + } + jint *src; + jint *srcRow = data + src_xoffset + + (src_yoffset + subHeight-1)*src_width; + unsigned char *dst; + unsigned char *destRow = ((unsigned char *) lockedRect.pBits) + + dst_xoffset + dst_yoffset*lockedRect.Pitch; + + int zshift = firstBit(ddpf.dwZBitMask); + DWORD mask; + int maxValue = ddpf.dwZBitMask >> zshift; + + + if ((ddpf.dwZBufferBitDepth <= 32) && + (ddpf.dwZBufferBitDepth > 24)) { + + for (int i=dst_yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=dst_xoffset; j < xlimit; j++) { + mask = *src++; + if (mask < maxValue) { + mask = mask << zshift; + } else { + mask = ddpf.dwZBitMask; + } + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow -= src_width; + destRow += lockedRect.Pitch; + } + } else if ((ddpf.dwZBufferBitDepth <= 24) && + (ddpf.dwZBufferBitDepth > 16)) { + + for (int i=dst_yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=dst_xoffset; j < xlimit; j++) { + mask = *src++; + if (mask < maxValue) { + mask = mask << zshift; + } else { + mask = ddpf.dwZBitMask; + } + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow -= src_width; + destRow += lockedRect.Pitch; + } + } else if ((ddpf.dwZBufferBitDepth <= 16) && + (ddpf.dwZBufferBitDepth > 8)) { + + for (int i=dst_yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=dst_xoffset; j < xlimit; j++) { + mask = *src++; + if (mask < maxValue) { + mask = mask << zshift; + } else { + mask = ddpf.dwZBitMask; + } + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow -= src_width; + destRow += lockedRect.Pitch; + } + } else if (ddpf.dwZBufferBitDepth <= 8) { + byte bmask = (byte) (ddpf.dwZBitMask & 0xff); + for (int i=dst_yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=dst_xoffset; j < xlimit; j++) { + mask = *src++; + if (mask < maxValue) { + *dst++ = (byte) ((mask << zshift) & 0xff); + } else { + *dst++ = bmask; + } + } + srcRow -= src_width; + destRow += lockedRect.Pitch; + } + + } + + hr = surf->UnlockRect(); + if (FAILED(hr)) { + printf("Fail to unlock depth surface: %s\n", DXGetErrorString8(hr)); + return; + } + +} + + +// copy data to DirectDraw depth surface from memory +// and reverse the Y axis +void copyDepthToSurfaceAlways(jint dst_xoffset, jint dst_yoffset, + jint src_xoffset, jint src_yoffset, + jint subWidth, jint subHeight, + jint src_width, jint src_height, + jfloat *data, + LPDIRECT3DSURFACE8 surf) +{ + D3DSURFACE_DESC ddsd; + DEPTHPIXELFORMAT ddpf; + D3DLOCKED_RECT lockedRect; + HRESULT hr; + + if (surf == NULL) { + return; + } + + surf->GetDesc(&ddsd); + DWORD width = ddsd.Width; + DWORD height = ddsd.Height; + computeDepthPixelFormat(&ddpf, ddsd.Format); + + + if ((dst_xoffset >= width) || (dst_yoffset >= height)) { + return; + } + + DWORD xlimit = min(dst_xoffset + subWidth, width); + DWORD ylimit = min(dst_yoffset + subHeight, height); + + hr = surf->LockRect(&lockedRect, NULL, 9); + + if (FAILED(hr)) { + if (debug) { + printf("Fail to lock depth surface: %s\n", DXGetErrorString8(hr)); + } + return; + } + jfloat *src; + jfloat *srcRow = data + src_xoffset + + (src_yoffset + subHeight-1)*src_width; + unsigned char *dst; + unsigned char *destRow = ((unsigned char *) lockedRect.pBits) + + dst_xoffset + dst_yoffset*lockedRect.Pitch; + + int zshift = firstBit(ddpf.dwZBitMask); + DWORD mask; + int maxValue = ddpf.dwZBitMask >> zshift; + float maxdepth = 1 << ddpf.dwZBufferBitDepth; + + if ((ddpf.dwZBufferBitDepth <= 32) && + (ddpf.dwZBufferBitDepth > 24)) { + + for (int i=dst_yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=dst_xoffset; j < xlimit; j++) { + mask = (DWORD) (*src++)*maxdepth; + if (mask < maxValue) { + mask = mask << zshift; + } else { + mask = ddpf.dwZBitMask; + } + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + srcRow -= src_width; + destRow += lockedRect.Pitch; + } + } else if ((ddpf.dwZBufferBitDepth <= 24) && + (ddpf.dwZBufferBitDepth > 16)) { + + for (int i=dst_yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=dst_xoffset; j < xlimit; j++) { + mask = (DWORD) (*src++)*maxdepth; + if (mask < maxValue) { + mask = mask << zshift; + } else { + mask = ddpf.dwZBitMask; + } + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + srcRow -= src_width; + destRow += lockedRect.Pitch; + } + } else if ((ddpf.dwZBufferBitDepth <= 16) && + (ddpf.dwZBufferBitDepth > 8)) { + + for (int i=dst_yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=dst_xoffset; j < xlimit; j++) { + mask = (DWORD) (*src++)*maxdepth; + if (mask < maxValue) { + mask = mask << zshift; + } else { + mask = ddpf.dwZBitMask; + } + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + srcRow -= src_width; + destRow += lockedRect.Pitch; + } + } else if (ddpf.dwZBufferBitDepth <= 8) { + byte bmask = (byte) (ddpf.dwZBitMask & 0xff); + for (int i=dst_yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=dst_xoffset; j < xlimit; j++) { + mask = (DWORD) (*src++)*maxdepth; + if (mask < maxValue) { + *dst++ = (byte) ((mask << zshift) & 0xff); + } else { + *dst++ = bmask; + } + } + srcRow -= src_width; + destRow += lockedRect.Pitch; + } + + } + + hr = surf->UnlockRect(); + if (FAILED(hr)) { + printf("Fail to unlock depth surface: %s\n", DXGetErrorString8(hr)); + return; + } + +} + +// copy data to DirectDraw depth surface from memory +// and reverse the Y axis with Z test D3DCMP_LESS +void copyDepthToSurfaceCmp(jint dst_xoffset, jint dst_yoffset, + jint src_xoffset, jint src_yoffset, + jint subWidth, jint subHeight, + jint src_width, jint src_height, + jint *data, + LPDIRECT3DSURFACE8 surf) +{ + D3DSURFACE_DESC ddsd; + DEPTHPIXELFORMAT ddpf; + D3DLOCKED_RECT lockedRect; + HRESULT hr; + + if (surf == NULL) { + return; + } + + surf->GetDesc(&ddsd); + DWORD width = ddsd.Width; + DWORD height = ddsd.Height; + computeDepthPixelFormat(&ddpf, ddsd.Format); + + + if ((dst_xoffset >= width) || (dst_yoffset >= height)) { + return; + } + + DWORD xlimit = min(dst_xoffset + subWidth, width); + DWORD ylimit = min(dst_yoffset + subHeight, height); + + hr = surf->LockRect(&lockedRect, NULL, 0); + + if (FAILED(hr)) { + if (debug) { + printf("Fail to lock depth surface: %s\n", DXGetErrorString8(hr)); + } + return; + } + + jint *src; + jint *srcRow = data + src_xoffset + + (src_yoffset + subHeight-1)*src_width; + unsigned char *dst; + unsigned char *destRow = ((unsigned char *) lockedRect.pBits) + + dst_xoffset + dst_yoffset*lockedRect.Pitch; + + + int zshift = firstBit(ddpf.dwZBitMask); + DWORD mask; + DWORD b1, b2, b3, b4; + DWORD zmask; + int maxValue = ddpf.dwZBitMask >> zshift; + + + if ((ddpf.dwZBufferBitDepth <= 32) && + (ddpf.dwZBufferBitDepth > 24)) { + + for (int i=dst_yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=dst_xoffset; j < xlimit; j++) { + b1 = *dst++; + b2 = *dst++; + b3 = *dst++; + b4 = *dst++; + zmask = (b4 << 24) | (b3 << 16) | + (b2 << 8) | b1; + zmask = (zmask & ddpf.dwZBitMask) >> zshift; + mask = *src++; + if (mask < zmask) { + // z depth test pass + if (mask < maxValue) { + mask = mask << zshift; + } else { + mask = ddpf.dwZBitMask; + } + dst -= 4; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + } + srcRow -= src_width; + destRow += lockedRect.Pitch; + } + } else if ((ddpf.dwZBufferBitDepth <= 24) && + (ddpf.dwZBufferBitDepth > 16)) { + + for (int i=dst_yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=dst_xoffset; j < xlimit; j++) { + b1 = *dst++; + b2 = *dst++; + b3 = *dst++; + zmask = (b3 << 16) | (b2 << 8) | b1; + zmask = (zmask & ddpf.dwZBitMask) >> zshift; + mask = *src++; + if (mask < zmask) { + if (mask < maxValue) { + mask = mask << zshift; + } else { + mask = ddpf.dwZBitMask; + } + dst -= 3; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + } + srcRow -= src_width; + destRow += lockedRect.Pitch; + } + } else if ((ddpf.dwZBufferBitDepth <= 16) && + (ddpf.dwZBufferBitDepth > 8)) { + + for (int i=dst_yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=dst_xoffset; j < xlimit; j++) { + b1 = *dst++; + b2 = *dst++; + zmask = (b2 << 8) | b1; + zmask = (zmask & ddpf.dwZBitMask) >> zshift; + mask = *src++; + if (mask < zmask) { + if (mask < maxValue) { + mask = mask << zshift; + } else { + mask = ddpf.dwZBitMask; + } + dst -= 2; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + } + srcRow -= src_width; + destRow += lockedRect.Pitch; + } + } else if (ddpf.dwZBufferBitDepth <= 8) { + byte bmask = (byte) (ddpf.dwZBitMask & 0xff); + for (int i=dst_yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=dst_xoffset; j < xlimit; j++) { + zmask = (*dst++ & ddpf.dwZBitMask) >> zshift; + mask = *src++; + if (mask < zmask) { + dst--; + if (mask < maxValue) { + *dst++ = (byte) ((mask << zshift) & 0xff); + } else { + *dst++ = bmask; + } + } + } + srcRow -= src_width; + destRow += lockedRect.Pitch; + } + + } + + hr = surf->UnlockRect(); + if (FAILED(hr)) { + printf("Fail to unlock depth surface: %s\n", DXGetErrorString8(hr)); + return; + } + +} + + +// copy data to DirectDraw depth surface from memory +// and reverse the Y axis with Z test D3DCMP_LESS +void copyDepthToSurfaceCmp(jint dst_xoffset, jint dst_yoffset, + jint src_xoffset, jint src_yoffset, + jint subWidth, jint subHeight, + jint src_width, jint src_height, + jfloat *data, + LPDIRECT3DSURFACE8 surf) +{ + D3DSURFACE_DESC ddsd; + DEPTHPIXELFORMAT ddpf; + D3DLOCKED_RECT lockedRect; + HRESULT hr; + + if (surf == NULL) { + return; + } + + surf->GetDesc(&ddsd); + DWORD width = ddsd.Width; + DWORD height = ddsd.Height; + computeDepthPixelFormat(&ddpf, ddsd.Format); + + + if ((dst_xoffset >= width) || (dst_yoffset >= height)) { + return; + } + + DWORD xlimit = min(dst_xoffset + subWidth, width); + DWORD ylimit = min(dst_yoffset + subHeight, height); + + hr = surf->LockRect(&lockedRect, NULL, 0); + + if (FAILED(hr)) { + if (debug) { + printf("Fail to lock depth surface: %s\n", DXGetErrorString8(hr)); + } + return; + } + jfloat *src; + jfloat *srcRow = data + src_xoffset + + (src_yoffset + subHeight-1)*src_width; + unsigned char *dst; + unsigned char *destRow = ((unsigned char *) lockedRect.pBits) + + dst_xoffset + dst_yoffset*lockedRect.Pitch; + + int zshift = firstBit(ddpf.dwZBitMask); + DWORD mask; + DWORD b1, b2, b3, b4; + DWORD zmask; + int maxValue = ddpf.dwZBitMask >> zshift; + float maxdepth = 1 << ddpf.dwZBufferBitDepth; + + if ((ddpf.dwZBufferBitDepth <= 32) && + (ddpf.dwZBufferBitDepth > 24)) { + + for (int i=dst_yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=dst_xoffset; j < xlimit; j++) { + b1 = *dst++; + b2 = *dst++; + b3 = *dst++; + b4 = *dst++; + zmask = (b4 << 24) | (b3 << 16) | + (b2 << 8) | b1; + zmask = (zmask & ddpf.dwZBitMask) >> zshift; + mask = (DWORD) (*src++)*maxdepth; + if (mask < zmask) { + // z depth test pass + if (mask < maxValue) { + mask = mask << zshift; + } else { + mask = ddpf.dwZBitMask; + } + dst -= 4; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } + } + srcRow -= src_width; + destRow += lockedRect.Pitch; + } + } else if ((ddpf.dwZBufferBitDepth <= 24) && + (ddpf.dwZBufferBitDepth > 16)) { + + for (int i=dst_yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=dst_xoffset; j < xlimit; j++) { + b1 = *dst++; + b2 = *dst++; + b3 = *dst++; + zmask = (b3 << 16) | (b2 << 8) | b1; + zmask = (zmask & ddpf.dwZBitMask) >> zshift; + mask = (DWORD) (*src++)*maxdepth; + if (mask < zmask) { + if (mask < maxValue) { + mask = mask << zshift; + } else { + mask = ddpf.dwZBitMask; + } + dst -= 3; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } + } + srcRow -= src_width; + destRow += lockedRect.Pitch; + } + } else if ((ddpf.dwZBufferBitDepth <= 16) && + (ddpf.dwZBufferBitDepth > 8)) { + + for (int i=dst_yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=dst_xoffset; j < xlimit; j++) { + b1 = *dst++; + b2 = *dst++; + zmask = (b2 << 8) | b1; + zmask = (zmask & ddpf.dwZBitMask) >> zshift; + mask = (DWORD) (*src++)*maxdepth; + if (mask < zmask) { + if (mask < maxValue) { + mask = mask << zshift; + } else { + mask = ddpf.dwZBitMask; + } + dst -= 2; + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } + } + srcRow -= src_width; + destRow += lockedRect.Pitch; + } + } else if (ddpf.dwZBufferBitDepth <= 8) { + byte bmask = (byte) (ddpf.dwZBitMask & 0xff); + for (int i=dst_yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=dst_xoffset; j < xlimit; j++) { + zmask = (*dst++ & ddpf.dwZBitMask) >> zshift; + mask = (DWORD) (*src++)*maxdepth; + if (mask < zmask) { + dst--; + if (mask < maxValue) { + *dst++ = (byte) ((mask << zshift) & 0xff); + } else { + *dst++ = bmask; + } + } + } + srcRow -= src_width; + destRow += lockedRect.Pitch; + } + + } + + hr = surf->UnlockRect(); + if (FAILED(hr)) { + printf("Fail to unlock depth surface: %s\n", DXGetErrorString8(hr)); + return; + } + +} + +// copy data to DirectDraw depth surface from memory +// and reverse the Y axis +void copyDepthToSurface(D3dCtx *d3dCtx, + LPDIRECT3DDEVICE8 device, + jint dst_xoffset, jint dst_yoffset, + jint src_xoffset, jint src_yoffset, + jint subWidth, jint subHeight, + jint src_width, jint src_height, + jint *data, + LPDIRECT3DSURFACE8 surf) +{ + + if (!d3dCtx->zWriteEnable) { + return; + } + + if (!d3dCtx->zEnable) { + copyDepthToSurfaceAlways(dst_xoffset, dst_yoffset, + src_xoffset, src_yoffset, + subWidth, subHeight, + src_width, src_height, + data, surf); + } else { + // Currently ZFUNC must be D3DCMP_LESS + copyDepthToSurfaceCmp(dst_xoffset, dst_yoffset, + src_xoffset, src_yoffset, + subWidth, subHeight, + src_width, src_height, + data, surf); + } +} + + +// copy data to DirectDraw depth surface from memory +// and reverse the Y axis +void copyDepthToSurface(D3dCtx *d3dCtx, + LPDIRECT3DDEVICE8 device, + jint dst_xoffset, jint dst_yoffset, + jint src_xoffset, jint src_yoffset, + jint subWidth, jint subHeight, + jint src_width, jint src_height, + jfloat *data, + LPDIRECT3DSURFACE8 surf) +{ + if (!d3dCtx->zWriteEnable) { + return; + } + + if (!d3dCtx->zEnable) { + copyDepthToSurfaceAlways(dst_xoffset, dst_yoffset, + src_xoffset, src_yoffset, + subWidth, subHeight, + src_width, src_height, + data, surf); + } else { + // Currently ZFUNC must be D3DCMP_LESS + copyDepthToSurfaceCmp(dst_xoffset, dst_yoffset, + src_xoffset, src_yoffset, + subWidth, subHeight, + src_width, src_height, + data, surf); + } +} + +// composite data from memory to DirectDraw surface +void compositeDataToSurface(jint px, jint py, + jint xoffset, jint yoffset, + jint subWidth, jint subHeight, + jint dataWidth, + jbyte *data, + LPDIRECT3DSURFACE8 surf) +{ + D3DSURFACE_DESC ddsd; + D3DLOCKED_RECT lockedRect; + PIXELFORMAT ddpf; + + HRESULT hr; + + if (surf == NULL) { + return; + } + + surf->GetDesc(&ddsd); + DWORD width = ddsd.Width; + DWORD height = ddsd.Height; + computePixelFormat(&ddpf, ddsd.Format); + + if ((xoffset >= width) || (yoffset >= height)) { + return; + } + + DWORD xlimit = min(xoffset + subWidth, width); + DWORD ylimit = min(yoffset + subHeight, height); + + hr = surf->LockRect(&lockedRect, NULL, 0); + + if (FAILED(hr)) { + printf("Fail to lock rendering surface: %s\n", DXGetErrorString8(hr)); + return; + } + + unsigned char *src; + unsigned char *dst; + DWORD r, g, b, a; + DWORD srcPitch; + int offset = (xoffset + yoffset*dataWidth) << 2; + unsigned char *srcRow = (unsigned char *) data + offset; + unsigned char *destRow = ((unsigned char *) lockedRect.pBits) + + ((px + xoffset) << 2) + (py + yoffset)*lockedRect.Pitch; + unsigned char a2; + float inv = 1.0f/255.0f; + ddpf.noAlpha = true; + + if (ddpf.dwRGBAlphaBitMask != 0) { + ddpf.noAlpha = false; + } + + srcPitch = dataWidth << 2; + + if ((ddpf.dwRGBBitCount == 32) && + (ddpf.dwRBitMask == 0xff0000) && + (ddpf.dwGBitMask == 0xff00) && + (ddpf.dwBBitMask == 0xff)) { + // Most common case + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + a = *src++; + b = *src++; + g = *src++; + r = *src++; + + if (a != 0) { + if (a == 0xff) { + *dst++ = b; + *dst++ = g; + *dst++ = r; + *dst++ = 0xff; + } else { + a2 = 255-a; + *dst++ = (*dst * a2 + b * a)*inv; + *dst++ = (*dst * a2 + g * a)*inv; + *dst++ = (*dst * a2 + r * a)*inv; + if (ddpf.noAlpha) { + *dst++ = a; + } else { + *dst++ = (*dst * a2 + a * a)*inv; + } + } + } else { + dst += 4; + } + } + srcRow += srcPitch; + destRow += lockedRect.Pitch; + } + } else { // handle less common (even weird) format + int rshift = firstBit(ddpf.dwRBitMask) + + countBits(ddpf.dwRBitMask) - 8; + int gshift = firstBit(ddpf.dwGBitMask) + + countBits(ddpf.dwGBitMask) - 8; + int bshift = firstBit(ddpf.dwBBitMask) + + countBits(ddpf.dwBBitMask) - 8; + int ashift = firstBit(ddpf.dwRGBAlphaBitMask) + + countBits(ddpf.dwRGBAlphaBitMask) - 8; + + DWORD mask, dmask; + DWORD dr, dg, db, da; + + if ((ddpf.dwRGBBitCount <= 32) && + (ddpf.dwRGBBitCount > 24)) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + a = *src++; + b = *src++; + g = *src++; + r = *src++; + + if (a != 0) { + if (a != 0xff) { + dmask = (*(dst+3) << 24) | + (*(dst+2) << 16) | + (*(dst+1) << 8) | + *dst; + if (rshift >= 0) { + dr = (byte) ((dmask & ddpf.dwRBitMask) >> + rshift); + } else { + dr = (byte) ((dmask & ddpf.dwRBitMask) << + -rshift); + } + if (gshift >= 0) { + dg = (byte) ((dmask & ddpf.dwGBitMask) >> + gshift); + } else { + dg = (byte) ((dmask & ddpf.dwGBitMask) << + -gshift); + } + if (bshift >= 0) { + db = (byte) ((dmask & ddpf.dwBBitMask) >> + bshift); + } else { + db = (byte) ((dmask & ddpf.dwBBitMask) << + -bshift); + } + a2 = 255 - a; + if (!ddpf.noAlpha) { + if (ashift >= 0) { + da = (byte) ((dmask & ddpf.dwRGBAlphaBitMask) >> + ashift); + } else { + da = (byte) ((dmask & ddpf.dwRGBAlphaBitMask) << + -ashift); + } + a = (da * a2 + a * a)*inv; + } + + g = (dg * a2 + g * a)*inv; + b = (db * a2 + b * a)*inv; + r = (dr * a2 + r * a)*inv; + } + if (rshift >= 0) { + mask = (r << rshift) & ddpf.dwRBitMask; + } else { + mask = (r >> -rshift) & ddpf.dwRBitMask; + } + if (gshift >= 0) { + mask |= (g << gshift) & ddpf.dwGBitMask; + } else { + mask |= (g >> -gshift) & ddpf.dwGBitMask; + } + if (bshift >= 0) { + mask |= (b << bshift) & ddpf.dwBBitMask; + } else { + mask |= (b >> -bshift) & ddpf.dwBBitMask; + } + if (!ddpf.noAlpha) { + if (ashift >= 0) { + mask |= (a << ashift) & ddpf.dwRGBAlphaBitMask; + } else { + mask |= (a >> -ashift) & ddpf.dwRGBAlphaBitMask; + } + } + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + *dst++ = (byte) ((mask >> 24) & 0xff); + } else { + dst += 4; + } + } + srcRow += srcPitch; + destRow += lockedRect.Pitch; + } + } else if ((ddpf.dwRGBBitCount <= 24) && + (ddpf.dwRGBBitCount > 16)) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + a = *src++; + b = *src++; + g = *src++; + r = *src++; + if (a != 0) { + if (a != 0xff) { + dmask = (*(dst+2) << 16) | + (*(dst+1) << 8) | + *dst; + if (rshift >= 0) { + dr = (byte) ((dmask & ddpf.dwRBitMask) >> + rshift); + } else { + dr = (byte) ((dmask & ddpf.dwRBitMask) << + -rshift); + } + if (gshift >= 0) { + dg = (byte) ((dmask & ddpf.dwGBitMask) >> + gshift); + } else { + dg = (byte) ((dmask & ddpf.dwGBitMask) << + -gshift); + } + if (bshift >= 0) { + db = (byte) ((dmask & ddpf.dwBBitMask) >> + bshift); + } else { + db = (byte) ((dmask & ddpf.dwBBitMask) << + -bshift); + } + a2 = 255 - a; + if (!ddpf.noAlpha) { + if (ashift >= 0) { + da = (byte) ((dmask & ddpf.dwRGBAlphaBitMask) >> + ashift); + } else { + da = (byte) ((dmask & ddpf.dwRGBAlphaBitMask) << + -ashift); + } + a = (da * a2 + a * a)*inv; + } + g = (dg * a2 + g * a)*inv; + b = (db * a2 + b * a)*inv; + r = (dr * a2 + r * a)*inv; + } + if (rshift >= 0) { + mask = (r << rshift) & ddpf.dwRBitMask; + } else { + mask = (r >> -rshift) & ddpf.dwRBitMask; + } + if (gshift >= 0) { + mask |= (g << gshift) & ddpf.dwGBitMask; + } else { + mask |= (g >> -gshift) & ddpf.dwGBitMask; + } + if (bshift >= 0) { + mask |= (b << bshift) & ddpf.dwBBitMask; + } else { + mask |= (b >> -bshift) & ddpf.dwBBitMask; + } + if (!ddpf.noAlpha) { + if (ashift >= 0) { + mask |= (a << ashift) & ddpf.dwRGBAlphaBitMask; + } else { + mask |= (a >> -ashift) & ddpf.dwRGBAlphaBitMask; + } + } + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + *dst++ = (byte) ((mask >> 16) & 0xff); + } else { + dst += 3; + } + } + srcRow += srcPitch; + destRow += lockedRect.Pitch; + } + } else if ((ddpf.dwRGBBitCount <= 16) && + (ddpf.dwRGBBitCount > 8)) { + + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + a = *src++; + b = *src++; + g = *src++; + r = *src++; + + if (a != 0) { + if (a != 0xff) { + dmask = (*(dst+1) << 8) | *dst; + + if (rshift >= 0) { + dr = (byte) ((dmask & ddpf.dwRBitMask) >> + rshift); + } else { + dr = (byte) ((dmask & ddpf.dwRBitMask) << + -rshift); + } + if (gshift >= 0) { + dg = (byte) ((dmask & ddpf.dwGBitMask) >> + gshift); + } else { + dg = (byte) ((dmask & ddpf.dwGBitMask) << + -gshift); + } + if (bshift >= 0) { + db = (byte) ((dmask & ddpf.dwBBitMask) >> + bshift); + } else { + db = (byte) ((dmask & ddpf.dwBBitMask) << + -bshift); + } + a2 = 255 - a; + + if (!ddpf.noAlpha) { + if (ashift >= 0) { + da = (byte) ((dmask & ddpf.dwRGBAlphaBitMask) >> + ashift); + } else { + da = (byte) ((dmask & ddpf.dwRGBAlphaBitMask) << + -ashift); + } + a = (da * a2 + a * a)*inv; + } + + g = (dg * a2 + g * a)*inv; + b = (db * a2 + b * a)*inv; + r = (dr * a2 + r * a)*inv; + } + + if (rshift >= 0) { + mask = (r << rshift) & ddpf.dwRBitMask; + } else { + mask = (r >> -rshift) & ddpf.dwRBitMask; + } + if (gshift >= 0) { + mask |= ((g << gshift) & ddpf.dwGBitMask); + } else { + mask |= ((g >> -gshift) & ddpf.dwGBitMask); + } + if (bshift >= 0) { + mask |= ((b << bshift) & ddpf.dwBBitMask); + } else { + mask |= ((b >> -bshift) & ddpf.dwBBitMask); + } + if (!ddpf.noAlpha) { + if (ashift >= 0) { + mask |= ((a << ashift) & ddpf.dwRGBAlphaBitMask); + } else { + mask |= ((a >> -ashift) & ddpf.dwRGBAlphaBitMask); + } + } + + *dst++ = (byte) (mask & 0xff); + *dst++ = (byte) ((mask >> 8) & 0xff); + } else { + dst += 2; + } + } + srcRow += srcPitch; + destRow += lockedRect.Pitch; + } + } else if (ddpf.dwRGBBitCount <= 8) { + for (int i=yoffset; i < ylimit; i++) { + src = srcRow; + dst = destRow; + for (int j=xoffset; j < xlimit; j++) { + a = *src++; + b = *src++; + g = *src++; + r = *src++; + if (a != 0) { + if (a != 0xff) { + dmask = *dst; + if (rshift >= 0) { + dr = (byte) ((dmask & ddpf.dwRBitMask) >> + rshift); + } else { + dr = (byte) ((dmask & ddpf.dwRBitMask) << + -rshift); + } + if (gshift >= 0) { + dg = (byte) ((dmask & ddpf.dwGBitMask) >> + gshift); + } else { + dg = (byte) ((dmask & ddpf.dwGBitMask) << + -gshift); + } + if (bshift >= 0) { + db = (byte) ((dmask & ddpf.dwBBitMask) >> + bshift); + } else { + db = (byte) ((dmask & ddpf.dwBBitMask) << + -bshift); + } + a2 = 255 - a; + if (!ddpf.noAlpha) { + if (ashift >= 0) { + da = (byte) ((dmask & ddpf.dwRGBAlphaBitMask) >> + ashift); + } else { + da = (byte) ((dmask & ddpf.dwRGBAlphaBitMask) << + -ashift); + } + a = (da * a2 + a * a)*inv; + } + + g = (dg * a2 + g * a)*inv; + b = (db * a2 + b * a)*inv; + r = (dr * a2 + r * a)*inv; + } + if (rshift >= 0) { + mask = (r << rshift) & ddpf.dwRBitMask; + } else { + mask = (r >> -rshift) & ddpf.dwRBitMask; + } + if (gshift >= 0) { + mask |= (g << gshift) & ddpf.dwGBitMask; + } else { + mask |= (g >> -gshift) & ddpf.dwGBitMask; + } + if (bshift >= 0) { + mask |= (b << bshift) & ddpf.dwBBitMask; + } else { + mask |= (b >> -bshift) & ddpf.dwBBitMask; + } + if (!ddpf.noAlpha) { + if (ashift >= 0) { + mask |= (a << ashift) & ddpf.dwRGBAlphaBitMask; + } else { + mask |= (a >> -ashift) & ddpf.dwRGBAlphaBitMask; + } + } + *dst++ = (byte) (mask & 0xff); + } else { + dst++; + } + } + srcRow += srcPitch; + destRow += lockedRect.Pitch; + } + } else { + // should not happen, RGBBitCount > 32. Even DirectX + // RGB mask can't address it. + printf("Texture memory with RGBBitCount = %d not support. \n", + ddpf.dwRGBBitCount); + } + } + + hr = surf->UnlockRect(); + if (FAILED(hr)) { + printf("Fail to unlock rendering surface: %s\n", DXGetErrorString8(hr)); + return; + } +} + + +void copyDataToVolume(jint storedFormat, + jint internalFormat, + jint xoffset, jint yoffset, + jint zoffset, + jint imgXOffset, jint imgYOffset, + jint imgZOffset, + jint subWidth, jint subHeight, jint subDepth, + jint tilew, jint tileh, + jbyte* data, + LPDIRECT3DVOLUMETEXTURE8 surf, + jint level) +{ + + D3DVOLUME_DESC ddsd; + D3DLOCKED_BOX lockedBox; + PIXELFORMAT ddpf; + HRESULT hr; + UINT i; + + if (surf == NULL) { + return; + } + surf->GetLevelDesc(level, &ddsd); + DWORD width = ddsd.Width; + DWORD height = ddsd.Height; + DWORD depth = ddsd.Depth; + computePixelFormat(&ddpf, ddsd.Format); + + // It is possible when texture is not a power of 2 or + // square only texture is required in hardware. In these + // case the hardware memory buffer may smaller than the + // texture pass in. + + if ((xoffset >= width) || + (yoffset >= height) || + (zoffset >= depth)) { + return; + } + + DWORD xlimit = min(xoffset + subWidth, width); + DWORD ylimit = min(yoffset + subHeight, height); + DWORD zlimit = min(zoffset + subDepth, depth); + + hr = surf->LockBox(level, &lockedBox, NULL, 0); + + + if (FAILED(hr)) { + printf("Fail to lock volume: %s\n", DXGetErrorString8(hr)); + return; + } + + int imgOffset = tilew*(tileh*imgZOffset + imgYOffset) + imgXOffset; + int srcSlicePitch = tilew*tileh; + unsigned char* p = (unsigned char *) lockedBox.pBits + + zoffset*lockedBox.SlicePitch; + + + + switch (storedFormat) { + case FORMAT_BYTE_RGBA : + // This is the one we use when byReference = false + data += (imgOffset << 2); + srcSlicePitch <<= 2; + + for (i = zoffset; i < zlimit; i++) { + copyDataToSurfaceRGBA(internalFormat, &ddpf, + p, + lockedBox.RowPitch, + data, + xoffset, yoffset, + xlimit, ylimit, + tilew); + p += lockedBox.SlicePitch; + data += srcSlicePitch; + } + + break; + case FORMAT_BYTE_RGB: + data += (imgOffset*3); + srcSlicePitch *= 3; + + for (i = zoffset; i < zlimit; i++) { + copyDataToSurfaceRGB(internalFormat, &ddpf, + p, + lockedBox.RowPitch, + data, + xoffset, yoffset, + xlimit, ylimit, + tilew); + p += lockedBox.SlicePitch; + data += srcSlicePitch; + } + break; + case FORMAT_BYTE_ABGR: + data += (imgOffset << 2); + srcSlicePitch <<= 2; + + for (i = zoffset; i < zlimit; i++) { + copyDataToSurfaceABGR(internalFormat, &ddpf, + p, + lockedBox.RowPitch, + data, + xoffset, yoffset, + xlimit, ylimit, + tilew); + p += lockedBox.SlicePitch; + data += srcSlicePitch; + } + break; + case FORMAT_BYTE_BGR: + data += (imgOffset*3); + srcSlicePitch *= 3; + + for (i = zoffset; i < zlimit; i++) { + copyDataToSurfaceBGR(internalFormat, &ddpf, + p, + lockedBox.RowPitch, + data, + xoffset, yoffset, + xlimit, ylimit, + tilew); + p += lockedBox.SlicePitch; + data += srcSlicePitch; + } + break; + case FORMAT_BYTE_LA: + data += (imgOffset << 1); + srcSlicePitch <<= 1; + + for (i = zoffset; i < zlimit; i++) { + copyDataToSurfaceLA(internalFormat, &ddpf, + p, + lockedBox.RowPitch, + data, + xoffset, yoffset, + xlimit, ylimit, + tilew); + p += lockedBox.SlicePitch; + data += srcSlicePitch; + } + break; + case FORMAT_BYTE_GRAY: + data += imgOffset; + + for (i = zoffset; i < zlimit; i++) { + copyDataToSurfaceGray(internalFormat, &ddpf, + p, + lockedBox.RowPitch, + data, + xoffset, yoffset, + xlimit, ylimit, + tilew); + p += lockedBox.SlicePitch; + data += srcSlicePitch; + } + break; + default: // should not happen + printf("[Java 3D] StoredFormat %d, internalFormat %d not support !\n", + storedFormat, internalFormat); + } + + hr = surf->UnlockBox(level); + if (FAILED(hr)) { + printf("Fail to unlock volume: %s\n", DXGetErrorString8(hr)); + return; + } +} + + +void copyDataToVolume(jint storedFormat, + jint internalFormat, + jint xoffset, jint yoffset, + jint zoffset, + jint imgXOffset, jint imgYOffset, + jint imgZOffset, + jint subWidth, jint subHeight, jint subDepth, + jint tilew, jint tileh, + jshort* data, + LPDIRECT3DVOLUMETEXTURE8 surf, + jint level) +{ + D3DVOLUME_DESC ddsd; + D3DLOCKED_BOX lockedBox; + PIXELFORMAT ddpf; + HRESULT hr; + UINT i; + + if (surf == NULL) { + return; + } + + surf->GetLevelDesc(level, &ddsd); + DWORD width = ddsd.Width; + DWORD height = ddsd.Height; + DWORD depth = ddsd.Depth; + + computePixelFormat(&ddpf, ddsd.Format); + + + if ((xoffset >= width) || + (yoffset >= height) || + (zoffset >= depth)) { + return; + } + + + DWORD xlimit = min(xoffset + subWidth, width); + DWORD ylimit = min(yoffset + subHeight, height); + DWORD zlimit = min(zoffset + subDepth, depth); + + hr = surf->LockBox(level, &lockedBox, NULL, 0); + + if (FAILED(hr)) { + printf("Fail to lock volume: %s\n", DXGetErrorString8(hr)); + return; + } + + int imgOffset = tilew*(tileh*imgZOffset + imgYOffset) + imgXOffset; + int srcSlicePitch = (tilew*tileh) << 1; + unsigned char* p = (unsigned char *) lockedBox.pBits + + zoffset*lockedBox.SlicePitch; + + data += (imgOffset << 1); + + for (i = zoffset; i < zlimit; i++) { + copyDataToSurfaceGray(internalFormat, &ddpf, + p, + lockedBox.RowPitch, + data, + xoffset, yoffset, + xlimit, ylimit, + tilew); + p += lockedBox.SlicePitch; + data += srcSlicePitch; + } + + hr = surf->UnlockBox(level); + if (FAILED(hr)) { + printf("Fail to unlock volume: %s\n", DXGetErrorString8(hr)); + return; + } +} + + +LPDIRECT3DTEXTURE8 createSurfaceFromImage(JNIEnv *env, + jobject pa2d, + jlong ctx, + int width, + int height, + jbyteArray imageYdown) +{ + GetDevice2(); + + int internalFormat; + jclass pa2d_class = env->GetObjectClass(pa2d); + + jfieldID id = env->GetFieldID(pa2d_class, "storedYdownFormat", "I"); + int storedFormat = env->GetIntField(pa2d, id); + + id = env->GetFieldID(pa2d_class, "internalFormat", "I"); + internalFormat = env->GetIntField(pa2d, id); + + + switch (internalFormat) { + case FORMAT_BYTE_RGBA: + internalFormat = J3D_RGBA; + break; + case FORMAT_BYTE_RGB: + internalFormat = J3D_RGB; + break; + case FORMAT_BYTE_LA: + internalFormat = LUMINANCE_ALPHA; + break; + case FORMAT_BYTE_GRAY: + case FORMAT_USHORT_GRAY: + internalFormat = LUMINANCE; + break; + default: + printf("Format %d not support for Image Component\n", internalFormat); + return NULL; + } + + + LPDIRECT3DTEXTURE8 surf; + + surf = createTextureSurface(d3dCtx, 1, internalFormat, + width, height); + + if (surf == NULL) { + return NULL; + } + + if (imageYdown != NULL) { + if (storedFormat != FORMAT_USHORT_GRAY) { + jbyte *byteData = (jbyte *) (env->GetPrimitiveArrayCritical( + imageYdown, NULL)); + copyDataToSurface(storedFormat, internalFormat, 0, 0, 0, 0, + width, height, width, byteData, surf, 0); + env->ReleasePrimitiveArrayCritical(imageYdown, byteData, 0); + + } else { + jshort *shortData = (jshort *)(env->GetPrimitiveArrayCritical( + imageYdown, NULL)); + copyDataToSurface(storedFormat, internalFormat, 0, 0, 0, 0, + width, height, width, shortData, surf, 0); + env->ReleasePrimitiveArrayCritical(imageYdown, shortData, 0); + } + } + return surf; +} + +VOID createLineModeIndexBuffer(D3dCtx *d3dCtx) +{ + HRESULT hr; + WORD *wptr; + + hr = d3dCtx->pDevice->CreateIndexBuffer(6*sizeof(WORD), + D3DUSAGE_WRITEONLY, + D3DFMT_INDEX16, + D3DPOOL_DEFAULT, + &d3dCtx->lineModeIndexBuffer); + if (FAILED(hr)) { + D3dCtx::d3dWarning(CREATEINDEXVBFAIL, hr); + return; + } + + + hr = d3dCtx->lineModeIndexBuffer->Lock(0, 0, (BYTE **) &wptr, 0); + if (FAILED(hr)) { + D3dCtx::d3dWarning(LOCKINDEXVBFAIL, hr); + return; + } + + *wptr++ = 0; + *wptr++ = 1; + *wptr++ = 2; + *wptr++ = 3; + *wptr++ = 0; + *wptr = 0; // not used + d3dCtx->lineModeIndexBuffer->Unlock(); +} + +// Return TRUE if index is adjust smaller +BOOL createQuadIndices(D3dCtx *d3dCtx, int vcount) +{ + DWORD dwIndexCount = (vcount*3) >> 1; + WORD *q; + LPDIRECT3DDEVICE8 device = d3dCtx->pDevice; + HRESULT hr; + BOOL adjustIdx = FALSE; + + if (dwIndexCount > d3dCtx->deviceInfo->maxVertexIndex) { + // We'll render the VB multiple times in this case + dwIndexCount = min(d3dCtx->deviceInfo->maxVertexIndex, + (d3dCtx->deviceInfo->maxPrimitiveCount << 1)); + adjustIdx = TRUE; + } + + if (dwIndexCount > d3dCtx->quadIndexBufferSize) { + d3dCtx->freeResource(d3dCtx->quadIndexBuffer); + hr = device->CreateIndexBuffer(dwIndexCount*sizeof(WORD), + D3DUSAGE_WRITEONLY, + D3DFMT_INDEX16, + D3DPOOL_MANAGED, + &d3dCtx->quadIndexBuffer); + if (FAILED(hr)) { + D3dCtx::d3dWarning(CREATEINDEXVBFAIL, hr); + d3dCtx->quadIndexBufferSize = 0; + d3dCtx->quadIndexBuffer = NULL; + if (d3dCtx->quadIndexBufferSize > 0) { + // indices has successfully set before, we prevent + // setting this when indices did not set before. + // It is becasue there is a bug in Nvidia driver which + // will crash in this case. + device->SetIndices(NULL, 0); + } + return adjustIdx; + } + + d3dCtx->quadIndexBufferSize = dwIndexCount; + hr = d3dCtx->quadIndexBuffer->Lock(0, 0, (BYTE **) &q, 0); + if (FAILED(hr)) { + D3dCtx::d3dWarning(LOCKINDEXVBFAIL, hr); + if (d3dCtx->quadIndexBufferSize > 0) { + device->SetIndices(NULL, 0); + } + return adjustIdx; + } + int i = -1; + int j = 0; + + while (j < dwIndexCount) { + q[j++] = ++i; // q[0] = 0 + q[j++] = i+1; // q[1] = 1 + q[j++] = i+2; // q[2] = 2 + q[j++] = i++; // q[3] = 0 + q[j++] = ++i; // q[4] = 2 + q[j++] = ++i; // q[5] = 3 + } + + d3dCtx->quadIndexBuffer->Unlock(); + } + + return adjustIdx; +} + + +int getPrimitiveNum(int primitive, int vcount) +{ + switch (primitive) { + case D3DPT_TRIANGLESTRIP: + return vcount-2; + case D3DPT_TRIANGLEFAN: + return vcount-2; + case D3DPT_LINESTRIP: + return vcount - 1; + case D3DPT_LINELIST: + return vcount >> 1; + case D3DPT_TRIANGLELIST: + return vcount/3; + case D3DPT_POINTLIST: + return vcount; + default: // should not happen + printf("[Java 3D] Unknown primitive type %d\n", primitive); + } + return 0; +} + + +/* + * Note that tThe condition width == height always holds + * when this function is invoked. + */ +LPDIRECT3DCUBETEXTURE8 createCubeMapTexture(D3dCtx *d3dCtx, + jint numLevels, + jint internalFormat, + jint width, + jint height) +{ + LPDIRECT3DCUBETEXTURE8 pTexture; + D3DFORMAT format; + HRESULT hr; + + LPDIRECT3DDEVICE8 pDevice = d3dCtx->pDevice; + D3dDeviceInfo *deviceInfo = d3dCtx->deviceInfo; + + if (!deviceInfo->supportMipmap) { + numLevels = 1; + } + + getTexWidthHeight(deviceInfo, &width, &height); + format = getTexFormat(internalFormat); + + // If format not support, the utility function will adjust the + // calling parameters automatically + hr = D3DXCreateCubeTexture(d3dCtx->pDevice, width, + numLevels, 0, format, D3DPOOL_MANAGED, + &pTexture); + + if (FAILED(hr)) { + if (debug) { + printf("Fail to create cube texture surface %dx%d, format %d, level %d : %s\n", + width, height, format, numLevels, DXGetErrorString8(hr)); + } + return NULL; + } + + return pTexture; +} + + +void copyDataToCubeMap(jint storedFormat, + jint internalFormat, + jint xoffset, jint yoffset, + jint imgXOffset, jint imgYOffset, + jint subWidth, jint subHeight, + jint tilew, + jshort *data, LPDIRECT3DCUBETEXTURE8 surf, + jint level, + jint face) +{ + D3DSURFACE_DESC ddsd; + D3DLOCKED_RECT lockedRect; + PIXELFORMAT ddpf; + HRESULT hr; + + if (surf == NULL) { + return; + } + + surf->GetLevelDesc(level, &ddsd); + DWORD width = ddsd.Width; + DWORD height = ddsd.Height; + computePixelFormat(&ddpf, ddsd.Format); + + if ((xoffset >= width) || (yoffset >= height)) { + return; + } + DWORD xlimit = min(xoffset + subWidth, width); + DWORD ylimit = min(yoffset + subHeight, height); + + hr = surf->LockRect(textureCubeMapFace[face], level, + &lockedRect, NULL, 0); + + if (FAILED(hr)) { + printf("Fail to lock surface: %s\n", DXGetErrorString8(hr)); + return; + } + + int offset = tilew*imgYOffset + imgXOffset; + + if ((face == D3DCUBEMAP_FACE_NEGATIVE_Y) || + (face == D3DCUBEMAP_FACE_POSITIVE_Y)) { + copyDataToSurfaceGray(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + + ((offset+tilew*(ylimit-yoffset)) << 1), + xoffset, yoffset, + xlimit, ylimit, -tilew); + } else { + copyDataToSurfaceGrayRev(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + (offset << 1), + xoffset, yoffset, + xlimit, ylimit, tilew); + } + + hr = surf->UnlockRect(textureCubeMapFace[face], level); + if (FAILED(hr)) { + printf("Fail to unlock surface: %s\n", DXGetErrorString8(hr)); + return; + } +} + + +void copyDataToCubeMap(jint storedFormat, + jint internalFormat, + jint xoffset, jint yoffset, + jint imgXOffset, jint imgYOffset, + jint subWidth, jint subHeight, + jint tilew, + jbyte* data, + LPDIRECT3DCUBETEXTURE8 surf, + jint level, + jint face) +{ + D3DSURFACE_DESC ddsd; + D3DLOCKED_RECT lockedRect; + PIXELFORMAT ddpf; + HRESULT hr; + + if (surf == NULL) { + return; + } + surf->GetLevelDesc(level, &ddsd); + DWORD width = ddsd.Width; + DWORD height = ddsd.Height; + computePixelFormat(&ddpf, ddsd.Format); + + // It is possible when texture is not a power of 2 or + // square only texture is required in hardware. In these + // case the hardware memory buffer may smaller than the + // texture pass in. + + if ((xoffset >= width) || (yoffset >= height)) { + return; + } + + DWORD xlimit = min(xoffset + subWidth, width); + DWORD ylimit = min(yoffset + subHeight, height); + + hr = surf->LockRect(textureCubeMapFace[face], + level, &lockedRect, NULL, 0); + + + if (FAILED(hr)) { + printf("Fail to lock surface: %s\n", DXGetErrorString8(hr)); + return; + } + int offset = tilew*imgYOffset + imgXOffset; + + switch (storedFormat) { + case FORMAT_BYTE_RGBA : + // This is the one we use when byReference = false + if ((face == D3DCUBEMAP_FACE_NEGATIVE_Y) || + (face == D3DCUBEMAP_FACE_POSITIVE_Y)) { + // Copy the pixel from bottom to up and + // left to right in this case to match OGL definition + copyDataToSurfaceRGBA(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + + ((offset + tilew*(ylimit-yoffset-1)) << 2), + xoffset, yoffset, + xlimit, ylimit, -tilew); + } else { + // Copy the pixel from up to bottom and + // right to left in this case to match OGL definition + copyDataToSurfaceRGBARev(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + (offset << 2), + xoffset, yoffset, + xlimit, ylimit, tilew); + } + break; + case FORMAT_BYTE_RGB: + if ((face == D3DCUBEMAP_FACE_NEGATIVE_Y) || + (face == D3DCUBEMAP_FACE_POSITIVE_Y)) { + copyDataToSurfaceRGB(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + + 3*(offset + tilew*(ylimit-yoffset-1)), + xoffset, yoffset, + xlimit, ylimit, -tilew); + } else { + copyDataToSurfaceRGBRev(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + 3*offset, + xoffset, yoffset, + xlimit, ylimit, tilew); + } + break; + case FORMAT_BYTE_ABGR: + if ((face == D3DCUBEMAP_FACE_NEGATIVE_Y) || + (face == D3DCUBEMAP_FACE_POSITIVE_Y)) { + copyDataToSurfaceABGR(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + + ((offset+tilew*(ylimit-yoffset-1)) << 2), + xoffset, yoffset, + xlimit, ylimit, -tilew); + } else { + copyDataToSurfaceABGRRev(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + (offset << 2), + xoffset, yoffset, + xlimit, ylimit, tilew); + } + break; + case FORMAT_BYTE_BGR: + if ((face == D3DCUBEMAP_FACE_NEGATIVE_Y) || + (face == D3DCUBEMAP_FACE_POSITIVE_Y)) { + copyDataToSurfaceBGR(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + + 3*(offset + tilew*(ylimit-yoffset-1)), + xoffset, yoffset, + xlimit, ylimit, -tilew); + } else { + copyDataToSurfaceBGRRev(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + 3*offset, + xoffset, yoffset, + xlimit, ylimit, tilew); + } + break; + case FORMAT_BYTE_LA: + if ((face == D3DCUBEMAP_FACE_NEGATIVE_Y) || + (face == D3DCUBEMAP_FACE_POSITIVE_Y)) { + copyDataToSurfaceLA(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + + ((offset+tilew*(ylimit-yoffset-1)) << 1), + xoffset, yoffset, + xlimit, ylimit, -tilew); + } else { + copyDataToSurfaceLARev(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + (offset << 1), + xoffset, yoffset, + xlimit, ylimit, tilew); + } + break; + case FORMAT_BYTE_GRAY: + if ((face == D3DCUBEMAP_FACE_NEGATIVE_Y) || + (face == D3DCUBEMAP_FACE_POSITIVE_Y)) { + copyDataToSurfaceGray(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + + offset + tilew*(ylimit-yoffset-1), + xoffset, yoffset, + xlimit, ylimit, -tilew); + } else { + copyDataToSurfaceGrayRev(internalFormat, &ddpf, + (unsigned char *) lockedRect.pBits, + lockedRect.Pitch, + data + offset, + xoffset, yoffset, + xlimit, ylimit, tilew); + } + break; + default: // should not happen + printf("[Java 3D] StoredFormat %d, internalFormat %d not support !\n", + storedFormat, internalFormat); + } + + hr = surf->UnlockRect(textureCubeMapFace[face], level); + if (FAILED(hr)) { + printf("Fail to unlock surface: %s\n", DXGetErrorString8(hr)); + return; + } +} + + +void drawTextureRect(D3dCtx *d3dCtx, + LPDIRECT3DDEVICE8 device, + LPDIRECT3DTEXTURE8 surf, + D3DTLVERTEX screenCoord, + int startx, int starty, + int endx, int endy, + int scaleWidth, int scaleHeight, + boolean texModeRepeat) +{ + LPDIRECT3DTEXTURE8 texture = NULL; + DWORD transflag, minstate, magstate, texcoordstate; + DWORD wrapU, wrapV; + DWORD colorOp, colorArg, alphaOp, alphaArg; + D3DMATRIX m; + + int h = endy - starty; + int w = endx - startx; + + device->SetRenderState(D3DRS_SPECULARENABLE, FALSE); + + device->GetTexture(0, (LPDIRECT3DBASETEXTURE8 *) &texture); + + device->GetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, + &transflag); + if (transflag != D3DTTFF_DISABLE) { + device->GetTransform(D3DTS_TEXTURE0, &m); + } + + device->GetTextureStageState(0, D3DTSS_MINFILTER, &minstate); + device->GetTextureStageState(0, D3DTSS_MAGFILTER, &magstate); + device->GetTextureStageState(0, D3DTSS_TEXCOORDINDEX, &texcoordstate); + device->SetTexture(0, surf); + device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, + D3DTTFF_DISABLE); + + if ((w == scaleWidth) && (h == scaleHeight)) { + device->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT); + device->SetTextureStageState(0, D3DTSS_MAGFILTER, + D3DTEXF_POINT); + } else { + device->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + device->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + } + device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); + device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + + device->GetTextureStageState(0, D3DTSS_COLOROP, &colorOp); + device->GetTextureStageState(0, D3DTSS_COLORARG1, &colorArg); + device->GetTextureStageState(0, D3DTSS_ALPHAOP, &alphaOp); + device->GetTextureStageState(0, D3DTSS_ALPHAARG1, &alphaArg); + + device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + if (d3dCtx->fillMode != D3DFILL_SOLID) { + device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + } + + D3DSURFACE_DESC ddsd; + surf->GetLevelDesc(0, &ddsd); + + + float tumax; + float tvmax; + float tumin = startx/(float) ddsd.Width; + float tvmin = starty/(float) ddsd.Height; + boolean multipleDraw; + + if (texModeRepeat) { + if ((w == ddsd.Width) && (h == ddsd.Height)) { + // width & height match texture, so there is + // no need to draw multiple time + tumax = scaleWidth/(float) ddsd.Width; + tvmax = scaleHeight/(float) ddsd.Height; + device->GetTextureStageState(0, D3DTSS_ADDRESSU, &wrapU); + device->GetTextureStageState(0, D3DTSS_ADDRESSV, &wrapV); + device->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + device->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + multipleDraw = false; + } else { + tumax = endx/(float) ddsd.Width; + tvmax = endy/(float) ddsd.Height; + multipleDraw = true; + } + } else { + tumax = endx/(float) ddsd.Width; + tvmax = endy/(float) ddsd.Height; + multipleDraw = false; + } + + + d3dCtx->rasterRect[0].tu = tumin; + d3dCtx->rasterRect[0].tv = tvmax; + d3dCtx->rasterRect[1].tu = tumin; + d3dCtx->rasterRect[1].tv = tvmin; + d3dCtx->rasterRect[2].tu = tumax; + d3dCtx->rasterRect[2].tv = tvmax; + d3dCtx->rasterRect[3].tu = tumax; + d3dCtx->rasterRect[3].tv = tvmin; + + d3dCtx->rasterRect[0].sx = screenCoord.sx; + d3dCtx->rasterRect[0].sz = screenCoord.sz; + d3dCtx->rasterRect[0].rhw = screenCoord.rhw; + + d3dCtx->rasterRect[1].sx = screenCoord.sx; + d3dCtx->rasterRect[1].sy = screenCoord.sy; + d3dCtx->rasterRect[1].sz = screenCoord.sz; + d3dCtx->rasterRect[1].rhw = screenCoord.rhw; + + d3dCtx->rasterRect[2].sz = screenCoord.sz; + d3dCtx->rasterRect[2].rhw = screenCoord.rhw; + + d3dCtx->rasterRect[3].sy = screenCoord.sy; + d3dCtx->rasterRect[3].sz = screenCoord.sz; + d3dCtx->rasterRect[3].rhw = screenCoord.rhw; + + if ((h > 0) && (w > 0)) { + device->SetVertexShader(D3DFVF_XYZRHW|D3DFVF_TEX1); + if (!multipleDraw) { + d3dCtx->rasterRect[0].sy = screenCoord.sy + scaleHeight; + d3dCtx->rasterRect[2].sx = screenCoord.sx + scaleWidth; + d3dCtx->rasterRect[2].sy = screenCoord.sy + scaleHeight; + d3dCtx->rasterRect[3].sx = screenCoord.sx + scaleWidth; + device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, + 2, + d3dCtx->rasterRect, + sizeof(D3DTLVERTEX)); + } else { + d3dCtx->rasterRect[0].sy = screenCoord.sy + h; + d3dCtx->rasterRect[2].sx = screenCoord.sx + w; + d3dCtx->rasterRect[2].sy = screenCoord.sy + h; + d3dCtx->rasterRect[3].sx = screenCoord.sx + w; + for (int i=0; i < ceil(scaleHeight/((double) h)); i++) { + for (int j=0; j < ceil(scaleWidth/((double) w)); j++) { + device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, + 2, + d3dCtx->rasterRect, + sizeof(D3DTLVERTEX)); + d3dCtx->rasterRect[0].sx += w; + d3dCtx->rasterRect[1].sx += w; + d3dCtx->rasterRect[2].sx += w; + d3dCtx->rasterRect[3].sx += w; + } + d3dCtx->rasterRect[0].sx = screenCoord.sx; + d3dCtx->rasterRect[1].sx = screenCoord.sx; + d3dCtx->rasterRect[2].sx = screenCoord.sx + w; + d3dCtx->rasterRect[3].sx = screenCoord.sx + w; + d3dCtx->rasterRect[0].sy += h; + d3dCtx->rasterRect[1].sy += h; + d3dCtx->rasterRect[2].sy += h; + d3dCtx->rasterRect[3].sy += h; + } + + } + } + + // restore original texture stage values + if (texture != NULL) { + device->SetTexture(0, texture); + texture->Release(); + } else { + device->SetTexture(0, NULL); + } + + device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, + transflag); + if (transflag != D3DTTFF_DISABLE) { + device->SetTransform(D3DTS_TEXTURE0, &m); + } + if (d3dCtx->fillMode != D3DFILL_SOLID) { + device->SetRenderState(D3DRS_FILLMODE, d3dCtx->fillMode); + } + device->SetTextureStageState(0, D3DTSS_MINFILTER, minstate); + device->SetTextureStageState(0, D3DTSS_MAGFILTER, magstate); + device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, texcoordstate); + + device->SetTextureStageState(0, D3DTSS_COLOROP, colorOp); + device->SetTextureStageState(0, D3DTSS_COLORARG1, colorArg); + device->SetTextureStageState(0, D3DTSS_ALPHAOP, alphaOp); + device->SetTextureStageState(0, D3DTSS_ALPHAARG1, alphaArg); + + if (texModeRepeat && !multipleDraw) { + device->SetTextureStageState(0, D3DTSS_ADDRESSU, wrapU); + device->SetTextureStageState(0, D3DTSS_ADDRESSV, wrapV); + } + device->SetRenderState(D3DRS_CULLMODE, d3dCtx->cullMode); + device->SetRenderState(D3DRS_SPECULARENABLE, TRUE); +} diff --git a/src/native/d3d/D3dUtil.hpp b/src/native/d3d/D3dUtil.hpp new file mode 100644 index 0000000..1e09d6e --- /dev/null +++ b/src/native/d3d/D3dUtil.hpp @@ -0,0 +1,310 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#if !defined(D3DUTIL_H) +#define D3DUTIL_H + +#include "StdAfx.h" + + +// Index to D3dErrorMessage +#define DRIVERNOTFOUND 0 +#define CANNOTRENDERWINDOW 1 +#define D3DNOTFOUND 2 +#define CARDNOTSUPPORT 3 +#define NEEDSWITCHMODE 4 +#define DEVICENOTFOUND 5 +#define CREATEDEVICEFAIL 6 +#define CREATEREFDEVICEFAIL 7 +#define VIEWPORTFAIL 8 +#define GETBACKBUFFERFAIL 9 +#define COLORMODENOTSUPPORT 10 +#define OUTOFMEMORY 11 +#define UNKNOWNDEVICE 12 +#define HALDEVICENOTFOUND 13 +#define TNLHALDEVICENOTFOUND 14 +#define NOSTENCILBUFFER 15 +#define NOTEXTUREMEMORY 16 +#define OFFSCREENCREATEFAIL 17 +#define CREATEVERTEXBUFFER 18 +#define RESETFAIL 19 +#define HALNOTCOMPATIBLE 20 +#define DEPTHSTENCILNOTFOUND 21 +#define LOCKVBFAIL 22 +#define CREATEVBFAIL 23 +#define CREATEINDEXVBFAIL 24 +#define LOCKINDEXVBFAIL 25 + +#define PI 3.14159265f + +// Same definition as in ImageComponent2DRetained +#define CLEAN 0 +#define MODIFY 1 +#define NOTLIVE 2 + +// If we want to synchrinized draw primitive, change the +// following to D3DDP_WAIT +#define DEFAULTMODE 0 + +#define D3D_STEREO 1 + + +// Macro +#define SafeRelease(p) if(p) {p->Release(); p = NULL;} +#define SafeDelete(p) if(p) { delete p; p = NULL;} +#define SafeFree(p) if(p) { free(p); p = NULL;} + +#define GetCtx() \ + if (ctx == 0) return; \ + D3dCtx *d3dCtx = reinterpret_cast(ctx); \ + + +#define GetDevice() \ + GetCtx() \ + LPDIRECT3DDEVICE8 device = d3dCtx->pDevice; \ + if (device == NULL) return; + +#define GetCtx2() \ + if (ctx == 0) return 0;\ + D3dCtx *d3dCtx = reinterpret_cast(ctx); \ + + +#define GetDevice2() \ + GetCtx2(); \ + LPDIRECT3DDEVICE8 device = d3dCtx->pDevice; \ + if (device == NULL) return 0; + +#define CopyColor(c, red, green, blue, alpha) \ + (c).a = alpha; (c).r = red; (c).g = green; (c).b = blue; + + +#define CopyTranspose(m, s) { \ + (m)._11 = (s)[0]; (m)._12 = (s)[4]; (m)._13 = (s)[8]; (m)._14 = (s)[12]; \ + (m)._21 = (s)[1]; (m)._22 = (s)[5]; (m)._23 = (s)[9]; (m)._24 = (s)[13]; \ + (m)._31 = (s)[2]; (m)._32 = (s)[6]; (m)._33 = (s)[10]; (m)._34 = (s)[14]; \ + (m)._41 = (s)[3]; (m)._42 = (s)[7]; (m)._43 = (s)[11]; (m)._44 = (s)[15]; } + +// Note that v should not be one of the reference in m +#define MultiplyScaler(m, v) { \ + (m)._11 *= v; (m)._12 *= v; (m)._13 *= v; (m)._14 *= v; \ + (m)._21 *= v; (m)._22 *= v; (m)._23 *= v; (m)._24 *= v; \ + (m)._31 *= v; (m)._32 *= v; (m)._33 *= v; (m)._34 *= v; \ + (m)._41 *= v; (m)._42 *= v; (m)._43 *= v; (m)._44 *= v; } + +#define Clamp(c) \ + if (c > 1.0f) { \ + c = 1.0f; \ + } else if (c < 0.0f) { \ + c = 0.0f; \ + } + +#define Magitude(x, y, z, w) sqrt((x)*(x) + (y)*(y) + (z)*(z) + (w)*(w)); + +#define NORMALIZE(x, y, z, w) { \ + float d; \ + d = Magitude(x, y, z, w); \ + (x) /= d; (y) /= d; (z) /= d; (w) /= d; } + +extern vector freePointerList0; +extern vector freePointerList1; +extern BOOL useFreePointerList0; + +extern HANDLE hSema; // handle to semaphore +extern BOOL firstError; +extern BOOL debug; + +// use for VertexBuffer +extern OSVERSIONINFO osvi; // OS info + +extern D3dCtx* findCtx(HWND hwnd); +extern VOID lock(); +extern VOID unlock(); +extern VOID lockImage(); +extern VOID unlockImage(); +extern VOID lockBackground(); +extern VOID unlockBackground(); +extern VOID lockGeometry(); +extern VOID unlockGeometry(); +extern VOID lockSurfaceList(); +extern VOID unlockSurfaceList(); +extern VOID freeSurface(LPDIRECT3DBASETEXTURE8 surf); +extern VOID freePointer(void* surf); +extern VOID freePointerList(); +extern VOID setWindowCallback(HWND topHwnd, HWND hwnd); +extern char* getErrorMessage(int idx); +extern HWND getTopWindow(HWND hwnd); + +extern LPDIRECT3DTEXTURE8 createTextureSurface(D3dCtx *d3dCtx, + jint numLevels, + jint internalFormat, + jint width, + jint height); + + +extern LPDIRECT3DVOLUMETEXTURE8 createVolumeTexture(D3dCtx *d3dCtx, + jint numLevels, + jint internalFormat, + jint width, + jint height, + jint depth); + + +extern LPDIRECT3DCUBETEXTURE8 createCubeMapTexture(D3dCtx *d3dCtx, + jint numLevels, + jint internalFormat, + jint width, + jint height); + + +extern void copyDataToSurface(jint format, + jint internalFormat, + jint xoffset, jint yoffset, + jint imgXOffset, jint imgYOffset, + jint width, jint height, jint tilew, + jshort *data, LPDIRECT3DTEXTURE8 surf, + jint level); + +extern void copyDataToSurface(jint format, + jint internalFormat, + jint xoffset, jint yoffset, + jint imgXOffset, jint imgYOffset, + jint width, jint height, jint tilew, + jbyte* data, + LPDIRECT3DTEXTURE8 surf, + jint level); + +extern void copyDataToVolume(jint format, + jint internalFormat, + jint xoffset, jint yoffset, + jint zoffset, + jint imgXOffset, jint imgYOffset, + jint imgZOffset, + jint width, jint height, jint depth, + jint tilew, jint tileh, + jshort *data, LPDIRECT3DVOLUMETEXTURE8 surf, + jint level); + + +extern void copyDataToVolume(jint format, + jint internalFormat, + jint xoffset, jint yoffset, + jint zoffset, + jint imgXOffset, jint imgYOffset, + jint imgZOffset, + jint width, jint height, jint depth, + jint tilew, jint tileh, + jbyte* data, + LPDIRECT3DVOLUMETEXTURE8 surf, + jint level); + +extern void copyDataToCubeMap(jint format, + jint internalFormat, + jint xoffset, jint yoffset, + jint imgXOffset, jint imgYOffset, + jint width, jint height, + jint tilew, + jshort *data, LPDIRECT3DCUBETEXTURE8 surf, + jint level, + jint face); + + +extern void copyDataToCubeMap(jint format, + jint internalFormat, + jint xoffset, jint yoffset, + jint imgXOffset, jint imgYOffset, + jint width, jint height, + jint tilew, + jbyte* data, + LPDIRECT3DCUBETEXTURE8 surf, + jint level, + jint face); + + +extern void copyDepthFromSurface(jint xoffset, jint yoffset, + jint subWidth, jint subHeight, + jint *data, + LPDIRECT3DSURFACE8 surf); + +extern void copyDepthFromSurface(jint xoffset, jint yoffset, + jint subWidth, jint subHeight, + jfloat *data, + LPDIRECT3DSURFACE8 surf); + +extern void copyDepthToSurface(D3dCtx *d3dCtx, + LPDIRECT3DDEVICE8 device, + jint dst_xoffset, jint dst_yoffset, + jint src_xoffset, jint src_yoffset, + jint subWidth, jint subHeight, + jint src_width, jint src_height, + jint *data, + LPDIRECT3DSURFACE8 surf); + +extern void copyDepthToSurface(D3dCtx *d3dCtx, + LPDIRECT3DDEVICE8 device, + jint dst_xoffset, jint dst_yoffset, + jint src_xoffset, jint src_yoffset, + jint subWidth, jint subHeight, + jint src_width, jint src_height, + jfloat *data, + LPDIRECT3DSURFACE8 surf); + +extern void copyDataFromSurface(jint internalFormat, + jint xoffset, jint yoffset, + jint width, jint height, + jbyte *data, LPDIRECT3DSURFACE8 surf); + +void compositeDataToSurface(jint px, jint py, + jint xoffset, jint yoffset, + jint subWidth, jint subHeight, + jint dataWidth, + jbyte *data, + LPDIRECT3DSURFACE8 surf); + +// extern BOOL isIdentity(jdouble *matrix); + +extern void CopyTextureStage(LPDIRECT3DDEVICE8 device, + int fromLevel, int toLevel); + + +extern LPDIRECT3DTEXTURE8 createSurfaceFromImage(JNIEnv *env, + jobject pa2d, + jlong ctx, + int width, + int height, + jbyteArray pixels); +extern "C" +DWORD countBits(DWORD mask); // Define in MasterControl.c + +extern BOOL createQuadIndices(D3dCtx *d3dCtx, int vcount); +extern VOID createLineModeIndexBuffer(D3dCtx *d3dCtx); +extern char *getPixelFormatName(D3DFORMAT format); +extern char *getMultiSampleName(D3DMULTISAMPLE_TYPE mtype); +extern char *getSwapEffectName(D3DSWAPEFFECT swapEffect); +extern int getPrimitiveNum(int primitive, int vcount); +extern int getMaxNumVertex(int primitive, int vcount); +extern void drawTextureRect(D3dCtx *d3dCtx, + LPDIRECT3DDEVICE8 device, + LPDIRECT3DTEXTURE8 tex, + D3DTLVERTEX screenCoord, + int startx, int starty, + int endx, int endy, + int scaleWidth, int scaleHeight, + boolean texModeRepeat); +extern int setTextureStage(D3dCtx *d3dCtx, + LPDIRECT3DDEVICE8 device, + int mapTexStage, + jint texStage); +extern void setTexTransformStageFlag(D3dCtx* d3dCtx, + LPDIRECT3DDEVICE8 device, + int tus, int ts, int genMode); +#endif + diff --git a/src/native/d3d/D3dVertexBuffer.cpp b/src/native/d3d/D3dVertexBuffer.cpp new file mode 100644 index 0000000..e3cb8d1 --- /dev/null +++ b/src/native/d3d/D3dVertexBuffer.cpp @@ -0,0 +1,259 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include "StdAfx.h" +#include "D3dVertexBuffer.hpp" + + +D3dVertexBuffer::D3dVertexBuffer() +{ + buffer = NULL; + indexBuffer = NULL; + numVertices = NULL; + numVerticesLen = 0; + isIndexPrimitive = FALSE; + nextVB = NULL; + stripLen = 0; + totalVertexCount = 0; + ctx = NULL; + next = NULL; + previous = NULL; + isPointFlagUsed = FALSE; + primitiveType = D3DPT_FORCE_DWORD; +} + +D3dVertexBuffer::~D3dVertexBuffer() +{ + release(); +} + +VOID D3dVertexBuffer::release() +{ + SafeRelease(buffer); + SafeRelease(indexBuffer); + SafeDelete(numVertices); + + numVerticesLen = 0; + isIndexPrimitive = FALSE; + isPointFlagUsed = FALSE; + stripLen = 0; + totalVertexCount = 0; + // recursively free the list + SafeDelete(nextVB); +} + + + +VOID D3dVertexBuffer::render(D3dCtx *d3dCtx) +{ + D3DPRIMITIVETYPE oldPrimitiveType; + BOOL renderPoint = false; + BOOL restorePointSize = false; + float oldPointSize = 1.0f; + + if ((buffer != NULL) && (numVertices != NULL)) { + // device is already check for NULL in callDisplayList + LPDIRECT3DDEVICE8 device = d3dCtx->pDevice; + BOOL setAmbientLight = false; + + if (((vertexFormat & D3DFVF_DIFFUSE) == 0) && + (!d3dCtx->isLightEnable)) { + setAmbientLight = true; + if (totalVertexCount > 0) { + // This is the first Node in the list + d3dCtx->setAmbientLightMaterial(); + } + } + + if ((d3dCtx->pointSize > 1) && + ((d3dCtx->fillMode == D3DFILL_POINT) || + (primitiveType == D3DPT_POINTLIST))) { + // Some driver may cull the point away if not + // set to CULL_NONE + if (!isPointFlagUsed) { + // restore point size to 1 + if (debug) { + printf("VB render with pointSize %d without D3DPOINT flag set\n", d3dCtx->pointSize); + } + device->SetRenderState(D3DRS_POINTSIZE, *((LPDWORD) + &oldPointSize)); + restorePointSize = true; + } else { + device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + // workaround for driver bug, otherwise you will + // see four corner points instead of one big point + // if fill mode is POINT + device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + if (d3dCtx->deviceInfo->maxPointSize < d3dCtx->pointSize) { + // Use software vertex processing mode + device->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, + TRUE); + } + oldPrimitiveType = primitiveType; + // For Polygon D3DFill_POINT mode we need to + // temporary switch primitive to point list + primitiveType = D3DPT_POINTLIST; + renderPoint = true; + } + } + + device->SetStreamSource(0, buffer, stride); + device->SetVertexShader(vertexFormat); + + int startIdx=0; + int vc, i; + + if (!isIndexPrimitive || + ((indexBuffer == NULL) && renderPoint)) { + for (i = 0; i < stripLen; i++) { + vc = numVertices[i]; + device->DrawPrimitive(primitiveType, + startIdx, + getPrimitiveNum(primitiveType,vc)); + startIdx += vc; + } + } else { + if (indexBuffer != NULL) { + device->SetIndices(indexBuffer, 0); + for (i = 0; i < stripLen; i++) { + vc = numVertices[i]; + device->DrawIndexedPrimitive(primitiveType, + 0, + vcount, + startIdx, + getPrimitiveNum(primitiveType, vc)); + startIdx += vc; + } + } else { + if (d3dCtx->quadIndexBufferSize > 0) { + // Index is successfully set + device->SetIndices(d3dCtx->quadIndexBuffer, 0); + device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, + 0, + numVertices[0], + 0, + numVertices[0] >> 1); + } + // Otherwise not enough memory when index buffer + // is created, so draw nothing. + } + } + + if (setAmbientLight && (nextVB == NULL)) { + // This is the last Node in the list + d3dCtx->restoreDefaultLightMaterial(); + } + + if (renderPoint) { + device->SetRenderState(D3DRS_CULLMODE, d3dCtx->cullMode); + device->SetRenderState(D3DRS_FILLMODE, d3dCtx->fillMode); + device->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, + d3dCtx->softwareVertexProcessing); + primitiveType = oldPrimitiveType; + } else if (restorePointSize) { + device->SetRenderState(D3DRS_POINTSIZE, + *((LPDWORD) &d3dCtx->pointSize)); + } + } + + if (nextVB != NULL) { + nextVB->render(d3dCtx); + } +} + + +VOID D3dVertexBuffer::addStride(int len) +{ + if (numVerticesLen <= stripLen) { + if (numVerticesLen == 0) { + numVertices = new USHORT[1]; + if (numVertices == NULL) { + D3dCtx::d3dWarning(OUTOFMEMORY); + return; + } + numVerticesLen = 1; + } else { + int size = numVerticesLen << 1; + USHORT *p = new USHORT[size]; + if (p == NULL) { + D3dCtx::d3dWarning(OUTOFMEMORY); + return; + } + CopyMemory(p, numVertices, numVerticesLen*sizeof(USHORT)); + delete numVertices; + numVertices = p; + numVerticesLen = size; + } + } + numVertices[stripLen++] = len; +} + + +/* + * This is used by Strip GeometryArray + * Replace all previously define stripLen by this one. + */ +VOID D3dVertexBuffer::addStrides(jint len, jint* strips) +{ + int i = len; + + if (numVerticesLen < len) { + if (numVertices) { + delete numVertices; + } + numVertices = new USHORT[len]; + numVerticesLen = len; + } + + USHORT *q = numVertices; + + while (--i >= 0) { + *q++ = *strips++; + } + stripLen = len; +} + + +/* + * This is used by D3dDisplayList optimize() + * Append this one to the current strip define. + */ +VOID D3dVertexBuffer::appendStrides(jint len, USHORT* strips) +{ + int i; + USHORT *oldVertices; + + if (numVerticesLen < stripLen + len) { + oldVertices = numVertices; + numVertices = new USHORT[len + stripLen]; + numVerticesLen = len + stripLen; + } + + USHORT *q = numVertices; + USHORT *p = oldVertices; + + if (oldVertices != NULL) { + i = stripLen; + while (--i >= 0) { + *q++ = *p++; + } + delete oldVertices; + } + + i = len; + while (--i >= 0) { + *q++ = *strips++; + } + + stripLen = numVerticesLen; +} + diff --git a/src/native/d3d/D3dVertexBuffer.hpp b/src/native/d3d/D3dVertexBuffer.hpp new file mode 100644 index 0000000..e5633fa --- /dev/null +++ b/src/native/d3d/D3dVertexBuffer.hpp @@ -0,0 +1,127 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#if !defined(D3DVERTEXBUFFER_H) +#define D3DVERTEXBUFFER_H + +#include "StdAfx.h" + +class D3dCtx; + +class D3dVertexBuffer; + +typedef D3dVertexBuffer* LPD3DVERTEXBUFFER; +typedef vector D3dVertexBufferVector; + + +class D3dVertexBuffer { +public: + + // Actual buffer memory to hold all the vertices + LPDIRECT3DVERTEXBUFFER8 buffer; + + // Indexed buffer for rendering IndexedGeometry + LPDIRECT3DINDEXBUFFER8 indexBuffer; + + // D3D type of this Vertex Buffer + D3DPRIMITIVETYPE primitiveType; + + // Length of following numVertices array allocate + UINT numVerticesLen; + + // Store the number of vertices for each strip + USHORT *numVertices; + + // It true when QuadArray is used or + // indexGeometry is used. + BOOL isIndexPrimitive; + + // If D3DUSAGE_POINTS flag is used to + // create this VertexBuffer + BOOL isPointFlagUsed; + + // Flexible vertex format for this VB + DWORD vertexFormat; + + // Stride of each vertex in the buffer + // compute from above vertexFormat + UINT stride; + + // Number of strips used for StripGeometryArray + // For each strip i the number of vertex is + // numVertices[i] + UINT stripLen; + + // Point to next overflow VB when size > VB limit + LPD3DVERTEXBUFFER nextVB; + + // content that this buffer belongs, only the first node set this one. + D3dCtx *ctx; + + // vcount is the number of vertex that this buffer + // can hold. vcount*stride is always equal to + // current VB size + UINT vcount; + + // indexCount is the number of index that this buffer + // can hold. indexCount*indexSize is always equal to + // current index VB size. + UINT indexCount; + + // Vertex count of all VBs link by nextVB, + // only the first node need to remember this info. + // The other overflow buffer always set it to zero. + DWORD totalVertexCount; + + // Same as above, except for indexBuffer + DWORD totalIndexCount; + + // This is a list of VB remember by D3dCtx + // so that it can release() all surface when canvas resize + // Only the header D3dVertexBuffer contains non-null entry + LPD3DVERTEXBUFFER next; + LPD3DVERTEXBUFFER previous; + + // Pointer back to the GeometryArrayRetained pVertexBuffers + // This is used to remove itself from pVertexBuffers table + // when ctx destroy + D3dVertexBufferVector* vbVector; + + // Last texture coordinate position = + // (i) textureCoordSetMap[pass] if executeVA() + // (ii) texCoordSetMapOffset[pass] if execute() or buildGA() + // (iii) TEX_EYE_LINEAR/TEX_SPHERE_MAP/TEX_OBJ_LINEAR/TEX_REFLECT_MAP + // if automatic texture generation is used + // This is used for VertexBuffer to know whether Texture + // coordinate need to copy or not in case texture unit swap + // or texture unit change from automatic texture generation + // to use coordinate index specifies by user. + int texCoordPosition[D3DDP_MAXTEXCOORD]; + + // Max vertex limit allow for this primitive type + // This is used for display list optimization without + // recompute it again. + int maxVertexLimit; + + D3dVertexBuffer(); + ~D3dVertexBuffer(); + + VOID release(); + VOID render(D3dCtx *d3dCtx); + BOOL initializeNumVertices(int len); + VOID addStride(int len); + VOID addStrides(jint stripLen, jint *strips); + VOID appendStrides(jint stripLen, USHORT *strips); +}; + + +#endif diff --git a/src/native/d3d/GeometryArrayRetained.cpp b/src/native/d3d/GeometryArrayRetained.cpp new file mode 100644 index 0000000..e8596d0 --- /dev/null +++ b/src/native/d3d/GeometryArrayRetained.cpp @@ -0,0 +1,5254 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include "StdAfx.h" + + +//#define VBDEBUG +//#define TEXDEBUG + +#define getVertexFormat(texSize) \ + (((texSize) << D3DFVF_TEXCOUNT_SHIFT) & D3DFVF_TEXCOUNT_MASK) + +/* + * This correspond to the constant in d3dtypes.h + * under D3D 7.0/8.0 header and may not portable : + * D3DFVF_TEXTUREFORMAT1 3 + * D3DFVF_TEXTUREFORMAT2 0 + * D3DFVF_TEXTUREFORMAT3 1 + * D3DFVF_TEXTUREFORMAT4 2 + */ +CONST static DWORD TexFormatSizeTable[5] = {0, 3, 0, 1, 2}; +static float defaultTexCoord[4] = {0, 0, 0, 0}; + +typedef struct _D3DDRAWPRIMITIVESTRIDEDDATA +{ + DWORD positionStride; + jfloat *fpositionPtr; + jdouble *dpositionPtr; + DWORD normalStride; + jfloat *normalPtr; + DWORD diffuseStride; + jfloat *fdiffusePtr; + jbyte *bdiffusePtr; + jint *indexPtr; + jint initialIndexIndex; + DWORD textureCoordsStride[D3DDP_MAXTEXCOORD]; + jfloat* textureCoordsPtr[D3DDP_MAXTEXCOORD]; + jint texCoordPosition[D3DDP_MAXTEXCOORD]; + boolean useAlpha; + boolean modulateAlpha; + jfloat alpha; +} D3DDRAWPRIMITIVESTRIDEDDATA, *LPD3DDRAWPRIMITIVESTRIDEDDATA; + + +void copyIndexVertexToVB(D3dCtx *d3dCtx, + D3DDRAWPRIMITIVESTRIDEDDATA* strideData, + DWORD indexCount, + jint cDirty, + BOOL insertStrideToVB, + BOOL expandQuadIndex) +{ + HRESULT hr; + + if (cDirty & javax_media_j3d_GeometryArrayRetained_INDEX_CHANGED) { + jint *src = strideData->indexPtr + strideData->initialIndexIndex; + LPDIRECT3DINDEXBUFFER8 indexBuffer = d3dCtx->pVB->indexBuffer; + D3DINDEXBUFFER_DESC desc; + BYTE *bptr; + + indexBuffer->GetDesc(&desc); + hr = indexBuffer->Lock(0, 0, &bptr, 0); + if (FAILED(hr)) { + D3dCtx::d3dWarning(LOCKINDEXVBFAIL, hr); + return; + } + + int i = indexCount; + + if (desc.Format == D3DFMT_INDEX16) { + USHORT *dst = (USHORT *) bptr; + + if (!expandQuadIndex) { + while (--i >= 0) { + *dst++ = *src++; + } + } else { + USHORT *endptr = dst + (USHORT) 3*indexCount/2; + + while (dst < endptr) { + *dst++ = *src; + *dst++ = *(src+1); + *dst++ = *(src+2); + *dst++ = *src; + src++; + src++; + *dst++ = *src; + src++; + *dst++ = *src; + src++; + } + } + } else { + UINT *dst = (UINT *) bptr; + + if (!expandQuadIndex) { + while (--i >= 0) { + *dst++ = *src++; + } + } else { + UINT *endptr = dst + (UINT) 3*indexCount/2; + while (dst < endptr) { + *dst++ = *src; + *dst++ = *(src+1); + *dst++ = *(src+2); + *dst++ = *src; + src++; + src++; + *dst++ = *src; + src++; + *dst++ = *src; + src++; + } + + dst = (UINT *) bptr; + } + } + + indexBuffer->Unlock(); + } + + if (insertStrideToVB) { + d3dCtx->pVB->addStride(d3dCtx->pVB->indexCount); + } +} + +// This function copy the stride vertex data into Vertex Buffer +// point by vbptr and update vbptr +void copyVertexToVB(D3dCtx *d3dCtx, + D3DDRAWPRIMITIVESTRIDEDDATA* strideData, + DWORD vcount, + float **vbptr, + jint cDirty, + BOOL insertStrideToVB, + jdouble* xform, + jdouble* nxform) +{ + float *dst; + float *src; + double *dsrc; + DWORD i; + DWORD srcStride; + DWORD currStride; + + DWORD dstStride = d3dCtx->pVB->stride >> 2; + DWORD vertexFormat = d3dCtx->pVB->vertexFormat; + float *endptr; + + // Copy Position + if (cDirty & javax_media_j3d_GeometryArrayRetained_COORDINATE_CHANGED) { + dst = *vbptr; + // Before we call two times src++ in position and + // normal copy so we only need to add dstStride - 2 + // at the end. + srcStride = strideData->positionStride - 2; + endptr = dst + vcount*dstStride; + dstStride -= 2; + src = strideData->fpositionPtr; + + if (xform == NULL) { + if (src != NULL) { + while (dst < endptr) { + *dst++ = *src++; // pos x + *dst++ = *src++; // pos y + *dst = *src; // pos z + dst += dstStride; + src += srcStride; + } + } else { + // double is used for position coordinate in executeVA() + dsrc = strideData->dpositionPtr; + while (dst < endptr) { + *dst++ = *dsrc++; // pos x + *dst++ = *dsrc++; // pos y + *dst = *dsrc; // pos z + dst += dstStride; + dsrc += srcStride; + } + } + } else { + if (src != NULL) { + float x, y, z, w; + while (dst < endptr) { + x = *src++; + y = *src++; + z = *src; // pos z + w = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]); + *dst++ = (xform[0]*x + xform[1]*y + xform[2]*z + xform[3])*w; + *dst++ = (xform[4]*x + xform[5]*y + xform[6]*z + xform[7])*w; + *dst = (xform[8]*x + xform[9]*y + xform[10]*z + xform[11])*w; + dst += dstStride; + src += srcStride; + } + } else { + double x, y, z, w; + // double is used for position coordinate in executeVA() + dsrc = strideData->dpositionPtr; + while (dst < endptr) { + x = *src++; + y = *src++; + z = *src; // pos z + w = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]); + *dst++ = (xform[0]*x + xform[1]*y + xform[2]*z + xform[3])*w; + *dst++ = (xform[4]*x + xform[5]*y + xform[6]*z + xform[7])*w; + *dst = (xform[8]*x + xform[9]*y + xform[10]*z + xform[11])*w; + dst += dstStride; + dsrc += srcStride; + } + } + + } + // restore value + dstStride += 2; + } + + // Copy Normal + if (vertexFormat & D3DFVF_NORMAL) { + if (cDirty & javax_media_j3d_GeometryArrayRetained_NORMAL_CHANGED) { + dst = *vbptr + 3; + src = strideData->normalPtr; + srcStride = strideData->normalStride - 2; + endptr = dst + vcount*dstStride; + dstStride -= 2; + if (nxform == NULL) { + while (dst < endptr) { + *dst++ = *src++; // norm x + *dst++ = *src++; // norm y + *dst = *src; // norm z + dst += dstStride; + src += srcStride; + } + } else { + float nx, ny, nz, nw; + while (dst < endptr) { + nx = *src++; + ny = *src++; + nz = *src; // pos z + nw = 1/(nxform[12]*nx + nxform[13]*ny + nxform[14]*nz + nxform[15]); + *dst++ = (nxform[0]*nx + nxform[1]*ny + nxform[2]*nz + nxform[3])*nw; + *dst++ = (nxform[4]*nx + nxform[5]*ny + nxform[6]*nz + nxform[7])*nw; + *dst = (nxform[8]*nx + nxform[9]*ny + nxform[10]*nz + nxform[11])*nw; + dst += dstStride; + dsrc += srcStride; + } + } + // restore value + dstStride += 2; + } + // nx,ny,nz copy in addtion to x, y, z + currStride = 6; + } else { + // This is used to keep track of the offset + // from beginning of the current type copy. + currStride = 3; // x,y,z already copy + } + + // Copy Diffuse Color (DWORD & float are of the same size) + + if (vertexFormat & D3DFVF_DIFFUSE) { + if (cDirty & javax_media_j3d_GeometryArrayRetained_COLOR_CHANGED) { + + DWORD* wdst = (DWORD *) *vbptr + currStride; + DWORD* wendptr = wdst + vcount*dstStride; + + if (strideData->fdiffusePtr) { + float* wsrc = strideData->fdiffusePtr; + float r, g, b, a; + if ((d3dCtx->currDisplayListID <= 0) || + !strideData->modulateAlpha) { + // execute() or executeVA() + + if (strideData->useAlpha) { + srcStride = strideData->diffuseStride - 3; + while (wdst < wendptr) { + r = *wsrc++; + g = *wsrc++; + b = *wsrc++; + a = *wsrc; + *wdst = D3DCOLOR_COLORVALUE(r, g, b, a); + wdst += dstStride; + wsrc += srcStride; + } + } else { + srcStride = strideData->diffuseStride - 2; + while (wdst < wendptr) { + r = *wsrc++; + g = *wsrc++; + b = *wsrc; + *wdst = D3DCOLOR_COLORVALUE(r, g, b, 0); + wdst += dstStride; + wsrc += srcStride; + } + } + } else { + // buildGA() & modulateAlpha + float alpha = strideData->alpha; + if (strideData->useAlpha) { + srcStride = strideData->diffuseStride - 3; + while (wdst < wendptr) { + r = *wsrc++; + g = *wsrc++; + b = *wsrc++; + a = *wsrc * alpha; + *wdst = D3DCOLOR_COLORVALUE(r, g, b, a); + wdst += dstStride; + wsrc += srcStride; + } + } else { + srcStride = strideData->diffuseStride - 2; + while (wdst < wendptr) { + r = *wsrc++; + g = *wsrc++; + b = *wsrc; + *wdst = D3DCOLOR_COLORVALUE(r, g, b, alpha); + wdst += dstStride; + wsrc += srcStride; + } + } + + } + } else { // byte color pointer + jbyte* wsrc = strideData->bdiffusePtr; + jbyte r, g, b, a; + if ((d3dCtx->currDisplayListID <= 0) || + !strideData->modulateAlpha) { + // execute() or executeVA() + + if (strideData->useAlpha) { + srcStride = strideData->diffuseStride - 3; + while (wdst < wendptr) { + r = *wsrc++; + g = *wsrc++; + b = *wsrc++; + a = *wsrc; + *wdst = D3DCOLOR_RGBA(r, g, b, a); + wdst += dstStride; + wsrc += srcStride; + } + } else { + srcStride = strideData->diffuseStride - 2; + while (wdst < wendptr) { + r = *wsrc++; + g = *wsrc++; + b = *wsrc; + *wdst = D3DCOLOR_RGBA(r, g, b, 0); + wdst += dstStride; + wsrc += srcStride; + } + } + } else { + // buildGA() & modeulateAlpha + // Currently buildGA() will not use byte color + // so this code should never execute. + jbyte alpha = (jbyte) 255*strideData->alpha; + if (strideData->useAlpha) { + srcStride = strideData->diffuseStride - 3; + while (wdst < wendptr) { + r = *wsrc++; + g = *wsrc++; + b = *wsrc++; + a = (jbyte)(((int)(*wsrc) & 0xff) * strideData->alpha); + *wdst = D3DCOLOR_RGBA(r, g, b, a); + wdst += dstStride; + wsrc += srcStride; + } + } else { + srcStride = strideData->diffuseStride - 2; + while (wdst < wendptr) { + r = *wsrc++; + g = *wsrc++; + b = *wsrc; + *wdst = D3DCOLOR_RGBA(r, g, b, alpha); + wdst += dstStride; + wsrc += srcStride; + } + } + + } + } + + } + + currStride++; // additional one DWORD of color copy + } + + // Copy Texture + int ts; + int texPos; + boolean invalidTexCoord; + +#ifdef TEXDEBUG + printf("In copyVertexToVB TexSet Used %d\n", d3dCtx->texSetUsed); +#endif + for (i=0; i < d3dCtx->texSetUsed; i++) { + ts = d3dCtx->texStride[i]; + + // TODO: skip when ts = 0 + if (ts == 0) { + continue; + } + texPos = strideData->texCoordPosition[i]; + + invalidTexCoord = ((texPos != d3dCtx->pVB->texCoordPosition[i]) || + (texPos == TEX_OBJ_LINEAR)); + +#ifdef TEXDEBUG + printf("%d texPos %d, invalidate Cached TexCoord %d, ts %d\n",i, texPos, invalidTexCoord, ts); +#endif + if ((cDirty & javax_media_j3d_GeometryArrayRetained_TEXTURE_CHANGED) || + invalidTexCoord) { + + if (texPos >= 0) { + dst = *vbptr + currStride; + src = strideData->textureCoordsPtr[i]; + endptr = dst + vcount*dstStride; +#ifdef TEXDEBUG + printf("copy directly, ts %d\n", ts); +#endif + if (ts == 2) { + dstStride--; + srcStride = strideData->textureCoordsStride[i] - 1; + while (dst < endptr) { + *dst++ = *src++; // tx + *dst = *src; // ty + dst += dstStride; + src += srcStride; + } + dstStride++; + } else if (ts == 3) { + dstStride -= 2; + srcStride = strideData->textureCoordsStride[i] - 2; + while (dst < endptr) { + *dst++ = *src++; // tx + *dst++ = *src++; // ty + *dst = *src; // tz + dst += dstStride; + src += srcStride; + } + dstStride += 2; + } else { + // ts == 4 + dstStride -= 3; + srcStride = strideData->textureCoordsStride[i] - 3; + while (dst < endptr) { + *dst++ = *src++; // tx + *dst++ = *src++; // ty + *dst++ = *src++; // tz + *dst = *src; // tw + dst += dstStride; + src += srcStride; + } + dstStride += 3; + } + + } else { + if (texPos == TEX_OBJ_LINEAR) { + // automatic texture generation for Object Linear + float *ps = d3dCtx->planeS[i]; + float *pt = d3dCtx->planeT[i]; + float *pr = d3dCtx->planeR[i]; + float *pq = d3dCtx->planeQ[i]; +#ifdef TEXDEBUG + printf("gen obj linear tex, ts %d\n", ts); +#endif + if (strideData->fpositionPtr) { + float x, y, z; + dst = *vbptr + currStride; + endptr = dst + vcount*dstStride; + src = strideData->fpositionPtr; + srcStride = strideData->positionStride - 2; + if (ts == 2) { + dstStride--; + if (xform == NULL) { + while (dst < endptr) { + x = *src++; + y = *src++; + z = *src; + *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3]; + *dst = pt[0]*x + pt[1]*y + pt[2]*z + pt[3]; + dst += dstStride; + src += srcStride; + } + } else { + float tx, ty, tz, tw; + while (dst < endptr) { + tx = *src++; + ty = *src++; + tz = *src; + tw = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]); + x = (xform[0]*tx + xform[1]*ty + xform[2]*tz + xform[3])*tw; + y = (xform[4]*tx + xform[5]*ty + xform[6]*tz + xform[7])*tw; + z = (xform[8]*tx + xform[9]*ty + xform[10]*tz + xform[11])*tw; + *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3]; + *dst = pt[0]*x + pt[1]*y + pt[2]*z + pt[3]; + dst += dstStride; + src += srcStride; + } + } + dstStride++; + } else if (ts == 3) { + dstStride -= 2; + if (xform == NULL) { + while (dst < endptr) { + x = *src++; + y = *src++; + z = *src; + *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3]; + *dst++ = pt[0]*x + pt[1]*y + pt[2]*z + pt[3]; + *dst = pr[0]*x + pr[1]*y + pr[2]*z + pr[3]; + dst += dstStride; + src += srcStride; + } + } else { + float tx, ty, tz, tw; + while (dst < endptr) { + tx = *src++; + ty = *src++; + tz = *src; + tw = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]); + x = (xform[0]*tx + xform[1]*ty + xform[2]*tz + xform[3])*tw; + y = (xform[4]*tx + xform[5]*ty + xform[6]*tz + xform[7])*tw; + z = (xform[8]*tx + xform[9]*ty + xform[10]*tz + xform[11])*tw; + *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3]; + *dst++ = pt[0]*x + pt[1]*y + pt[2]*z + pt[3]; + *dst = pr[0]*x + pr[1]*y + pr[2]*z + pr[3]; + dst += dstStride; + src += srcStride; + } + } + + dstStride += 2; + } else { + // ts == 4 + dstStride -= 3; + + if (!d3dCtx->texTransformSet[i]) { + if (xform == NULL) { + while (dst < endptr) { + x = *src++; + y = *src++; + z = *src; + *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3]; + *dst++ = pt[0]*x + pt[1]*y + pt[2]*z + pt[3]; + *dst++ = pr[0]*x + pr[1]*y + pr[2]*z + pr[3]; + *dst = pq[0]*x + pq[1]*y + pq[2]*z + pq[3]; + dst += dstStride; + src += srcStride; + } + } else { + float tx, ty, tz, tw; + while (dst < endptr) { + tx = *src++; + ty = *src++; + tz = *src; + tw = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]); + x = (xform[0]*tx + xform[1]*ty + xform[2]*tz + xform[3])*tw; + y = (xform[4]*tx + xform[5]*ty + xform[6]*tz + xform[7])*tw; + z = (xform[8]*tx + xform[9]*ty + xform[10]*tz + xform[11])*tw; + *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3]; + *dst++ = pt[0]*x + pt[1]*y + pt[2]*z + pt[3]; + *dst++ = pr[0]*x + pr[1]*y + pr[2]*z + pr[3]; + *dst = pq[0]*x + pq[1]*y + pq[2]*z + pq[3]; + dst += dstStride; + src += srcStride; + } + } + } else { + // do texture transform manually + D3DXMATRIX *m = &(d3dCtx->texTransform[i]); + double tx, ty, tz, tw; + if (xform == NULL) { + while (dst < endptr) { + x = *src++; + y = *src++; + z = *src; + tx = ps[0]*x + ps[1]*y + ps[2]*z + ps[3]; + ty = pt[0]*x + pt[1]*y + pt[2]*z + pt[3]; + tz = pr[0]*x + pr[1]*y + pr[2]*z + pr[3]; + tw = pq[0]*x + pq[1]*y + pq[2]*z + pq[3]; + *dst++ = (*m)._11*tx + (*m)._21*ty + (*m)._31*tz + (*m)._41*tw; + *dst++ = (*m)._12*tx + (*m)._22*ty + (*m)._32*tz + (*m)._42*tw; + *dst++ = (*m)._13*tx + (*m)._23*ty + (*m)._33*tz + (*m)._43*tw; + *dst = (*m)._14*tx + (*m)._24*ty + (*m)._34*tz + (*m)._44*tw; + dst += dstStride; + src += srcStride; + } + } else { + float tx, ty, tz, tw; + while (dst < endptr) { + tx = *src++; + ty = *src++; + tz = *src; + tw = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]); + x = (xform[0]*tx + xform[1]*ty + xform[2]*tz + xform[3])*tw; + y = (xform[4]*tx + xform[5]*ty + xform[6]*tz + xform[7])*tw; + z = (xform[8]*tx + xform[9]*ty + xform[10]*tz + xform[11])*tw; + tx = ps[0]*x + ps[1]*y + ps[2]*z + ps[3]; + ty = pt[0]*x + pt[1]*y + pt[2]*z + pt[3]; + tz = pr[0]*x + pr[1]*y + pr[2]*z + pr[3]; + tw = pq[0]*x + pq[1]*y + pq[2]*z + pq[3]; + *dst++ = (*m)._11*tx + (*m)._21*ty + (*m)._31*tz + (*m)._41*tw; + *dst++ = (*m)._12*tx + (*m)._22*ty + (*m)._32*tz + (*m)._42*tw; + *dst++ = (*m)._13*tx + (*m)._23*ty + (*m)._33*tz + (*m)._43*tw; + *dst = (*m)._14*tx + (*m)._24*ty + (*m)._34*tz + (*m)._44*tw; + dst += dstStride; + src += srcStride; + } + } + } + dstStride += 3; + } + } else { + // double type position pointer + double x, y, z; + dst = *vbptr + currStride; + endptr = dst + vcount*dstStride; + dsrc = strideData->dpositionPtr; + srcStride = strideData->positionStride - 2; + if (ts == 2) { + dstStride--; + if (xform == NULL) { + while (dst < endptr) { + x = *dsrc++; + y = *dsrc++; + z = *dsrc; + *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3]; + *dst = pt[0]*x + pt[1]*y + pt[2]*z + pt[3]; + dst += dstStride; + dsrc += srcStride; + } + } else { + double tx, ty, tz, tw; + while (dst < endptr) { + tx = *src++; + ty = *src++; + tz = *src; + tw = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]); + x = (xform[0]*tx + xform[1]*ty + xform[2]*tz + xform[3])*tw; + y = (xform[4]*tx + xform[5]*ty + xform[6]*tz + xform[7])*tw; + z = (xform[8]*tx + xform[9]*ty + xform[10]*tz + xform[11])*tw; + *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3]; + *dst = pt[0]*x + pt[1]*y + pt[2]*z + pt[3]; + dst += dstStride; + src += srcStride; + } + } + dstStride++; + } else if (ts == 3) { + dstStride -= 2; + if (xform == NULL) { + while (dst < endptr) { + x = *dsrc++; + y = *dsrc++; + z = *dsrc; + *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3]; + *dst++ = pt[0]*x + pt[1]*y + pt[2]*z + pt[3]; + *dst = pr[0]*x + pr[1]*y + pr[2]*z + pr[3]; + dst += dstStride; + dsrc += srcStride; + } + } else { + double tx, ty, tz, tw; + while (dst < endptr) { + tx = *src++; + ty = *src++; + tz = *src; + tw = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]); + x = (xform[0]*tx + xform[1]*ty + xform[2]*tz + xform[3])*tw; + y = (xform[4]*tx + xform[5]*ty + xform[6]*tz + xform[7])*tw; + z = (xform[8]*tx + xform[9]*ty + xform[10]*tz + xform[11])*tw; + *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3]; + *dst++ = pt[0]*x + pt[1]*y + pt[2]*z + pt[3]; + *dst = pr[0]*x + pr[1]*y + pr[2]*z + pr[3]; + dst += dstStride; + src += srcStride; + } + } + dstStride += 2; + } else { + // ts == 4 + dstStride -= 3; + if (!d3dCtx->texTransformSet[i]) { + if (xform == NULL) { + while (dst < endptr) { + x = *dsrc++; + y = *dsrc++; + z = *dsrc; + *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3]; + *dst++ = pt[0]*x + pt[1]*y + pt[2]*z + pt[3]; + *dst++ = pr[0]*x + pr[1]*y + pr[2]*z + pr[3]; + *dst = pq[0]*x + pq[1]*y + pq[2]*z + pq[3]; + dst += dstStride; + dsrc += srcStride; + } + } else { + double tx, ty, tz, tw; + while (dst < endptr) { + tx = *src++; + ty = *src++; + tz = *src; + tw = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]); + x = (xform[0]*tx + xform[1]*ty + xform[2]*tz + xform[3])*tw; + y = (xform[4]*tx + xform[5]*ty + xform[6]*tz + xform[7])*tw; + z = (xform[8]*tx + xform[9]*ty + xform[10]*tz + xform[11])*tw; + *dst++ = ps[0]*x + ps[1]*y + ps[2]*z + ps[3]; + *dst++ = pt[0]*x + pt[1]*y + pt[2]*z + pt[3]; + *dst++ = pr[0]*x + pr[1]*y + pr[2]*z + pr[3]; + *dst = pq[0]*x + pq[1]*y + pq[2]*z + pq[3]; + dst += dstStride; + src += srcStride; + } + } + } else { +// do texture transform manually + D3DXMATRIX *m = &(d3dCtx->texTransform[i]); + double tx, ty, tz, tw; + if (xform == NULL) { + while (dst < endptr) { + x = *src++; + y = *src++; + z = *src; + tx = ps[0]*x + ps[1]*y + ps[2]*z + ps[3]; + ty = pt[0]*x + pt[1]*y + pt[2]*z + pt[3]; + tz = pr[0]*x + pr[1]*y + pr[2]*z + pr[3]; + tw = pq[0]*x + pq[1]*y + pq[2]*z + pq[3]; + *dst++ = ((*m)._11*tx + (*m)._21*ty + (*m)._31*tz + (*m)._41*tw); + *dst++ = ((*m)._12*tx + (*m)._22*ty + (*m)._32*tz + (*m)._42*tw); + *dst++ = ((*m)._13*tx + (*m)._23*ty + (*m)._33*tz + (*m)._43*tw); + *dst = (*m)._14*tx + (*m)._24*ty + (*m)._34*tz + (*m)._44*tw; + dst += dstStride; + src += srcStride; + } + } else { + float tx, ty, tz, tw; + while (dst < endptr) { + tx = *src++; + ty = *src++; + tz = *src; + tw = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]); + x = (xform[0]*tx + xform[1]*ty + xform[2]*tz + xform[3])*tw; + y = (xform[4]*tx + xform[5]*ty + xform[6]*tz + xform[7])*tw; + z = (xform[8]*tx + xform[9]*ty + xform[10]*tz + xform[11])*tw; + tx = ps[0]*x + ps[1]*y + ps[2]*z + ps[3]; + ty = pt[0]*x + pt[1]*y + pt[2]*z + pt[3]; + tz = pr[0]*x + pr[1]*y + pr[2]*z + pr[3]; + tw = pq[0]*x + pq[1]*y + pq[2]*z + pq[3]; + *dst++ = ((*m)._11*tx + (*m)._21*ty + (*m)._31*tz + (*m)._41*tw); + *dst++ = ((*m)._12*tx + (*m)._22*ty + (*m)._32*tz + (*m)._42*tw); + *dst++ = ((*m)._13*tx + (*m)._23*ty + (*m)._33*tz + (*m)._43*tw); + *dst = (*m)._14*tx + (*m)._24*ty + (*m)._34*tz + (*m)._44*tw; + dst += dstStride; + src += srcStride; + } + } + } + dstStride += 3; + } + } + } else if (texPos == TEX_GEN_INVALID) { + // application error, disable by setting texCoord to zero +#ifdef TEXDEBUG + printf("app error, ts %d\n", ts); +#endif + dst = *vbptr + currStride; + endptr = dst + vcount*dstStride; + if (ts == 2) { + dstStride--; + while (dst < endptr) { + *dst++ = 0; + *dst = 0; + dst += dstStride; + } + dstStride++; + } else if (ts == 3) { + dstStride -= 2; + while (dst < endptr) { + *dst++ = 0; + *dst++ = 0; + *dst = 0; + dst += dstStride; + } + dstStride += 2; + } else { + // ts == 4 + dstStride -= 3; + while (dst < endptr) { + *dst++ = 0; + *dst++ = 0; + *dst++ = 0; + *dst = 0; + dst += dstStride; + } + dstStride += 3; + } + } else { + // Other automatic texture generation type handle + // by driver + //printf("TexStage %d, Tex gen by driver, texPos = %d\n", i, texPos); + } + } + } + + currStride += ts; + } + + if (insertStrideToVB) { + d3dCtx->pVB->addStride(vcount); + } + + // Adjust VB pointer so that when this function is invoked + // again, it append to the VB correctly. + *vbptr += (vcount*dstStride); +} + + +void copyOneVertexToVB(D3dCtx *d3dCtx, + float **vbptr, + D3DDRAWPRIMITIVESTRIDEDDATA* strideData, + DWORD idx, + jint cDirty, + jdouble* xform, + jdouble* nxform) +{ + float *src; + float *dst = *vbptr; + DWORD vertexFormat = d3dCtx->pVB->vertexFormat; + float posX, posY, posZ; + + // Copy Position + + // if (cDirty & javax_media_j3d_GeometryArrayRetained_COORDINATE_CHANGED) + // Set the posX, posY, posZ anyway since TexGeneration will use it + // if dirty. + + if (strideData->fpositionPtr != NULL) { + src = strideData->fpositionPtr + + idx*strideData->positionStride; + + if (xform == NULL) { + posX = *src++; // pos x + posY = *src++; // pos y + posZ = *src; // pos z + } else { + float x, y, z, w; + x = *src++; + y = *src++; + z = *src; + w = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]); + posX = (xform[0]*x + xform[1]*y + xform[2]*z + xform[3])*w; + posY = (xform[4]*x + xform[5]*y + xform[6]*z + xform[7])*w; + posZ = (xform[8]*x + xform[9]*y + xform[10]*z + xform[11])*w; + } + } else { + // double is used for position coordinate in executeVA() + double *dsrc = strideData->dpositionPtr + + idx*strideData->positionStride; + + if (xform == NULL) { + posX = (float) *dsrc++; // pos x + posY = (float) *dsrc++; // pos y + posZ = (float) *dsrc; // pos z + } else { + double x, y, z, w; + x = *dsrc++; + y = *dsrc++; + z = *dsrc; + w = 1/(xform[12]*x + xform[13]*y + xform[14]*z + xform[15]); + posX = (float) (xform[0]*x + xform[1]*y + xform[2]*z + xform[3])*w; + posY = (float) (xform[4]*x + xform[5]*y + xform[6]*z + xform[7])*w; + posZ = (float) (xform[8]*x + xform[9]*y + xform[10]*z + xform[11])*w; + } + } + *dst++ = posX; + *dst++ = posY; + *dst++ = posZ; + + // Copy Normal + if (vertexFormat & D3DFVF_NORMAL) { + if (cDirty & javax_media_j3d_GeometryArrayRetained_NORMAL_CHANGED) { + src = strideData->normalPtr + + idx*strideData->normalStride; + if (nxform == NULL) { + *dst++ = *src++; // norm x + *dst++ = *src++; // norm y + *dst++ = *src; // norm z + } else { + float nx, ny, nz, nw; + nx = *src++; // norm x + ny = *src++; // norm y + nz = *src; // norm z + nw = 1/(nxform[12]*nx + nxform[13]*ny + nxform[14]*nz + nxform[15]); + *dst++ = (nxform[0]*nx + nxform[1]*ny + nxform[2]*nz + nxform[3])*nw; + *dst++ = (nxform[4]*nx + nxform[5]*ny + nxform[6]*nz + nxform[7])*nw; + *dst = (nxform[8]*nx + nxform[9]*ny + nxform[10]*nz + nxform[11])*nw; + } + } + } + + + // Copy Diffuse Color (DWORD & float are of the same size) + if (vertexFormat & D3DFVF_DIFFUSE) { + if (cDirty & javax_media_j3d_GeometryArrayRetained_COLOR_CHANGED) { + DWORD* wdst = (DWORD *) dst; + if (strideData->fdiffusePtr) { + src = strideData->fdiffusePtr + + idx*strideData->diffuseStride; + float r, g, b, a; + if ((d3dCtx->currDisplayListID <= 0) || + !strideData->modulateAlpha) { + // execute() or executeVA() + if (strideData->useAlpha) { + r = *src++; + g = *src++; + b = *src++; + a = *src; + } else { + r = *src++; + g = *src++; + b = *src; + a = 0; + } + } else { + // buildGA() & modeulateAlpha + if (strideData->useAlpha) { + r = *src++; + g = *src++; + b = *src++; + a = *src * strideData->alpha; + } else { + r = *src++; + g = *src++; + b = *src; + a = strideData->alpha; + } + } + *wdst = D3DCOLOR_COLORVALUE(r, g, b, a); + } else { // byte color pointer + jbyte* wsrc = strideData->bdiffusePtr + + idx*strideData->diffuseStride; + jbyte r, g, b, a; + if ((d3dCtx->currDisplayListID <= 0) || + !strideData->modulateAlpha) { + // execute() or executeVA() + if (strideData->useAlpha) { + r = *wsrc++; + g = *wsrc++; + b = *wsrc++; + a = *wsrc; + } else { + r = *wsrc++; + g = *wsrc++; + b = *wsrc; + a = 0; + } + } else { + // buildGA() & modeulateAlpha + // Currently buildGA() will not use byte color + // so this code should never execute. + jbyte alpha = (jbyte) (255*strideData->alpha); + if (strideData->useAlpha) { + r = *wsrc++; + g = *wsrc++; + b = *wsrc++; + a = (jbyte)(((int)(*wsrc) & 0xff) * strideData->alpha); + } else { + r = *wsrc++; + g = *wsrc++; + b = *wsrc; + a = alpha; + + } + } + *wdst = D3DCOLOR_RGBA(r, g, b, a); + } + } + dst++; // additional one DWORD of color copy + } + + + // Copy Texture + int ts; + int texPos; + boolean invalidTexCoord; + + for (int i=0; i < d3dCtx->texSetUsed; i++) { + ts = d3dCtx->texStride[i]; + if (ts == 0) { + continue; + } + texPos = strideData->texCoordPosition[i]; + + invalidTexCoord = ((texPos != d3dCtx->pVB->texCoordPosition[i]) || + (texPos == TEX_OBJ_LINEAR)); + + if ((cDirty & javax_media_j3d_GeometryArrayRetained_TEXTURE_CHANGED) || invalidTexCoord) { + if (texPos >= 0) { + src = strideData->textureCoordsPtr[i] + + idx*strideData->textureCoordsStride[i]; + *dst++ = *src++; // tx + *dst++ = *src++; // ty + if (ts >= 3) { + *dst++ = *src++; // tx + if (ts >= 4) { + *dst++ = *src; // tx + } + } + } else { + // automatic texture generation + if (texPos == TEX_OBJ_LINEAR) { + float *ps = d3dCtx->planeS[i]; + float *pt = d3dCtx->planeT[i]; + float *pr = d3dCtx->planeR[i]; + float *pq = d3dCtx->planeQ[i]; + + if ((ts < 4) || (!d3dCtx->texTransformSet[i])) { + *dst++ = ps[0]*posX + ps[1]*posY + ps[2]*posZ + ps[3]; + *dst++ = pt[0]*posX + pt[1]*posY + pt[2]*posZ + pt[3]; + if (ts >= 3) { + *dst++ = pr[0]*posX + pr[1]*posY + pr[2]*posZ + pr[3]; + if (ts >= 4) { + *dst++ = pq[0]*posX + pq[1]*posY + pq[2]*posZ + pq[3]; + } + } + } else { + float tx, ty, tz, tw; + D3DXMATRIX *m = &(d3dCtx->texTransform[i]); + tx = ps[0]*posX + ps[1]*posY + ps[2]*posZ + ps[3]; + ty = pt[0]*posX + pt[1]*posY + pt[2]*posZ + pt[3]; + tz = pr[0]*posX + pr[1]*posY + pr[2]*posZ + pr[3]; + tw = pq[0]*posX + pq[1]*posY + pq[2]*posZ + pq[3]; + *dst++ = (*m)._11*tx + (*m)._21*ty + (*m)._31*tz + (*m)._41*tw; + *dst++ = (*m)._12*tx + (*m)._22*ty + (*m)._32*tz + (*m)._42*tw; + *dst++ = (*m)._13*tx + (*m)._23*ty + (*m)._33*tz + (*m)._43*tw; + *dst++ = (*m)._14*tx + (*m)._24*ty + (*m)._34*tz + (*m)._44*tw; + } + } else if (texPos == TEX_GEN_INVALID) { + // application error, disable by setting texCoord to zero + *dst++ = 0; + *dst++ = 0; + if (ts >= 3) { + *dst++ = 0; + if (ts >= 4) { + *dst++ = 0; + } + } + } else { + // should not happen + dst += ts; + } + } + } else { + dst += ts; + } + } + + *vbptr = dst; +} + + +float* allocateVB(D3dCtx *d3dCtx, + LPDIRECT3DDEVICE8 device, + int vcount, + int maxVertexLimit, + jint *cdirty) +{ + LPD3DVERTEXBUFFER vb = d3dCtx->pVB->nextVB; + HRESULT hr; + float *ptr = NULL; + + + if (vcount > maxVertexLimit) { + vcount = maxVertexLimit; + } + + if ((vb != NULL) && (vb->vcount < vcount)) { + delete vb; + d3dCtx->pVB->nextVB = NULL; + vb = NULL; + } + + if (vb == NULL) { + vb = new D3dVertexBuffer(); + if (vb == NULL) { + D3dCtx::d3dWarning(OUTOFMEMORY); + return NULL; + } + + vb->stride = d3dCtx->pVB->stride; + vb->vertexFormat = d3dCtx->pVB->vertexFormat; + // Don't set totalVertexCount + vb->isIndexPrimitive = d3dCtx->pVB->isIndexPrimitive; + vb->primitiveType = d3dCtx->pVB->primitiveType; + vb->isPointFlagUsed = d3dCtx->pVB->isPointFlagUsed; + vb->vcount = vcount; + vb->maxVertexLimit = maxVertexLimit; + +#ifdef VBDEBUG + printf("Create secondary VertexBuffer of size %d, display list ID %d, pointFlag %d\n", + vb->vcount, d3dCtx->currDisplayListID, vb->isPointFlagUsed); +#endif + if (!vb->isPointFlagUsed) { + hr = device->CreateVertexBuffer(vb->stride*vcount, + D3DUSAGE_WRITEONLY, + vb->vertexFormat, + D3DPOOL_DEFAULT, + &vb->buffer); + } else { + hr = device->CreateVertexBuffer(vb->stride*vcount, + D3DUSAGE_WRITEONLY|D3DUSAGE_POINTS, + vb->vertexFormat, + D3DPOOL_DEFAULT, + &vb->buffer); + } + if (FAILED(hr)) { + vb->buffer = NULL; + delete vb; + D3dCtx::d3dWarning(CREATEVBFAIL, hr); + return NULL; + } + d3dCtx->pVB->nextVB = vb; + *cdirty = javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED; + } + + hr = vb->buffer->Lock(0, 0, (BYTE**) &ptr, 0); + + if (FAILED(hr)) { + D3dCtx::d3dWarning(LOCKVBFAIL, hr); + delete vb; + d3dCtx->pVB->nextVB = NULL; + return NULL; + } + + d3dCtx->pVB = vb; + + vb->stripLen = 0; + return ptr; +} + + + +BOOL createCopyVBVertex(D3dCtx *d3dCtx, + LPDIRECT3DDEVICE8 device, + D3DDRAWPRIMITIVESTRIDEDDATA *strideData, + int vcount, jint cDirty, + jdouble* xform, + jdouble* nxform) +{ + LPD3DVERTEXBUFFER vb = d3dCtx->pVB; + float *vbptr; + + + if (vb->stripLen > 0) { + // VertexBuffer already used, create a new one or used + // the next VB in the list + // maxVertexLimit is already check before, so we can + // pass vcount as maxVertexLimit + vbptr = allocateVB(d3dCtx, device, vcount, vcount, &cDirty); + if (vbptr == NULL) { + return FALSE; + } + + } else { + // use the same VB + HRESULT hr; + hr = vb->buffer->Lock(0, 0, (BYTE**)&vbptr, 0); + + if (FAILED(hr)) { + D3dCtx::d3dWarning(LOCKVBFAIL, hr); + return FALSE; + } + + } + + copyVertexToVB(d3dCtx, strideData, vcount, &vbptr, cDirty, true, + xform, nxform); + + d3dCtx->pVB->buffer->Unlock(); + return TRUE; +} + + +/* + * Draw Primitive with vertexCount > D3DMAXNUMVERTICES. + * In this case we call the drawing routine multiple times. + */ +void splitVertexToMultipleVB(D3dCtx *d3dCtx, + LPD3DDRAWPRIMITIVESTRIDEDDATA strideData, + int vcount, + int maxVertexLimit, + jint cDirty, + jdouble* xform, + jdouble* nxform) +{ + int i, inc; + int min = 0; + int max = 0; + jfloat *oldfPosition; + double *olddPosition; + jfloat *oldNormal; + jfloat *oldfDiffuse; + jbyte *oldbDiffuse; + float* oldTexCoords[D3DDP_MAXTEXCOORD]; + int vc; + int texSetUsed = d3dCtx->texSetUsed; + LPDIRECT3DDEVICE8 device = d3dCtx->pDevice; + jfloat fr, fg, fb, fa; + jbyte br, bg, bb, ba; + boolean success; + + DWORD vertexFormat = d3dCtx->pVB->vertexFormat; + + // save stride pointers since strip set may have + // multiple call to this procedure. + oldfPosition = strideData->fpositionPtr; + olddPosition = strideData->dpositionPtr; + oldNormal = strideData->normalPtr; + oldfDiffuse = strideData->fdiffusePtr; + oldbDiffuse = strideData->bdiffusePtr; + + for (i=0; i < texSetUsed; i++) { + oldTexCoords[i] = strideData->textureCoordsPtr[i]; + } + + + + switch (d3dCtx->pVB->primitiveType) { + case D3DPT_TRIANGLEFAN: + { + // Copy the very first vertx and repeat the last vertex + jfloat fx, fy, fz, nx, ny, nz; + jdouble dx, dy, dz; + jfloat tx[D3DDP_MAXTEXCOORD]; + jfloat ty[D3DDP_MAXTEXCOORD]; + jfloat tz[D3DDP_MAXTEXCOORD]; + jfloat tw[D3DDP_MAXTEXCOORD]; + inc = maxVertexLimit - 2; + + if (oldfPosition) { + fx = *oldfPosition; + fy = *(oldfPosition+1); + fz = *(oldfPosition+2); + } else { + // must be double, since this routine will + // not invoke when there is no position available + dx = *olddPosition; + dy = *(olddPosition+1); + dz = *(olddPosition+2); + } + + if (oldNormal) { + nx = *oldNormal; + ny = *(oldNormal+1); + nz = *(oldNormal+2); + } + if (oldfDiffuse) { + fr = *oldfDiffuse; + fg = *(oldfDiffuse+1); + fb = *(oldfDiffuse+2); + if (strideData->useAlpha) { + fa = *(oldfDiffuse+3); + } + } else if (oldbDiffuse) { + br = *oldbDiffuse; + bg = *(oldbDiffuse+1); + bb = *(oldbDiffuse+2); + if (strideData->useAlpha) { + ba = *(oldbDiffuse+3); + } + } + + for (i=0; i < texSetUsed; i++) { + tx[i] = *oldTexCoords[i]; + ty[i] = *(oldTexCoords[i]+1); + if (d3dCtx->texStride[i] > 2) { + tz[i] = *(oldTexCoords[i]+2); + if (d3dCtx->texStride[i] > 3) { + tw[i] = *(oldTexCoords[i]+3); + } + } + } + while (true) { + vc = (vcount >= maxVertexLimit ? maxVertexLimit : vcount); + + success = createCopyVBVertex(d3dCtx, device, strideData, + vc, cDirty, xform, nxform); + // restore old values + if (oldfPosition) { + *(strideData->fpositionPtr) = fx; + *(strideData->fpositionPtr+1) = fy; + *(strideData->fpositionPtr+2) = fz; + } else { + *(strideData->dpositionPtr) = dx; + *(strideData->dpositionPtr+1) = dy; + *(strideData->dpositionPtr+2) = dz; + } + if (oldNormal) { + *(strideData->normalPtr) = nx; + *(strideData->normalPtr+1) = ny; + *(strideData->normalPtr+2) = nz; + } + if (oldfDiffuse) { + *(strideData->fdiffusePtr) = fr; + *(strideData->fdiffusePtr+1) = fg; + *(strideData->fdiffusePtr+2) = fb; + if (strideData->useAlpha) { + *(strideData->fdiffusePtr+3) = fa; + } + } else if (oldbDiffuse) { + *(strideData->bdiffusePtr) = br; + *(strideData->bdiffusePtr+1) = bg; + *(strideData->bdiffusePtr+2) = bb; + if (strideData->useAlpha) { + *(strideData->bdiffusePtr+3) = ba; + } + } + for (i=0; i < texSetUsed; i++) { + *(strideData->textureCoordsPtr[i]) = tx[i]; + *(strideData->textureCoordsPtr[i]+1) = ty[i]; + if (d3dCtx->texStride[i] > 2) { + *(strideData->textureCoordsPtr[i]+2) = tz[i]; + if (d3dCtx->texStride[i] > 3) { + *(strideData->textureCoordsPtr[i]+3) = tw[i]; + } + } + } + + vcount -= inc; + if (!success || (vcount <= 2)) { + break; + } + + if (oldfPosition) { + strideData->fpositionPtr += strideData->positionStride*inc; + fx = *strideData->fpositionPtr; + *strideData->fpositionPtr = *oldfPosition; + fy = *(strideData->fpositionPtr+1); + *(strideData->fpositionPtr+1) = *(oldfPosition+1); + fz = *(strideData->fpositionPtr+2); + *(strideData->fpositionPtr+2) = *(oldfPosition+2); + } else { + strideData->dpositionPtr += strideData->positionStride*inc; + dx = *strideData->dpositionPtr; + *strideData->dpositionPtr = *olddPosition; + dy = *(strideData->dpositionPtr+1); + *(strideData->dpositionPtr+1) = *(olddPosition+1); + dz = *(strideData->dpositionPtr+2); + *(strideData->dpositionPtr+2) = *(olddPosition+2); + } + + + if (oldNormal) { + strideData->normalPtr += strideData->normalStride*inc; + nx = *strideData->normalPtr; + *strideData->normalPtr = *oldNormal; + ny = *(strideData->normalPtr+1); + *(strideData->normalPtr+1) = *(oldNormal+1); + nz = *(strideData->normalPtr+2); + *(strideData->normalPtr+2) = *(oldNormal+2); + } + + if (oldfDiffuse) { + strideData->fdiffusePtr += strideData->diffuseStride*inc; + fr = *strideData->fdiffusePtr; + *strideData->fdiffusePtr = *oldfDiffuse; + fg = *(strideData->fdiffusePtr+1); + *(strideData->fdiffusePtr+1) = *(oldfDiffuse+1); + fb = *(strideData->fdiffusePtr+2); + *(strideData->fdiffusePtr+2) = *(oldfDiffuse+2); + if (strideData->useAlpha) { + fa = *(strideData->fdiffusePtr+3); + *(strideData->fdiffusePtr+3) = *(oldfDiffuse+3); + } + } else if (oldbDiffuse) { + strideData->bdiffusePtr += strideData->diffuseStride*inc; + br = *strideData->bdiffusePtr; + *strideData->bdiffusePtr = *oldbDiffuse; + bg = *(strideData->bdiffusePtr+1); + *(strideData->bdiffusePtr+1) = *(oldbDiffuse+1); + bb = *(strideData->bdiffusePtr+2); + *(strideData->bdiffusePtr+2) = *(oldbDiffuse+2); + if (strideData->useAlpha) { + ba = *(strideData->bdiffusePtr+3); + *(strideData->bdiffusePtr+3) = *(oldbDiffuse+3); + } + } + + for (i=0; i < texSetUsed; i++) { + strideData->textureCoordsPtr[i] += + strideData->textureCoordsStride[i]*inc; + + tx[i] = *strideData->textureCoordsPtr[i]; + ty[i] = *(strideData->textureCoordsPtr[i]+1); + *(strideData->textureCoordsPtr[i]) = *oldTexCoords[i]; + *(strideData->textureCoordsPtr[i]+1) = *(oldTexCoords[i]+1); + if (d3dCtx->texStride[i] > 2) { + tz[i] = *(strideData->textureCoordsPtr[i]+2); + *(strideData->textureCoordsPtr[i]+2) + = *(oldTexCoords[i]+ 2); + if (d3dCtx->texStride[i] > 3) { + tw[i] = *(strideData->textureCoordsPtr[i]+3); + *(strideData->textureCoordsPtr[i]+3) + = *(oldTexCoords[i]+ 3); + } + + } + } + + } + break; + } + case D3DPT_POINTLIST: + if (max == 0) { + max = maxVertexLimit; + } + // fall through + case D3DPT_LINESTRIP: + if (max == 0) { + max = maxVertexLimit; + min = 1; // repeat the last vertex; + } + // fall through + case D3DPT_TRIANGLELIST: + if (max == 0) { + if (d3dCtx->pVB->isIndexPrimitive) { + // QuadArray + max = maxVertexLimit - (maxVertexLimit % 4); + } else { + max = maxVertexLimit - (maxVertexLimit % 3); + } + } + // fall through + case D3DPT_LINELIST: + if (max == 0) { + max = maxVertexLimit - (maxVertexLimit % 2); + } + // fall through + case D3DPT_TRIANGLESTRIP: + if (max == 0) { + max = maxVertexLimit - (maxVertexLimit % 4); + min = 2; // repeat the last two vertices + } + inc = max - min; + + while (true) { + vc = (vcount >= max ? max : vcount); + + if (!createCopyVBVertex(d3dCtx, device, strideData, vc, + cDirty, xform, nxform)) { + break; + } + + vcount -= inc; + if (vcount <= min) { + break; + } + if (oldfPosition) { + strideData->fpositionPtr += strideData->positionStride*inc; + } else { + strideData->dpositionPtr += strideData->positionStride*inc; + } + + if (oldNormal) { + strideData->normalPtr += strideData->normalStride*inc; + } + if (oldfDiffuse) { + strideData->fdiffusePtr += strideData->diffuseStride*inc; + } else if (oldbDiffuse) { + strideData->bdiffusePtr += strideData->diffuseStride*inc; + } + for (i=0; i < texSetUsed; i++) { + strideData->textureCoordsPtr[i] += + strideData->textureCoordsStride[i]*inc; + } + } + break; + } + + // Restore old pointers; + strideData->fpositionPtr = oldfPosition; + strideData->dpositionPtr = olddPosition; + strideData->normalPtr = oldNormal; + strideData->fdiffusePtr = oldfDiffuse; + strideData->bdiffusePtr = oldbDiffuse; + + for (i=0; i < texSetUsed; i++) { + strideData->textureCoordsPtr[i] = oldTexCoords[i]; + } +} + + +BOOL reIndexifyIndexVertexToVBs(D3dCtx *d3dCtx, + D3DDRAWPRIMITIVESTRIDEDDATA* strideData, + DWORD indexCount, + DWORD vcount, + jint cDirty, + BOOL expandQuadIndex, + DWORD maxVertexLimit, + jdouble* xform, + jdouble* nxform) +{ + LPD3DVERTEXBUFFER vb = d3dCtx->pVB; + HRESULT hr; + LPDIRECT3DDEVICE8 device = d3dCtx->pDevice; + + int vbSize; + + if (!expandQuadIndex) { + vbSize = indexCount; + } else { + vbSize = (3*indexCount) >> 1; + } + + if (vb->stripLen > 0) { + // VertexBuffer already used, create a new one or used + // the next VB in the list + // maxVertexLimit is already check before, so we can + // pass indexCount as maxVertexLimit. + // The maximum vertex that can happens is equal + // to indexCount so we can just set vcount = indexCount + vb = vb->nextVB; + if ((vb != NULL) && (vb->vcount < vbSize)) { + delete vb; + d3dCtx->pVB->nextVB = NULL; + vb = NULL; + } + + if (vb == NULL) { + vb = new D3dVertexBuffer(); + if (vb == NULL) { + D3dCtx::d3dWarning(OUTOFMEMORY); + return false; + } + + vb->stride = d3dCtx->pVB->stride; + vb->vertexFormat = d3dCtx->pVB->vertexFormat; + // Don't set totalVertexCount + vb->isIndexPrimitive = d3dCtx->pVB->isIndexPrimitive; + vb->primitiveType = d3dCtx->pVB->primitiveType; + vb->isPointFlagUsed = d3dCtx->pVB->isPointFlagUsed; + vb->vcount = vbSize; + vb->maxVertexLimit = maxVertexLimit; + +#ifdef VBDEBUG + printf("Create secondary VertexBuffer of size %d, display list ID %d, pointFlag %d\n", + vbSize, d3dCtx->currDisplayListID, vb->isPointFlagUsed); +#endif + + if (!vb->isPointFlagUsed) { + hr = device->CreateVertexBuffer(vb->stride*vbSize, + D3DUSAGE_WRITEONLY, + vb->vertexFormat, + D3DPOOL_DEFAULT, + &vb->buffer); + } else { + hr = device->CreateVertexBuffer(vb->stride*vbSize, + D3DUSAGE_WRITEONLY|D3DUSAGE_POINTS, + vb->vertexFormat, + D3DPOOL_DEFAULT, + &vb->buffer); + vb->isPointFlagUsed = true; + } + + if (FAILED(hr)) { + vb->buffer = NULL; + vb->release(); + D3dCtx::d3dWarning(CREATEVBFAIL, hr); + return false; + } + d3dCtx->pVB->nextVB = vb; + cDirty = javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED; + } + } + + if (vb->indexBuffer == NULL) { + // No need to set totalIndexCount + vb->indexCount = vbSize; + + if (indexCount <= 0xffff) { + hr = device->CreateIndexBuffer(vbSize*sizeof(WORD), + D3DUSAGE_WRITEONLY, + D3DFMT_INDEX16, + D3DPOOL_DEFAULT, + &vb->indexBuffer); + } else { + hr = device->CreateIndexBuffer(vbSize*sizeof(UINT), + D3DUSAGE_WRITEONLY, + D3DFMT_INDEX32, + D3DPOOL_DEFAULT, + &vb->indexBuffer); + } + + if (FAILED(hr)) { + vb->indexBuffer = NULL; + vb->release(); + D3dCtx::d3dWarning(CREATEINDEXVBFAIL, hr); + return false; + } + + cDirty |= javax_media_j3d_GeometryArrayRetained_INDEX_CHANGED; + } + + float *vbptr; + // Note that DWORD (use for color) is of same size + // as float (use for vertex/normal) + hr = vb->buffer->Lock(0, 0, (BYTE**)&vbptr, 0); + if (FAILED(hr)) { + D3dCtx::d3dWarning(LOCKVBFAIL, hr); + // recreate it next time + vb->release(); + return false; + } + + d3dCtx->pVB = vb; + + // The current VB is not yet used. + vb->stripLen = 0; + + if (cDirty) { + D3DINDEXBUFFER_DESC desc; + BYTE *bptr; + + vb->indexBuffer->GetDesc(&desc); + hr = vb->indexBuffer->Lock(0, 0, &bptr, 0); + if (FAILED(hr)) { + D3dCtx::d3dWarning(LOCKINDEXVBFAIL, hr); + vb->buffer->Unlock(); + return false; + } + + if (d3dCtx->reIndexifyTable == NULL) { + // vcount will not change during renderIndexGeometry + // and splitIndexVertex so it is safe not to check + // size of reIndexifyTable and recreate a bigger + // one. + d3dCtx->reIndexifyTable = new DWORD[vcount]; + if (d3dCtx->reIndexifyTable == NULL) { + D3dCtx::d3dWarning(OUTOFMEMORY, hr); + vb->release(); + return false; + } + + } + + ZeroMemory(d3dCtx->reIndexifyTable, sizeof(DWORD)*vcount); + + DWORD i; + jint *idxPtr = strideData->indexPtr + strideData->initialIndexIndex; + USHORT firstEntry = *idxPtr; + DWORD *table = d3dCtx->reIndexifyTable; + + if (desc.Format == D3DFMT_INDEX16) { + USHORT *dst = (USHORT *) bptr; + USHORT newIdx, prevIdx = -1, count = 0; + USHORT idx[3], vc = 0; + + for (i=0; i < indexCount; i++) { + newIdx = table[*idxPtr]; + if ((newIdx == 0) && (*idxPtr != firstEntry)) { + newIdx = ++count; + table[*idxPtr] = newIdx; + } + if (!expandQuadIndex) { + *dst++ = newIdx; + } else { + if (vc < 3) { + idx[vc++] = newIdx; + } else { + // vc = 3 + *dst++ = idx[0]; + *dst++ = idx[1]; + *dst++ = idx[2]; + *dst++ = idx[0]; + *dst++ = idx[2]; + *dst++ = newIdx; + vc = 0; + } + } + if (newIdx != prevIdx) { + copyOneVertexToVB(d3dCtx, &vbptr, strideData, + *idxPtr++, cDirty, xform, nxform); + prevIdx = newIdx; + } else { + idxPtr++; + } + + } + } else { + DWORD *dst = (DWORD *) bptr; + DWORD newIdx, prevIdx = -1, count = 0; + DWORD idx[3], vc = 0; + + for (i=0; i < indexCount; i++) { + newIdx = table[*idxPtr]; + if ((newIdx == 0) && (*idxPtr != firstEntry)) { + newIdx = ++count; + table[*idxPtr] = newIdx; + } + if (!expandQuadIndex) { + *dst++ = newIdx; + } else { + if (vc < 3) { + idx[vc++] = newIdx; + } else { + // vc = 3 + *dst++ = idx[0]; + *dst++ = idx[1]; + *dst++ = idx[2]; + *dst++ = idx[0]; + *dst++ = idx[2]; + *dst++ = newIdx; + vc = 0; + } + } + if (newIdx != prevIdx) { + copyOneVertexToVB(d3dCtx, &vbptr, strideData, + *idxPtr++, cDirty, xform, nxform); + prevIdx = newIdx; + } else { + idxPtr++; + } + } + } + } + + + vb->addStride(vbSize); + vb->indexBuffer->Unlock(); + vb->buffer->Unlock(); + return true; +} + + +void splitIndexVertexToMultipleVB(D3dCtx *d3dCtx, + LPD3DDRAWPRIMITIVESTRIDEDDATA strideData, + int indexCount, + int vertexCount, + int maxVertexLimit, + jint cDirty, + BOOL expandQuadIndex, + jdouble* xform, + jdouble* nxform) +{ + int vc; + BOOL success; + int inc; + int min = 0; + int max = 0; + int initialIdxIdx = strideData->initialIndexIndex; + + + switch (d3dCtx->pVB->primitiveType) { + case D3DPT_TRIANGLEFAN: + { + jint firstIdx = strideData->indexPtr[initialIdxIdx]; + jint prevIdx = firstIdx; + + inc = maxVertexLimit - 2; + + while (true) { + vc = (indexCount >= maxVertexLimit ? maxVertexLimit : indexCount); + success = reIndexifyIndexVertexToVBs(d3dCtx, + strideData, + vc, + vertexCount, + cDirty, + expandQuadIndex, + maxVertexLimit, + xform, nxform); + // restore index + strideData->indexPtr[strideData->initialIndexIndex] = prevIdx; + indexCount -= inc; + + if (!success || (indexCount <= 2)) { + break; + } + // repeat the last index + strideData->initialIndexIndex += (vc - 2); + // replace by first index + prevIdx = strideData->indexPtr[strideData->initialIndexIndex]; + strideData->indexPtr[strideData->initialIndexIndex] = firstIdx; + } + } + break; + case D3DPT_POINTLIST: + if (max == 0) { + max = maxVertexLimit; + } + // fall through + case D3DPT_LINESTRIP: + if (max == 0) { + max = maxVertexLimit; + min = 1; // repeat the last vertex; + } + // fall through + case D3DPT_TRIANGLELIST: + if (max == 0) { + if (expandQuadIndex) { + // QuadArray + max = maxVertexLimit - (maxVertexLimit % 4); + } else { + max = maxVertexLimit - (maxVertexLimit % 3); + } + } + // fall through + case D3DPT_LINELIST: + if (max == 0) { + max = maxVertexLimit - (maxVertexLimit % 2); + } + // fall through + case D3DPT_TRIANGLESTRIP: + if (max == 0) { + max = maxVertexLimit - (maxVertexLimit % 4); + min = 2; // repeat the last two vertices + } + inc = max - min; + + while (true) { + vc = (indexCount >= max ? max : indexCount); + + if (!reIndexifyIndexVertexToVBs(d3dCtx, + strideData, + vc, + vertexCount, + cDirty, + expandQuadIndex, + maxVertexLimit, + xform, nxform)) { + break; + } + + indexCount -= inc; + if (indexCount <= min) { + break; + } + strideData->initialIndexIndex += inc; + } + } + strideData->initialIndexIndex = initialIdxIdx; +} + +// This is used by quad polygon line mode +void DrawPolygonLine(D3dCtx *d3dCtx, + LPDIRECT3DDEVICE8 device, + DWORD vertexFormat, + D3DDRAWPRIMITIVESTRIDEDDATA *strideData) +{ + HRESULT hr; + float *vbptr; + + hr = d3dCtx->pVB->buffer->Lock(0, 0, (BYTE**) &vbptr, 0 ); + if (FAILED(hr)) { + D3dCtx::d3dWarning(LOCKVBFAIL, hr); + return; + } + // DisplayList will not use in this case, so xform = nxform = NULL + copyVertexToVB(d3dCtx, strideData, 4, &vbptr, + javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED, true, + NULL, NULL); + d3dCtx->pVB->buffer->Unlock(); + device->SetStreamSource(0, d3dCtx->pVB->buffer, + d3dCtx->pVB->stride); + device->SetIndices(d3dCtx->lineModeIndexBuffer, 0); + device->SetVertexShader(vertexFormat); + + device->DrawIndexedPrimitive(D3DPT_LINESTRIP, 0, 4, 0, 4); +} + + +// This is used by indexed quad polygon line mode +void DrawIndexPolygonLine(D3dCtx *d3dCtx, + LPDIRECT3DDEVICE8 device, + DWORD vertexFormat, + D3DDRAWPRIMITIVESTRIDEDDATA *strideData, + jint idx0, jint idx1, jint idx2, jint idx3) +{ + HRESULT hr; + float *vbptr; + + hr = d3dCtx->pVB->buffer->Lock(0, 0, (BYTE**) &vbptr, 0 ); + if (FAILED(hr)) { + D3dCtx::d3dWarning(LOCKVBFAIL, hr); + return; + } + + copyOneVertexToVB(d3dCtx, &vbptr, strideData, idx0, + javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED, + NULL, NULL); + copyOneVertexToVB(d3dCtx, &vbptr, strideData, idx1, + javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED, + NULL, NULL); + copyOneVertexToVB(d3dCtx, &vbptr, strideData, idx2, + javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED, + NULL, NULL); + copyOneVertexToVB(d3dCtx, &vbptr, strideData, idx3, + javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED, + NULL, NULL); + + d3dCtx->pVB->buffer->Unlock(); + device->SetStreamSource(0, d3dCtx->pVB->buffer, + d3dCtx->pVB->stride); + device->SetVertexShader(vertexFormat); + device->SetIndices(d3dCtx->lineModeIndexBuffer, 0); + + device->DrawIndexedPrimitive(D3DPT_LINESTRIP, 0, 4, 0, 4); +} + + +void renderGeometry(JNIEnv *env, + D3dCtx *d3dCtx, + LPDIRECT3DDEVICE8 device, + jobject geo, + jint geo_type, + D3DDRAWPRIMITIVESTRIDEDDATA *strideData, + DWORD vertexFormat, + jint vcount, + jdouble* xform, + jdouble* nxform, + jint cDirty) +{ + D3DPRIMITIVETYPE d3dRenderType; + BOOL renderTypeSet = false; + int i, j, genMode; + LPD3DVERTEXBUFFER vb = NULL; + D3dVertexBufferVector *vbVector; + float *vbptr; + +#ifdef VBDEBUG + BOOL createNew = false; +#endif + + if (vcount <= 0) { + return; + } + + jclass geoClass = env->GetObjectClass(geo); + DWORD maxVertexLimit = d3dCtx->deviceInfo->maxVertexCount[geo_type]; + DWORD texSetUsed = d3dCtx->texSetUsed; + HRESULT hr; + BOOL needPointFlag = (geo_type == GEO_TYPE_POINT_SET) || + ((geo_type != GEO_TYPE_LINE_STRIP_SET) && + (geo_type != GEO_TYPE_LINE_SET) && + (d3dCtx->fillMode == D3DFILL_POINT)); + + BOOL buildDL = (d3dCtx->currDisplayListID > 0); + + lockGeometry(); + + if (!buildDL) { + jfieldID fieldID = env->GetFieldID(geoClass, "pVertexBuffers", "J"); + jobject cloneSource = NULL; + + vbVector = reinterpret_cast + (env->GetLongField(geo, fieldID)); + + if (vbVector == NULL) { + // It is possible this is the mirrorGeometry + // from cloneNonIndexGeometry() + jfieldID fieldID2 = env->GetFieldID(geoClass, + "cloneSourceArray", + "Ljavax/media/j3d/IndexedGeometryArrayRetained;"); + cloneSource = env->GetObjectField(geo, fieldID2); + + if (cloneSource != NULL) { + jclass cloneClass = env->GetObjectClass(cloneSource); + fieldID = env->GetFieldID(cloneClass, "pVertexBuffers", "J"); + + vbVector = reinterpret_cast + (env->GetLongField(cloneSource, fieldID)); + } + + } + + + // This is the first time rendering is invoked on the + // first GeometryArray + if (vbVector == NULL) { + vbVector = new D3dVertexBufferVector(); + if (vbVector == NULL) { + D3dCtx::d3dWarning(OUTOFMEMORY); + unlockGeometry(); + return; + } + if (cloneSource == NULL) { + env->SetLongField(geo, fieldID, + reinterpret_cast(vbVector)); + } else { + env->SetLongField(cloneSource, fieldID, + reinterpret_cast(vbVector)); + } + + } else { + // Found the vb in the list of vbVector + for (LPD3DVERTEXBUFFER *s = vbVector->begin(); + s != vbVector->end(); ++s) { + if ((*s)->ctx == d3dCtx) { + vb = *s; + break; + } + } + } + } + + if (vb == NULL) { + // This is the first time rendering is invoked + // using this ctx + vb = new D3dVertexBuffer(); + + if (vb == NULL) { + D3dCtx::d3dWarning(OUTOFMEMORY); + unlockGeometry(); + return; + } + vb->ctx = d3dCtx; + vb->maxVertexLimit = maxVertexLimit; + + if (!buildDL) { + vb->vbVector = vbVector; + + // add it to the GeometryArray pVertexBuffers list + vbVector->push_back(vb); + + // add it to the ctx lists + vb->next = d3dCtx->vertexBufferTable.next; + vb->previous = &(d3dCtx->vertexBufferTable); + d3dCtx->vertexBufferTable.next = vb; + if (vb->next != NULL) { + vb->next->previous = vb; + } + } + } + + if ((vb->buffer != NULL) && + ((vb->vertexFormat != vertexFormat) || + (vb->totalVertexCount < vcount) || + (cDirty & + javax_media_j3d_GeometryArrayRetained_STRIPCOUNT_CHANGED) || + (!vb->isPointFlagUsed && needPointFlag))) { + // immediate release VB and reconstruct a new one + vb->release(); + } + + if (vb->buffer == NULL) { + vb->stride = D3DXGetFVFVertexSize(vertexFormat); + vb->vertexFormat = vertexFormat; + vb->totalVertexCount = vcount; + vb->vcount = (vcount >= maxVertexLimit ? maxVertexLimit : vcount); +#ifdef VBDEBUG + printf("Create primary VertexBuffer of size %d, display list ID %d, pointFlag %d\n", + vb->vcount, d3dCtx->currDisplayListID, needPointFlag); +#endif + if (!needPointFlag) { + hr = device->CreateVertexBuffer(vb->stride*vb->vcount, + D3DUSAGE_WRITEONLY, + vertexFormat, + D3DPOOL_DEFAULT, + &vb->buffer); + } else { + hr = device->CreateVertexBuffer(vb->stride*vb->vcount, + D3DUSAGE_WRITEONLY|D3DUSAGE_POINTS, + vertexFormat, + D3DPOOL_DEFAULT, + &vb->buffer); + vb->isPointFlagUsed = true; + } + + if (FAILED(hr)) { + vb->buffer = NULL; + D3dCtx::d3dWarning(CREATEVBFAIL, hr); + unlockGeometry(); + return; + } +#ifdef VBDEBUG + createNew = true; +#endif + cDirty = javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED; + } + + unlockGeometry(); + + if (buildDL) { + // In display list mode, add it to the displayList ID table + d3dCtx->displayListTable[d3dCtx->currDisplayListID]->add(vb); + } else { + + if (vb->primitiveType == D3DPT_FORCE_DWORD) { + // This happens when previous frame use Quad Line + // so buffer not yet initialize + cDirty = javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED; + } + + if (!cDirty && + ((geo_type != GEO_TYPE_QUAD_SET) || + (d3dCtx->fillMode != D3DFILL_WIREFRAME))) { + for (i=0; i < d3dCtx->texSetUsed; i++) { + genMode = strideData->texCoordPosition[i]; + if ((genMode == TEX_OBJ_LINEAR) || + ((genMode != vb->texCoordPosition[i]) && + (genMode != TEX_GEN_AUTO))) { + // For object linear mode user can set the plane + // equations so we need to change texture coordinate. + break; + } + } + if (i == d3dCtx->texSetUsed) { + vb->render(d3dCtx); +#ifdef TEXDEBUG + printf("Skip VB Copy\n"); +#endif + return; + } + } + } + + // Note that DWORD (use for color) is of same size + // as float (use for vertex/normal) + + hr = vb->buffer->Lock(0, 0, (BYTE**)&vbptr, 0); + if (FAILED(hr)) { + D3dCtx::d3dWarning(LOCKVBFAIL, hr); + // recreate it next time + vb->release(); + return; + } + + d3dCtx->pVB = vb; + // The current VB is not yet used. + vb->stripLen = 0; + + switch (geo_type) { + case GEO_TYPE_TRI_STRIP_SET: + d3dRenderType = D3DPT_TRIANGLESTRIP; + renderTypeSet = true; +#ifdef VBDEBUG + if (createNew) { + printf("Tri strip set %d\n", vcount); + } +#endif + // fall through + case GEO_TYPE_TRI_FAN_SET: + if (renderTypeSet == false) { +#ifdef VBDEBUG + if (createNew) { + printf("Tri fan set %d\n", vcount); + } +#endif + d3dRenderType = D3DPT_TRIANGLEFAN; + renderTypeSet = true; + } + // fall through + case GEO_TYPE_LINE_STRIP_SET: + { + if (renderTypeSet == false) { + d3dRenderType = D3DPT_LINESTRIP; + renderTypeSet = true; +#ifdef VBDEBUG + if (createNew) { + printf("Tri line set %d \n", vcount); + } +#endif + } + + jfieldID strip_field = env->GetFieldID(geoClass, + "stripVertexCounts", "[I"); + jarray sarray = (jarray)env->GetObjectField(geo, strip_field); + jsize strip_len = (jsize)env->GetArrayLength(sarray); + + jint* strips = (jint *)env->GetPrimitiveArrayCritical(sarray, NULL); + + int nlastStrip = 0; + int totalLen = 0; + int oldTotalLen = 0; + int vsum = 0; + + vb->primitiveType = d3dRenderType; + + if (vcount <= vb->vcount) { + copyVertexToVB(d3dCtx, strideData, vcount, + &vbptr, cDirty, false, xform, nxform); + vb->addStrides(strip_len, strips); +#ifdef VBDEBUG + if (createNew) { + printf("Strip Length %d : ", strip_len); + for (int k=0; k < strip_len; k++) { + printf("%d ", strips[k]); + } + printf("\n"); + } +#endif + } else { +#ifdef VBDEBUG + if (createNew) { + printf("Strip Length %d : ", strip_len); + } +#endif + + for (i = 0; i < strip_len; i++) { + if (strideData->fpositionPtr) { + strideData->fpositionPtr += + strideData->positionStride*nlastStrip; + } else { + strideData->dpositionPtr += + strideData->positionStride*nlastStrip; + } + + if (strideData->normalPtr) { + strideData->normalPtr += + strideData->normalStride*nlastStrip; + } + + if (strideData->fdiffusePtr) { + strideData->fdiffusePtr += + strideData->diffuseStride*nlastStrip; + } else if (strideData->bdiffusePtr) { + strideData->bdiffusePtr += + strideData->diffuseStride*nlastStrip; + } + + + if (strideData->textureCoordsPtr[0]) { + for (j=0; j < texSetUsed; j++) { + strideData->textureCoordsPtr[j] += + strideData->textureCoordsStride[j]* nlastStrip; + } + } + + + nlastStrip = strips[i]; + oldTotalLen = totalLen; + totalLen += nlastStrip; + + if (totalLen > vcount) { + // This should not happen since + // setValidVertexCount is disable + // in v1.3. We should always have + // (sum of strips[] < vcount) + nlastStrip = (vcount - (totalLen - nlastStrip)); + totalLen = vcount; + } + + if (nlastStrip <= 0) { + continue; + } + + + if (vbptr == NULL) { + // This happen when the lastStrip copy + // is greater than maxVertexLimit. + // So we Unlock the last buffer + vbptr = allocateVB(d3dCtx, device, + vcount - oldTotalLen, + maxVertexLimit, &cDirty); + vsum = 0; + if (vbptr == NULL) { + break; // render whatever geometry the current VB have + } + } +#ifdef VBDEBUG + if (createNew) { + printf(" %d ", nlastStrip); + } +#endif + if ((vsum + nlastStrip) <= d3dCtx->pVB->vcount) { + // There is space available to put in vertices + vsum += nlastStrip; + copyVertexToVB(d3dCtx, strideData, nlastStrip, + &vbptr, cDirty, true, xform, nxform); + } else { + // Need to create a new VB + if (nlastStrip <= maxVertexLimit) { + // No need to split strip in multiple VB + if (d3dCtx->pVB->stripLen > 0) { + if (vbptr != NULL) { + d3dCtx->pVB->buffer->Unlock(); + } + vbptr = allocateVB(d3dCtx, device, + vcount - oldTotalLen, + maxVertexLimit, &cDirty); + if (vbptr == NULL) { + break; + } + vsum = 0; + } + vsum += nlastStrip; + copyVertexToVB(d3dCtx, strideData, nlastStrip, + &vbptr, cDirty, true, + xform, nxform); + } else { + d3dCtx->pVB->buffer->Unlock(); + vbptr = NULL; + vsum = 0; + // Multiple VBs for large vertex size + splitVertexToMultipleVB(d3dCtx, strideData, + nlastStrip, + maxVertexLimit, + cDirty, xform, nxform); + vbptr = NULL; + } + } + } +#ifdef VBDEBUG + if (createNew) { + printf("\n"); + } +#endif + } + env->ReleasePrimitiveArrayCritical(sarray, strips, NULL); + } + break; + case GEO_TYPE_QUAD_SET: +#ifdef VBDEBUG + if (createNew) { + printf("quad set %d\n", vcount); + } +#endif + + if (buildDL || + (d3dCtx->fillMode != D3DFILL_WIREFRAME)) { + /* + * Note we can't just check + * if (d3dCtx->fillMode != D3DFILL_WIREFRAME) + * since the fillMode may set back to + * non-line mode AFTER build display list + * In fact it is gaurantee that when displaylist + * mode is used we are not in line mode + */ + + // break down solid into two triangles + if (createQuadIndices(d3dCtx, vcount)) { + // It happens when + // vcount*3/2 != d3dCtx->quadIndexBufferSize + // to conform with index buffer Limitation in + // graphics card. So we adjust using a smaller + // maxVertexLimit when spliting into + // multiple Vertex Buffers. + maxVertexLimit = 2*d3dCtx->quadIndexBufferSize/3; + vb->maxVertexLimit = maxVertexLimit; + vb->vcount = vb->maxVertexLimit; + } + d3dRenderType = D3DPT_TRIANGLELIST; + vb->isIndexPrimitive = true; + renderTypeSet = true; + // fall through + } else { // line mode + // we don't want to see extra line appear in the + // diagonal of quads if it splits into two + // triangles. This is REALLY SLOW !!! + int len = vcount >> 2; + int offsetPos = 0; + int offsetNorm = 0; + int offsetColor = 0; + int strideOffsetPos = strideData->positionStride << 2; + int strideOffsetNorm = strideData->normalStride << 2; + int strideOffsetColor = strideData->diffuseStride << 2; + jfloat *pdf = strideData->fpositionPtr; + jdouble *pdd = strideData->dpositionPtr; + jfloat *pn = strideData->normalPtr; + jfloat *pcf = strideData->fdiffusePtr; + jbyte *pcb = strideData->bdiffusePtr; + jfloat* pt[D3DDP_MAXTEXCOORD]; + + pt[0] = NULL; + + if (((vertexFormat & D3DFVF_DIFFUSE) == 0) && + (!d3dCtx->isLightEnable)) { + d3dCtx->setAmbientLightMaterial(); + } + + vb->buffer->Unlock(); + vbptr = NULL; +#ifdef VBDEBUG + if (createNew) { + printf("quad set polygon line %d\n", vcount); + } +#endif + + for (i=0; i < texSetUsed; i++) { + pt[i] = (FLOAT *) strideData->textureCoordsPtr[i]; + } + + jfloat *fptr; + jdouble *dptr; + jbyte *bptr; + jfloat *fspt; + jdouble *dspt; + int posStride = strideData->positionStride; + D3DVERTEX worldCoord[3]; + D3DTLVERTEX screenCoord[3]; + + vb->primitiveType = D3DPT_FORCE_DWORD; + + if (d3dCtx->lineModeIndexBuffer == NULL) { + createLineModeIndexBuffer(d3dCtx); + } + + for (i = 0; i < (vcount >> 2); i++) { + if (pdf) { + fspt = fptr = pdf + offsetPos; + strideData->fpositionPtr = fptr; + } else { + dspt = dptr = pdd + offsetPos; + strideData->dpositionPtr = dptr; + } + + if (pn) { + fptr = pn + offsetNorm; + strideData->normalPtr = fptr; + } + + if (pcf) { + fptr = pcf + offsetColor; + strideData->fdiffusePtr = fptr; + } else if (pcb) { + bptr = pcb + offsetColor; + strideData->bdiffusePtr = bptr; + } + + if (pt[0]) { + for (j=0; j < texSetUsed; j++) { + DWORD stride3 = 3*strideData->textureCoordsStride[j]; + fptr = pt[j] + i*(strideData->textureCoordsStride[j] << 2); + strideData->textureCoordsPtr[j] = fptr; + } + } + if (d3dCtx->cullMode != D3DCULL_NONE) { + // Do back face culling here + if (pdf) { + worldCoord[0].x = fspt[0]; + worldCoord[0].y = fspt[1]; + worldCoord[0].z = fspt[2]; + fspt += posStride; + worldCoord[1].x = fspt[0]; + worldCoord[1].y = fspt[1]; + worldCoord[1].z = fspt[2]; + fspt += posStride; + worldCoord[2].x = fspt[0]; + worldCoord[2].y = fspt[1]; + worldCoord[2].z = fspt[2]; + } else { + worldCoord[0].x = dspt[0]; + worldCoord[0].y = dspt[1]; + worldCoord[0].z = dspt[2]; + dspt += posStride; + worldCoord[1].x = dspt[0]; + worldCoord[1].y = dspt[1]; + worldCoord[1].z = dspt[2]; + dspt += posStride; + worldCoord[2].x = dspt[0]; + worldCoord[2].y = dspt[1]; + worldCoord[2].z = dspt[2]; + } + d3dCtx->transform(&worldCoord[0], &screenCoord[0]); + d3dCtx->transform(&worldCoord[1], &screenCoord[1]); + d3dCtx->transform(&worldCoord[2], &screenCoord[2]); + screenCoord[0].sx -= screenCoord[1].sx; + screenCoord[0].sy -= screenCoord[1].sy; + screenCoord[2].sx -= screenCoord[1].sx; + screenCoord[2].sy -= screenCoord[1].sy; + if (d3dCtx->cullMode == D3DCULL_CW) { + // clip back face + if ((screenCoord[0].sx*screenCoord[2].sy - + screenCoord[2].sx*screenCoord[0].sy) >= 0) { + DrawPolygonLine(d3dCtx, + device, + vertexFormat, + strideData); + } + } else { // Clip front face + if ((screenCoord[0].sx*screenCoord[2].sy - + screenCoord[2].sx*screenCoord[0].sy) <= 0) { + DrawPolygonLine(d3dCtx, + device, + vertexFormat, + strideData); + } + } + } else { + // cullMode == D3DCULL_NONE + DrawPolygonLine(d3dCtx, + device, + vertexFormat, + strideData); + } + offsetPos += strideOffsetPos; + offsetNorm += strideOffsetNorm; + offsetColor += strideOffsetColor; + } + + if (((vertexFormat & D3DFVF_DIFFUSE) == 0) && + (!d3dCtx->isLightEnable)) { + d3dCtx->restoreDefaultLightMaterial(); + } + // Don't call vb->Renderer() at the end + return; + } + // fallthrough + case GEO_TYPE_TRI_SET: + if (renderTypeSet == false) { + d3dRenderType = D3DPT_TRIANGLELIST; + renderTypeSet = true; +#ifdef VBDEBUG + if (createNew) { + printf("tri set %d\n", vcount); + } +#endif + } + // fallthrough + case GEO_TYPE_LINE_SET: + if (renderTypeSet == false) { + d3dRenderType = D3DPT_LINELIST; + renderTypeSet = true; +#ifdef VBDEBUG + if (createNew) { + printf("line set %d\n", vcount); + } +#endif + } + // fallthrough + case GEO_TYPE_POINT_SET: + if (renderTypeSet == false) { + d3dRenderType = D3DPT_POINTLIST; +#ifdef VBDEBUG + if (createNew) { + printf("point set %d\n", vcount); + } +#endif + } + vb->primitiveType = d3dRenderType; + + if (vcount <= vb->vcount) { + copyVertexToVB(d3dCtx, strideData, vcount, &vbptr, + cDirty, true, xform, nxform); + } else { + if (vbptr != NULL) { + vb->buffer->Unlock(); + vbptr = NULL; + } + + splitVertexToMultipleVB(d3dCtx, strideData, vcount, + maxVertexLimit, + cDirty, xform, nxform); + vbptr = NULL; + } + break; + default: + printf("GeometryArrayRetained_execute:unknown geo_type %ld \n", geo_type); + } + + if (vbptr != NULL) { + // d3dCtx->pVB is the last reference in VB list + d3dCtx->pVB->buffer->Unlock(); + } + + for (i=0; i < d3dCtx->texSetUsed; i++) { + d3dCtx->pVB->texCoordPosition[i] = + strideData->texCoordPosition[i]; + } + + if (!buildDL) { + // Not in displaylist mode, directly render VB + // vb is the root reference in VB list + vb->render(d3dCtx); + } +} + + +void renderIndexGeometry(JNIEnv *env, + D3dCtx *d3dCtx, + LPDIRECT3DDEVICE8 device, + jobject geo, + jint geo_type, + D3DDRAWPRIMITIVESTRIDEDDATA *strideData, + DWORD vertexFormat, + jint vcount, + jint indexCount, + jdouble* xform, + jdouble* nxform, + jint cDirty) +{ + D3DPRIMITIVETYPE d3dRenderType; + BOOL renderTypeSet = false; + BOOL expandQuadIndex = false; + int i; + LPD3DVERTEXBUFFER vb = NULL; + D3dVertexBufferVector *vbVector; + float *vbptr; + +#ifdef VBDEBUG + BOOL createNew = false; +#endif + + if (indexCount <= 0) { + return; + } + + jclass geoClass = env->GetObjectClass(geo); + DWORD maxVertexLimit = + min(d3dCtx->deviceInfo->maxVertexCount[geo_type], + d3dCtx->deviceInfo->maxVertexIndex); + DWORD texSetUsed = d3dCtx->texSetUsed; + HRESULT hr; + BOOL needPointFlag = (geo_type == GEO_TYPE_INDEXED_POINT_SET) || + ((geo_type != GEO_TYPE_INDEXED_LINE_STRIP_SET) && + (geo_type != GEO_TYPE_INDEXED_LINE_SET) && + (d3dCtx->fillMode == D3DFILL_POINT)); + + BOOL buildDL = (d3dCtx->currDisplayListID > 0); + + if (geo_type == GEO_TYPE_INDEXED_QUAD_SET) { + // Since the index we create with be 1.5 times the original index + maxVertexLimit = 2*maxVertexLimit/3; + } + + + lockGeometry(); + + if (!buildDL) { + jfieldID fieldID = env->GetFieldID(geoClass, "pVertexBuffers", "J"); + vbVector = reinterpret_cast + (env->GetLongField(geo, fieldID)); + + if (vbVector == NULL) { + // This is the first time rendering is invoked on the + // first GeometryArray + vbVector = new D3dVertexBufferVector(); + if (vbVector == NULL) { + D3dCtx::d3dWarning(OUTOFMEMORY); + unlockGeometry(); + return; + } + env->SetLongField(geo, fieldID, reinterpret_cast(vbVector)); + } else { + // Found the vb in the list of vbVector + for (LPD3DVERTEXBUFFER *s = vbVector->begin(); + s != vbVector->end(); ++s) { + if ((*s)->ctx == d3dCtx) { + vb = *s; + break; + } + } + } + } + + if (vb == NULL) { + // This is the first time rendering is invoked + // using this ctx + vb = new D3dVertexBuffer(); + + if (vb == NULL) { + D3dCtx::d3dWarning(OUTOFMEMORY); + unlockGeometry(); + return; + } + vb->ctx = d3dCtx; + vb->maxVertexLimit = maxVertexLimit; + + if (!buildDL) { + vb->vbVector = vbVector; + + // add it to the GeometryArray pVertexBuffers list + vbVector->push_back(vb); + + // add it to the ctx lists + vb->next = d3dCtx->vertexBufferTable.next; + vb->previous = &(d3dCtx->vertexBufferTable); + d3dCtx->vertexBufferTable.next = vb; + if (vb->next != NULL) { + vb->next->previous = vb; + } + } + } + + if (((vb->indexBuffer != NULL) && + (vb->totalIndexCount < indexCount)) || + ((vb->buffer != NULL) && + ((vb->vertexFormat != vertexFormat) || + (vb->totalVertexCount < vcount) || + (!vb->isPointFlagUsed && needPointFlag)))) { + // immediate release VB and reconstruct a new one + vb->release(); + } + + + if (vb->buffer == NULL) { + vb->stride = D3DXGetFVFVertexSize(vertexFormat); + vb->vertexFormat = vertexFormat; + vb->totalVertexCount = vcount; + vb->isIndexPrimitive = true; + vb->vcount = (vcount >= maxVertexLimit ? maxVertexLimit : vcount); +#ifdef VBDEBUG + printf("Create primary VertexBuffer of size %d, display list ID %d, pointFlag %d\n", + vb->vcount, d3dCtx->currDisplayListID, needPointFlag); +#endif + + if (!needPointFlag) { + hr = device->CreateVertexBuffer(vb->stride*vb->vcount, + D3DUSAGE_WRITEONLY, + vertexFormat, + D3DPOOL_DEFAULT, + &vb->buffer); + } else { + hr = device->CreateVertexBuffer(vb->stride*vb->vcount, + D3DUSAGE_WRITEONLY|D3DUSAGE_POINTS, + vertexFormat, + D3DPOOL_DEFAULT, + &vb->buffer); + vb->isPointFlagUsed = true; + } + + if (FAILED(hr)) { + vb->buffer = NULL; + D3dCtx::d3dWarning(CREATEVBFAIL, hr); + unlockGeometry(); + return; + } +#ifdef VBDEBUG + createNew = true; +#endif + cDirty = javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED; + } + + if (vb->indexBuffer == NULL) { + + vb->totalIndexCount = indexCount; + vb->indexCount = (indexCount >= maxVertexLimit ? + maxVertexLimit : indexCount); + + if (geo_type == GEO_TYPE_INDEXED_QUAD_SET) { + // Since we will construct another index with + // 1.5 times of the original. + vb->indexCount = (3*vb->indexCount) >> 1; + vb->totalIndexCount = (3*indexCount) >> 1; + } + + + if (indexCount <= 0xffff) { + hr = device->CreateIndexBuffer(vb->indexCount*sizeof(WORD), + D3DUSAGE_WRITEONLY, + D3DFMT_INDEX16, + D3DPOOL_DEFAULT, + &vb->indexBuffer); + } else { + hr = device->CreateIndexBuffer(vb->indexCount*sizeof(UINT), + D3DUSAGE_WRITEONLY, + D3DFMT_INDEX32, + D3DPOOL_DEFAULT, + &vb->indexBuffer); + } + + if (FAILED(hr)) { + vb->indexBuffer = NULL; + D3dCtx::d3dWarning(CREATEINDEXVBFAIL, hr); + unlockGeometry(); + return; + } + + cDirty |= javax_media_j3d_GeometryArrayRetained_INDEX_CHANGED; + } + + unlockGeometry(); + + if (buildDL) { + // In display list mode, add it to the displayList ID table + d3dCtx->displayListTable[d3dCtx->currDisplayListID]->add(vb); + } else { + + if (vb->primitiveType == D3DPT_FORCE_DWORD) { + // This happens when previous frame use Quad Line + // so buffer not yet initialize + cDirty = + javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED | + javax_media_j3d_GeometryArrayRetained_INDEX_CHANGED; + } + + if (!cDirty && + ((geo_type != GEO_TYPE_INDEXED_QUAD_SET) || + (d3dCtx->fillMode != D3DFILL_WIREFRAME))) { + for (i=0; i < d3dCtx->texSetUsed; i++) { + if ((strideData->texCoordPosition[i] != + vb->texCoordPosition[i]) + && + (strideData->texCoordPosition[i] != TEX_GEN_AUTO)) { + break; + } + } + if (i == d3dCtx->texSetUsed) { + vb->render(d3dCtx); + return; + } + } + } + + // Note that DWORD (use for color) is of same size + // as float (use for vertex/normal) + hr = vb->buffer->Lock(0, 0, (BYTE**)&vbptr, 0); + if (FAILED(hr)) { + D3dCtx::d3dWarning(LOCKVBFAIL, hr); + // recreate it next time + vb->release(); + return; + } + + d3dCtx->pVB = vb; + + // The current VB is not yet used. + vb->stripLen = 0; + + switch (geo_type) { + case GEO_TYPE_INDEXED_TRI_STRIP_SET: + d3dRenderType = D3DPT_TRIANGLESTRIP; + renderTypeSet = true; +#ifdef VBDEBUG + if (createNew) { + printf("Tri strip set %d\n", vcount); + } +#endif + // fall through + case GEO_TYPE_INDEXED_TRI_FAN_SET: + if (renderTypeSet == false) { +#ifdef VBDEBUG + if (createNew) { + printf("Tri fan set %d\n", vcount); + } +#endif + d3dRenderType = D3DPT_TRIANGLEFAN; + renderTypeSet = true; + } + // fall through + case GEO_TYPE_INDEXED_LINE_STRIP_SET: + { + if (renderTypeSet == false) { + d3dRenderType = D3DPT_LINESTRIP; + renderTypeSet = true; +#ifdef VBDEBUG + if (createNew) { + printf("Tri line set %d \n", vcount); + } +#endif + } + + jfieldID strip_field = env->GetFieldID(geoClass, + "stripIndexCounts", "[I"); + jarray sarray = (jarray)env->GetObjectField(geo, strip_field); + jsize strip_len = (jsize)env->GetArrayLength(sarray); + + jint* strips = (jint *)env->GetPrimitiveArrayCritical(sarray, NULL); + int nlastStrip = 0; + + vb->primitiveType = d3dRenderType; +#ifdef VBDEBUG + if (createNew) { + printf("Strip Length %d : ", strip_len); + } +#endif + + if ((vb->totalIndexCount <= vb->indexCount) && + (vcount <= vb->vcount)) { + copyIndexVertexToVB(d3dCtx, strideData, + indexCount, cDirty, false, false); + copyVertexToVB(d3dCtx, strideData, vcount, + &vbptr, cDirty, false, xform, nxform); + vb->addStrides(strip_len, strips); + } else { + vb->buffer->Unlock(); + vbptr = NULL; + strideData->indexPtr += strideData->initialIndexIndex; + strideData->initialIndexIndex = 0; + for (i = 0; i < strip_len; i++) { + strideData->indexPtr += nlastStrip; + + nlastStrip = strips[i]; + + if (nlastStrip <= 0) { + continue; + } +#ifdef VBDEBUG + if (createNew) { + printf(" %d", nlastStrip); + } +#endif + if (nlastStrip <= vb->indexCount) { + reIndexifyIndexVertexToVBs(d3dCtx, strideData, + nlastStrip, vcount, + cDirty, + false, + maxVertexLimit, + xform, nxform); + } else { + // Multiple VBs for large vertex size + splitIndexVertexToMultipleVB(d3dCtx, + strideData, + nlastStrip, + vcount, + maxVertexLimit, + cDirty, + false, + xform, nxform); + } + SafeDelete(d3dCtx->reIndexifyTable); + } +#ifdef VBDEBUG + if (createNew) { + printf("\n"); + } +#endif + } + env->ReleasePrimitiveArrayCritical(sarray, strips, NULL); + } + + break; + case GEO_TYPE_INDEXED_QUAD_SET: +#ifdef VBDEBUG + if (createNew) { + printf("quad set %d\n", vcount); + } +#endif + if (buildDL || + (d3dCtx->fillMode != D3DFILL_WIREFRAME)) { + d3dRenderType = D3DPT_TRIANGLELIST; + renderTypeSet = true; + expandQuadIndex = true; + // fall through + } else { // polygon line mode + // we don't want to see extra line appear in the + // diagonal of quads if it splits into two + // triangles. This is REALLY SLOW !!! + int posStride = strideData->positionStride; + D3DVERTEX worldCoord[3]; + D3DTLVERTEX screenCoord[3]; + jint *idxPtr = strideData->indexPtr; + jfloat *fspt; + jdouble *dspt; + jint idx0, idx1, idx2, idx3; + + if (((vertexFormat & D3DFVF_DIFFUSE) == 0) && + (!d3dCtx->isLightEnable)) { + d3dCtx->setAmbientLightMaterial(); + } + + vb->buffer->Unlock(); + vbptr = NULL; +#ifdef VBDEBUG + if (createNew) { + printf("indexed quad set polygon line %d\n", vcount); + } +#endif + if (d3dCtx->lineModeIndexBuffer == NULL) { + createLineModeIndexBuffer(d3dCtx); + } + + vb->primitiveType = D3DPT_FORCE_DWORD; + + for (i = 0; i < (indexCount >> 2); i++) { + if (d3dCtx->cullMode != D3DCULL_NONE) { + // Do back face culling here + idx0 = *idxPtr++; + idx1 = *idxPtr++; + idx2 = *idxPtr++; + idx3 = *idxPtr++; + if (strideData->fpositionPtr) { + fspt = strideData->fpositionPtr + posStride*idx0; + worldCoord[0].x = *fspt++; + worldCoord[0].y = *fspt++; + worldCoord[0].z = *fspt++; + fspt = strideData->fpositionPtr + posStride*idx1; + worldCoord[1].x = *fspt++; + worldCoord[1].y = *fspt++; + worldCoord[1].z = *fspt++; + fspt = strideData->fpositionPtr + posStride*idx2; + worldCoord[2].x = *fspt++; + worldCoord[2].y = *fspt++; + worldCoord[2].z = *fspt++; + } else { + dspt = strideData->dpositionPtr + posStride*idx0; + worldCoord[0].x = *dspt++; + worldCoord[0].y = *dspt++; + worldCoord[0].z = *dspt++; + dspt = strideData->dpositionPtr + posStride*idx1; + worldCoord[1].x = *dspt++; + worldCoord[1].y = *dspt++; + worldCoord[1].z = *dspt++; + dspt = strideData->dpositionPtr + posStride*idx2; + worldCoord[2].x = *dspt++; + worldCoord[2].y = *dspt++; + worldCoord[2].z = *dspt++; + } + + d3dCtx->transform(&worldCoord[0], &screenCoord[0]); + d3dCtx->transform(&worldCoord[1], &screenCoord[1]); + d3dCtx->transform(&worldCoord[2], &screenCoord[2]); + screenCoord[0].sx -= screenCoord[1].sx; + screenCoord[0].sy -= screenCoord[1].sy; + screenCoord[2].sx -= screenCoord[1].sx; + screenCoord[2].sy -= screenCoord[1].sy; + if (d3dCtx->cullMode == D3DCULL_CW) { + if ((screenCoord[0].sx*screenCoord[2].sy - + screenCoord[2].sx*screenCoord[0].sy) >= 0) { + DrawIndexPolygonLine(d3dCtx, + device, + vertexFormat, + strideData, + idx0, idx1, + idx2, idx3); + } + } else { // Clip front face + if ((screenCoord[0].sx*screenCoord[2].sy - + screenCoord[2].sx*screenCoord[0].sy) <= 0) { + DrawIndexPolygonLine(d3dCtx, + device, + vertexFormat, + strideData, + idx0, idx1, + idx2, idx3); + } + } + } else { + // cullMode == D3DCULL_NONE + DrawIndexPolygonLine(d3dCtx, + device, + vertexFormat, + strideData, + idx0, idx1, + idx2, idx3); + } + } + if (((vertexFormat & D3DFVF_DIFFUSE) == 0) && + (!d3dCtx->isLightEnable)) { + d3dCtx->restoreDefaultLightMaterial(); + } + // Don't call vb->Renderer() at the end + return; + } + // fall through + case GEO_TYPE_INDEXED_TRI_SET: + if (renderTypeSet == false) { + d3dRenderType = D3DPT_TRIANGLELIST; + renderTypeSet = true; +#ifdef VBDEBUG + if (createNew) { + printf("tri set %d\n", vcount); + } +#endif + } + // fallthrough + case GEO_TYPE_INDEXED_LINE_SET: + if (renderTypeSet == false) { + d3dRenderType = D3DPT_LINELIST; + renderTypeSet = true; +#ifdef VBDEBUG + if (createNew) { + printf("line set %d\n", vcount); + } +#endif + } + // fallthrough + case GEO_TYPE_INDEXED_POINT_SET: + if (renderTypeSet == false) { + d3dRenderType = D3DPT_POINTLIST; +#ifdef VBDEBUG + if (createNew) { + printf("point set %d\n", vcount); + } +#endif + } + vb->primitiveType = d3dRenderType; + + if (vb->totalIndexCount <= vb->indexCount) { + if (vcount <= vb->vcount) { + copyIndexVertexToVB(d3dCtx, strideData, + indexCount, + cDirty, true, expandQuadIndex); + copyVertexToVB(d3dCtx, strideData, vcount, &vbptr, + cDirty, false, xform, nxform); + } else { + vb->buffer->Unlock(); + vbptr = NULL; + reIndexifyIndexVertexToVBs(d3dCtx, strideData, + indexCount, vcount, + cDirty, + expandQuadIndex, + maxVertexLimit, + xform, nxform); + SafeDelete(d3dCtx->reIndexifyTable); + } + } else { + vb->buffer->Unlock(); + vbptr = NULL; + splitIndexVertexToMultipleVB(d3dCtx, + strideData, + indexCount, + vcount, + maxVertexLimit, + cDirty, + expandQuadIndex, + xform, nxform); + SafeDelete(d3dCtx->reIndexifyTable); + } + break; + default: + printf("IndexedGeometryArrayRetained_execute:unknown geo_type %ld \n", geo_type); + } + + if (vbptr != NULL) { + // d3dCtx->pVB is the last reference in VB list + d3dCtx->pVB->buffer->Unlock(); + } + + // Save new texture position to detect any change + // in next round. + for (i=0; i < d3dCtx->texSetUsed; i++) { + d3dCtx->pVB->texCoordPosition[i] = + strideData->texCoordPosition[i]; + } + + if (!buildDL) { + // Not in displaylist mode, directly render VB + // vb is the root reference in VB list + vb->render(d3dCtx); + } +} + + +/* + * Set the default texture coordinate pointers when automatically + * texture generation is used or when there is application error + */ +inline void setDefaultTextureCoordPointers(D3dCtx *d3dCtx, + D3DDRAWPRIMITIVESTRIDEDDATA *strideData, + DWORD* vertexFormat, + jint ts, + int genMode, + int tus) +{ + strideData->textureCoordsPtr[tus] = &defaultTexCoord[0]; + strideData->textureCoordsStride[tus] = 0; + strideData->texCoordPosition[tus] = genMode; + d3dCtx->texStride[tus] = ts; + *vertexFormat |= (TexFormatSizeTable[ts] << (tus*2 + 16)); +} + + +/* + * Set the textureCoordStride & textureCoordsPtr in strideData + */ +void setTextureCoordPointers(JNIEnv *env, + D3dCtx* d3dCtx, + LPDIRECT3DDEVICE8 device, + D3DDRAWPRIMITIVESTRIDEDDATA *strideData, + jint pass, + jint texoff, + jint texStride, + jint ts, + jboolean textureDefined, + jintArray tcoordsetmap, + jint texCoordMapLength, + jintArray texUnitOffset, + jint numActiveTexUnit, + jintArray tunitstatemap, + DWORD* vertexFormat, + // Used by executeGeometryArray() & + // executeIndexedGeometryArray() only + jfloat* verts, + // Used by executeGeometryArrayVA() & + // executeIndexedGeometryArrayVA() only + jfloat** texCoordPointer, + // Used by executeGeometryArrayVA() only + jintArray texindices) + +{ + jint *texUnitStateMap = NULL; + jint *texCoordSetMapOffset = NULL; + jint *initialTexIndices = NULL; + jint *texCoordSetMap = NULL; + jint textureUnitIndex; + int genMode; + jint offsetOrTexset; + BOOL nonVAGeom = (verts != NULL); + int texSetInVB = 0; + + /* + * In case of automatic texture generation, + * (vformat & GA_TEXTURE_COORDINATE) may equal to zero so we + * can't wrap around this whole block with the condition. + */ + d3dCtx->texSetUsed = 0; + + // For GA buildGA(), numActiveTexUnit is 1 even though texture + // is not used. This is only accurate for execute() immediate case. + if (numActiveTexUnit <= 0) { + return; + } + + if (texCoordMapLength > 0) { + if (nonVAGeom) { + // In executeGeometryArray() or executeIndexedGeometryArray() + texCoordSetMapOffset = (jint *) env->GetPrimitiveArrayCritical(texUnitOffset, NULL); + } else { + // In executeGeometryArrayVA() or executeIndexedGeometryArrayVA() + texCoordSetMap = (jint *) + env->GetPrimitiveArrayCritical(tcoordsetmap, NULL); + } + + } + + if (texindices != NULL) { + // In executeGeometryArrayVA() + initialTexIndices = (jint *) env->GetPrimitiveArrayCritical(texindices, NULL); + } + + if (pass >= 0) { + /* + * Single texture coordinate used or in multi-pass mode. + * In multi-pass mode, texture stage 0 is set so we + * should not use + * setTextureStage(d3dCtx, device, 0, pass); + */ + + genMode = setTextureStage(d3dCtx, device, 0, 0); + +#ifdef TEXDEBUG + printf("*** Single Pass *** %d, nonVAGeom %d, buildDL %d, numActiveTexUnit, texCoordMapLength %d, texDef %d, genMode %d \n", pass, nonVAGeom, (d3dCtx->currDisplayListID > 0), numActiveTexUnit, texCoordMapLength, textureDefined, genMode); +#endif + + if ((texCoordMapLength > 0) && + (pass < texCoordMapLength)) { + offsetOrTexset = (nonVAGeom ? + texCoordSetMapOffset[pass] : texCoordSetMap[pass]); + } else { + // TexUnitState is not used or disable, + // so by default we use texUnitIndex 0 + offsetOrTexset = 0; + } + + if (genMode != TEX_OBJ_LINEAR) { + // Only Object Linear Mode will not use DisplayList at + // all. That mean genMode must be correctly set before + // enter this Geometry execute() function/ + // In non displaylist mode genMode may not set correctly + // when so we can't rely on it. + if (textureDefined) { + if (offsetOrTexset != -1) { + if (nonVAGeom) { + // In executeGeometryArray() or executeIndexedGeometryArray() + strideData->textureCoordsPtr[0] = + &verts[texoff + offsetOrTexset]; + } else if (initialTexIndices != NULL) { + // executeGeometryArrayVA() + strideData->textureCoordsPtr[0] = + &(texCoordPointer[offsetOrTexset][initialTexIndices[offsetOrTexset]*texStride]); + } else { // executeIndexedGeometryArrayVA() + strideData->textureCoordsPtr[0] = + &(texCoordPointer[offsetOrTexset][0]); + } + + strideData->textureCoordsStride[0] = texStride; + *vertexFormat |= (TexFormatSizeTable[ts] << 16); + d3dCtx->texSetUsed = 1; + strideData->texCoordPosition[0] = offsetOrTexset; + d3dCtx->texStride[0] = ts; + setTexTransformStageFlag(d3dCtx, device, 0, ts, genMode); +#ifdef TEXDEBUG + printf("[pass 0] Non Object Linear, texDefined, ts=%d\n", ts); +#endif + } + } else { + // may be automatic texture generation used + // TexSetUsed remain unchange i.e. 0 since we will not + // allocate VB space for texture coords. + setTexTransformStageFlag(d3dCtx, device, 0, + d3dCtx->texCoordFormat[0], genMode); +#ifdef TEXDEBUG + printf("[pass 0] Non Object Linear, No texDefined, ts=%d\n", + d3dCtx->texCoordFormat[0]); +#endif + } + } else { + // Automatic texture generation Object Linear + // strideData->textureCoordsPtr[0] & + // strideData->textureCoordsStride[0] + // are not use in VertexBuffer texture copy so + // it doesn't matter to set them using default. + setDefaultTextureCoordPointers(d3dCtx, strideData, + vertexFormat, + d3dCtx->texCoordFormat[0], + genMode, 0); + setTexTransformStageFlag(d3dCtx, device, 0, + d3dCtx->texCoordFormat[0], genMode); + d3dCtx->texSetUsed = 1; +#ifdef TEXDEBUG + printf("[pass 0] Object Linear, ts=%d\n", d3dCtx->texCoordFormat[0]); +#endif + } + texSetInVB = d3dCtx->texSetUsed; + + } else { + // DisplayList is used for multiple texture single pass mode + // Or when go through the VertexArray in OGL, pass = -1 + int tus; +#ifdef TEXDEBUG + printf("*** Multiple Pass *** %d, nonVAGeom %d, buildDL %d, numActiveTexUnit %d, texCoordMapLength %d, texDef %d\n", pass, + nonVAGeom, (d3dCtx->currDisplayListID > 0), + numActiveTexUnit, texCoordMapLength, textureDefined); +#endif + + if (tunitstatemap != NULL) { + texUnitStateMap = (jint *) env->GetPrimitiveArrayCritical(tunitstatemap, NULL); + } + for (textureUnitIndex = 0; textureUnitIndex < numActiveTexUnit; + textureUnitIndex++) { + + tus = (texUnitStateMap != NULL ? + texUnitStateMap[textureUnitIndex]: textureUnitIndex); + + if (d3dCtx->currDisplayListID > 0) { + genMode = setTextureStage(d3dCtx, device, + textureUnitIndex, tus); + } else { + // This happen when we switch from displayList to + // vertexArray mode. The displayList is already + // built with 1-1 mapping so we can't use the + // textureUnitIndex Mapping + genMode = setTextureStage(d3dCtx, device, + textureUnitIndex, + textureUnitIndex); + } +#ifdef TEXDEBUG + printf("[pass %d] genMode %d, tus %d\n", textureUnitIndex, + genMode, tus); +#endif + if (genMode != TEX_OBJ_LINEAR) { + if (textureDefined) { + if (tus < texCoordMapLength) { + offsetOrTexset = (nonVAGeom ? + texCoordSetMapOffset[tus]:texCoordSetMap[tus]); + + if (offsetOrTexset != -1) { + if (nonVAGeom) { + strideData->textureCoordsPtr[textureUnitIndex] = + &verts[texoff + offsetOrTexset]; + } else if (initialTexIndices != NULL) { + strideData->textureCoordsPtr[textureUnitIndex] = + &(texCoordPointer[offsetOrTexset][initialTexIndices[offsetOrTexset]*texStride]); + } else { + strideData->textureCoordsPtr[textureUnitIndex] = + &(texCoordPointer[offsetOrTexset][0]); + } + strideData->textureCoordsStride[textureUnitIndex] = texStride; + strideData->texCoordPosition[textureUnitIndex] + = offsetOrTexset; + *vertexFormat |= (TexFormatSizeTable[ts] << (textureUnitIndex*2 + 16)); + d3dCtx->texStride[textureUnitIndex] = ts; + setTexTransformStageFlag(d3dCtx, device, + textureUnitIndex, + ts, genMode); + texSetInVB++; +#ifdef TEXDEBUG + printf("[pass %d] Non Object Linear, texDefined, ts=%d, tus %d\n", textureUnitIndex, ts, tus); +#endif + } else { + // This texture status is disable, this + // should not happen in D3D since + // TextureBin always compact unused state + // - unless when DisplayList is build and + // automatic texture generation + // used. Since if DL use + // updateAttributes() not yet invoke to + // set genMode correctly. + if (debug && (d3dCtx->currDisplayListID <= 0)) { + printf("[Java3D] TextureBin not compact textureUnitState correctly, numActiveTex %d, disableUnit %d, current mapped Texture Unit %d\n", numActiveTexUnit, tus, textureUnitIndex); + } + setDefaultTextureCoordPointers(d3dCtx, strideData, + vertexFormat, ts, + genMode, + textureUnitIndex); + setTexTransformStageFlag(d3dCtx, device, + textureUnitIndex, + ts, genMode); + texSetInVB++; +#ifdef TEXDEBUG + printf("[pass %d] Non Object Linear, texDefined, ts=%d\n", textureUnitIndex, ts); +#endif + } + } else { + // Internal error, should not happen. + if (debug) { + printf("[Java3D] TextureCoordMapLength length %d, is smaller than texture unit %d, map texture unit %d\n", texCoordMapLength, tus, textureUnitIndex); + } + setDefaultTextureCoordPointers(d3dCtx, strideData, + vertexFormat, ts, + TEX_GEN_INVALID, + textureUnitIndex); + setTexTransformStageFlag(d3dCtx, device, + textureUnitIndex, ts, + genMode); + + texSetInVB++; +#ifdef TEXDEBUG + printf("[pass %d] Non Object Linear, texDefined, offset/texset = -1, ts=%d\n", textureUnitIndex, ts); +#endif + } + } else { + // May be in automatically texture coordinate + // generation mode. + // May have trouble if automatically texture + // coordinate not used. Note that we pass ts = 0 + // so that copyVertexToVB() will not inc. the + // stride for this unused tex stage. + + // It is also the case in buildGA() case when + // numActiveTexUnit is 1 by default even though + // texture is not used. + /* + if ((d3dCtx->currDisplayListID <= 0) && + (genMode == TEX_GEN_NONE)) { + // application error, use default TexCoord + setDefaultTextureCoordPointers(d3dCtx, strideData, + vertexFormat, + ts, + TEX_GEN_NONE, + textureUnitIndex); + texSetInVB++; + } + */ + + setDefaultTextureCoordPointers(d3dCtx, strideData, + vertexFormat, + 0, + // This must be < 0 + TEX_GEN_AUTO, + textureUnitIndex); + setTexTransformStageFlag(d3dCtx, device, textureUnitIndex, + d3dCtx->texCoordFormat[textureUnitIndex], genMode); + + +#ifdef TEXDEBUG + printf("[pass %d] Non Object Linear, No texDefined, ts=0\n", textureUnitIndex); +#endif + } + } else { + // Automatic Texture generation Object Linear is used + setDefaultTextureCoordPointers(d3dCtx, strideData, + vertexFormat, + d3dCtx->texCoordFormat[textureUnitIndex], + genMode, + textureUnitIndex); + setTexTransformStageFlag(d3dCtx, device, textureUnitIndex, + d3dCtx->texCoordFormat[textureUnitIndex], genMode); + texSetInVB++; +#ifdef TEXDEBUG + printf("[pass %d] Object Linear, No texDefined, ts=%d\n", textureUnitIndex, d3dCtx->texCoordFormat[textureUnitIndex]); +#endif + } + } + d3dCtx->texSetUsed = numActiveTexUnit; +#ifdef TEXDEBUG + printf("No of texSetInVB %d, numActiveTexUnit %d\n", + texSetInVB, numActiveTexUnit); +#endif + if (texUnitStateMap != NULL) { + env->ReleasePrimitiveArrayCritical(tunitstatemap, texUnitStateMap, NULL); + } + } + + if (texCoordSetMapOffset != NULL) { + env->ReleasePrimitiveArrayCritical(texUnitOffset, + texCoordSetMapOffset, NULL); + } + + if (texCoordSetMap != NULL) { + env->ReleasePrimitiveArrayCritical(tcoordsetmap, + texCoordSetMap, NULL); + } + + if (initialTexIndices != NULL) { + env->ReleasePrimitiveArrayCritical(texindices, + initialTexIndices, NULL); + } + + // texSetInVB <= d3dCtx->TexSetUsed + *vertexFormat |= getVertexFormat(texSetInVB); +} + + + +void executeGeometryArrayVA( + JNIEnv *env, + jobject obj, + jlong ctx, + jobject geo, + jint geo_type, + jboolean isNonUniformScale, + jboolean modAlpha, + float alpha, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint vcount, + jint vformat, + jint vdefined, + jint initialCoordIndex, + jfloat* fverts, + jdouble* dverts, + jint initialColorIndex, + jfloat* fclrs, + jbyte* bclrs, + jint initialNormalIndex, + jfloat* norms, + int pass, // or texUnitIndex + int texCoordMapLength, + jintArray tcoordsetmap, + jint numActiveTexUnit, + jintArray tunitstatemap, + jintArray texindices, + jint texStride, + jfloat** texCoordPointer, + jdoubleArray xform, + jdoubleArray nxform, + jint cDirty) +{ + D3DDRAWPRIMITIVESTRIDEDDATA strideData; + DWORD vertexFormat = 0; + + jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0); + jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0); + jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0); + jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0); + jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0); + jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0); + + GetDevice(); + + ZeroMemory(&strideData, sizeof(D3DDRAWPRIMITIVESTRIDEDDATA)); + + strideData.modulateAlpha = modAlpha; + strideData.alpha = alpha; + + + // setup coordinate pointers + if (floatCoordDefined || doubleCoordDefined) { + vertexFormat |= D3DFVF_XYZ; + + if (floatCoordDefined) { + strideData.fpositionPtr = &fverts[initialCoordIndex*3]; + } else if (doubleCoordDefined) { + strideData.dpositionPtr = &dverts[initialCoordIndex*3]; + } + + strideData.positionStride = 3; + + } else { + // nothing worth doing if no coordinates define + return; + } + + // setup normal pointers + if (normalsDefined) { + vertexFormat |= D3DFVF_NORMAL; + strideData.normalPtr = &norms[initialNormalIndex*3]; + strideData.normalStride = 3; + } + + + // setup color pointers + if (!(floatColorsDefined || byteColorsDefined) + || ignoreVertexColors) { + // Use Material color + // Assume VertexBuffer will recreate when ignoreVertexColors + // property changed. Otherwise we need to remove + // the following one line + vertexFormat &= ~D3DFVF_DIFFUSE; + } else { + if ((vformat & GA_WITH_ALPHA) != 0) { + strideData.diffuseStride = 4; + strideData.useAlpha = true; + } else { + strideData.diffuseStride = 3; + strideData.useAlpha = false; + } + if (floatColorsDefined) { + strideData.fdiffusePtr = &fclrs[initialColorIndex*strideData.diffuseStride]; + } else { + strideData.bdiffusePtr = &bclrs[initialColorIndex*strideData.diffuseStride]; + } + + vertexFormat |= D3DFVF_DIFFUSE; + } + + int ts = 2; // In case of automatic texture generation + + if ((vformat & GA_TEXTURE_COORDINATE_3) != 0) { + ts = 3; + } else if ((vformat & GA_TEXTURE_COORDINATE_4) != 0) { + ts = 4; + } + + + // setup texture pointer + setTextureCoordPointers(env, d3dCtx, device, + &strideData, + pass, 0, texStride, ts, + textureDefined, + tcoordsetmap, + texCoordMapLength, + NULL, + numActiveTexUnit, + tunitstatemap, + &vertexFormat, + NULL, texCoordPointer, + texindices); + + + + jdouble* xform_ptr = NULL; + jdouble* nxform_ptr = NULL; + + if (xform != NULL) { + xform_ptr = (jdouble *) env->GetPrimitiveArrayCritical(xform, NULL); + + } + + if (nxform != NULL) { + nxform_ptr = (jdouble *) env->GetPrimitiveArrayCritical(nxform, NULL); + } + + // Construct/update VertexBuffer, render() if not in display list mode + renderGeometry(env, d3dCtx, device, geo, geo_type, &strideData, + vertexFormat, vcount, xform_ptr, nxform_ptr, cDirty); + + if (xform_ptr != NULL) { + env->ReleasePrimitiveArrayCritical(xform, xform_ptr, 0); + } + if (nxform_ptr != NULL) { + env->ReleasePrimitiveArrayCritical(nxform, nxform_ptr, 0); + } + +} + + + + +/* execute geometry array with java array format */ +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_executeVABuffer( + JNIEnv *env, + jobject obj, + jlong ctx, + jobject geo, + jint geo_type, + jboolean isNonUniformScale, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint vcount, + jint vformat, + jint vdefined, + jint initialCoordIndex, + jobject vcoords, + jint initialColorIndex, + jobject cdataBuffer, + jfloatArray cfdata, + jbyteArray cbdata, + jint initialNormalIndex, + jobject ndata, + jint pass, + jint texCoordMapLength, + jintArray tcoordsetmap, + jint numActiveTexUnit, + jintArray tunitstatemap, + jintArray texindices, + jint texStride, + jobjectArray texCoords, + jint cdirty) +{ + + jfloat *fverts = NULL; + jdouble *dverts = NULL ; + jbyte *bclrs = NULL; + jfloat *fclrs = NULL, *norms = NULL; + jfloat* texCoordPointer[D3DDP_MAXTEXCOORD]; + jarray texobjs[D3DDP_MAXTEXCOORD]; + int i; + + jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0); + jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0); + jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0); + jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0); + jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0); + jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0); + + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + texobjs[i] = (jarray)env->GetObjectArrayElement(texCoords, i); + } + } + + /* get coordinate array */ + if (floatCoordDefined) { + fverts = (jfloat *)env->GetDirectBufferAddress( vcoords ); + } else if (doubleCoordDefined) { + dverts = (jdouble *)env->GetDirectBufferAddress( vcoords ); + } + + if(fverts == NULL && dverts == NULL) + return; + + /* get color array */ + if (floatColorsDefined) { + if(cfdata != NULL) { + fclrs = (jfloat *) env->GetPrimitiveArrayCritical( cfdata, NULL); + } else { + fclrs = (jfloat *) env->GetDirectBufferAddress (cdataBuffer); + + } + } + else if (byteColorsDefined) { + if(cbdata != NULL) { + bclrs = (jbyte *) env->GetPrimitiveArrayCritical( cbdata, NULL); + } else { + bclrs = (jbyte *) env->GetDirectBufferAddress(cdataBuffer); + } + } + + /* get normal array */ + if (normalsDefined) { + norms = (jfloat *)env->GetDirectBufferAddress(ndata); + } + + /* get texture arrays */ + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + if (texobjs[i] != NULL) + texCoordPointer[i] = (jfloat*)env->GetDirectBufferAddress(texobjs[i]); + else + texCoordPointer[i] = NULL; + + } + } + + executeGeometryArrayVA(env, obj, ctx, geo, geo_type, + isNonUniformScale, false, 0, + multiScreen, ignoreVertexColors, + vcount, vformat, vdefined, initialCoordIndex, + fverts, dverts, initialColorIndex, + fclrs, bclrs, initialNormalIndex, + norms, pass, texCoordMapLength, + tcoordsetmap,numActiveTexUnit, tunitstatemap, + texindices,texStride,texCoordPointer, NULL, + NULL, cdirty); + + if(floatColorsDefined && cfdata != NULL) + env->ReleasePrimitiveArrayCritical( cfdata, fclrs, 0); + else if(byteColorsDefined && cbdata != NULL) + env->ReleasePrimitiveArrayCritical(cbdata, bclrs, 0); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_executeVA( + JNIEnv *env, + jobject obj, + jlong ctx, + jobject geo, + jint geo_type, + jboolean isNonUniformScale, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint vcount, + jint vformat, + jint vdefined, + jint initialCoordIndex, + jfloatArray vfcoords, + jdoubleArray vdcoords, + jint initialColorIndex, + jfloatArray cfdata, + jbyteArray cbdata, + jint initialNormalIndex, + jfloatArray ndata, + jint pass, // or texUnitIndex + jint texCoordMapLength, + jintArray tcoordsetmap, + jint numActiveTexUnit, + jintArray tunitstatemap, + jintArray texindices, + jint texStride, + jobjectArray texCoords, + jint cDirty) + { + + jfloat *fverts = NULL; + jdouble *dverts = NULL; + jfloat *fclrs = NULL; + jbyte *bclrs = NULL; + jfloat *norms = NULL; + jfloat* texCoordPointer[D3DDP_MAXTEXCOORD]; + jarray texobjs[D3DDP_MAXTEXCOORD]; + int i; + + jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0); + jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0); + jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0); + jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0); + jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0); + jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0); + + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + texobjs[i] = (jarray)env->GetObjectArrayElement( texCoords, i); + } + } + + /* get coordinate array */ + if (floatCoordDefined) { + fverts= (jfloat *) env->GetPrimitiveArrayCritical( vfcoords, NULL); + } else if (doubleCoordDefined) { + dverts= (jdouble *) env->GetPrimitiveArrayCritical( vdcoords, NULL); + } + + if ((fverts == NULL) && (dverts == NULL)) { + return; + } + + /* get color array */ + if (floatColorsDefined) { + fclrs = (jfloat *) env->GetPrimitiveArrayCritical( cfdata, NULL); + } else if (byteColorsDefined) { + bclrs = (jbyte *)env->GetPrimitiveArrayCritical( cbdata, NULL); + } + + /* get normal array */ + if (normalsDefined) { + norms = (jfloat *) env->GetPrimitiveArrayCritical(ndata, NULL); + } + + /* get texture arrays */ + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + if (texobjs[i] != NULL) { + texCoordPointer[i] = (jfloat*)env->GetPrimitiveArrayCritical(texobjs[i], NULL); + } else { + texCoordPointer[i] = NULL; + } + + } + } + executeGeometryArrayVA(env, obj, ctx, geo, geo_type, + isNonUniformScale, false, 0, + multiScreen, ignoreVertexColors, + vcount, vformat, vdefined, initialCoordIndex, + fverts, dverts, initialColorIndex, + fclrs, bclrs, initialNormalIndex, + norms, pass, texCoordMapLength, + tcoordsetmap,numActiveTexUnit, tunitstatemap, + texindices,texStride,texCoordPointer, + NULL, NULL, cDirty); + + if (floatCoordDefined) { + env->ReleasePrimitiveArrayCritical( vfcoords, fverts, 0); + } + else if (doubleCoordDefined) { + env->ReleasePrimitiveArrayCritical( vdcoords, dverts, 0); + } + + if (floatColorsDefined) { + env->ReleasePrimitiveArrayCritical( cfdata, fclrs, 0); + } + else if (byteColorsDefined) { + env->ReleasePrimitiveArrayCritical( cbdata, bclrs, 0); + } + + if (normalsDefined) { + env->ReleasePrimitiveArrayCritical( ndata, norms, 0); + } + + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + if (texCoordPointer[i] != NULL) { + env->ReleasePrimitiveArrayCritical(texobjs[i], texCoordPointer[i], 0); + } + } + } +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_setGlobalAlpha( + JNIEnv *env, + jobject obj, + jlong ctx, + jfloat alpha) +{ + // not use in D3D +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_disableGlobalAlpha( + JNIEnv *env, + jobject obj, + jlong ctx, + jint vformat, + jboolean useAlpha, + jboolean ignoreVertexColors) +{ + // not use in D3D +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_setVertexFormat( + JNIEnv *env, + jobject obj, + jint vformat, + jboolean useAlpha, + jboolean ignoreVertexColors, + jlong ctx) +{ + // not use in D3D +} + + +extern "C" JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_GeometryArrayRetained_globalAlphaSUN + (JNIEnv *env, jobject obj, jlong ctx) +{ + return JNI_FALSE; +} + + + +void executeGeometryArray(JNIEnv *env, + jobject obj, jlong ctx, + jobject geo, jint geo_type, + jboolean isNonUniformScale, + jboolean modAlpha, // buildGA, should alpha be mode + jfloat alpha, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint startVIndex, + jint vcount, jint vformat, jint texCoordSetCount, + jintArray texCoordSetMapArray, + jint texCoordMapLength, + jintArray texUnitOffset, + jint numActiveTexUnit, + jintArray tunitstatemap, + jfloat* verts, jfloatArray carray, jint pass, + jdoubleArray xform, jdoubleArray nxform, + jint cDirty, + jboolean useAlpha) // Should alpha be sent down +{ + D3DDRAWPRIMITIVESTRIDEDDATA strideData; + DWORD vertexFormat = 0; + jint stride, coordoff, normoff, coloroff, texoff; + int texStride, ts = 0; + + GetDevice(); + + ZeroMemory(&strideData, sizeof(D3DDRAWPRIMITIVESTRIDEDDATA)); + + strideData.modulateAlpha = modAlpha; + strideData.alpha = alpha; + + /* This matches the code in GeometryArrayRetained.java */ + stride = coordoff = normoff = coloroff = texoff = 0; + + if ((vformat & GA_COORDINATES) != 0) { + stride += 3; + vertexFormat |= D3DFVF_XYZ; + } else { + // nothing worth doing if no coordinates define + return; + } + + if ((vformat & GA_NORMALS) != 0) { + stride += 3; + coordoff += 3; + vertexFormat |= D3DFVF_NORMAL; + } + + if ((vformat & GA_COLOR) != 0) { + if ((vformat & GA_WITH_ALPHA) != 0 ) { + stride += 4; + normoff += 4; + coordoff += 4; + } else { // Handle the case of executeInterleaved 3f + stride += 3; + normoff += 3; + coordoff += 3; + } + vertexFormat |= D3DFVF_DIFFUSE; + } + + // In case of automatic texture generation + ts = 2; + + if (vformat & GA_TEXTURE_COORDINATE) { + if ((vformat & GA_TEXTURE_COORDINATE_2) != 0) { + texStride = texCoordSetCount << 1; + } else if ((vformat & GA_TEXTURE_COORDINATE_3) != 0) { + ts = 3; + texStride = texCoordSetCount*3; + } else { // GA_TEXTURE_COORDINATE_4 + ts = 4; + texStride = texCoordSetCount << 2; + } + stride += texStride; + normoff += texStride; + coloroff += texStride; + coordoff += texStride; + } + + jfloat *cverts = NULL; + + texoff = startVIndex*stride; + coordoff += texoff; + normoff += texoff; + + if (carray != NULL) { + // separate color array is used + coloroff = startVIndex*4; + } else { + coloroff += texoff; + } + + // setup coordinates pointer + strideData.fpositionPtr = &verts[coordoff]; + strideData.positionStride = stride; + + // setup color pointer + if (((vformat & GA_COLOR) == 0) || ignoreVertexColors) { + // Use Material color + // Assume VertexBuffer will recreate when ignoreVertexColors + // property changed. Otherwise we need to remove + // the following one line + vertexFormat &= ~D3DFVF_DIFFUSE; + } else { + if (carray == NULL) { + strideData.fdiffusePtr = &verts[coloroff]; + strideData.diffuseStride = stride; + strideData.useAlpha = (vformat & GA_WITH_ALPHA); + } else { + cverts = (jfloat*) env->GetPrimitiveArrayCritical(carray, NULL); + strideData.fdiffusePtr = &cverts[coloroff]; + strideData.diffuseStride = 4; + strideData.useAlpha = true; + } + } + + + // setup normal pointer + if ((vformat & GA_NORMALS) != 0) { + strideData.normalPtr = &verts[normoff]; + strideData.normalStride = stride; + } + + // setup texture pointer + setTextureCoordPointers(env, d3dCtx, device, + &strideData, + pass, texoff, stride, ts, + (vformat & GA_TEXTURE_COORDINATE), + NULL, + texCoordMapLength, + texUnitOffset, + numActiveTexUnit, + tunitstatemap, + &vertexFormat, + verts, NULL, NULL); + + + jdouble* xform_ptr = NULL; + jdouble* nxform_ptr = NULL; + + if (xform != NULL) { + xform_ptr = (jdouble *) env->GetPrimitiveArrayCritical(xform, NULL); + + } + + if (nxform != NULL) { + nxform_ptr = (jdouble *) env->GetPrimitiveArrayCritical(nxform, NULL); + } + + renderGeometry(env, d3dCtx, device, geo, geo_type, &strideData, + vertexFormat, vcount, xform_ptr, nxform_ptr, cDirty); + + if (xform_ptr != NULL) { + env->ReleasePrimitiveArrayCritical(xform, xform_ptr, 0); + } + if (nxform_ptr != NULL) { + env->ReleasePrimitiveArrayCritical(nxform, nxform_ptr, 0); + } + + + /* env->ReleasePrimitiveArrayCritical(varray, verts, NULL); */ + + if (cverts != NULL) { + env->ReleasePrimitiveArrayCritical(carray, cverts, NULL); + } +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_buildGA(JNIEnv *env, + jobject obj, jlong ctx, jobject geo, jint geo_type, + jboolean isNonUniformScale, jboolean updateAlpha, float alpha, + jboolean ignoreVertexColors, + jint startVIndex, + jint vcount, jint vformat, + jint texCoordSetCount, + jintArray texCoordSetMapArray, + jint texCoordMapLength, + jintArray texUnitOffset, + jdoubleArray xform, jdoubleArray nxform, + jfloatArray varray) +{ + + jfloat *verts = NULL; + + if (varray != NULL) { + verts = (jfloat *) env->GetPrimitiveArrayCritical(varray, NULL); + } + + if (verts == NULL) { + return; + } + + if (((vformat & GA_COLOR) != 0) && + ((vformat & GA_BY_REFERENCE) == 0)) { + // alpha component is added for buildGA + vformat |= GA_WITH_ALPHA; + } + + + executeGeometryArray(env, + obj, ctx, geo, geo_type, isNonUniformScale, + updateAlpha, + alpha, + false, + ignoreVertexColors, + startVIndex, + vcount, + vformat, + texCoordSetCount, + texCoordSetMapArray, + texCoordMapLength, + texUnitOffset, + texCoordMapLength, + NULL, + verts, NULL, + -1, + xform, nxform, + javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED, + false); + + env->ReleasePrimitiveArrayCritical( varray, verts, 0); +} + + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_execute(JNIEnv *env, + jobject obj, jlong ctx, + jobject geo, jint geo_type, + jboolean isNonUniformScale, jboolean useAlpha, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint startVIndex, + jint vcount, jint vformat, jint texCoordSetCount, + jintArray texCoordSetMapArray, + jint texCoordMapLength, jintArray texUnitOffset, + jint numActiveTexUnit, + jintArray tunitstatemap, + jfloatArray varray, jfloatArray carray, + jint texUnitIndex, jint cDirty) +{ + jfloat *verts = NULL; + + if (varray != NULL) { + verts = (jfloat *) env->GetPrimitiveArrayCritical( varray, NULL); + } + + if (verts == NULL) { + return; + } + + executeGeometryArray(env, obj, ctx, geo, geo_type, + isNonUniformScale, + false, + 0, multiScreen, + ignoreVertexColors, startVIndex, + vcount, vformat, texCoordSetCount, + texCoordSetMapArray, + texCoordMapLength, texUnitOffset, + numActiveTexUnit, tunitstatemap, + verts, carray, texUnitIndex, NULL, NULL, cDirty,useAlpha); + + env->ReleasePrimitiveArrayCritical( varray, verts, 0); + +} + + +/* interleaved data with nio buffer as data format */ +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_executeInterleavedBuffer(JNIEnv *env, + jobject obj, jlong ctx, jobject geo, jint geo_type, + jboolean isNonUniformScale, jboolean useAlpha, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint startVIndex, + jint vcount, jint vformat, + jint texCoordSetCount, + jintArray texCoordSetMapArray, jint texCoordMapLength, + jintArray texUnitOffset, + jint numActiveTexUnit, + jintArray tunitstatemap, + jobject varray, jfloatArray carray, + jint texUnitIndex, jint cDirty) { + + jfloat *verts = NULL; + + /* get the direct buffer address */ + if (varray != NULL) { + verts = (jfloat *) env->GetDirectBufferAddress(varray); + } + + if (verts == NULL) { + return; + } + + /* call executeGeometryArray */ + executeGeometryArray(env, obj, ctx, geo, geo_type, + isNonUniformScale, + false, + 0, multiScreen, + ignoreVertexColors, startVIndex, + vcount, vformat, texCoordSetCount, + texCoordSetMapArray, + texCoordMapLength, texUnitOffset, + numActiveTexUnit, tunitstatemap, + verts, carray, texUnitIndex, NULL, NULL, cDirty,useAlpha); + +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_freeD3DArray + (JNIEnv *env, jobject geo, jboolean deleteVB) +{ + + lockGeometry(); + + jclass geoClass = (jclass) env->GetObjectClass(geo); + // Free VertexBuffer associate with this GeometryArray + jfieldID fieldID = env->GetFieldID(geoClass, "pVertexBuffers", "J"); + + D3dVertexBufferVector *vbVector = + reinterpret_cast (env->GetLongField(geo, fieldID)); + + + if (vbVector != NULL) { + // clearLive() invoke this in Renderer thread + for (LPD3DVERTEXBUFFER *s = vbVector->begin(); + s != vbVector->end(); ++s) { + // This notify vb that parent vector is already free + // so there is no need to remove itself from vbVector + (*s)->vbVector = NULL; + (*s)->ctx->freeVB(*s); + } + env->SetLongField(geo, fieldID, 0); + vbVector->clear(); + delete vbVector; + } + + unlockGeometry(); +} + + + +void executeIndexedGeometryArray(JNIEnv *env, + jobject obj, jlong ctx, + jobject geo, jint geo_type, + jboolean isNonUniformScale, + jboolean modAlpha, // buildGA, should alpha be mode + jfloat alpha, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint vcount, + jint vformat, + jint texCoordSetCount, + jintArray texCoordSetMapArray, + jint texCoordMapLength, + jintArray texUnitOffset, + jint numActiveTexUnit, + jintArray tunitstatemap, + jfloat* verts, jfloatArray carray, jint pass, + jdoubleArray xform, jdoubleArray nxform, + jint cDirty, + jboolean useAlpha, + jint initialIndexIndex, + jint indexCount, + jintArray indexCoord) // Should alpha be sent down +{ + D3DDRAWPRIMITIVESTRIDEDDATA strideData; + DWORD vertexFormat = 0; + jint stride, coordoff, normoff, coloroff, texoff; + int texStride, ts = 0; + + GetDevice(); + + ZeroMemory(&strideData, sizeof(D3DDRAWPRIMITIVESTRIDEDDATA)); + + strideData.modulateAlpha = modAlpha; + strideData.alpha = alpha; + + /* This matches the code in GeometryArrayRetained.java */ + stride = coordoff = normoff = coloroff = texoff = 0; + + if ((vformat & GA_COORDINATES) != 0) { + stride += 3; + vertexFormat |= D3DFVF_XYZ; + } else { + // nothing worth doing if no coordinates define + return; + } + + if ((vformat & GA_NORMALS) != 0) { + stride += 3; + coordoff += 3; + vertexFormat |= D3DFVF_NORMAL; + } + + if ((vformat & GA_COLOR) != 0) { + if ((vformat & GA_WITH_ALPHA) != 0 ) { + stride += 4; + normoff += 4; + coordoff += 4; + } else { // Handle the case of executeInterleaved 3f + stride += 3; + normoff += 3; + coordoff += 3; + } + vertexFormat |= D3DFVF_DIFFUSE; + } + + // In case of automatic texture generation + ts = 2; + + if (vformat & GA_TEXTURE_COORDINATE) { + if ((vformat & GA_TEXTURE_COORDINATE_2) != 0) { + texStride = texCoordSetCount << 1; + } else if ((vformat & GA_TEXTURE_COORDINATE_3) != 0) { + ts = 3; + texStride = texCoordSetCount*3; + } else { // GA_TEXTURE_COORDINATE_4 + ts = 4; + texStride = texCoordSetCount << 2; + } + stride += texStride; + normoff += texStride; + coloroff += texStride; + coordoff += texStride; + } + + jfloat *cverts = NULL; + + if (carray != NULL) { + // separate color array is used + coloroff = 0; + } else { + coloroff += texoff; + } + + // setup coordinates pointer + strideData.fpositionPtr = &verts[coordoff]; + strideData.positionStride = stride; + + // setup color pointer + if (((vformat & GA_COLOR) == 0) || ignoreVertexColors) { + // Use Material color + // Assume VertexBuffer will recreate when ignoreVertexColors + // property changed. Otherwise we need to remove + // the following one line + vertexFormat &= ~D3DFVF_DIFFUSE; + } else { + if (carray == NULL) { + strideData.fdiffusePtr = &verts[coloroff]; + strideData.diffuseStride = stride; + strideData.useAlpha = (vformat & GA_WITH_ALPHA); + } else { + cverts = (jfloat*) env->GetPrimitiveArrayCritical(carray, NULL); + strideData.fdiffusePtr = &cverts[coloroff]; + strideData.diffuseStride = 4; + strideData.useAlpha = true; + } + } + + + // setup normal pointer + if ((vformat & GA_NORMALS) != 0) { + strideData.normalPtr = &verts[normoff]; + strideData.normalStride = stride; + } + + + // setup texture pointer + setTextureCoordPointers(env, d3dCtx, device, + &strideData, + pass, texoff, stride, ts, + (vformat & GA_TEXTURE_COORDINATE), + NULL, + texCoordMapLength, + texUnitOffset, + numActiveTexUnit, + tunitstatemap, + &vertexFormat, + verts, NULL, NULL); + + // setup index pointer + strideData.indexPtr = (jint *) env->GetPrimitiveArrayCritical(indexCoord, NULL); + strideData.initialIndexIndex = initialIndexIndex; + + + jdouble* xform_ptr = NULL; + jdouble* nxform_ptr = NULL; + + if (xform != NULL) { + xform_ptr = (jdouble *) env->GetPrimitiveArrayCritical(xform, NULL); + + } + + if (nxform != NULL) { + nxform_ptr = (jdouble *) env->GetPrimitiveArrayCritical(nxform, NULL); + } + + renderIndexGeometry(env, d3dCtx, device, geo, geo_type, &strideData, + vertexFormat, vcount, indexCount, + xform_ptr, nxform_ptr, cDirty); + + + + if (xform_ptr != NULL) { + env->ReleasePrimitiveArrayCritical(xform, xform_ptr, 0); + } + if (nxform_ptr != NULL) { + env->ReleasePrimitiveArrayCritical(nxform, nxform_ptr, 0); + } + + if (cverts != NULL) { + env->ReleasePrimitiveArrayCritical(carray, cverts, NULL); + } + + env->ReleasePrimitiveArrayCritical(indexCoord, + strideData.indexPtr, NULL); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometry( + JNIEnv *env, + jobject obj, jlong ctx, + jobject geo, jint geo_type, + jboolean isNonUniformScale, jboolean useAlpha, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint initialIndexIndex, + jint indexCount, + jint vcount, + jint vformat, jint texCoordSetCount, + jintArray texCoordSetMapArray, + jint texCoordMapLength, jintArray texUnitOffset, + jint numActiveTexUnit, + jintArray tunitstatemap, + jfloatArray varray, jfloatArray carray, + jint texUnitIndex, jint cDirty, + jintArray indexCoord) +{ + jfloat *verts = NULL; + + if (varray != NULL) { + verts = (jfloat *) env->GetPrimitiveArrayCritical( varray, NULL); + } + + if (verts == NULL) { + return; + } + + executeIndexedGeometryArray(env, obj, ctx, geo, geo_type, + isNonUniformScale, + false, 0, multiScreen, + ignoreVertexColors, + vcount, + vformat, texCoordSetCount, + texCoordSetMapArray, + texCoordMapLength, + texUnitOffset, + numActiveTexUnit, + tunitstatemap, + verts, + carray, + texUnitIndex, + NULL, NULL, + cDirty, + useAlpha, + initialIndexIndex, + indexCount, + indexCoord); + + env->ReleasePrimitiveArrayCritical( varray, verts, 0); +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometryBuffer( + JNIEnv *env, + jobject obj, jlong ctx, + jobject geo, jint geo_type, + jboolean isNonUniformScale, jboolean useAlpha, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint initialIndexIndex, + jint indexCount, + jint vcount, + jint vformat, jint texCoordSetCount, + jintArray texCoordSetMapArray, + jint texCoordMapLength, jintArray texUnitOffset, + jint numActiveTexUnit, + jintArray tunitstatemap, + jobject varray, jfloatArray carray, + jint texUnitIndex, jint cDirty, + jintArray indexCoord) +{ + jfloat *verts = NULL; + + /* get the direct buffer address */ + if (varray != NULL) { + verts = (jfloat *) env->GetDirectBufferAddress(varray ); + } + + if (verts == NULL) + return; + + executeIndexedGeometryArray(env, obj, ctx, geo, geo_type, + isNonUniformScale, + false, 0, multiScreen, + ignoreVertexColors, + vcount, + vformat, texCoordSetCount, + texCoordSetMapArray, + texCoordMapLength, + texUnitOffset, + numActiveTexUnit, + tunitstatemap, + verts, + carray, + texUnitIndex, + NULL, NULL, + cDirty, + useAlpha, + initialIndexIndex, + indexCount, + indexCoord); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_buildIndexedGeometry( + JNIEnv *env, + jobject obj, jlong ctx, jobject geo, + jint geo_type, + jboolean isNonUniformScale, jboolean updateAlpha, float alpha, + jboolean ignoreVertexColors, + jint initialIndexIndex, + jint indexCount, + jint vertexCount, + jint vformat, + jint texCoordSetCount, + jintArray texCoordSetMapArray, + jint texCoordMapLength, + jintArray texUnitOffset, + jdoubleArray xform, jdoubleArray nxform, + jfloatArray varray, jintArray indexCoord) +{ + + jfloat *verts = NULL; + + if (varray != NULL) { + verts = (jfloat *) env->GetPrimitiveArrayCritical( varray, NULL); + } + + if (verts == NULL) { + return; + } + + if ((vformat & GA_COLOR) != 0) { + // alpha component is added for buildGA + vformat |= GA_WITH_ALPHA; + } + + executeIndexedGeometryArray(env, obj, ctx, geo, geo_type, + isNonUniformScale, + updateAlpha, alpha, + false, + ignoreVertexColors, + vertexCount, + vformat, + texCoordSetCount, + texCoordSetMapArray, + texCoordMapLength, + texUnitOffset, + texCoordMapLength, + NULL, + verts, + NULL, -1, + xform, nxform, + javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED| + javax_media_j3d_GeometryArrayRetained_INDEX_CHANGED, + false, + initialIndexIndex, + indexCount, + indexCoord); + + env->ReleasePrimitiveArrayCritical( varray, verts, 0); + +} + + + +void executeIndexedGeometryArrayVA( + JNIEnv *env, + jobject obj, + jlong ctx, + jobject geo, + jint geo_type, + jboolean isNonUniformScale, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint initialIndexIndex, + jint indexCount, + jint vertexCount, + jint vformat, + jint vdefined, + jfloat* fverts, + jdouble* dverts, + jfloat* fclrs, + jbyte* bclrs, + jfloat* norms, + jint pass, + jint texCoordMapLength, + jintArray tcoordsetmap, + jint numActiveTexUnit, + jintArray tunitstatemap, + jint texStride, + jfloat** texCoordPointer, + jint cDirty, + jintArray indexCoord) +{ + D3DDRAWPRIMITIVESTRIDEDDATA strideData; + DWORD vertexFormat = 0; + jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0); + jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0); + jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0); + jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0); + jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0); + jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0); + + GetDevice(); + + ZeroMemory(&strideData, sizeof(D3DDRAWPRIMITIVESTRIDEDDATA)); + + // setup coordinate pointers + if (floatCoordDefined || doubleCoordDefined) { + vertexFormat |= D3DFVF_XYZ; + + if (floatCoordDefined ) { + strideData.fpositionPtr = &fverts[0]; + } else if (doubleCoordDefined) { + strideData.dpositionPtr = &dverts[0]; + } + strideData.positionStride = 3; + + } else { + // nothing worth doing if no coordinates define + return; + } + + // setup normal pointers + if (normalsDefined) { + vertexFormat |= D3DFVF_NORMAL; + strideData.normalPtr = &norms[0]; + strideData.normalStride = 3; + } + + // setup color pointers + if (!(floatColorsDefined || byteColorsDefined) + || ignoreVertexColors) { + // Use Material color + // Assume VertexBuffer will recreate when ignoreVertexColors + // property changed. Otherwise we need to remove + // the following one line + vertexFormat &= ~D3DFVF_DIFFUSE; + } else { + if ((vformat & GA_WITH_ALPHA) != 0) { + strideData.diffuseStride = 4; + strideData.useAlpha = true; + } else { + strideData.diffuseStride = 3; + strideData.useAlpha = false; + } + if (floatColorsDefined) { + strideData.fdiffusePtr = &fclrs[0]; + } else { + strideData.bdiffusePtr = &bclrs[0]; + } + + vertexFormat |= D3DFVF_DIFFUSE; + } + + + int ts = 2; // In case of automatic texture generation + + if ((vformat & GA_TEXTURE_COORDINATE_3) != 0) { + ts = 3; + } else if ((vformat & GA_TEXTURE_COORDINATE_4) != 0) { + ts = 4; + } + + // setup texture pointer + setTextureCoordPointers(env, d3dCtx, device, + &strideData, + pass, 0, + texStride, ts, + textureDefined, + tcoordsetmap, + texCoordMapLength, + NULL, + numActiveTexUnit, + tunitstatemap, + &vertexFormat, + NULL, texCoordPointer, + NULL); + + // setup index pointer + strideData.indexPtr = (jint *) env->GetPrimitiveArrayCritical(indexCoord, NULL); + strideData.initialIndexIndex = initialIndexIndex; + + // Construct/update VertexBuffer, render() if not in display list mode + renderIndexGeometry(env, d3dCtx, device, geo, geo_type, &strideData, + vertexFormat, vertexCount, indexCount, + NULL, NULL, cDirty); + + env->ReleasePrimitiveArrayCritical(indexCoord, + strideData.indexPtr, NULL); + + +} +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometryVA( + JNIEnv *env, + jobject obj, + jlong ctx, + jobject geo, + jint geo_type, + jboolean isNonUniformScale, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint initialIndexIndex, + jint indexCount, + jint vertexCount, + jint vformat, + jint vdefined, + jfloatArray vfcoords, + jdoubleArray vdcoords, + jfloatArray cfdata, + jbyteArray cbdata, + jfloatArray ndata, + jint pass, + jint texCoordMapLength, + jintArray tcoordsetmap, + jint numActiveTexUnit, + jintArray tunitstatemap, + jint texStride, + jobjectArray texCoords, + jint cDirty, + jintArray indexCoord) +{ + jfloat *fverts = NULL; + jdouble *dverts = NULL; + jfloat *fclrs = NULL; + jbyte *bclrs = NULL; + jfloat *norms = NULL; + jfloat* texCoordPointer[D3DDP_MAXTEXCOORD]; + jarray texobjs[D3DDP_MAXTEXCOORD]; + int i; + + jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0); + jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0); + jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0); + jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0); + jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0); + jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0); + + /* get texture arrays */ + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + texobjs[i] = (jarray)env->GetObjectArrayElement( texCoords, i); + } + } + + /* get coordinate array */ + if (floatCoordDefined) { + fverts= (jfloat *) env->GetPrimitiveArrayCritical( vfcoords, NULL); + } else if (doubleCoordDefined) { + dverts= (jdouble *) env->GetPrimitiveArrayCritical( vdcoords, NULL); + } + + if ((fverts == NULL) && (dverts == NULL)) { + return; + } + + /* get color array */ + if (floatColorsDefined) { + fclrs = (jfloat *) env->GetPrimitiveArrayCritical( cfdata, NULL); + } else if (byteColorsDefined) { + bclrs = (jbyte *)env->GetPrimitiveArrayCritical( cbdata, NULL); + } + + /* get normal array */ + if (normalsDefined) { + norms = (jfloat *) env->GetPrimitiveArrayCritical(ndata, NULL); + } + + /* get texture arrays */ + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + if (texobjs[i] != NULL) { + texCoordPointer[i] = + (jfloat*)env->GetPrimitiveArrayCritical(texobjs[i], NULL); + } else { + texCoordPointer[i] = NULL; + } + + } + } + + + executeIndexedGeometryArrayVA(env, + obj, + ctx, + geo, + geo_type, + isNonUniformScale, + multiScreen, + ignoreVertexColors, + initialIndexIndex, + indexCount, + vertexCount, + vformat, + vdefined, + fverts, + dverts, + fclrs, + bclrs, + norms, + pass, + texCoordMapLength, + tcoordsetmap, + numActiveTexUnit, + tunitstatemap, + texStride, + texCoordPointer, + cDirty, + indexCoord); + + // Free memory + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + if (texCoordPointer[i] != NULL) { + env->ReleasePrimitiveArrayCritical(texobjs[i], texCoordPointer[i], NULL); + } + } + } + + if (floatColorsDefined) { + env->ReleasePrimitiveArrayCritical(cfdata, fclrs, 0); + } else if (byteColorsDefined) { + env->ReleasePrimitiveArrayCritical(cbdata, bclrs, 0); + } + + if (normalsDefined) { + env->ReleasePrimitiveArrayCritical(ndata, norms, 0); + } + + if (floatCoordDefined) { + env->ReleasePrimitiveArrayCritical(vfcoords, fverts, 0); + } else if (doubleCoordDefined) { + env->ReleasePrimitiveArrayCritical(vdcoords, dverts, 0); + } +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometryVABuffer( + JNIEnv *env, + jobject obj, + jlong ctx, + jobject geo, + jint geo_type, + jboolean isNonUniformScale, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint initialIndexIndex, + jint indexCount, + jint vertexCount, + jint vformat, + jint vdefined, + jobject vcoords, + jobject cdataBuffer, + jfloatArray cfdata, + jbyteArray cbdata, + jobject ndata, + jint pass, + jint texCoordMapLength, + jintArray tcoordsetmap, + jint numActiveTexUnit, + jintArray tunitstatemap, + jint texStride, + jobjectArray texCoords, + jint cDirty, + jintArray indexCoord) +{ + jfloat *fverts = NULL; + jdouble *dverts = NULL; + jfloat *fclrs = NULL; + jbyte *bclrs = NULL; + jfloat *norms = NULL; + jfloat* texCoordPointer[D3DDP_MAXTEXCOORD]; + jarray texobjs[D3DDP_MAXTEXCOORD]; + int i; + + jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0); + jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0); + jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0); + jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0); + jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0); + jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0); + + /* get texture arrays */ + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + texobjs[i] = (jarray)env->GetObjectArrayElement( texCoords, i); + } + } + + /* get coordinate array */ + if (floatCoordDefined) { + fverts = (jfloat *)env->GetDirectBufferAddress( vcoords ); + } else if (doubleCoordDefined) { + dverts = (jdouble *)env->GetDirectBufferAddress( vcoords ); + } + + if ((fverts == NULL) && (dverts == NULL)) { + return; + } + + /* get color array */ + if (floatColorsDefined) { + if(cfdata != NULL) { + fclrs = (jfloat *) env->GetPrimitiveArrayCritical( cfdata, NULL); + } else { + fclrs = (jfloat *) env->GetDirectBufferAddress (cdataBuffer); + } + } else if (byteColorsDefined) { + if (cbdata != NULL) { + bclrs = (jbyte *) env->GetPrimitiveArrayCritical( cbdata, NULL); + } else { + bclrs = (jbyte *) env->GetDirectBufferAddress(cdataBuffer); + } + } + + /* get normal array */ + if (normalsDefined) { + norms = (jfloat *)env->GetDirectBufferAddress(ndata); + } + /* get texture arrays */ + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + if (texobjs[i] != NULL) + texCoordPointer[i] = (jfloat*)env->GetDirectBufferAddress(texobjs[i]); + else + texCoordPointer[i] = NULL; + + } + } + + + executeIndexedGeometryArrayVA( + env, + obj, + ctx, + geo, + geo_type, + isNonUniformScale, + multiScreen, + ignoreVertexColors, + initialIndexIndex, + indexCount, + vertexCount, + vformat, + vdefined, + fverts, + dverts, + fclrs, + bclrs, + norms, + pass, + texCoordMapLength, + tcoordsetmap, + numActiveTexUnit, + tunitstatemap, + texStride, + texCoordPointer, + cDirty, + indexCoord); + + if (floatColorsDefined && cfdata != NULL) { + env->ReleasePrimitiveArrayCritical( cfdata, fclrs, 0); + } else if (byteColorsDefined && cbdata != NULL) { + env->ReleasePrimitiveArrayCritical(cbdata, bclrs, 0); + } +} + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_buildGAForBuffer( + JNIEnv *env, + jobject obj, + jlong ctx, + jobject geo, + jint geo_type, + jboolean isNonUniformScale, + jboolean updateAlpha, + jfloat alpha, + jboolean ignoreVertexColors, + jint vcount, + jint vformat, + jint vdefined, + jint initialCoordIndex, + jobject vcoords, + jint initialColorIndex, + jobject cdataBuffer, + jint initialNormalIndex, + jobject ndata, + jint texCoordMapLength, + jintArray tcoordsetmap, + jintArray texindices, + jint texStride, + jobjectArray texCoords, + jdoubleArray xform, + jdoubleArray nxform) +{ + jfloat *fverts = NULL; + jdouble *dverts = NULL ; + jbyte *bclrs = NULL; + jfloat *fclrs = NULL, *norms = NULL; + jfloat* texCoordPointer[D3DDP_MAXTEXCOORD]; + jarray texobjs[D3DDP_MAXTEXCOORD]; + int i; + + jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0); + jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0); + jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0); + jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0); + jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0); + jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0); + + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + texobjs[i] = (jarray)env->GetObjectArrayElement(texCoords, i); + } + } + + /* get coordinate array */ + if (floatCoordDefined) { + fverts = (jfloat *)env->GetDirectBufferAddress( vcoords ); + } else if (doubleCoordDefined) { + dverts = (jdouble *)env->GetDirectBufferAddress( vcoords ); + } + + if ((fverts == NULL) && (dverts == NULL)) { + return; + } + + /* get color array */ + if (floatColorsDefined) { + fclrs = (jfloat *) env->GetDirectBufferAddress(cdataBuffer); + } else if (byteColorsDefined) { + bclrs = (jbyte *) env->GetDirectBufferAddress(cdataBuffer); + } + + /* get normal array */ + if (normalsDefined) { + norms = (jfloat *)env->GetDirectBufferAddress(ndata); + } + + /* get texture arrays */ + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + if (texobjs[i] != NULL) + texCoordPointer[i] = (jfloat*)env->GetDirectBufferAddress(texobjs[i]); + else + texCoordPointer[i] = NULL; + + } + } + + executeGeometryArrayVA(env, obj, ctx, geo, geo_type, + isNonUniformScale, updateAlpha, alpha, + false, ignoreVertexColors, + vcount, vformat, vdefined, initialCoordIndex, + fverts, dverts, initialColorIndex, + fclrs, bclrs, initialNormalIndex, + norms, -1, texCoordMapLength, + tcoordsetmap,texCoordMapLength, NULL, + texindices,texStride,texCoordPointer, + xform, nxform, + javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_buildGAForByRef( + JNIEnv *env, + jobject obj, + jlong ctx, + jobject geo, + jint geo_type, + jboolean isNonUniformScale, + jboolean updateAlpha, + jfloat alpha, + jboolean ignoreVertexColors, + jint vcount, + jint vformat, + jint vdefined, + jint initialCoordIndex, + jfloatArray vfcoords, + jdoubleArray vdcoords, + jint initialColorIndex, + jfloatArray cfdata, + jbyteArray cbdata, + jint initialNormalIndex, + jfloatArray ndata, + jint texCoordMapLength, + jintArray tcoordsetmap, + jintArray texindices, + jint texStride, + jobjectArray texCoords, + jdoubleArray xform, + jdoubleArray nxform) +{ + jfloat *fverts = NULL; + jdouble *dverts = NULL; + jfloat *fclrs = NULL; + jbyte *bclrs = NULL; + jfloat *norms = NULL; + jfloat* texCoordPointer[D3DDP_MAXTEXCOORD]; + jarray texobjs[D3DDP_MAXTEXCOORD]; + int i; + + jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0); + jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0); + jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0); + jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0); + jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0); + jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0); + + + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + texobjs[i] = (jarray)env->GetObjectArrayElement( texCoords, i); + } + } + + /* get coordinate array */ + if (floatCoordDefined) { + fverts= (jfloat *) env->GetPrimitiveArrayCritical( vfcoords, NULL); + } else if (doubleCoordDefined) { + dverts= (jdouble *) env->GetPrimitiveArrayCritical( vdcoords, NULL); + } + + if ((fverts == NULL) && (dverts == NULL)) { + return; + } + + /* get color array */ + if (floatColorsDefined) { + fclrs = (jfloat *) env->GetPrimitiveArrayCritical( cfdata, NULL); + } else if (byteColorsDefined) { + bclrs = (jbyte *)env->GetPrimitiveArrayCritical( cbdata, NULL); + } + + /* get normal array */ + if (normalsDefined) { + norms = (jfloat *) env->GetPrimitiveArrayCritical(ndata, NULL); + } + + /* get texture arrays */ + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + if (texobjs[i] != NULL) { + texCoordPointer[i] = (jfloat*)env->GetPrimitiveArrayCritical(texobjs[i], NULL); + } else { + texCoordPointer[i] = NULL; + } + + } + } + + + executeGeometryArrayVA(env, obj, ctx, geo, geo_type, + isNonUniformScale, updateAlpha, alpha, + false, ignoreVertexColors, + vcount, vformat, vdefined, initialCoordIndex, + fverts, dverts, initialColorIndex, + fclrs, bclrs, initialNormalIndex, + norms, -1, texCoordMapLength, + tcoordsetmap,texCoordMapLength, NULL, + texindices,texStride,texCoordPointer, + xform, nxform, + javax_media_j3d_GeometryArrayRetained_VERTEX_CHANGED); + + if (floatCoordDefined) { + env->ReleasePrimitiveArrayCritical( vfcoords, fverts, 0); + } + else if (doubleCoordDefined) { + env->ReleasePrimitiveArrayCritical( vdcoords, dverts, 0); + } + + if (floatColorsDefined) { + env->ReleasePrimitiveArrayCritical( cfdata, fclrs, 0); + } + else if (byteColorsDefined) { + env->ReleasePrimitiveArrayCritical( cbdata, bclrs, 0); + } + + if (normalsDefined) { + env->ReleasePrimitiveArrayCritical( ndata, norms, 0); + } + + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + if (texCoordPointer[i] != NULL) { + env->ReleasePrimitiveArrayCritical(texobjs[i], texCoordPointer[i], 0); + } + } + } +} diff --git a/src/native/d3d/GraphicsContext3D.cpp b/src/native/d3d/GraphicsContext3D.cpp new file mode 100644 index 0000000..db89b3d --- /dev/null +++ b/src/native/d3d/GraphicsContext3D.cpp @@ -0,0 +1,150 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include "StdAfx.h" + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_GraphicsContext3D_readRasterNative( + JNIEnv *env, jobject obj, jlong ctx, + jint type, jint xOffset, jint yOffset, + jint wRaster, jint hRaster, jint hCanvas, jint format, + jobject image, jobject depth, jobject gc) +{ + + GetDevice(); + + jclass gc_class = env->GetObjectClass(gc); + jfieldID id; + + if ((type & javax_media_j3d_Raster_RASTER_COLOR) != 0) { + jclass image_class = env->GetObjectClass(image); + + if (image_class == NULL) { + return; + } + + id = env->GetFieldID(gc_class, "byteBuffer","[B"); + jarray byteData_array = (jarray) env->GetObjectField(gc, id); + jbyte *byteData; + + if ((d3dCtx->d3dPresent.SwapEffect == D3DSWAPEFFECT_DISCARD) + // For offScreen rendering, swapBuffer never invoked + // so it is safe to use backBuffer + && (!d3dCtx->offScreen) + // If fail to createFrontBuffer, fallback to use + // backSurface. There is no gaurantee this fallback + // will work, but at least in non-debug DirectX library + // it works. + && ((d3dCtx->frontSurface != NULL) || + (d3dCtx->frontSurface == NULL) && + d3dCtx->createFrontBuffer())) { + + + HRESULT hr = device->GetFrontBuffer(d3dCtx->frontSurface); + if (FAILED(hr)) { + printf("GetFrontBuffer fail %s\n", DXGetErrorString8(hr)); + return; + } + + byteData = (jbyte *) + env->GetPrimitiveArrayCritical(byteData_array, NULL); + + if (!d3dCtx->bFullScreen) { + // We need to invoke GetWindowRect() everytime + // since message resize() will not receive + // when Canvas3D inside browers. + d3dCtx->getScreenRect(d3dCtx->hwnd, &d3dCtx->windowRect); + copyDataFromSurface(format, + xOffset + d3dCtx->windowRect.left, + yOffset + d3dCtx->windowRect.top, + wRaster, + hRaster, + byteData, + d3dCtx->frontSurface); + } else { + copyDataFromSurface(format, xOffset, yOffset, + wRaster, hRaster, byteData, + d3dCtx->frontSurface); + } + } else { + if (d3dCtx->backSurface == NULL) { + HRESULT hr = device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, + &d3dCtx->backSurface); + if (FAILED(hr)) { + printf("GetBackBuffer fail %s\n", DXGetErrorString8(hr)); + return; + } + } + byteData = (jbyte *) + env->GetPrimitiveArrayCritical(byteData_array, NULL); + + copyDataFromSurface(format, xOffset, yOffset, wRaster, + hRaster, byteData, d3dCtx->backSurface); + } + + + + env->ReleasePrimitiveArrayCritical(byteData_array, byteData, 0); + } + + if ((type & javax_media_j3d_Raster_RASTER_DEPTH) != 0) { + jclass depth_class = env->GetObjectClass(depth); + + if (depth_class == NULL) { + return; + } + + id = env->GetFieldID(depth_class, "width", "I"); + int wDepth = env->GetIntField(depth, id); + id = env->GetFieldID(depth_class, "type", "I"); + int depth_type = env->GetIntField(depth, id); + + if (d3dCtx->depthStencilSurface == NULL) { + HRESULT hr = + device->GetDepthStencilSurface(&d3dCtx->depthStencilSurface); + if (FAILED(hr)) { + if (debug) { + printf("[Java3D] Fail to get depth stencil surface %s\n", + DXGetErrorString8(hr)); + } + return; + } + } + + if (depth_type == javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_INT) { + id = env->GetFieldID(gc_class, "intBuffer","[I"); + jarray intData_array = (jarray) env->GetObjectField(gc, id); + jint *intData = (jint *) + env->GetPrimitiveArrayCritical(intData_array, NULL); + + // yOffset is adjusted for OpenGL - Y upward + + copyDepthFromSurface(xOffset, yOffset, wRaster, + hRaster, intData, d3dCtx->depthStencilSurface); + + env->ReleasePrimitiveArrayCritical(intData_array, intData, 0); + + } else { // javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_FLOAT + id = env->GetFieldID(gc_class, "floatBuffer","[F"); + jarray floatData_array = (jarray) env->GetObjectField(gc, id); + jfloat *floatData = (jfloat *) + env->GetPrimitiveArrayCritical(floatData_array, NULL); + + // yOffset is adjusted for OpenGL - Y upward + copyDepthFromSurface(xOffset, yOffset, wRaster, + hRaster, floatData, d3dCtx->depthStencilSurface); + + env->ReleasePrimitiveArrayCritical(floatData_array, + floatData, 0); + } + } +} diff --git a/src/native/d3d/Lights.cpp b/src/native/d3d/Lights.cpp new file mode 100644 index 0000000..f865c6b --- /dev/null +++ b/src/native/d3d/Lights.cpp @@ -0,0 +1,155 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include "StdAfx.h" + + #define D3DLIGHT_RANGE_MAX sqrt(FLT_MAX) + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_DirectionalLightRetained_updateLight( + JNIEnv *env, + jobject light, + jlong ctx, + jint lightSlot, + jfloat red, + jfloat green, + jfloat blue, + jfloat dirx, + jfloat diry, + jfloat dirz) +{ + D3DLIGHT8 d3dLight; + + GetDevice(); + + d3dLight.Type = D3DLIGHT_DIRECTIONAL; + + d3dLight.Direction.x = dirx; + d3dLight.Direction.y = diry; + d3dLight.Direction.z = dirz; + + // Although spec. said this value is ignore, but + // if we don't set it the debug version will fail + // to set directional light + d3dLight.Range = D3DLIGHT_RANGE_MAX; + // D3D will not clamp to range [0, 1] automatically like OGL did + /* + Clamp(red); + Clamp(green); + Clamp(blue); + */ + CopyColor(d3dLight.Diffuse, red, green, blue, 1.0f); + CopyColor(d3dLight.Ambient, 0.0f, 0.0f, 0.0f, 1.0f); + CopyColor(d3dLight.Specular, red, green, blue, 1.0f); + + device->SetLight(lightSlot, &d3dLight); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_PointLightRetained_updateLight( + JNIEnv *env, + jobject light, + jlong ctx, + jint lightSlot, + jfloat red, + jfloat green, + jfloat blue, + jfloat attenx, + jfloat atteny, + jfloat attenz, + jfloat posx, + jfloat posy, + jfloat posz) +{ + D3DLIGHT8 d3dLight; + + GetDevice(); + + d3dLight.Type = D3DLIGHT_POINT; + + d3dLight.Position.x = posx; + d3dLight.Position.y = posy; + d3dLight.Position.z = posz; + /* + Clamp(red); + Clamp(green); + Clamp(blue); + */ + CopyColor(d3dLight.Diffuse, red, green, blue, 1.0f); + CopyColor(d3dLight.Ambient, 0.0f, 0.0f, 0.0f, 1.0f); + CopyColor(d3dLight.Specular, red, green, blue, 1.0f); + + d3dLight.Attenuation0 = attenx; + d3dLight.Attenuation1 = atteny; + d3dLight.Attenuation2 = attenz; + d3dLight.Range = D3DLIGHT_RANGE_MAX; + + device->SetLight(lightSlot, &d3dLight); +} + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_SpotLightRetained_updateLight( + JNIEnv *env, + jobject light, + jlong ctx, + jint lightSlot, + jfloat red, + jfloat green, + jfloat blue, + jfloat attenx, + jfloat atteny, + jfloat attenz, + jfloat posx, + jfloat posy, + jfloat posz, + jfloat spreadAngle, + jfloat concentration, + jfloat dirx, + jfloat diry, + jfloat dirz) +{ + D3DLIGHT8 d3dLight; + + GetDevice(); + + d3dLight.Type = D3DLIGHT_SPOT; + d3dLight.Direction.x = dirx; + d3dLight.Direction.y = diry; + d3dLight.Direction.z = dirz; + d3dLight.Position.x = posx; + d3dLight.Position.y = posy; + d3dLight.Position.z = posz; + /* + Clamp(red); + Clamp(green); + Clamp(blue); + */ + CopyColor(d3dLight.Diffuse, red, green, blue, 1.0f); + CopyColor(d3dLight.Ambient, 0.0f, 0.0f, 0.0f, 1.0f); + CopyColor(d3dLight.Specular, red, green, blue, 1.0f); + + d3dLight.Attenuation0 = attenx; + d3dLight.Attenuation1 = atteny; + d3dLight.Attenuation2 = attenz; + d3dLight.Range = D3DLIGHT_RANGE_MAX; + d3dLight.Theta = 0; + d3dLight.Phi = spreadAngle*2; + if (d3dLight.Phi > PI) { + d3dLight.Phi = PI; + } + d3dLight.Falloff = concentration; + + device->SetLight(lightSlot, &d3dLight); +} + diff --git a/src/native/d3d/NativeAPIInfo.c b/src/native/d3d/NativeAPIInfo.c new file mode 100644 index 0000000..3bc622c --- /dev/null +++ b/src/native/d3d/NativeAPIInfo.c @@ -0,0 +1,23 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include + +#include "javax_media_j3d_MasterControl.h" + + +JNIEXPORT +jint JNICALL Java_javax_media_j3d_NativeAPIInfo_getRenderingAPI( + JNIEnv *env, jobject obj) +{ + return (jint)javax_media_j3d_MasterControl_RENDER_DIRECT3D; +} diff --git a/src/native/d3d/NativeConfigTemplate3D.cpp b/src/native/d3d/NativeConfigTemplate3D.cpp new file mode 100644 index 0000000..e29f018 --- /dev/null +++ b/src/native/d3d/NativeConfigTemplate3D.cpp @@ -0,0 +1,140 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include "StdAfx.h" + + +extern "C" JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isStereoAvailable( + JNIEnv *env, + jobject obj, + jlong ctx, + jlong display, + jint screen, + jint pixelFormat) +{ + // DirectX 8.0 don't support stereo + return false; + +} + +extern "C" JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isDoubleBufferAvailable( + JNIEnv *env, + jobject obj, + jlong ctx, + jlong display, + jint screen, + jint pixelFormat) +{ + // D3D always support double buffer + return true; +} + +extern "C" JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isSceneAntialiasingMultiSamplesAvailable( + JNIEnv *env, + jobject obj, + jlong ctx, + jlong display, + jint screen, + jint pixelFormat) +{ + BOOL antialiasingSupport = false; + + lock(); + if (d3dDriverList == NULL) { + D3dDriverInfo::initialize(env); + } + + if (d3dDriverList != NULL) { + D3dDriverInfo *driverInfo = d3dDriverList[screen]; + for (int i=0; i < numDeviceTypes; i++) { + D3dDeviceInfo *pDeviceInfo = driverInfo->d3dDeviceList[i]; + if (pDeviceInfo->desktopCompatible && + pDeviceInfo->supportAntialiasing()) { + antialiasingSupport = true; + break; + } + } + } + unlock(); + return antialiasingSupport; +} +extern "C" JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isSceneAntialiasingAccumAvailable(JNIEnv *env, + jobject obj, + jlong ctx, + jlong display, + jint screen, + jint pixelFormat) +{ + return JNI_FALSE; +} + +extern "C" JNIEXPORT +jint JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_choosePixelFormat( + JNIEnv *env, + jobject obj, + jlong ctx, + jint screen, + jintArray attrList) +{ + int depth, red, green, blue; + int retValue = -1; + + jint *mx_ptr = (jint *) env->GetPrimitiveArrayCritical(attrList, NULL); + red = mx_ptr[RED_SIZE]; + green = mx_ptr[GREEN_SIZE]; + blue = mx_ptr[BLUE_SIZE]; + depth = mx_ptr[DEPTH_SIZE]; + + env->ReleasePrimitiveArrayCritical(attrList, mx_ptr, 0); + + if (mx_ptr[STEREO] != REQUIRED) { + lock(); + + if (d3dDriverList == NULL) { + D3dDriverInfo::initialize(env); + } + + if (d3dDriverList != NULL) { + BOOL bFullScreen; + D3dDriverInfo *pDriver = d3dDriverList[screen]; + D3dDeviceInfo *deviceInfo = + D3dCtx::setDeviceInfo(pDriver, &bFullScreen, depth); + + if (deviceInfo != NULL) { + if ((depth <= deviceInfo->maxZBufferDepthSize) && + (red <= pDriver->redDepth) && + (green <= pDriver->greenDepth) && + (blue <= pDriver->blueDepth)) { + retValue = depth; + } + } + } + unlock(); + } + + if (mx_ptr[ANTIALIASING] == REQUIRED) { + if (Java_javax_media_j3d_NativeConfigTemplate3D_isSceneAntialiasingMultiSamplesAvailable( + env, obj, ctx, 0, screen, 0) == JNI_TRUE) + { + retValue |= (1 << 31); + } else { + retValue = -1; + } + } + + return retValue; +} + diff --git a/src/native/d3d/NativeWSInfo.cpp b/src/native/d3d/NativeWSInfo.cpp new file mode 100644 index 0000000..2cd0646 --- /dev/null +++ b/src/native/d3d/NativeWSInfo.cpp @@ -0,0 +1,92 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include "StdAfx.h" + + + +#ifdef STRICT +typedef WNDPROC PROC_TYPE; +#else +typedef FARPROC PROC_TYPE; +#endif + + +static PROC_TYPE g_lpDefWindowProcChild; +static long oldWindowHandle = 0; + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_NativeWSInfo_subclass( + JNIEnv * env, + jobject obj, + jint hwnd) +{ + // For some reason, setting the callback before + // setCooperative level will cause setCooperative level + // to hang when start in fullscreen mode + // So we delay it later. +} + +// Handle child move request +static LRESULT CALLBACK canvas3dWndProcChild( + HWND hwnd, + UINT message, + WPARAM wParam, + LPARAM lParam) +{ + /* + switch (message) { + case WM_NCPAINT: + // handle switch mode from 256 back to >= 16 bits color mode + DWORD status; + if (hSema != NULL) { + status = WaitForSingleObject(hSema, 0); + if (status == WAIT_OBJECT_0) { + // This prevent deadlock, otherwise the window event + // thread will hangs if lock already acquired + // during window resize/toggle. + D3dCtx *ctx = findCtx(hwnd); + if (ctx != NULL) { + ctx->retryRestoreSurface = true; + } + unlock(); + } + } + break; + } + */ + return CallWindowProc(g_lpDefWindowProcChild, hwnd, message, + wParam, lParam); +} + + +VOID setWindowCallback(HWND topHwnd, HWND hwnd) +{ + // For some reasons, setting proc for the same handle + // will crash the application. So we work around this + // by checking the old window handle before setting the + // new one. + // long newWindowHandle; + /* + if (oldWindowHandle == 0) { + oldWindowHandle = GetWindowLong((HWND) hwnd, GWL_WNDPROC); + } + + newWindowHandle = GetWindowLong((HWND) hwnd, GWL_WNDPROC); + if (newWindowHandle == oldWindowHandle) { + g_lpDefWindowProcChild = (PROC_TYPE) + SetWindowLong((HWND) hwnd, GWL_WNDPROC, + (LONG) canvas3dWndProcChild); + } + */ +} + diff --git a/src/native/d3d/RasterRetained.cpp b/src/native/d3d/RasterRetained.cpp new file mode 100644 index 0000000..cbe6b7a --- /dev/null +++ b/src/native/d3d/RasterRetained.cpp @@ -0,0 +1,255 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include "StdAfx.h" + +D3dImageComponent RasterList; +D3dImageComponent BackgroundImageList; + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_RasterRetained_execute(JNIEnv *env, + jobject obj, jlong ctx, jobject geo, + jboolean updateAlpha, jfloat alpha, + jint type, jint w_raster, jint h_raster, + jint x_offset, jint y_offset, jfloat x, jfloat y, jfloat z, + jbyteArray imageYdown) +{ + jfieldID id; + int width, height; + int hashCode; + D3DVERTEX worldCoord; + D3DTLVERTEX screenCoord; + + GetDevice(); + + int startx = x_offset; + int starty = y_offset; + int endx = x_offset + w_raster; + int endy = y_offset + h_raster; + + jclass geo_class = env->GetObjectClass(geo); + + if ((type == javax_media_j3d_Raster_RASTER_COLOR) || + (type == javax_media_j3d_Raster_RASTER_COLOR_DEPTH)) { + + int alphaChanged = 0; // used so we can get alpha data from + // JNI before using it so we can use + // GetPrimitiveArrayCritical + + id = env->GetFieldID(geo_class, "image", + "Ljavax/media/j3d/ImageComponent2DRetained;"); + jobject image = env->GetObjectField(geo, id); + + + jclass image_class = env->GetObjectClass(image); + + if (image_class == NULL) { + return; + } + /* + id = env->GetFieldID(image_class, "surfaceDirty", "I"); + if (env->GetIntField(image, id) == NOTLIVE) { + return; + } + */ + id = env->GetFieldID(image_class, "width", "I"); + width = env->GetIntField(image, id); + id = env->GetFieldID(image_class, "height", "I"); + height = env->GetIntField(image, id); + + id = env->GetFieldID(image_class, "hashId", "I"); + hashCode = env->GetIntField(image, id); + + // clipping + if (startx > width) { + startx = width; + } else if (startx < 0) { + startx = 0; + } + if (starty > height) { + starty = height; + } else if (starty < 0) { + starty = 0; + } + if (endx > width) { + endx = width; + } else if (endx < 0) { + endx = 0; + } + if (endy > height) { + endy = height; + } else if (endy < 0) { + endy = 0; + } + + // raster position is upper left corner, default for Java3D + // ImageComponent currently has the data reverse in Y + worldCoord.x = x; + worldCoord.y = y; + worldCoord.z = z; + + lockImage(); + + D3dImageComponent* d3dImage = + D3dImageComponent::find(&RasterList, d3dCtx, hashCode); + + LPDIRECT3DTEXTURE8 surf = NULL ; + + if ((d3dImage == NULL) || (d3dImage->surf == NULL)) { + + surf = createSurfaceFromImage(env, image, ctx, + width, height, imageYdown); + + if (surf == NULL) { + if (d3dImage != NULL) { + D3dImageComponent::remove(&RasterList, d3dImage); + } + unlockImage(); + return; + } + if (d3dImage == NULL) { + d3dImage = D3dImageComponent::add(&RasterList, d3dCtx, hashCode, surf); + + if (d3dImage == NULL) { + return; + } + + } else { + d3dImage->surf = surf; + } + } + + d3dCtx->transform(&worldCoord, &screenCoord); + if ((screenCoord.sz >= 0) && (screenCoord.sz <= 1)) { + screenCoord.sx -= 0.5f; + screenCoord.sy -= 0.5f; + drawTextureRect(d3dCtx, device, d3dImage->surf, screenCoord, + startx, starty, endx, endy, + endx - startx, endy - starty, false); + } + unlockImage(); + + } + + if ((type == javax_media_j3d_Raster_RASTER_DEPTH) || + (type == javax_media_j3d_Raster_RASTER_COLOR_DEPTH)) { + id = env->GetFieldID(geo_class, "depthComponent", + "Ljavax/media/j3d/DepthComponentRetained;"); + + jobject depth = env->GetObjectField(geo, id); + jclass depth_class = env->GetObjectClass(depth); + + if (depth_class == NULL) { + return; + } + id = env->GetFieldID(depth_class, "type", "I"); + int depth_type = env->GetIntField(depth, id); + id = env->GetFieldID(depth_class, "width", "I"); + width = env->GetIntField(depth, id); + id = env->GetFieldID(depth_class, "height", "I"); + height = env->GetIntField(depth, id); + + + + // clipping + if (startx > width) { + startx = width; + } else if (startx < 0) { + startx = 0; + } + if (starty > height) { + starty = height; + } else if (starty < 0) { + starty = 0; + } + if (endx > width) { + endx = width; + } else if (endx < 0) { + endx = 0; + } + if (endy > height) { + endy = height; + } else if (endy < 0) { + endy = 0; + } + + int h = endy - starty; + int w = endx - startx; + + // raster position is upper left corner, default for Java3D + // ImageComponent currently has the data reverse in Y + if ((h > 0) && (w > 0)) { + worldCoord.x = x; + worldCoord.y = y; + worldCoord.z = z; + + d3dCtx->transform(&worldCoord, &screenCoord); + + if (d3dCtx->depthStencilSurface == NULL) { + HRESULT hr = + device->GetDepthStencilSurface(&d3dCtx->depthStencilSurface); + if (FAILED(hr)) { + if (debug) { + printf("[Java3D] Fail to get depth stencil surface %s\n", + DXGetErrorString8(hr)); + } + return; + } + } + + if (depth_type == javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_INT) { + id = env->GetFieldID(depth_class, "depthData","[I"); + jintArray intData_array = (jintArray) env->GetObjectField(depth, id); + jint * intData = (jint *) env->GetPrimitiveArrayCritical( + intData_array, NULL); + copyDepthToSurface(d3dCtx, + device, + screenCoord.sx, + screenCoord.sy, + x_offset, y_offset, + w, h,width, height, + intData, d3dCtx->depthStencilSurface); + env->ReleasePrimitiveArrayCritical(intData_array, + intData, 0); + } else { // javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_FLOAT + + id = env->GetFieldID(depth_class, "depthData","[F"); + jfloatArray floatData_array = (jfloatArray) + env->GetObjectField(depth, id); + + jfloat *floatData = (jfloat *) env->GetPrimitiveArrayCritical( + floatData_array, NULL); + copyDepthToSurface(d3dCtx, + device, + screenCoord.sx, + screenCoord.sy, + x_offset, y_offset, + w, h, width, height, + floatData, d3dCtx->depthStencilSurface); + env->ReleasePrimitiveArrayCritical(floatData_array, + floatData, 0); + } + } + } +} + + + +extern "C" JNIEXPORT +void JNICALL Java_javax_media_j3d_RasterRetained_executeTiled(JNIEnv *env, + jobject obj, jlong ctx, jobject geo, + jint format, jint w_raster, jint h_raster, + jint x_offset, jint y_offset, jint deltaw, jint deltah, + jfloat x, jfloat y, jfloat z, jbyteArray tile) +{ + // This is is not used by both OGL and D3D +} diff --git a/src/native/d3d/StdAfx.h b/src/native/d3d/StdAfx.h new file mode 100644 index 0000000..76a4b00 --- /dev/null +++ b/src/native/d3d/StdAfx.h @@ -0,0 +1,54 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#if !defined(AFX_STDAFX_H) +#define AFX_STDAFX_H + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +// Exclude rarely-used stuff from Windows headers +#define WIN32_LEAN_AND_MEAN + +// Windows Header Files: +#include +#include +#include +#include + +// C RunTime Header Files +#include +#include +#include +#include +#include +#include +#include +#define D3D_OVERLOADS +#include +#include +#include +#include +#include +using namespace std ; + +// Local header file +#include "gldefs.h" +#include "D3dDeviceInfo.hpp" +#include "D3dDriverInfo.hpp" +#include "D3dCtx.hpp" +#include "D3dUtil.hpp" +#include "D3dVertexBuffer.hpp" +#include "D3dDisplayList.hpp" +#include "D3dImageComponent.hpp" +#endif diff --git a/src/native/d3d/build-windows-i586-gcc.xml b/src/native/d3d/build-windows-i586-gcc.xml new file mode 100644 index 0000000..fd4fdf0 --- /dev/null +++ b/src/native/d3d/build-windows-i586-gcc.xml @@ -0,0 +1,17 @@ + + + + + diff --git a/src/native/d3d/build-windows-i586-vc.xml b/src/native/d3d/build-windows-i586-vc.xml new file mode 100644 index 0000000..7836f67 --- /dev/null +++ b/src/native/d3d/build-windows-i586-vc.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/native/ogl/Attributes.c b/src/native/ogl/Attributes.c new file mode 100644 index 0000000..397593e --- /dev/null +++ b/src/native/ogl/Attributes.c @@ -0,0 +1,3505 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include +#include +#include +#include +#include + +#include "gldefs.h" + +#ifdef DEBUG +/* Uncomment the following for VERBOSE debug messages */ +/* #define VERBOSE */ +#endif /* DEBUG */ + + +/* + * Screen door transparency table. + */ +const unsigned int screen_door[17][32] = { +/* 0 / 16 */ + { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + }, +/* 1 / 16 */ + { + 0x00000000, 0x22222222, 0x00000000, 0x00000000, + 0x00000000, 0x22222222, 0x00000000, 0x00000000, + 0x00000000, 0x22222222, 0x00000000, 0x00000000, + 0x00000000, 0x22222222, 0x00000000, 0x00000000, + 0x00000000, 0x22222222, 0x00000000, 0x00000000, + 0x00000000, 0x22222222, 0x00000000, 0x00000000, + 0x00000000, 0x22222222, 0x00000000, 0x00000000, + 0x00000000, 0x22222222, 0x00000000, 0x00000000, + }, +/* 2 / 16 */ + { + 0x00000000, 0x22222222, 0x00000000, 0x88888888, + 0x00000000, 0x22222222, 0x00000000, 0x88888888, + 0x00000000, 0x22222222, 0x00000000, 0x88888888, + 0x00000000, 0x22222222, 0x00000000, 0x88888888, + 0x00000000, 0x22222222, 0x00000000, 0x88888888, + 0x00000000, 0x22222222, 0x00000000, 0x88888888, + 0x00000000, 0x22222222, 0x00000000, 0x88888888, + 0x00000000, 0x22222222, 0x00000000, 0x88888888, + }, +/* 3 / 16 */ + { + 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, + }, +/* 4 / 16 */ + { + 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + }, +/* 5 / 16 */ + { + 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + }, +/* 6 / 16 */ + { + 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + }, +/* 7 / 16 */ + { + 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + }, +/* 8 / 16 */ + { + 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + }, +/* 9 / 16 */ + { + 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + }, +/* 10 / 16 */ + { + 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + }, +/* 11 / 16 */ + { + 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + }, +/* 12 / 16 */ + { + 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, + }, +/* 13 / 16 */ + { + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, + }, +/* 14 / 16 */ + { + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, + }, +/* 15 / 16 */ + { + 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, + }, +/* 16 / 16 */ + { + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + }, +}; + + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_LinearFogRetained_update( + JNIEnv *env, + jobject fog, + jlong ctxInfo, + jfloat red, + jfloat green, + jfloat blue, + jdouble fdist, + jdouble bdist) +{ + + float color[3]; +#ifdef VERBOSE + fprintf(stderr, "LinearFog is on: %f %f %f %f %f\n", + red, green, blue, fdist, bdist); +#endif + + color[0] = red; + color[1] = green; + color[2] = blue; + glFogi(GL_FOG_MODE, GL_LINEAR); + glFogfv(GL_FOG_COLOR, color); + glFogf(GL_FOG_START, (float) fdist); + glFogf(GL_FOG_END, (float) bdist); + glEnable(GL_FOG); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_ExponentialFogRetained_update( + JNIEnv *env, + jobject fog, + jlong ctxInfo, + jfloat red, + jfloat green, + jfloat blue, + jfloat density) +{ + + float color[3]; +#ifdef VERBOSE + fprintf(stderr, "ExponentialFog is on: %f %f %f %f\n", + red, green, blue, density); +#endif + + color[0] = red; + color[1] = green; + color[2] = blue; + glFogi(GL_FOG_MODE, GL_EXP); + glFogfv(GL_FOG_COLOR, color); + glFogf(GL_FOG_DENSITY, density); + glEnable(GL_FOG); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_ModelClipRetained_update( + JNIEnv *env, + jobject modelClip, + jlong ctxInfo, + jint planeNum, + jboolean enableFlag, + jdouble A, + jdouble B, + jdouble C, + jdouble D) +{ + + double equation[4]; + GLenum pl = GL_CLIP_PLANE0 + planeNum; + +#ifdef VERBOSE + fprintf(stderr, "ModelClip is on: %d %d %f %f %f %f\n", + planeNum, enableFlag, A, B, C, D); +#endif + + /* OpenGL clip planes are opposite to J3d clip planes + */ + if (enableFlag) { + equation[0] = -A; + equation[1] = -B; + equation[2] = -C; + equation[3] = -D; + glClipPlane(pl, equation); + glEnable(pl); + } else + glDisable(pl); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setModelViewMatrix( + JNIEnv * env, + jobject obj, + jlong ctxInfo, + jdoubleArray viewMatrix, + jdoubleArray modelMatrix) +{ + jdouble *vmatrix_pointer; + jdouble *mmatrix_pointer; + JNIEnv table = *env; + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + vmatrix_pointer = (jdouble *)(*(table->GetPrimitiveArrayCritical))(env, + viewMatrix , NULL); + mmatrix_pointer = (jdouble *)(*(table->GetPrimitiveArrayCritical))(env, + modelMatrix , NULL); + + + glMatrixMode(GL_MODELVIEW); + + + if (ctxProperties->arb_transpose_matrix) { + ctxProperties->glLoadTransposeMatrixdARB(vmatrix_pointer); + ctxProperties->glMultTransposeMatrixdARB(mmatrix_pointer); + } else { + double v[16]; + double m[16]; + + COPY_TRANSPOSE(vmatrix_pointer, v); + COPY_TRANSPOSE(mmatrix_pointer, m); + + glLoadMatrixd(v); + glMultMatrixd(m); +#ifdef VERBOSE + fprintf(stderr, "\n"); + fprintf(stderr, "Canvas3D.setModelViewMatrix()\n"); + fprintf(stderr, "-----------------------------\n"); + fprintf(stderr, "VIEW : %f %f %f %f\n", v[0], v[4], v[8], v[12]); + fprintf(stderr, " : %f %f %f %f\n", v[1], v[5], v[9], v[13]); + fprintf(stderr, " : %f %f %f %f\n", v[2], v[6], v[10], v[14]); + fprintf(stderr, " : %f %f %f %f\n", v[3], v[7], v[11], v[15]); + fprintf(stderr, "\n"); + fprintf(stderr, "MODEL : %f %f %f %f\n", m[0], m[4], m[8], m[12]); + fprintf(stderr, " : %f %f %f %f\n", m[1], m[5], m[9], m[13]); + fprintf(stderr, " : %f %f %f %f\n", m[2], m[6], m[10], m[14]); + fprintf(stderr, " : %f %f %f %f\n", m[3], m[7], m[11], m[15]); + fprintf(stderr, "\n\n"); +#endif + } + (*(table->ReleasePrimitiveArrayCritical))(env, viewMatrix, + vmatrix_pointer, 0); + (*(table->ReleasePrimitiveArrayCritical))(env, modelMatrix, + mmatrix_pointer, 0); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setProjectionMatrix( + JNIEnv * env, + jobject obj, + jlong ctxInfo, + jdoubleArray projMatrix) +{ + jdouble *matrix_pointer; + JNIEnv table = *env; + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + matrix_pointer = (jdouble *)(*(table->GetPrimitiveArrayCritical))(env, + projMatrix, NULL); + + glMatrixMode(GL_PROJECTION); + + if (ctxProperties->arb_transpose_matrix) { + /* + * Invert the Z value in clipping coordinates because OpenGL uses + * left-handed clipping coordinates, while Java3D defines right-handed + * coordinates everywhere. + */ + matrix_pointer[8] *= -1.0; + matrix_pointer[9] *= -1.0; + matrix_pointer[10] *= -1.0; + matrix_pointer[11] *= -1.0; + ctxProperties->glLoadTransposeMatrixdARB(matrix_pointer); + matrix_pointer[8] *= -1.0; + matrix_pointer[9] *= -1.0; + matrix_pointer[10] *= -1.0; + matrix_pointer[11] *= -1.0; + } else { + double p[16]; + + COPY_TRANSPOSE(matrix_pointer, p); + /* + * Invert the Z value in clipping coordinates because OpenGL uses + * left-handed clipping coordinates, while Java3D defines right-handed + * coordinates everywhere. + */ + p[2] *= -1.0; + p[6] *= -1.0; + p[10] *= -1.0; + p[14] *= -1.0; + + glLoadMatrixd(p); +#ifdef VERBOSE + fprintf(stderr, "\n"); + fprintf(stderr, "Canvas3D.setProjectionMatrix()\n"); + fprintf(stderr, "------------------------------\n"); + fprintf(stderr, "PROJECTION : %f %f %f %f\n", p[0], p[4], p[8], p[12]); + fprintf(stderr, " : %f %f %f %f\n", p[1], p[5], p[9], p[13]); + fprintf(stderr, " : %f %f %f %f\n", p[2], p[6], p[10], p[14]); + fprintf(stderr, " : %f %f %f %f\n", p[3], p[7], p[11], p[15]); + fprintf(stderr, "\n\n"); +#endif + + } + + (*(table->ReleasePrimitiveArrayCritical))(env, projMatrix, + matrix_pointer, 0); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setViewport( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jint x, + jint y, + jint width, + jint height) +{ + + glViewport(x, y, width, height); +} + +#ifdef WIN32 +#define M_PI 3.14159265358979323846 +#endif + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setSceneAmbient( + JNIEnv *env, + jobject cv, + jlong ctxInfo, + jfloat red, + jfloat green, + jfloat blue) +{ + float color[4]; + + color[0] = red; + color[1] = green; + color[2] = blue; + color[3] = 1.0f; + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, color); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setLightEnables( + JNIEnv *env, + jobject cv, + jlong ctxInfo, + jlong enable_mask, + jint nlights) +{ + int i; + +#ifdef VERBOSE + fprintf(stderr, "Canvas3D.updateLightEnables: mask = 0x%x, 0x%x\n", + (int) ((enable_mask >> 32) & 0xffffffff), + (int) (enable_mask & 0xffffffff)); +#endif + + for (i=0; iGetPrimitiveArrayCritical))(env, + vworldToEc, NULL); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + if (ctxProperties->arb_transpose_matrix) { + ctxProperties->glLoadTransposeMatrixdARB(mat); + } else { + jdouble v[16]; + COPY_TRANSPOSE(mat, v); + glLoadMatrixd(v); + } + + (*(table->ReleasePrimitiveArrayCritical))(env, vworldToEc, + mat, 0); + + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGenfv(GL_S, GL_EYE_PLANE, planeS); + glTexGenfv(GL_T, GL_EYE_PLANE, planeT); + + if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_3) { + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGenfv(GL_R, GL_EYE_PLANE, planeR); + } else if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_4) { + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGenfv(GL_R, GL_EYE_PLANE, planeR); + glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGenfv(GL_Q, GL_EYE_PLANE, planeQ); + } + glPopMatrix(); + break; + case javax_media_j3d_TexCoordGeneration_SPHERE_MAP: + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_3) { + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + } else if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_4) { + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + } + + break; + case javax_media_j3d_TexCoordGeneration_NORMAL_MAP: + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT); + if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_3) { + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT); + } else if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_4) { + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT); + glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT); + } + break; + case javax_media_j3d_TexCoordGeneration_REFLECTION_MAP: + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT); + if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_3) { + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT); + } else if (format == javax_media_j3d_TexCoordGeneration_TEXTURE_COORDINATE_4) { + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT); + glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT); + } + break; + } + } else { + glDisable(GL_TEXTURE_GEN_S); + glDisable(GL_TEXTURE_GEN_T); + glDisable(GL_TEXTURE_GEN_R); + glDisable(GL_TEXTURE_GEN_Q); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_resetTextureAttributes( + JNIEnv *env, + jobject cv, + jlong ctxInfo) +{ + float color[] = {0.0, 0.0, 0.0, 0.0}; + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + glPushAttrib(GL_MATRIX_MODE); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glPopAttrib(); + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + + if(ctxProperties->textureRegisterCombinersAvailable) + glDisable(GL_REGISTER_COMBINERS_NV); + + if(ctxProperties->textureColorTableAvailable) + glDisable(GL_TEXTURE_COLOR_TABLE_SGI); + /* GL_SGI_texture_color_table */ +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureAttributesRetained_updateNative( + JNIEnv *env, + jobject cv, + jlong ctxInfo, + jdoubleArray transform, + jboolean isIdentity, + jint textureMode, + jint perspCorrectionMode, + jfloat textureBlendColorRed, + jfloat textureBlendColorGreen, + jfloat textureBlendColorBlue, + jfloat textureBlendColorAlpha, + jint textureFormat) +{ + jdouble *mx_ptr; + float color[4]; + JNIEnv table = *env; + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if (perspCorrectionMode == javax_media_j3d_TextureAttributes_NICEST) { + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + } else { + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); + } + + /* set OGL texture matrix */ + glPushAttrib(GL_MATRIX_MODE); + glMatrixMode(GL_TEXTURE); + + mx_ptr = (jdouble *)(*(table->GetPrimitiveArrayCritical))(env, transform, + NULL); + if (isIdentity) { + glLoadIdentity(); + } else if (ctxProperties->arb_transpose_matrix) { + ctxProperties->glLoadTransposeMatrixdARB(mx_ptr); + } else { + double mx[16]; + COPY_TRANSPOSE(mx_ptr, mx); + glLoadMatrixd(mx); + } + + (*(table->ReleasePrimitiveArrayCritical))(env, transform, mx_ptr, 0); + + glPopAttrib(); + + /* set texture color */ + color[0] = textureBlendColorRed; + color[1] = textureBlendColorGreen; + color[2] = textureBlendColorBlue; + color[3] = textureBlendColorAlpha; + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color); + + /* set texture environment mode */ + + switch (textureMode) { + case javax_media_j3d_TextureAttributes_MODULATE: + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + break; + case javax_media_j3d_TextureAttributes_DECAL: + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + break; + case javax_media_j3d_TextureAttributes_BLEND: + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); + break; + case javax_media_j3d_TextureAttributes_REPLACE: + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + break; + case javax_media_j3d_TextureAttributes_COMBINE: + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, + ctxProperties->combine_enum); + break; + } + + if(ctxProperties->textureColorTableAvailable) + glDisable(GL_TEXTURE_COLOR_TABLE_SGI); + /* GL_SGI_texture_color_table */ +} + +GLenum getCombinerArg(jint arg, GLenum textureUnit, GLenum combUnit) { + GLenum comb; + + switch (arg) { + case javax_media_j3d_TextureAttributes_COMBINE_OBJECT_COLOR: + if (combUnit == GL_COMBINER0_NV) { + comb = GL_PRIMARY_COLOR_NV; + } else { + comb = GL_SPARE0_NV; + } + break; + case javax_media_j3d_TextureAttributes_COMBINE_TEXTURE_COLOR: + comb = textureUnit; + break; + case javax_media_j3d_TextureAttributes_COMBINE_CONSTANT_COLOR: + comb = GL_CONSTANT_COLOR0_NV; + break; + case javax_media_j3d_TextureAttributes_COMBINE_PREVIOUS_TEXTURE_UNIT_STATE: + comb = textureUnit -1; + break; + } + + return (comb); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureAttributesRetained_updateNativeRegisterCombiners( + JNIEnv *env, + jobject cv, + jlong ctxInfo, + jdoubleArray transform, + jboolean isIdentity, + jint textureMode, + jint perspCorrectionMode, + jfloat textureBlendColorRed, + jfloat textureBlendColorGreen, + jfloat textureBlendColorBlue, + jfloat textureBlendColorAlpha, + jint textureFormat, + jint combineRgbMode, + jint combineAlphaMode, + jintArray combineRgbSrc, + jintArray combineAlphaSrc, + jintArray combineRgbFcn, + jintArray combineAlphaFcn, + jint combineRgbScale, + jint combineAlphaScale) +{ + jdouble *mx_ptr; + float color[4]; + JNIEnv table = *env; + GLenum textureUnit; + GLenum combinerUnit; + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jint * rgbSrc; + GLenum color1, color2; + GLenum fragment; + + if (perspCorrectionMode == javax_media_j3d_TextureAttributes_NICEST) { + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + } else { + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); + } + + /* set OGL texture matrix */ + glPushAttrib(GL_MATRIX_MODE); + glMatrixMode(GL_TEXTURE); + + mx_ptr = (jdouble *)(*(table->GetPrimitiveArrayCritical))(env, transform, + NULL); + if (isIdentity) { + glLoadIdentity(); + } else if (ctxProperties->arb_transpose_matrix) { + ctxProperties->glLoadTransposeMatrixdARB(mx_ptr); + } else { + double mx[16]; + COPY_TRANSPOSE(mx_ptr, mx); + glLoadMatrixd(mx); + } + + (*(table->ReleasePrimitiveArrayCritical))(env, transform, mx_ptr, 0); + + glPopAttrib(); + + /* set texture color */ + color[0] = textureBlendColorRed; + color[1] = textureBlendColorGreen; + color[2] = textureBlendColorBlue; + color[3] = textureBlendColorAlpha; + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color); + + /* set texture environment mode */ + glEnable(GL_REGISTER_COMBINERS_NV); + textureUnit = ctxProperties->currentTextureUnit; + combinerUnit = ctxProperties->currentCombinerUnit; + if (combinerUnit == GL_COMBINER0_NV) { + fragment = GL_PRIMARY_COLOR_NV; + } else { + fragment = GL_SPARE0_NV; + } + + switch (textureMode) { + case javax_media_j3d_TextureAttributes_MODULATE: + + ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB, + GL_VARIABLE_A_NV, fragment, + GL_UNSIGNED_IDENTITY_NV, GL_RGB); + ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB, + GL_VARIABLE_B_NV, textureUnit, + GL_UNSIGNED_IDENTITY_NV, GL_RGB); + ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA, + GL_VARIABLE_A_NV, fragment, + GL_UNSIGNED_IDENTITY_NV, GL_ALPHA); + ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA, + GL_VARIABLE_B_NV, textureUnit, + GL_UNSIGNED_IDENTITY_NV, GL_ALPHA); + + ctxProperties->glCombinerOutputNV(combinerUnit, GL_RGB, + GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE); + ctxProperties->glCombinerOutputNV(combinerUnit, GL_ALPHA, + GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE); + break; + + case javax_media_j3d_TextureAttributes_DECAL: + + ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB, + GL_VARIABLE_A_NV, fragment, + GL_UNSIGNED_IDENTITY_NV, GL_RGB); + ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB, + GL_VARIABLE_B_NV, textureUnit, + GL_UNSIGNED_INVERT_NV, GL_ALPHA); + ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB, + GL_VARIABLE_C_NV, textureUnit, + GL_UNSIGNED_IDENTITY_NV, GL_RGB); + ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB, + GL_VARIABLE_D_NV, textureUnit, + GL_UNSIGNED_IDENTITY_NV, GL_ALPHA); + + ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA, + GL_VARIABLE_A_NV, fragment, + GL_UNSIGNED_IDENTITY_NV, GL_ALPHA); + ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA, + GL_VARIABLE_B_NV, GL_ZERO, + GL_UNSIGNED_INVERT_NV, GL_ALPHA); + + ctxProperties->glCombinerOutputNV(combinerUnit, GL_RGB, + GL_DISCARD_NV, GL_DISCARD_NV, GL_SPARE0_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE); + ctxProperties->glCombinerOutputNV(combinerUnit, GL_ALPHA, + GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE); + break; + + case javax_media_j3d_TextureAttributes_BLEND: + + ctxProperties->glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, color); + + ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB, + GL_VARIABLE_A_NV, fragment, + GL_UNSIGNED_IDENTITY_NV, GL_RGB); + ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB, + GL_VARIABLE_B_NV, textureUnit, + GL_UNSIGNED_INVERT_NV, GL_RGB); + ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB, + GL_VARIABLE_C_NV, GL_CONSTANT_COLOR0_NV, + GL_UNSIGNED_IDENTITY_NV, GL_RGB); + ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB, + GL_VARIABLE_D_NV, textureUnit, + GL_UNSIGNED_IDENTITY_NV, GL_RGB); + + ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA, + GL_VARIABLE_A_NV, fragment, + GL_UNSIGNED_IDENTITY_NV, GL_ALPHA); + ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA, + GL_VARIABLE_B_NV, textureUnit, + GL_UNSIGNED_IDENTITY_NV, GL_ALPHA); + + ctxProperties->glCombinerOutputNV(combinerUnit, GL_RGB, + GL_DISCARD_NV, GL_DISCARD_NV, GL_SPARE0_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE); + ctxProperties->glCombinerOutputNV(combinerUnit, GL_ALPHA, + GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE); + break; + + case javax_media_j3d_TextureAttributes_REPLACE: + + ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB, + GL_VARIABLE_A_NV, textureUnit, + GL_UNSIGNED_IDENTITY_NV, GL_RGB); + ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB, + GL_VARIABLE_B_NV, GL_ZERO, + GL_UNSIGNED_INVERT_NV, GL_RGB); + ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA, + GL_VARIABLE_A_NV, textureUnit, + GL_UNSIGNED_IDENTITY_NV, GL_ALPHA); + ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA, + GL_VARIABLE_B_NV, GL_ZERO, + GL_UNSIGNED_INVERT_NV, GL_ALPHA); + + ctxProperties->glCombinerOutputNV(combinerUnit, GL_RGB, + GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE); + ctxProperties->glCombinerOutputNV(combinerUnit, GL_ALPHA, + GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE); + break; + + case javax_media_j3d_TextureAttributes_COMBINE: + if (combineRgbMode == + javax_media_j3d_TextureAttributes_COMBINE_DOT3) { + rgbSrc = (jint *)(*(table->GetPrimitiveArrayCritical))( + env, combineRgbSrc, NULL); + color1 = getCombinerArg(rgbSrc[0], textureUnit, combinerUnit); + ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB, + GL_VARIABLE_A_NV, color1, + GL_EXPAND_NORMAL_NV, GL_RGB); + color2 = getCombinerArg(rgbSrc[1], textureUnit, combinerUnit); + ctxProperties->glCombinerInputNV(combinerUnit, GL_RGB, + GL_VARIABLE_B_NV, color2, + GL_EXPAND_NORMAL_NV, GL_RGB); + (*(table->ReleasePrimitiveArrayCritical))(env, combineRgbSrc, + rgbSrc, 0); + ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA, + GL_VARIABLE_A_NV, GL_ZERO, + GL_UNSIGNED_INVERT_NV, GL_ALPHA); + ctxProperties->glCombinerInputNV(combinerUnit, GL_ALPHA, + GL_VARIABLE_B_NV, GL_ZERO, + GL_UNSIGNED_INVERT_NV, GL_ALPHA); + + ctxProperties->glCombinerOutputNV(combinerUnit, GL_RGB, + GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE/*SCALE_BY_FOUR_NV*/, GL_NONE, GL_TRUE, + GL_FALSE, GL_FALSE); + ctxProperties->glCombinerOutputNV(combinerUnit, GL_ALPHA, + GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, + GL_NONE, GL_NONE, GL_FALSE, + GL_FALSE, GL_FALSE); + } + break; + } + + + ctxProperties->glFinalCombinerInputNV(GL_VARIABLE_A_NV, + GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB); + ctxProperties->glFinalCombinerInputNV(GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); + ctxProperties->glFinalCombinerInputNV(GL_VARIABLE_C_NV, + GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB); + ctxProperties->glFinalCombinerInputNV(GL_VARIABLE_D_NV, + GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB); + ctxProperties->glFinalCombinerInputNV(GL_VARIABLE_E_NV, + GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB); + ctxProperties->glFinalCombinerInputNV(GL_VARIABLE_F_NV, + GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB); + ctxProperties->glFinalCombinerInputNV(GL_VARIABLE_G_NV, + GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA); + + if(ctxProperties->textureColorTableAvailable) + glDisable(GL_TEXTURE_COLOR_TABLE_SGI); + /* GL_SGI_texture_color_table */ +} + +void getGLCombineMode(GraphicsContextPropertiesInfo *ctxInfo, + jint combineRgbMode, jint combineAlphaMode, + jint *GLrgbMode, jint *GLalphaMode) { + + switch (combineRgbMode) { + case javax_media_j3d_TextureAttributes_COMBINE_REPLACE: + *GLrgbMode = GL_REPLACE; + break; + case javax_media_j3d_TextureAttributes_COMBINE_MODULATE: + *GLrgbMode = GL_MODULATE; + break; + case javax_media_j3d_TextureAttributes_COMBINE_ADD: + *GLrgbMode = GL_ADD; + break; + case javax_media_j3d_TextureAttributes_COMBINE_ADD_SIGNED: + *GLrgbMode = ctxInfo->combine_add_signed_enum; + break; + case javax_media_j3d_TextureAttributes_COMBINE_SUBTRACT: + *GLrgbMode = ctxInfo->combine_subtract_enum; + break; + case javax_media_j3d_TextureAttributes_COMBINE_INTERPOLATE: + *GLrgbMode = ctxInfo->combine_interpolate_enum; + break; + case javax_media_j3d_TextureAttributes_COMBINE_DOT3: + *GLrgbMode = ctxInfo->combine_dot3_rgb_enum; + break; + default: + break; + } + + switch (combineAlphaMode) { + case javax_media_j3d_TextureAttributes_COMBINE_REPLACE: + *GLalphaMode = GL_REPLACE; + break; + case javax_media_j3d_TextureAttributes_COMBINE_MODULATE: + *GLalphaMode = GL_MODULATE; + break; + case javax_media_j3d_TextureAttributes_COMBINE_ADD: + *GLalphaMode = GL_ADD; + break; + case javax_media_j3d_TextureAttributes_COMBINE_ADD_SIGNED: + *GLalphaMode = ctxInfo->combine_add_signed_enum; + break; + case javax_media_j3d_TextureAttributes_COMBINE_SUBTRACT: + *GLalphaMode = ctxInfo->combine_subtract_enum; + break; + case javax_media_j3d_TextureAttributes_COMBINE_INTERPOLATE: + *GLalphaMode = ctxInfo->combine_interpolate_enum; + break; + case javax_media_j3d_TextureAttributes_COMBINE_DOT3: + /* dot3 will only make sense for alpha if rgb is also + doing dot3. So if rgb is not doing dot3, fallback to replace + */ + if (combineRgbMode == javax_media_j3d_TextureAttributes_COMBINE_DOT3) { + *GLrgbMode = ctxInfo->combine_dot3_rgba_enum; + } else { + *GLalphaMode = GL_REPLACE; + } + break; + default: + break; + } + + return; +} + +/* mapping from java enum to gl enum + */ + +jint _gl_combineRgbSrcIndex[] = { + GL_SOURCE0_RGB_ARB, + GL_SOURCE1_RGB_ARB, + GL_SOURCE2_RGB_ARB, +}; + +jint _gl_combineAlphaSrcIndex[] = { + GL_SOURCE0_ALPHA_ARB, + GL_SOURCE1_ALPHA_ARB, + GL_SOURCE2_ALPHA_ARB, +}; + +jint _gl_combineRgbOpIndex[] = { + GL_OPERAND0_RGB_ARB, + GL_OPERAND1_RGB_ARB, + GL_OPERAND2_RGB_ARB, +}; + +jint _gl_combineAlphaOpIndex[] = { + GL_OPERAND0_ALPHA_ARB, + GL_OPERAND1_ALPHA_ARB, + GL_OPERAND2_ALPHA_ARB, +}; + +jint _gl_combineSrc[] = { + GL_PRIMARY_COLOR_ARB, /* TextureAttributes.COMBINE_OBJECT_COLOR */ + GL_TEXTURE, /* TextureAttributes.COMBINE_TEXTURE */ + GL_CONSTANT_ARB, /* TextureAttributes.COMBINE_CONSTANT_COLOR */ + GL_PREVIOUS_ARB, /* TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE */ +}; + +jint _gl_combineFcn[] = { + GL_SRC_COLOR, /* TextureAttributes.COMBINE_SRC_COLOR */ + GL_ONE_MINUS_SRC_COLOR, /* TextureAttributes.COMBINE_ONE_MINUS_SRC_COLOR */ + GL_SRC_ALPHA, /* TextureAttributes.COMBINE_SRC_ALPHA */ + GL_ONE_MINUS_SRC_ALPHA, /* TextureAttributes.COMBINE_ONE_MINUS_SRC_ALPHA */ +}; + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureAttributesRetained_updateCombinerNative( + JNIEnv *env, + jobject cv, + jlong ctxProperties, + jint combineRgbMode, + jint combineAlphaMode, + jintArray combineRgbSrc, + jintArray combineAlphaSrc, + jintArray combineRgbFcn, + jintArray combineAlphaFcn, + jint combineRgbScale, + jint combineAlphaScale) { + + + JNIEnv table = *env; + GraphicsContextPropertiesInfo *ctxInfo = + (GraphicsContextPropertiesInfo *)ctxProperties; + jint *rgbSrc, *alphaSrc, *rgbFcn, *alphaFcn; + jint GLrgbMode, GLalphaMode; + jint nargs, i; + + rgbSrc = (jint *)(*(table->GetPrimitiveArrayCritical))( + env, combineRgbSrc, NULL); + alphaSrc = (jint *)(*(table->GetPrimitiveArrayCritical))( + env, combineAlphaSrc, NULL); + rgbFcn = (jint *)(*(table->GetPrimitiveArrayCritical))( + env, combineRgbFcn, NULL); + alphaFcn = (jint *)(*(table->GetPrimitiveArrayCritical))( + env, combineAlphaFcn, NULL); + + getGLCombineMode(ctxInfo, combineRgbMode, combineAlphaMode, + &GLrgbMode, &GLalphaMode); + + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GLrgbMode); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GLalphaMode); + + if (combineRgbMode == javax_media_j3d_TextureAttributes_COMBINE_REPLACE) { + nargs = 1; + } else if (combineRgbMode == javax_media_j3d_TextureAttributes_COMBINE_INTERPOLATE) { + nargs = 3; + } else { + nargs = 2; + } + + for (i = 0; i < nargs; i++) { + glTexEnvi(GL_TEXTURE_ENV, _gl_combineRgbSrcIndex[i], + _gl_combineSrc[rgbSrc[i]]); + glTexEnvi(GL_TEXTURE_ENV, _gl_combineRgbOpIndex[i], + _gl_combineFcn[rgbFcn[i]]); + } + + if (combineAlphaMode == javax_media_j3d_TextureAttributes_COMBINE_REPLACE) { + nargs = 1; + } else if (combineAlphaMode == javax_media_j3d_TextureAttributes_COMBINE_INTERPOLATE) { + nargs = 3; + } else { + nargs = 2; + } + + for (i = 0; i < nargs; i++) { + glTexEnvi(GL_TEXTURE_ENV, _gl_combineAlphaSrcIndex[i], + _gl_combineSrc[alphaSrc[i]]); + glTexEnvi(GL_TEXTURE_ENV, _gl_combineAlphaOpIndex[i], + _gl_combineFcn[alphaFcn[i]]); + } + + glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, combineRgbScale); + glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, combineAlphaScale); + + (*(table->ReleasePrimitiveArrayCritical))(env, combineRgbSrc, rgbSrc, 0); + (*(table->ReleasePrimitiveArrayCritical))(env, combineAlphaSrc, alphaSrc, 0); + (*(table->ReleasePrimitiveArrayCritical))(env, combineRgbFcn, rgbFcn, 0); + (*(table->ReleasePrimitiveArrayCritical))(env, combineAlphaFcn, alphaFcn, 0); + +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureAttributesRetained_updateTextureColorTableNative( + JNIEnv *env, + jobject cv, + jlong ctxInfo, + jint numComponents, + jint colorTableSize, + jintArray textureColorTable) +{ + JNIEnv table = *env; + jint *ctable; + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if(ctxProperties->textureColorTableAvailable) { + ctable = (jint *)(*(table->GetPrimitiveArrayCritical))(env, + textureColorTable, NULL); + if (numComponents == 3) { + ctxProperties->glColorTable(GL_TEXTURE_COLOR_TABLE_SGI, GL_RGB, + colorTableSize, GL_RGB, GL_INT, ctable); + } else { + ctxProperties->glColorTable(GL_TEXTURE_COLOR_TABLE_SGI, GL_RGBA, + colorTableSize, GL_RGBA, GL_INT, ctable); + } + + (*(table->ReleasePrimitiveArrayCritical))(env, textureColorTable, ctable, 0); + glEnable(GL_TEXTURE_COLOR_TABLE_SGI); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_updateMaterial( + JNIEnv *env, + jobject cv, + jlong ctxInfo, + jfloat colorRed, + jfloat colorGreen, + jfloat colorBlue, + jfloat transparency) +{ + float color[4]; + + color[0] = colorRed; + color[1] = colorGreen; + color[2] = colorBlue; + color[3] = transparency; + glColor4fv(color); + glDisable(GL_LIGHTING); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_MaterialRetained_updateNative( + JNIEnv *env, + jobject cv, + jlong ctxInfo, + jfloat colorRed, + jfloat colorGreen, + jfloat colorBlue, + jfloat transparency, + jfloat aRed, + jfloat aGreen, + jfloat aBlue, + jfloat eRed, + jfloat eGreen, + jfloat eBlue, + jfloat dRed, + jfloat dGreen, + jfloat dBlue, + jfloat sRed, + jfloat sGreen, + jfloat sBlue, + jfloat shininess, + jint colorTarget, + jboolean lightEnable) +{ + float color[4]; + + color[3] = 1.0f; + glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &shininess); + if (colorTarget == javax_media_j3d_Material_DIFFUSE) { + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + } + else if (colorTarget == javax_media_j3d_Material_AMBIENT) { + glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT); + } + else if (colorTarget == javax_media_j3d_Material_EMISSIVE) { + glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION); + } + else if (colorTarget == javax_media_j3d_Material_SPECULAR) { + glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); + } + else if (colorTarget == javax_media_j3d_Material_AMBIENT_AND_DIFFUSE) { + glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); + } + + color[0] = eRed; color[1] = eGreen; color[2] = eBlue; + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color); + + color[0] = aRed; color[1] = aGreen; color[2] = aBlue; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); + + color[0] = sRed; color[1] = sGreen; color[2] = sBlue; + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color); + + if (lightEnable == JNI_TRUE) { + color[0] = dRed; color[1] = dGreen; color[2] = dBlue; + } else { + color[0] = colorRed; color[1] = colorGreen; color[2] = colorBlue; + } + color[3] = transparency; + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); + glColor4fv(color); + + if (lightEnable) { + glEnable(GL_LIGHTING); + } else { + glDisable(GL_LIGHTING); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_resetTransparency( + JNIEnv *env, + jobject cv, + jlong ctxInfo, + jint geometryType, + jint polygonMode, + jboolean lineAA, + jboolean pointAA) +{ + if (((((geometryType & javax_media_j3d_RenderMolecule_LINE) != 0) || + (polygonMode == javax_media_j3d_PolygonAttributes_POLYGON_LINE)) + && lineAA == JNI_TRUE) || + ((((geometryType & javax_media_j3d_RenderMolecule_POINT) != 0) || + (polygonMode == javax_media_j3d_PolygonAttributes_POLYGON_POINT)) + && pointAA == JNI_TRUE)) { + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } else { + glDisable (GL_BLEND); + } + glDisable(GL_POLYGON_STIPPLE); + +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TransparencyAttributesRetained_updateNative( + JNIEnv *env, + jobject tr, + jlong ctxInfo, + jfloat transparency, + jint geometryType, + jint polygonMode, + jboolean lineAA, + jboolean pointAA, + jint transparencyMode, + jint srcBlendFunction, + jint dstBlendFunction) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if (transparencyMode != javax_media_j3d_TransparencyAttributes_SCREEN_DOOR) { + glDisable(GL_POLYGON_STIPPLE); + } else { + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple((GLubyte *)(screen_door[(int)((transparency)*16)])); + } + + if ((transparencyMode < javax_media_j3d_TransparencyAttributes_SCREEN_DOOR) || + ((((geometryType & javax_media_j3d_RenderMolecule_LINE) != 0) || + (polygonMode == javax_media_j3d_PolygonAttributes_POLYGON_LINE)) + && lineAA == JNI_TRUE) || + ((((geometryType & javax_media_j3d_RenderMolecule_POINT) != 0) || + (polygonMode == javax_media_j3d_PolygonAttributes_POLYGON_POINT)) + && pointAA == JNI_TRUE)) { + glEnable (GL_BLEND); + /* valid range of blendFunction 0..3 is already verify in Java code. */ + glBlendFunc(ctxProperties->blendFunctionTable[srcBlendFunction], + ctxProperties->blendFunctionTable[dstBlendFunction]); + } else { + glDisable (GL_BLEND); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_resetColoringAttributes( + JNIEnv *env, + jobject cv, + jlong ctxInfo, + jfloat colorRed, + jfloat colorGreen, + jfloat colorBlue, + jfloat transparency, + jboolean lightEnable) +{ + + float color[4]; + + if (lightEnable != JNI_TRUE) { + color[0] = colorRed; color[1] = colorGreen; color[2] = colorBlue; + color[3] = transparency; + glColor4fv(color); + + } + glShadeModel(GL_SMOOTH); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_ColoringAttributesRetained_updateNative( + JNIEnv *env, + jobject cv, + jlong ctxInfo, + jfloat dRed, + jfloat dGreen, + jfloat dBlue, + jfloat colorRed, + jfloat colorGreen, + jfloat colorBlue, + jfloat transparency, + jboolean lightEnable, + jint shadeModel) +{ + + float color[4]; + + if (lightEnable == JNI_TRUE) { + color[0] = dRed; color[1] = dGreen; color[2] = dBlue; + } else { + color[0] = colorRed; color[1] = colorGreen; color[2] = colorBlue; + } + color[3] = transparency; + + glColor4fv(color); + if (shadeModel == javax_media_j3d_ColoringAttributes_SHADE_FLAT) { + glShadeModel(GL_FLAT); + } else { + glShadeModel(GL_SMOOTH); + } +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_resetTextureNative( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint texUnitIndex) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if(ctxProperties->arb_multitexture) { + + if (texUnitIndex >= 0) { + ctxProperties->glActiveTextureARB(texUnitIndex + GL_TEXTURE0_ARB); + ctxProperties->glClientActiveTextureARB(texUnitIndex + GL_TEXTURE0_ARB); + } + } + + glDisable(GL_TEXTURE_1D); + glDisable(GL_TEXTURE_2D); + + if(ctxProperties->texture3DAvailable) { + glDisable(ctxProperties->texture_3D_ext_enum); + } + + if(ctxProperties->textureCubeMapAvailable) { + glDisable(ctxProperties->texture_cube_map_ext_enum); + } +} + + +/* + * A set of common updateTexture functions shared among Texture2D, Texture3D, + * and TextureCubeMap for setting texture parameters + */ +void updateTextureFilterModes( + GraphicsContextPropertiesInfo *ctxProperties, + jint target, + jint minFilter, + jint magFilter) { + + /* set texture min filter */ + switch(minFilter) { + case javax_media_j3d_Texture_FASTEST: + case javax_media_j3d_Texture_BASE_LEVEL_POINT: + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + break; + case javax_media_j3d_Texture_BASE_LEVEL_LINEAR: + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + break; + case javax_media_j3d_Texture_MULTI_LEVEL_POINT: + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, + GL_NEAREST_MIPMAP_NEAREST); + break; + case javax_media_j3d_Texture_NICEST: + case javax_media_j3d_Texture_MULTI_LEVEL_LINEAR: + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + break; + case javax_media_j3d_Texture_FILTER4: + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, + ctxProperties->filter4_enum); + break; + + } + + /* set texture mag filter */ + switch(magFilter){ + case javax_media_j3d_Texture_FASTEST: + case javax_media_j3d_Texture_BASE_LEVEL_POINT: + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + break; + case javax_media_j3d_Texture_NICEST: + case javax_media_j3d_Texture_BASE_LEVEL_LINEAR: + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + break; + case javax_media_j3d_Texture_LINEAR_SHARPEN: + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, + ctxProperties->linear_sharpen_enum); + break; + case javax_media_j3d_Texture_LINEAR_SHARPEN_RGB: + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, + ctxProperties->linear_sharpen_rgb_enum); + break; + case javax_media_j3d_Texture_LINEAR_SHARPEN_ALPHA: + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, + ctxProperties->linear_sharpen_alpha_enum); + break; + case javax_media_j3d_Texture2D_LINEAR_DETAIL: + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, + ctxProperties->linear_detail_enum); + break; + case javax_media_j3d_Texture2D_LINEAR_DETAIL_RGB: + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, + ctxProperties->linear_detail_rgb_enum); + break; + case javax_media_j3d_Texture2D_LINEAR_DETAIL_ALPHA: + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, + ctxProperties->linear_detail_alpha_enum); + break; + case javax_media_j3d_Texture_FILTER4: + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, + ctxProperties->filter4_enum); + break; + } +} + + +void updateTextureLodRange( + GraphicsContextPropertiesInfo *ctxProperties, + jint target, + jint baseLevel, + jint maximumLevel, + float minimumLod, float maximumLod) { + + /* + * checking of the availability of the extension is already done + * in the java side + */ + glTexParameteri(target, ctxProperties->texture_base_level_enum, + baseLevel); + glTexParameteri(target, ctxProperties->texture_max_level_enum, + maximumLevel); + glTexParameterf(target, ctxProperties->texture_min_lod_enum, + minimumLod); + glTexParameterf(target, ctxProperties->texture_max_lod_enum, + maximumLod); +} + +void updateTextureLodOffset( + GraphicsContextPropertiesInfo *ctxProperties, + jint target, + float lodOffsetS, float lodOffsetT, float lodOffsetR) { + + /* + * checking of the availability of the extension is already done + * in the java side + */ + glTexParameterf(target, GL_TEXTURE_LOD_BIAS_S_SGIX, lodOffsetS); + glTexParameterf(target, GL_TEXTURE_LOD_BIAS_T_SGIX, lodOffsetT); + glTexParameterf(target, GL_TEXTURE_LOD_BIAS_R_SGIX, lodOffsetR); +} + + +void updateTextureBoundary( + GraphicsContextPropertiesInfo *ctxProperties, + jint target, + jint boundaryModeS, + jint boundaryModeT, + jint boundaryModeR, + jfloat boundaryRed, + jfloat boundaryGreen, + jfloat boundaryBlue, + jfloat boundaryAlpha) +{ + float color[4]; + + /* set texture wrap parameter */ + switch (boundaryModeS){ + case javax_media_j3d_Texture_WRAP: + glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT); + break; + case javax_media_j3d_Texture_CLAMP: + glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP); + break; + case javax_media_j3d_Texture_CLAMP_TO_EDGE: + glTexParameteri(target, GL_TEXTURE_WRAP_S, + ctxProperties->texture_clamp_to_edge_enum); + break; + case javax_media_j3d_Texture_CLAMP_TO_BOUNDARY: + glTexParameteri(target, GL_TEXTURE_WRAP_S, + ctxProperties->texture_clamp_to_border_enum); + break; + } + + switch (boundaryModeT) { + case javax_media_j3d_Texture_WRAP: + glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT); + break; + case javax_media_j3d_Texture_CLAMP: + glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP); + break; + case javax_media_j3d_Texture_CLAMP_TO_EDGE: + glTexParameteri(target, GL_TEXTURE_WRAP_T, + ctxProperties->texture_clamp_to_edge_enum); + break; + case javax_media_j3d_Texture_CLAMP_TO_BOUNDARY: + glTexParameteri(target, GL_TEXTURE_WRAP_T, + ctxProperties->texture_clamp_to_border_enum); + break; + } + + /* applies to Texture3D only */ + if (boundaryModeR != -1) { + switch (boundaryModeR) { + case javax_media_j3d_Texture_WRAP: + glTexParameteri(target, + ctxProperties->texture_wrap_r_ext_enum, GL_REPEAT); + break; + + case javax_media_j3d_Texture_CLAMP: + glTexParameteri(target, + ctxProperties->texture_wrap_r_ext_enum, GL_CLAMP); + break; + case javax_media_j3d_Texture_CLAMP_TO_EDGE: + glTexParameteri(target, + ctxProperties->texture_wrap_r_ext_enum, + ctxProperties->texture_clamp_to_edge_enum); + break; + case javax_media_j3d_Texture_CLAMP_TO_BOUNDARY: + glTexParameteri(target, + ctxProperties->texture_wrap_r_ext_enum, + ctxProperties->texture_clamp_to_border_enum); + break; + } + } + + if (boundaryModeS == javax_media_j3d_Texture_CLAMP || + boundaryModeT == javax_media_j3d_Texture_CLAMP || + boundaryModeR == javax_media_j3d_Texture_CLAMP) { + /* set texture border color */ + color[0] = boundaryRed; + color[1] = boundaryGreen; + color[2] = boundaryBlue; + color[3] = boundaryAlpha; + glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, color); + } +} + +void updateTextureSharpenFunc( + JNIEnv *env, + GraphicsContextPropertiesInfo *ctxProperties, + jint target, + jint numPts, + jfloatArray pts) +{ + /* + * checking of the availability of sharpen texture functionality + * is already done in the java side + */ + + JNIEnv table = *env; + jfloat *funcPts = NULL; + + if (numPts > 0) { + funcPts = (jfloat *)(*(table->GetPrimitiveArrayCritical))( + env, pts, NULL); + } + + ctxProperties->glSharpenTexFuncSGIS(target, numPts, funcPts); + + if (funcPts != NULL) { + (*(table->ReleasePrimitiveArrayCritical))(env, pts, funcPts, 0); + } +} + + +void updateTextureFilter4Func( + JNIEnv *env, + GraphicsContextPropertiesInfo *ctxProperties, + jint target, + jint numPts, + jfloatArray pts) +{ + /* + * checking of the availability of filter4 functionality + * is already done in the java side + */ + + JNIEnv table = *env; + jfloat *funcPts = NULL; + + if (numPts > 0) { + funcPts = (jfloat *)(*(table->GetPrimitiveArrayCritical))( + env, pts, NULL); + } + + ctxProperties->glTexFilterFuncSGIS(target, ctxProperties->filter4_enum, + numPts, funcPts); + + if (funcPts != NULL) { + (*(table->ReleasePrimitiveArrayCritical))(env, pts, funcPts, 0); + } +} + +void updateTextureAnisotropicFilter( + JNIEnv *env, + GraphicsContextPropertiesInfo *ctxProperties, + jint target, + jfloat degree) +{ + /* + * checking of the availability of anisotropic filter functionality + * is already done in the java side + */ + glTexParameterf(target, + ctxProperties->texture_filter_anisotropic_ext_enum, + degree); +} + + +/* + * common function to define 2D texture image for different target + */ +void updateTexture2DImage( + JNIEnv *env, + GraphicsContextPropertiesInfo *ctxProperties, + jint target, + jint numLevels, + jint level, + jint internalFormat, + jint format, + jint width, + jint height, + jint boundaryWidth, + jbyteArray imageYup) +{ + GLenum oglFormat = 0, oglInternalFormat=0; + JNIEnv table = *env; + jbyte *byteData; + jshort *shortData; + + switch (internalFormat) { + case INTENSITY: + oglInternalFormat = GL_INTENSITY; + break; + case LUMINANCE: + oglInternalFormat = GL_LUMINANCE; + break; + case ALPHA: + oglInternalFormat = GL_ALPHA; + break; + case LUMINANCE_ALPHA: + oglInternalFormat = GL_LUMINANCE_ALPHA; + break; + case J3D_RGB: + oglInternalFormat = GL_RGB; + break; + case J3D_RGBA: + oglInternalFormat = GL_RGBA; + break; + } + switch (format) { + case FORMAT_BYTE_RGBA: + /* all RGB types are stored as RGBA */ + oglFormat = GL_RGBA; + break; + case FORMAT_BYTE_RGB: + oglFormat = GL_RGB; + break; + + case FORMAT_BYTE_ABGR: + if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */ + oglFormat = GL_ABGR_EXT; + } + break; + + case FORMAT_BYTE_BGR: + if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */ + oglFormat = ctxProperties->bgr_ext_enum; + } + break; + + case FORMAT_BYTE_LA: + /* all LA types are stored as LA8 */ + oglFormat = GL_LUMINANCE_ALPHA; + break; + case FORMAT_BYTE_GRAY: + case FORMAT_USHORT_GRAY: + if (oglInternalFormat == GL_ALPHA) { + oglFormat = GL_ALPHA; + } else { + oglFormat = GL_LUMINANCE; + } + break; + } + /* + fprintf(stderr,"native updateTextureImage\n"); + fprintf(stderr,"internalFormat = %x\n",internalFormat); + fprintf(stderr,"format = %x\n",format); + fprintf(stderr,"oglFormat = %x\n",oglFormat); + fprintf(stderr,"oglInternalFormat = %x\n",oglInternalFormat); + fprintf(stderr,"boundaryWidth= %d\n", boundaryWidth); + */ + if (imageYup != NULL) { + if (format != FORMAT_USHORT_GRAY) { + byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env, + imageYup, + NULL); + /* + { + jbyte *c = byteData; + int i, j; + for (i = 0; i < 1; i++) { + for (j = 0; j < 8; j++, c++) { + fprintf(stderr, "%x ",*c); + } + fprintf(stderr, "\n"); + } + } + */ + } + else { /* unsigned short */ + shortData = (jshort *)(*(table->GetPrimitiveArrayCritical))(env, + imageYup, + NULL); + } + } + else { + byteData = NULL; + shortData = NULL; + } + if (format != FORMAT_USHORT_GRAY) { + glTexImage2D(target, level, oglInternalFormat, + width, height, boundaryWidth, + oglFormat, GL_UNSIGNED_BYTE, (GLvoid *)byteData); + } + else { + glTexImage2D(target, level, oglInternalFormat, + width, height, boundaryWidth, + oglFormat, GL_UNSIGNED_SHORT, (GLvoid *)shortData); + } + + if (imageYup != NULL) { + if (format != FORMAT_USHORT_GRAY) { + (*(table->ReleasePrimitiveArrayCritical))(env, imageYup, byteData, 0); + } + else { + (*(table->ReleasePrimitiveArrayCritical))(env, imageYup, shortData, 0); + } + } + + /* No idea why we need following call. */ + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); +} + + +/* + * common function to update 2D texture image for different target + */ + +void updateTexture2DSubImage( + JNIEnv *env, + GraphicsContextPropertiesInfo *ctxProperties, + jint target, + jint level, + jint xoffset, + jint yoffset, + jint internalFormat, + jint format, + jint imgXOffset, + jint imgYOffset, + jint tilew, + jint width, + jint height, + jbyteArray image) { + + GLenum oglFormat = 0, oglInternalFormat=0; + JNIEnv table = *env; + jbyte *byteData, *tmpByte; + jshort *shortData, *tmpShort; + jint numBytes = 0; + jboolean pixelStore = JNI_FALSE; + + + switch (internalFormat) { + case INTENSITY: + oglInternalFormat = GL_INTENSITY; + break; + case LUMINANCE: + oglInternalFormat = GL_LUMINANCE; + break; + case ALPHA: + oglInternalFormat = GL_ALPHA; + break; + case LUMINANCE_ALPHA: + oglInternalFormat = GL_LUMINANCE_ALPHA; + break; + case J3D_RGB: + oglInternalFormat = GL_RGB; + break; + case J3D_RGBA: + oglInternalFormat = GL_RGBA; + break; + } + + switch (format) { + case FORMAT_BYTE_RGBA: + /* all RGB types are stored as RGBA */ + oglFormat = GL_RGBA; + numBytes = 4; + break; + case FORMAT_BYTE_RGB: + oglFormat = GL_RGB; + numBytes = 3; + break; + + case FORMAT_BYTE_ABGR: + if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */ + oglFormat = GL_ABGR_EXT; + numBytes = 4; + } + break; + case FORMAT_BYTE_BGR: + if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */ + oglFormat = ctxProperties->bgr_ext_enum; + numBytes = 3; + } + break; + + case FORMAT_BYTE_LA: + /* all LA types are stored as LA8 */ + oglFormat = GL_LUMINANCE_ALPHA; + numBytes = 2; + break; + case FORMAT_BYTE_GRAY: + if (oglInternalFormat == GL_ALPHA) { + oglFormat = GL_ALPHA; + } else { + oglFormat = GL_LUMINANCE; + } + numBytes = 1; + case FORMAT_USHORT_GRAY: + if (oglInternalFormat == GL_ALPHA) { + oglFormat = GL_ALPHA; + } else { + oglFormat = GL_LUMINANCE; + } + numBytes = 2; + break; + } + /* + fprintf(stderr,"format = %x\n",format); + fprintf(stderr,"oglFormat = %x\n",oglFormat); + fprintf(stderr, "imgXOffset = %d\n",imgXOffset); + fprintf(stderr, "imgYOffset = %d\n",imgYOffset); + fprintf(stderr, "xoffset = %d\n",xoffset); + fprintf(stderr, "yoffset = %d\n",yoffset); + fprintf(stderr, "tilew = %d\n",tilew); + fprintf(stderr, "numBytes = %d\n",numBytes); + fprintf(stderr, "width = %d\n",width); + fprintf(stderr, "height = %d\n",height); + */ + if (imgXOffset > 0 || (width < tilew)) { + pixelStore = JNI_TRUE; + glPixelStorei(GL_UNPACK_ROW_LENGTH, tilew); + } + + if (format != FORMAT_USHORT_GRAY) { + int off = 0; + byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env, + image, + NULL); + /* offset by the imageOffset */ + off = (tilew * imgYOffset + imgXOffset) * numBytes; + tmpByte = byteData+(off); + +/* +printf("tmpByte: %x %x %x %x\n", *(tmpByte), *(tmpByte+1), + *(tmpByte+2), *(tmpByte+3)); +*/ + + glTexSubImage2D(target, level, xoffset, yoffset, width, height, + oglFormat, GL_UNSIGNED_BYTE, (GLvoid *)tmpByte); + (*(table->ReleasePrimitiveArrayCritical))(env, image, byteData, 0); + } else { /* unsigned short */ + shortData = (jshort *)(*(table->GetPrimitiveArrayCritical))(env, + image, + NULL); + tmpShort = (jshort*)((jbyte*)shortData+ + (tilew * imgYOffset + imgXOffset)*numBytes); + glTexSubImage2D(target, level, xoffset, yoffset, width, height, + oglFormat, GL_UNSIGNED_SHORT, (GLvoid *)tmpShort); + (*(table->ReleasePrimitiveArrayCritical))(env, image, shortData, 0); + } + if (pixelStore) { + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_bindTexture( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint objectId, + jboolean enable) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if (ctxProperties->textureCubeMapAvailable) { + glDisable(ctxProperties->texture_cube_map_ext_enum); + } + if (ctxProperties->texture3DAvailable) { + glDisable(ctxProperties->texture_3D_ext_enum); + } + + if (enable == JNI_FALSE) { + glDisable(GL_TEXTURE_2D); + + } else { + glBindTexture(GL_TEXTURE_2D, objectId); + glEnable(GL_TEXTURE_2D); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureFilterModes( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint minFilter, + jint magFilter) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTextureFilterModes(ctxProperties, GL_TEXTURE_2D, + minFilter, magFilter); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureLodRange( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint baseLevel, + jint maximumLevel, + jfloat minimumLOD, + jfloat maximumLOD) +{ + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTextureLodRange(ctxProperties, GL_TEXTURE_2D, + baseLevel, maximumLevel, + minimumLOD, maximumLOD); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureLodOffset( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jfloat lodOffsetS, + jfloat lodOffsetT, + jfloat lodOffsetR) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTextureLodOffset(ctxProperties, GL_TEXTURE_2D, + lodOffsetS, lodOffsetT, lodOffsetR); +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureBoundary( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint boundaryModeS, + jint boundaryModeT, + jfloat boundaryRed, + jfloat boundaryGreen, + jfloat boundaryBlue, + jfloat boundaryAlpha) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTextureBoundary(ctxProperties, GL_TEXTURE_2D, + boundaryModeS, boundaryModeT, -1, + boundaryRed, boundaryGreen, + boundaryBlue, boundaryAlpha); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureSharpenFunc( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint numPts, + jfloatArray pts) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTextureSharpenFunc(env, ctxProperties, GL_TEXTURE_2D, numPts, pts); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureFilter4Func( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint numPts, + jfloatArray pts) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTextureFilter4Func(env, ctxProperties, GL_TEXTURE_2D, numPts, pts); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureRetained_updateTextureAnisotropicFilter( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jfloat degree) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTextureAnisotropicFilter(env, ctxProperties, GL_TEXTURE_2D, degree); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture2DRetained_updateTextureSubImage( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint level, + jint xoffset, + jint yoffset, + jint internalFormat, + jint format, + jint imgXOffset, + jint imgYOffset, + jint tilew, + jint width, + jint height, + jbyteArray image) { + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + updateTexture2DSubImage(env, ctxProperties, GL_TEXTURE_2D, + level, xoffset, yoffset, + internalFormat, format, + imgXOffset, imgYOffset, tilew, width, height, + image); +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture2DRetained_updateTextureImage( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint numLevels, + jint level, + jint internalFormat, + jint format, + jint width, + jint height, + jint boundaryWidth, + jbyteArray imageYup) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTexture2DImage(env, ctxProperties, GL_TEXTURE_2D, + numLevels, level, internalFormat, format, + width, height, boundaryWidth, imageYup); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture2DRetained_updateDetailTextureParameters( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint mode, + jint level, + jint nPts, + jfloatArray funcPts) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + float *pts = NULL; + JNIEnv table = *env; + + if (ctxProperties->textureDetailAvailable) { + switch (mode) { + case javax_media_j3d_Texture2D_DETAIL_ADD: + glTexParameterf(GL_TEXTURE_2D, + ctxProperties->texture_detail_mode_enum, GL_ADD); + break; + case javax_media_j3d_Texture2D_DETAIL_MODULATE: + glTexParameterf(GL_TEXTURE_2D, + ctxProperties->texture_detail_mode_enum, GL_MODULATE); + break; + } + + glTexParameteri(GL_TEXTURE_2D, + ctxProperties->texture_detail_level_enum, -level); + + if (nPts > 0) { + pts = (jfloat *)(*(table->GetPrimitiveArrayCritical))(env, + funcPts, NULL); + } + ctxProperties->glDetailTexFuncSGIS(GL_TEXTURE_2D, nPts, pts); + + if (pts != NULL) { + (*(table->ReleasePrimitiveArrayCritical))(env, funcPts, pts, 0); + } + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_DetailTextureImage_bindTexture( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint objectId) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if (ctxProperties->textureDetailAvailable) { + glBindTexture(ctxProperties->texture_detail_ext_enum, objectId); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_DetailTextureImage_updateTextureSubImage( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint level, + jint xoffset, + jint yoffset, + jint internalFormat, + jint format, + jint imgXOffset, + jint imgYOffset, + jint tilew, + jint width, + jint height, + jbyteArray image) { + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if (ctxProperties->textureDetailAvailable) { + updateTexture2DSubImage(env, ctxProperties, + ctxProperties->texture_detail_ext_enum, + level, xoffset, yoffset, + internalFormat, format, + imgXOffset, imgYOffset, tilew, width, height, + image); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_DetailTextureImage_updateTextureImage( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint numLevels, + jint level, + jint internalFormat, + jint format, + jint width, + jint height, + jint boundaryWidth, + jbyteArray imageYup) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if (ctxProperties->textureDetailAvailable) { + updateTexture2DImage(env, ctxProperties, + ctxProperties->texture_detail_ext_enum, + numLevels, level, internalFormat, format, + width, height, boundaryWidth, imageYup); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_bindTexture( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint objectId, + jboolean enable) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if (ctxProperties->textureCubeMapAvailable) { + /* textureCubeMap will take precedure over 3D Texture */ + glDisable(ctxProperties->texture_cube_map_ext_enum); + } + + if (enable == JNI_FALSE) { + if(ctxProperties->texture3DAvailable) { + glDisable(ctxProperties->texture_3D_ext_enum); + } + + } else { + if(ctxProperties->texture3DAvailable){ + glBindTexture(ctxProperties->texture_3D_ext_enum, objectId); + glEnable(ctxProperties->texture_3D_ext_enum); + } + } +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureFilterModes( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint minFilter, + jint magFilter) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTextureFilterModes(ctxProperties, GL_TEXTURE_3D, + minFilter, magFilter); +} + + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureLodRange( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint baseLevel, + jint maximumLevel, + jfloat minimumLOD, + jfloat maximumLOD) +{ + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTextureLodRange(ctxProperties, GL_TEXTURE_3D, + baseLevel, maximumLevel, + minimumLOD, maximumLOD); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureLodOffset( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jfloat lodOffsetS, + jfloat lodOffsetT, + jfloat lodOffsetR) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTextureLodOffset(ctxProperties, GL_TEXTURE_3D, + lodOffsetS, lodOffsetT, lodOffsetR); +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureBoundary( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint boundaryModeS, + jint boundaryModeT, + jint boundaryModeR, + jfloat boundaryRed, + jfloat boundaryGreen, + jfloat boundaryBlue, + jfloat boundaryAlpha) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTextureBoundary(ctxProperties, GL_TEXTURE_3D, + boundaryModeS, boundaryModeT, boundaryModeR, + boundaryRed, boundaryGreen, + boundaryBlue, boundaryAlpha); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureSharpenFunc( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint numPts, + jfloatArray pts) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTextureSharpenFunc(env, ctxProperties, GL_TEXTURE_3D, numPts, pts); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureFilter4Func( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint numPts, + jfloatArray pts) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTextureFilter4Func(env, ctxProperties, GL_TEXTURE_3D, numPts, pts); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureAnisotropicFilter( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jfloat degree) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTextureAnisotropicFilter(env, ctxProperties, GL_TEXTURE_3D, degree); +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureImage( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint numLevels, + jint level, + jint internalFormat, + jint format, + jint width, + jint height, + jint depth, + jint boundaryWidth, + jbyteArray imageYup) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if(ctxProperties->texture3DAvailable) { + + GLenum oglFormat = 0, oglInternalFormat=0; + JNIEnv table = *env; + jbyte *byteData; + jshort *shortData; + + switch (internalFormat) { + case INTENSITY: + oglInternalFormat = GL_INTENSITY; + break; + case LUMINANCE: + oglInternalFormat = GL_LUMINANCE; + break; + case ALPHA: + oglInternalFormat = GL_ALPHA; + break; + case LUMINANCE_ALPHA: + oglInternalFormat = GL_LUMINANCE_ALPHA; + break; + case J3D_RGB: + oglInternalFormat = GL_RGB; + break; + case J3D_RGBA: + oglInternalFormat = GL_RGBA; + break; + } + + switch (format) { + case FORMAT_BYTE_RGBA: + /* all RGB types are stored as RGBA */ + oglFormat = GL_RGBA; + break; + case FORMAT_BYTE_RGB: + oglFormat = GL_RGB; + break; + + case FORMAT_BYTE_ABGR: + if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */ + oglFormat = GL_ABGR_EXT; + } + break; + case FORMAT_BYTE_BGR: + if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */ + oglFormat = ctxProperties->bgr_ext_enum; + } + break; + case FORMAT_BYTE_LA: + /* all LA types are stored as LA8 */ + oglFormat = GL_LUMINANCE_ALPHA; + break; + case FORMAT_BYTE_GRAY: + case FORMAT_USHORT_GRAY: + if (oglInternalFormat == GL_ALPHA) { + oglFormat = GL_ALPHA; + } else { + oglFormat = GL_LUMINANCE; + } + break; + } + + /* + fprintf(stderr,"internalFormat = %x\n",internalFormat); + fprintf(stderr,"format = %x\n",format); + fprintf(stderr,"oglFormat = %x\n",oglFormat); + fprintf(stderr,"oglInternalFormat = %x\n",oglInternalFormat); + */ + if (imageYup != NULL) { + if (format != FORMAT_USHORT_GRAY) { + byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env, + imageYup, + NULL); + } + else { /* unsigned short */ + shortData = (jshort *)(*(table->GetPrimitiveArrayCritical))(env, + imageYup, + NULL); + + } + } else { + byteData = NULL; + shortData = NULL; + } + + if (format != FORMAT_USHORT_GRAY) { + + ctxProperties->glTexImage3DEXT(ctxProperties->texture_3D_ext_enum, + level, oglInternalFormat, + width, height, depth, boundaryWidth, + oglFormat, GL_UNSIGNED_BYTE, + (GLvoid *)byteData); + } + else { + ctxProperties->glTexImage3DEXT(ctxProperties->texture_3D_ext_enum, + level, oglInternalFormat, + width, height, depth, boundaryWidth, + oglFormat, GL_UNSIGNED_SHORT, + (GLvoid *)shortData); + } + if (imageYup != NULL) { + if (format != FORMAT_USHORT_GRAY) { + (*(table->ReleasePrimitiveArrayCritical))(env, imageYup, byteData, 0); + } else { /* unsigned short */ + (*(table->ReleasePrimitiveArrayCritical))(env, imageYup, shortData, 0); + + } + } + + /* No idea why we need following call. */ + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + } + +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Texture3DRetained_updateTextureSubImage( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint level, + jint xoffset, + jint yoffset, + jint zoffset, + jint internalFormat, + jint format, + jint imgXOffset, + jint imgYOffset, + jint imgZOffset, + jint tilew, + jint tileh, + jint width, + jint height, + jint depth, + jbyteArray image) { + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if (ctxProperties->texture3DAvailable) { + GLenum oglFormat = 0, oglInternalFormat=0; + JNIEnv table = *env; + jbyte *byteData, *tmpByte; + jshort *shortData, *tmpShort; + jint numBytes = 0; + jboolean pixelStore = JNI_FALSE; + + switch (internalFormat) { + case INTENSITY: + oglInternalFormat = GL_INTENSITY; + break; + case LUMINANCE: + oglInternalFormat = GL_LUMINANCE; + break; + case ALPHA: + oglInternalFormat = GL_ALPHA; + break; + case LUMINANCE_ALPHA: + oglInternalFormat = GL_LUMINANCE_ALPHA; + break; + case J3D_RGB: + oglInternalFormat = GL_RGB; + break; + case J3D_RGBA: + oglInternalFormat = GL_RGBA; + break; + } + + switch (format) { + case FORMAT_BYTE_RGBA: + /* all RGB types are stored as RGBA */ + oglFormat = GL_RGBA; + numBytes = 4; + break; + case FORMAT_BYTE_RGB: + oglFormat = GL_RGB; + numBytes = 3; + break; + + case FORMAT_BYTE_ABGR: + if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */ + oglFormat = GL_ABGR_EXT; + numBytes = 4; + } + break; + case FORMAT_BYTE_BGR: + if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */ + oglFormat = ctxProperties->bgr_ext_enum; + numBytes = 3; + } + break; + + case FORMAT_BYTE_LA: + /* all LA types are stored as LA8 */ + oglFormat = GL_LUMINANCE_ALPHA; + numBytes = 2; + break; + case FORMAT_BYTE_GRAY: + if (oglInternalFormat == GL_ALPHA) { + oglFormat = GL_ALPHA; + } else { + oglFormat = GL_LUMINANCE; + } + numBytes = 1; + case FORMAT_USHORT_GRAY: + if (oglInternalFormat == GL_ALPHA) { + oglFormat = GL_ALPHA; + } else { + oglFormat = GL_LUMINANCE; + } + numBytes = 2; + break; + } + /* + fprintf(stderr,"format = %x\n",format); + fprintf(stderr,"oglFormat = %x\n",oglFormat); + fprintf(stderr, "imgXOffset = %d\n",imgXOffset); + fprintf(stderr, "imgYOffset = %d\n",imgYOffset); + fprintf(stderr, "imgZOffset = %d\n",imgZOffset); + fprintf(stderr, "xoffset = %d\n",xoffset); + fprintf(stderr, "yoffset = %d\n",yoffset); + fprintf(stderr, "zoffset = %d\n",zoffset); + fprintf(stderr, "tilew = %d\n",tilew); + fprintf(stderr, "tileh = %d\n",tilew); + fprintf(stderr, "numBytes = %d\n",numBytes); + fprintf(stderr, "width = %d\n",width); + fprintf(stderr, "height = %d\n",height); + fprintf(stderr, "depth = %d\n",depth); + */ + if (imgXOffset > 0 || (width < tilew)) { + pixelStore = JNI_TRUE; + glPixelStorei(GL_UNPACK_ROW_LENGTH, tilew); + } + + if (format != FORMAT_USHORT_GRAY) { + byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env, + image, NULL); + + tmpByte = byteData + + (tilew * tileh * imgZOffset + + tilew * imgYOffset + imgXOffset) * numBytes; + + ctxProperties->glTexSubImage3DEXT( + ctxProperties->texture_3D_ext_enum, + level, xoffset, yoffset, zoffset, + width, height, depth, + oglFormat, GL_UNSIGNED_BYTE, + (GLvoid *)tmpByte); + + (*(table->ReleasePrimitiveArrayCritical))(env, image, byteData, 0); + } else { /* unsigned short */ + shortData = (jshort *)(*(table->GetPrimitiveArrayCritical))(env, + image, NULL); + tmpShort = (jshort*)((jbyte*)shortData+ + (tilew * tileh * imgZOffset + + tilew * imgYOffset + imgXOffset)*numBytes); + + ctxProperties->glTexSubImage3DEXT( + ctxProperties->texture_3D_ext_enum, + level, xoffset, yoffset, zoffset, + width, height, depth, + oglFormat, GL_UNSIGNED_SHORT, + (GLvoid *)tmpShort); + (*(table->ReleasePrimitiveArrayCritical))(env, image, shortData, 0); + } + if (pixelStore) { + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + } + } +} + + +/* + * mapping from java enum to gl enum + */ + +jint _gl_textureCubeMapFace[] = { + GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT, +}; + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_bindTexture( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint objectId, + jboolean enable) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + /* + * TextureCubeMap will take precedure over 3D Texture so + * there is no need to disable 3D Texture here. + */ + if (ctxProperties->textureCubeMapAvailable) { + if (enable == JNI_FALSE) { + glDisable(ctxProperties->texture_cube_map_ext_enum); + } else { + glBindTexture(ctxProperties->texture_cube_map_ext_enum, objectId); + glEnable(ctxProperties->texture_cube_map_ext_enum); + } + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureFilterModes( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint minFilter, + jint magFilter) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if (ctxProperties->textureCubeMapAvailable) { + updateTextureFilterModes(ctxProperties, + ctxProperties->texture_cube_map_ext_enum, + minFilter, magFilter); + } +} + + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureLodRange( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint baseLevel, + jint maximumLevel, + jfloat minimumLOD, + jfloat maximumLOD) +{ + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTextureLodRange(ctxProperties, + ctxProperties->texture_cube_map_ext_enum, + baseLevel, maximumLevel, + minimumLOD, maximumLOD); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureLodOffset( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jfloat lodOffsetS, + jfloat lodOffsetT, + jfloat lodOffsetR) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + updateTextureLodOffset(ctxProperties, + ctxProperties->texture_cube_map_ext_enum, + lodOffsetS, lodOffsetT, lodOffsetR); +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureBoundary( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint boundaryModeS, + jint boundaryModeT, + jfloat boundaryRed, + jfloat boundaryGreen, + jfloat boundaryBlue, + jfloat boundaryAlpha) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if (ctxProperties->textureCubeMapAvailable) { + updateTextureBoundary(ctxProperties, + ctxProperties->texture_cube_map_ext_enum, + boundaryModeS, boundaryModeT, -1, + boundaryRed, boundaryGreen, + boundaryBlue, boundaryAlpha); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureSharpenFunc( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint numPts, + jfloatArray pts) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if (ctxProperties->textureCubeMapAvailable) { + updateTextureSharpenFunc(env, ctxProperties, + ctxProperties->texture_cube_map_ext_enum, + numPts, pts); + } +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureFilter4Func( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint numPts, + jfloatArray pts) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if (ctxProperties->textureCubeMapAvailable) { + updateTextureFilter4Func(env, ctxProperties, + ctxProperties->texture_cube_map_ext_enum, + numPts, pts); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureAnisotropicFilter( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jfloat degree) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if (ctxProperties->textureCubeMapAvailable) { + updateTextureAnisotropicFilter(env, ctxProperties, + ctxProperties->texture_cube_map_ext_enum, + degree); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureSubImage( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint face, + jint level, + jint xoffset, + jint yoffset, + jint internalFormat, + jint format, + jint imgXOffset, + jint imgYOffset, + jint tilew, + jint width, + jint height, + jbyteArray image) { + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + updateTexture2DSubImage(env, ctxProperties, _gl_textureCubeMapFace[face], + level, xoffset, yoffset, internalFormat, + format, imgXOffset, imgYOffset, tilew, + width, height, image); +} + + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureCubeMapRetained_updateTextureImage( + JNIEnv *env, + jobject texture, + jlong ctxInfo, + jint face, + jint numLevels, + jint level, + jint internalFormat, + jint format, + jint width, + jint height, + jint boundaryWidth, + jbyteArray imageYup) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + updateTexture2DImage(env, ctxProperties, _gl_textureCubeMapFace[face], + numLevels, level, internalFormat, format, + width, height, boundaryWidth, imageYup); +} + + +JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_Canvas3D_decal1stChildSetup( + JNIEnv *env, + jobject obj, + jlong ctxInfo) +{ + glEnable(GL_STENCIL_TEST); + glClearStencil(0x0); + glClear(GL_STENCIL_BUFFER_BIT); + glStencilFunc (GL_ALWAYS, 0x1, 0x1); + glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); + if (glIsEnabled(GL_DEPTH_TEST)) + return JNI_TRUE; + else + return JNI_FALSE; +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_decalNthChildSetup( + JNIEnv *env, + jobject obj, + jlong ctxInfo) +{ + glDisable(GL_DEPTH_TEST); + glStencilFunc (GL_EQUAL, 0x1, 0x1); + glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_decalReset( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jboolean depthBufferEnable) +{ + glDisable(GL_STENCIL_TEST); + if (depthBufferEnable == JNI_TRUE) + glEnable(GL_DEPTH_TEST); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_ctxUpdateEyeLightingEnable( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jboolean localEyeLightingEnable) +{ + if (localEyeLightingEnable == JNI_TRUE) { + glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); + } else { + glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_updateSeparateSpecularColorEnable( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jboolean enable) +{ + /* + * This method will not be called if the rendering layer does not support + * separate specular color control. The checking of the availability + * of the functionality is done in Renderer at rendering time + */ + + /* 1.2 feature only */ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if(ctxProperties->seperate_specular_color) { + if (enable == JNI_TRUE) { + glLightModeli(ctxProperties->light_model_color_control_enum, + ctxProperties->seperate_specular_color_enum); + } else { + glLightModeli(ctxProperties->light_model_color_control_enum, ctxProperties->single_color_enum); + } + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_TextureUnitStateRetained_updateTextureUnitState( + JNIEnv *env, + jobject cv, + jlong ctxInfo, + jint index, + jboolean enable) +{ + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if(ctxProperties->arb_multitexture) { + if (index >= 0) { + ctxProperties->glActiveTextureARB(index + GL_TEXTURE0_ARB); + ctxProperties->glClientActiveTextureARB(GL_TEXTURE0_ARB + index); + if (ctxProperties->textureRegisterCombinersAvailable) { + ctxProperties->currentTextureUnit = index + GL_TEXTURE0_ARB; + ctxProperties->currentCombinerUnit = index + GL_COMBINER0_NV; + if (ctxProperties->glCombinerParameteriNV!=NULL) + ctxProperties->glCombinerParameteriNV( + GL_NUM_GENERAL_COMBINERS_NV, index + 1); + + } + } + } /* GL_ARB_multitexture */ + + if (enable == JNI_FALSE) { + /* if not enabled, then don't enable any tex mapping */ + + glDisable(GL_TEXTURE_1D); + glDisable(GL_TEXTURE_2D); + + if(ctxProperties->texture3DAvailable) + glDisable(ctxProperties->texture_3D_ext_enum); + + if(ctxProperties->textureCubeMapAvailable) + glDisable(ctxProperties->texture_cube_map_ext_enum); + } + + /* + * if it is enabled, the enable flag will be taken care of + * in the bindTexture call + */ +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setDepthFunc( + JNIEnv * env, + jobject obj, + jlong ctxInfo, + jint func) +{ + if (func == javax_media_j3d_RenderingAttributesRetained_LESS) + glDepthFunc(GL_LESS); + else if (func == javax_media_j3d_RenderingAttributesRetained_LEQUAL) + glDepthFunc(GL_LEQUAL); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setBlendColor( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jfloat colorRed, + jfloat colorGreen, + jfloat colorBlue, + jfloat colorAlpha) +{ + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if (ctxProperties->blend_color_ext) { + /* + fprintf(stderr, "setBlendColor is on: %f %f %f %f\n", + colorRed, colorGreen, colorBlue, colorAlpha); + */ + + ctxProperties->glBlendColor(colorRed, colorGreen, colorBlue, colorAlpha); + } +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setBlendFunc( + JNIEnv * env, + jobject obj, + jlong ctxInfo, + jint srcBlendFunction, + jint dstBlendFunction) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + glEnable(GL_BLEND); + glBlendFunc(ctxProperties->blendFunctionTable[srcBlendFunction], + ctxProperties->blendFunctionTable[dstBlendFunction]); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setFogEnableFlag( + JNIEnv * env, + jobject obj, + jlong ctxInfo, + jboolean enable) +{ + if (enable == JNI_TRUE) + glEnable(GL_FOG); + else + glDisable(GL_FOG); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_activeTextureUnit( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jint index) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + if(ctxProperties->arb_multitexture){ + ctxProperties->glActiveTextureARB(GL_TEXTURE0_ARB + index); + ctxProperties->glClientActiveTextureARB(GL_TEXTURE0_ARB + index); + /* GL_ARB_multitexture */ + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_updateTexUnitStateMap( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jint numActiveTexUnit, + jintArray texUnitStateMapArray) +{ + /* + * texture unit state map is explicitly handled in + * execute; for display list, texture unit has to match + * texture unit state. + */ +} diff --git a/src/native/ogl/Canvas3D.c b/src/native/ogl/Canvas3D.c new file mode 100644 index 0000000..86d037d --- /dev/null +++ b/src/native/ogl/Canvas3D.c @@ -0,0 +1,3388 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + * Portions of this code were derived from work done by the Blackdown + * group (www.blackdown.org), who did the initial Linux implementation + * of the Java 3D API. + */ + +#include +#include +#include +#include +#include + + +#include "gldefs.h" + +#ifdef DEBUG +/* Uncomment the following for VERBOSE debug messages */ +/* #define VERBOSE */ +#endif /* DEBUG */ + + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef BOOL +#define BOOL int +#endif + +static char *gl_VERSION; +static char *gl_VENDOR; + +void initializeCtxInfo(JNIEnv *env, GraphicsContextPropertiesInfo* ctxInfo); +void cleanupCtxInfo(GraphicsContextPropertiesInfo* ctxInfo); + +/* + * Class: javax_media_j3d_Canvas3D + * Method: getTextureColorTableSize + * Signature: ()I + */ +int getTextureColorTableSize( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + char *extensionStr, + int minorVersion); + + +#ifdef WIN32 + extern HDC getMonitorDC(int screen); +#endif + +/* + * extract the version numbers + * when return , numbers[0] contains major version number + * numbers[1] contains minor version number + */ +void extractVersionInfo(char *versionStr, int* numbers){ + char *majorNumStr; + char *minorNumStr; + majorNumStr = strtok(versionStr, (char *)"."); + minorNumStr = strtok(0, (char *)"."); + if (majorNumStr != NULL) + numbers[0] = atoi(majorNumStr); + if (minorNumStr != NULL) + numbers[1] = atoi(minorNumStr); + + /* fprintf(stderr, "majorNumStr = %d, minNumStr = %d \n", numbers[0], numbers[1]); */ + return; +} + +/* + * check if the extension is supported + */ +int isExtensionSupported(const char *allExtensions, const char *extension) +{ + const char *start; + const char *where, *terminator; + + /* Extension names should not have spaces. */ + where = (const char *) strchr(extension, ' '); + if (where || *extension == '\0') + return 0; + + /* + * It takes a bit of care to be fool-proof about parsing the + * OpenGL extensions string. Don't be fooled by sub-strings, + * etc. + */ + start = allExtensions; + for (;;) { + where = (const char *) strstr((const char *) start, extension); + if (!where) + break; + terminator = where + strlen(extension); + if (where == start || *(where - 1) == ' ') + if (*terminator == ' ' || *terminator == '\0') + return 1; + start = terminator; + } + return 0; +} + +void checkTextureExtensions( + JNIEnv *env, + jobject obj, + char *tmpExtensionStr, + int versionNumber, + GraphicsContextPropertiesInfo* ctxInfo) { + + if(isExtensionSupported(tmpExtensionStr, "GL_ARB_multitexture")) { + ctxInfo->arb_multitexture = JNI_TRUE ; + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_MULTI_TEXTURE; + glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &ctxInfo->textureUnitCount); + + } + + if(isExtensionSupported(tmpExtensionStr,"GL_SGI_texture_color_table" )){ + ctxInfo->textureColorTableAvailable = JNI_TRUE; + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_COLOR_TABLE; + + /* get texture color table size */ + /* need to check later */ + ctxInfo->textureColorTableSize = getTextureColorTableSize(env, obj, (jlong)ctxInfo, tmpExtensionStr, versionNumber); + if (ctxInfo->textureColorTableSize <= 0) { + ctxInfo->textureColorTableAvailable = JNI_FALSE; + ctxInfo->textureExtMask &= ~javax_media_j3d_Canvas3D_TEXTURE_COLOR_TABLE; + } + if (ctxInfo->textureColorTableSize > 256) { + ctxInfo->textureColorTableSize = 256; + } + } + + if(isExtensionSupported(tmpExtensionStr,"GL_ARB_texture_env_combine" )){ + ctxInfo->textureEnvCombineAvailable = JNI_TRUE; + ctxInfo->textureCombineSubtractAvailable = JNI_TRUE; + + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_COMBINE; + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_COMBINE_SUBTRACT; + ctxInfo->combine_enum = GL_COMBINE_ARB; + ctxInfo->combine_add_signed_enum = GL_ADD_SIGNED_ARB; + ctxInfo->combine_interpolate_enum = GL_INTERPOLATE_ARB; + ctxInfo->combine_subtract_enum = GL_SUBTRACT_ARB; + + } else if(isExtensionSupported(tmpExtensionStr,"GL_EXT_texture_env_combine" )){ + ctxInfo->textureEnvCombineAvailable = JNI_TRUE; + ctxInfo->textureCombineSubtractAvailable = JNI_FALSE; + + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_COMBINE; + ctxInfo->combine_enum = GL_COMBINE_EXT; + ctxInfo->combine_add_signed_enum = GL_ADD_SIGNED_EXT; + ctxInfo->combine_interpolate_enum = GL_INTERPOLATE_EXT; + + /* EXT_texture_env_combine does not include subtract */ + ctxInfo->combine_subtract_enum = 0; + } + + if(isExtensionSupported(tmpExtensionStr,"GL_NV_register_combiners" )) { + ctxInfo->textureRegisterCombinersAvailable = JNI_TRUE; + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_REGISTER_COMBINERS; +#if defined(SOLARIS) || defined(__linux__) + ctxInfo->glCombinerInputNV = + (MYPFNGLCOMBINERINPUTNV) glCombinerInputNV; + ctxInfo->glFinalCombinerInputNV = + (MYPFNGLFINALCOMBINERINPUTNV) glFinalCombinerInputNV; + ctxInfo->glCombinerOutputNV = + (MYPFNGLCOMBINEROUTPUTNV) glCombinerOutputNV; + ctxInfo->glCombinerParameterfvNV = + (MYPFNGLCOMBINERPARAMETERFVNV) glCombinerParameterfvNV; + ctxInfo->glCombinerParameterivNV = + (MYPFNGLCOMBINERPARAMETERIVNV) glCombinerParameterivNV; + ctxInfo->glCombinerParameterfNV = + (MYPFNGLCOMBINERPARAMETERFNV) glCombinerParameterfNV; + ctxInfo->glCombinerParameteriNV = + (MYPFNGLCOMBINERPARAMETERINV) glCombinerParameteriNV; + if (ctxInfo->glCombinerInputNV == NULL || + ctxInfo->glFinalCombinerInputNV == NULL || + ctxInfo->glCombinerOutputNV == NULL || + ctxInfo->glCombinerParameterfvNV == NULL || + ctxInfo->glCombinerParameterivNV == NULL || + ctxInfo->glCombinerParameterfNV == NULL || + ctxInfo->glCombinerParameteriNV == NULL) { + /* lets play safe: */ + ctxInfo->textureExtMask &= + ~javax_media_j3d_Canvas3D_TEXTURE_REGISTER_COMBINERS; + ctxInfo->textureRegisterCombinersAvailable = JNI_FALSE; + } +#endif + +#ifdef WIN32 + ctxInfo->glCombinerInputNV = + (MYPFNGLCOMBINERINPUTNV) wglGetProcAddress("glCombinerInputNV"); + ctxInfo->glFinalCombinerInputNV = + (MYPFNGLFINALCOMBINERINPUTNV) wglGetProcAddress("glFinalCombinerInputNV"); + ctxInfo->glCombinerOutputNV = + (MYPFNGLCOMBINEROUTPUTNV) wglGetProcAddress("glCombinerOutputNV"); + ctxInfo->glCombinerParameterfvNV = + (MYPFNGLCOMBINERPARAMETERFVNV) wglGetProcAddress("glCombinerParameterfvNV"); + ctxInfo->glCombinerParameterivNV = + (MYPFNGLCOMBINERPARAMETERIVNV) wglGetProcAddress("glCombinerParameterivNV"); + ctxInfo->glCombinerParameterfNV = + (MYPFNGLCOMBINERPARAMETERFNV) wglGetProcAddress("glCombinerParameterfNV"); + ctxInfo->glCombinerParameteriNV = + (MYPFNGLCOMBINERPARAMETERINV) wglGetProcAddress("glCombinerParameteriNV"); + + /* + if (ctxInfo->glCombinerInputNV == NULL) { + printf("glCombinerInputNV == NULL\n"); + } + if (ctxInfo->glFinalCombinerInputNV == NULL) { + printf("glFinalCombinerInputNV == NULL\n"); + } + if (ctxInfo->glCombinerOutputNV == NULL) { + printf("ctxInfo->glCombinerOutputNV == NULL\n"); + } + if (ctxInfo->glCombinerParameterfvNV == NULL) { + printf("ctxInfo->glCombinerParameterfvNV == NULL\n"); + } + if (ctxInfo->glCombinerParameterivNV == NULL) { + printf("ctxInfo->glCombinerParameterivNV == NULL\n"); + } + if (ctxInfo->glCombinerParameterfNV == NULL) { + printf("ctxInfo->glCombinerParameterfNV == NULL\n"); + } + if (ctxInfo->glCombinerParameteriNV == NULL) { + printf("ctxInfo->glCombinerParameteriNV == NULL\n"); + } + */ + if ((ctxInfo->glCombinerInputNV == NULL) || + (ctxInfo->glFinalCombinerInputNV == NULL) || + (ctxInfo->glCombinerOutputNV == NULL) || + (ctxInfo->glCombinerParameterfvNV == NULL) || + (ctxInfo->glCombinerParameterivNV == NULL) || + (ctxInfo->glCombinerParameterfNV == NULL) || + (ctxInfo->glCombinerParameteriNV == NULL)) { + ctxInfo->textureExtMask &= ~javax_media_j3d_Canvas3D_TEXTURE_REGISTER_COMBINERS; + ctxInfo->textureRegisterCombinersAvailable = JNI_FALSE; + } + +#endif + + } + + if(isExtensionSupported(tmpExtensionStr,"GL_ARB_texture_env_dot3" )) { + ctxInfo->textureCombineDot3Available = JNI_TRUE; + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_COMBINE_DOT3; + ctxInfo->combine_dot3_rgb_enum = GL_DOT3_RGB_ARB; + ctxInfo->combine_dot3_rgba_enum = GL_DOT3_RGBA_ARB; + } else if(isExtensionSupported(tmpExtensionStr,"GL_EXT_texture_env_dot3" )) { + ctxInfo->textureCombineDot3Available = JNI_TRUE; + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_COMBINE_DOT3; + ctxInfo->combine_dot3_rgb_enum = GL_DOT3_RGB_EXT; + ctxInfo->combine_dot3_rgba_enum = GL_DOT3_RGBA_EXT; + } + + if (isExtensionSupported(tmpExtensionStr, "GL_ARB_texture_cube_map")) { + ctxInfo->texture_cube_map_ext_enum = GL_TEXTURE_CUBE_MAP_ARB; + ctxInfo->textureCubeMapAvailable = JNI_TRUE; + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_CUBE_MAP; + } else if (isExtensionSupported(tmpExtensionStr, "GL_EXT_texture_cube_map")) { + ctxInfo->texture_cube_map_ext_enum = GL_TEXTURE_CUBE_MAP_EXT; + ctxInfo->textureCubeMapAvailable = JNI_TRUE; + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_CUBE_MAP; + } + + if (isExtensionSupported(tmpExtensionStr, "GL_SGIS_sharpen_texture")) { + ctxInfo->textureSharpenAvailable = JNI_TRUE; + ctxInfo->linear_sharpen_enum = GL_LINEAR_SHARPEN_SGIS; + ctxInfo->linear_sharpen_rgb_enum = GL_LINEAR_SHARPEN_COLOR_SGIS; + ctxInfo->linear_sharpen_alpha_enum = GL_LINEAR_SHARPEN_ALPHA_SGIS; + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_SHARPEN; +#if defined(SOLARIS) || defined(__linux__) + ctxInfo->glSharpenTexFuncSGIS = + (MYPFNGLSHARPENTEXFUNCSGI) glSharpenTexFuncSGIS; +#endif +#ifdef WIN32 + ctxInfo->glSharpenTexFuncSGIS = (MYPFNGLSHARPENTEXFUNCSGI) + wglGetProcAddress("glSharpenTexFuncSGIS"); + if (ctxInfo->glSharpenTexFuncSGIS == NULL) { + /* printf("ctxInfo->glSharpenTexFuncSGIS == NULL\n"); */ + ctxInfo->textureExtMask &= ~javax_media_j3d_Canvas3D_TEXTURE_SHARPEN; + ctxInfo->textureSharpenAvailable = JNI_FALSE; + } +#endif + } + + if (isExtensionSupported(tmpExtensionStr, "GL_SGIS_detail_texture")) { + ctxInfo->textureDetailAvailable = JNI_TRUE; + ctxInfo->texture_detail_ext_enum = GL_DETAIL_TEXTURE_2D_SGIS; + ctxInfo->linear_detail_enum = GL_LINEAR_DETAIL_SGIS; + ctxInfo->linear_detail_rgb_enum = GL_LINEAR_DETAIL_COLOR_SGIS; + ctxInfo->linear_detail_alpha_enum = GL_LINEAR_DETAIL_ALPHA_SGIS; + ctxInfo->texture_detail_mode_enum = GL_DETAIL_TEXTURE_MODE_SGIS; + ctxInfo->texture_detail_level_enum = GL_DETAIL_TEXTURE_LEVEL_SGIS; + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_DETAIL; +#if defined(SOLARIS) || defined(__linux__) + ctxInfo->glDetailTexFuncSGIS = + (MYPFNGLDETAILTEXFUNCSGI) glDetailTexFuncSGIS; +#endif +#ifdef WIN32 + ctxInfo->glDetailTexFuncSGIS = (MYPFNGLDETAILTEXFUNCSGI) + wglGetProcAddress("glDetailTexFuncSGIS"); + if (ctxInfo->glDetailTexFuncSGIS == NULL) { + /* printf("ctxInfo->glDetailTexFuncSGIS == NULL\n"); */ + ctxInfo->textureExtMask &= ~javax_media_j3d_Canvas3D_TEXTURE_DETAIL; + ctxInfo->textureDetailAvailable = JNI_FALSE; + } +#endif + } + + if (isExtensionSupported(tmpExtensionStr, "GL_SGIS_texture_filter4")) { + ctxInfo->textureFilter4Available = JNI_TRUE; + ctxInfo->filter4_enum = GL_FILTER4_SGIS; + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_FILTER4; +#if defined(SOLARIS) || defined(__linux__) + ctxInfo->glTexFilterFuncSGIS = + (MYPFNGLTEXFILTERFUNCSGI) glTexFilterFuncSGIS; +#endif +#ifdef WIN32 + ctxInfo->glTexFilterFuncSGIS = (MYPFNGLTEXFILTERFUNCSGI) + wglGetProcAddress("glTexFilterFuncSGIS"); + if (ctxInfo->glTexFilterFuncSGIS == NULL) { + /* printf("ctxInfo->glTexFilterFuncSGIS == NULL\n"); */ + ctxInfo->textureExtMask &= ~javax_media_j3d_Canvas3D_TEXTURE_FILTER4; + ctxInfo->textureFilter4Available = JNI_FALSE; + } +#endif + } + + if (isExtensionSupported(tmpExtensionStr, + "GL_EXT_texture_filter_anisotropic")) { + ctxInfo->textureAnisotropicFilterAvailable = JNI_TRUE; + ctxInfo->texture_filter_anisotropic_ext_enum = + GL_TEXTURE_MAX_ANISOTROPY_EXT; + ctxInfo->max_texture_filter_anisotropy_enum = + GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT; + ctxInfo->textureExtMask |= + javax_media_j3d_Canvas3D_TEXTURE_ANISOTROPIC_FILTER; + } + + if (isExtensionSupported(tmpExtensionStr, + "GL_ARB_texture_border_clamp")) { + ctxInfo->texture_clamp_to_border_enum = GL_CLAMP_TO_BORDER_ARB; + } else if (isExtensionSupported(tmpExtensionStr, + "GL_SGIS_texture_border_clamp")) { + ctxInfo->texture_clamp_to_border_enum = GL_CLAMP_TO_BORDER_SGIS; + } else { + ctxInfo->texture_clamp_to_border_enum = GL_CLAMP; + } + + if (isExtensionSupported(tmpExtensionStr, + "GL_SGIX_texture_lod_bias")) { + ctxInfo->textureLodBiasAvailable = JNI_TRUE; + ctxInfo->textureExtMask |= + javax_media_j3d_Canvas3D_TEXTURE_LOD_OFFSET; + } +} + +BOOL getJavaBoolEnv(JNIEnv *env, char* envStr) +{ + JNIEnv table = *env; + jclass cls; + jfieldID fieldID; + jobject obj; + + cls = (jclass) (*(table->FindClass))(env, "javax/media/j3d/VirtualUniverse"); + + if (cls == NULL) { + return FALSE; + } + + fieldID = (jfieldID) (*(table->GetStaticFieldID))(env, cls, "mc", + "Ljavax/media/j3d/MasterControl;"); + if (fieldID == NULL) { + return FALSE; + } + + obj = (*(table->GetStaticObjectField))(env, cls, fieldID); + + if (obj == NULL) { + return FALSE; + } + + cls = (jclass) (*(table->FindClass))(env, "javax/media/j3d/MasterControl"); + + if (cls == NULL) { + return FALSE; + } + + fieldID = (jfieldID) (*(table->GetFieldID))(env, cls, envStr, "Z"); + + if (fieldID == NULL ) { + return FALSE; + } + + return (*(table->GetBooleanField))(env, obj, fieldID); +} + + +/* + * get properties from current context + */ +BOOL getPropertiesFromCurrentContext( + JNIEnv *env, + jobject obj, + GraphicsContextPropertiesInfo *ctxInfo, + jlong hdc, + int pixelFormat, + long display, + jlong vinfo) +{ + JNIEnv table = *env; + + /* version and extension */ + char *glversion; + char *extensionStr; + char *tmpVersionStr; + char *tmpExtensionStr; + int versionNumbers[2]; + char *cgHwStr = 0; + int stencilSize; + +#ifdef WIN32 + PFNWGLGETPIXELFORMATATTRIBIVEXTPROC wglGetPixelFormatAttribivEXT = NULL; + PIXELFORMATDESCRIPTOR pfd; + int attr[3]; + int piValues[2]; +#endif + + /* get OpenGL version */ + glversion = (char *)glGetString(GL_VERSION); + if (glversion == NULL) { + fprintf(stderr, "glversion == null\n"); + return FALSE; + } + gl_VERSION = glversion; + tmpVersionStr = strdup(glversion); + gl_VENDOR = (char *)glGetString(GL_VENDOR); + if (gl_VENDOR == NULL) { + gl_VENDOR = ""; + } + + /* Get the extension */ + extensionStr = (char *)glGetString(GL_EXTENSIONS); + if (extensionStr == NULL) { + fprintf(stderr, "extensionStr == null\n"); + return FALSE; + } + tmpExtensionStr = strdup(extensionStr); + + ctxInfo->versionStr = strdup(glversion); + ctxInfo->extensionStr = strdup(extensionStr); + + + /* find out the version, major and minor version number */ + extractVersionInfo(tmpVersionStr, versionNumbers); + + /* *********************************************************/ + /* setup the graphics context properties */ + if (versionNumbers[1] >= 2) { /* check 1.2 core and above */ + /* 1.2 core */ + ctxInfo->rescale_normal_ext = JNI_TRUE; + ctxInfo->rescale_normal_ext_enum = GL_RESCALE_NORMAL; + ctxInfo->bgr_ext = JNI_TRUE; + ctxInfo->bgr_ext_enum = GL_BGR; + ctxInfo->texture3DAvailable = JNI_TRUE; + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_3D; +#if defined(SOLARIS) || defined(__linux__) + ctxInfo->glTexImage3DEXT = (MYPFNGLTEXIMAGE3DPROC )glTexImage3D; + ctxInfo->glTexSubImage3DEXT = (MYPFNGLTEXSUBIMAGE3DPROC )glTexSubImage3D; +#endif +#ifdef WIN32 + ctxInfo->glTexImage3DEXT = (MYPFNGLTEXIMAGE3DPROC )wglGetProcAddress("glTexImage3D"); + ctxInfo->glTexSubImage3DEXT = (MYPFNGLTEXSUBIMAGE3DPROC )wglGetProcAddress("glTexSubImage3D"); + if ((ctxInfo->glTexImage3DEXT == NULL) || (ctxInfo->glTexSubImage3DEXT == NULL)) { + ctxInfo->textureExtMask &= ~javax_media_j3d_Canvas3D_TEXTURE_3D; + ctxInfo->texture3DAvailable = JNI_FALSE; + } +#endif + ctxInfo->texture_3D_ext_enum = GL_TEXTURE_3D; + ctxInfo->texture_wrap_r_ext_enum = GL_TEXTURE_WRAP_R; + ctxInfo->texture_clamp_to_edge_enum = GL_CLAMP_TO_EDGE; + + if(isExtensionSupported(tmpExtensionStr, "GL_ARB_imaging")){ + ctxInfo->blend_color_ext = JNI_TRUE; + ctxInfo->blendFunctionTable[7] = GL_CONSTANT_COLOR; +#if defined(SOLARIS) || defined(__linux__) + ctxInfo->glBlendColor = (MYPFNGLBLENDCOLORPROC )glBlendColor; +#endif +#ifdef WIN32 + ctxInfo->glBlendColor = (MYPFNGLBLENDCOLORPROC )wglGetProcAddress("glBlendColor"); + if (ctxInfo->glBlendColor == NULL) { + ctxInfo->blend_color_ext = JNI_FALSE; + } +#endif + } + + ctxInfo->seperate_specular_color = JNI_TRUE; + ctxInfo->light_model_color_control_enum = GL_LIGHT_MODEL_COLOR_CONTROL; + ctxInfo->single_color_enum = GL_SINGLE_COLOR; + ctxInfo->seperate_specular_color_enum = GL_SEPARATE_SPECULAR_COLOR; + + ctxInfo->textureLodAvailable = JNI_TRUE; + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_LOD_RANGE; + ctxInfo->texture_min_lod_enum = GL_TEXTURE_MIN_LOD; + ctxInfo->texture_max_lod_enum = GL_TEXTURE_MAX_LOD; + ctxInfo->texture_base_level_enum = GL_TEXTURE_BASE_LEVEL; + ctxInfo->texture_max_level_enum = GL_TEXTURE_MAX_LEVEL; + + /* ... */ + + } else { /* check 1.1 extension */ + if(isExtensionSupported(tmpExtensionStr,"GL_EXT_rescale_normal")){ + ctxInfo->rescale_normal_ext = JNI_TRUE; + ctxInfo->rescale_normal_ext_enum = GL_RESCALE_NORMAL_EXT; + } + if(isExtensionSupported(tmpExtensionStr,"GL_BGR_EXT")) { + ctxInfo->bgr_ext = 1; + ctxInfo->bgr_ext_enum = GL_BGR_EXT; + } + + if(isExtensionSupported(tmpExtensionStr,"GL_EXT_texture3D" )){ + ctxInfo->texture3DAvailable = JNI_TRUE; + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_3D; + ctxInfo->texture_3D_ext_enum = GL_TEXTURE_3D_EXT; + ctxInfo->texture_wrap_r_ext_enum = GL_TEXTURE_WRAP_R_EXT; +#if defined(SOLARIS) || defined(__linux__) + ctxInfo->glTexImage3DEXT = (MYPFNGLTEXIMAGE3DPROC )glTexImage3DEXT; + ctxInfo->glTexSubImage3DEXT = (MYPFNGLTEXSUBIMAGE3DPROC )glTexSubImage3DEXT; + /* Fallback to non-EXT variants, needed for older + NVIDIA drivers which announce GL_EXT_texture3D but + don't have the EXT variants */ + if (ctxInfo->glTexImage3DEXT == NULL || + ctxInfo->glTexSubImage3DEXT == NULL) { + + ctxInfo->glTexImage3DEXT = + (MYPFNGLTEXIMAGE3DPROC) glTexImage3D; + ctxInfo->glTexSubImage3DEXT = + (MYPFNGLTEXSUBIMAGE3DPROC) glTexSubImage3D; + + if (ctxInfo->glTexImage3DEXT == NULL || + ctxInfo->glTexSubImage3DEXT == NULL) { + + ctxInfo->textureExtMask &= + ~javax_media_j3d_Canvas3D_TEXTURE_3D; + ctxInfo->texture3DAvailable = JNI_FALSE; + } + } + +#endif +#ifdef WIN32 + ctxInfo->glTexImage3DEXT = (MYPFNGLTEXIMAGE3DPROC )wglGetProcAddress("glTexImage3DEXT"); + ctxInfo->glTexSubImage3DEXT = (MYPFNGLTEXSUBIMAGE3DPROC )wglGetProcAddress("glTexSubImage3DEXT"); + if ((ctxInfo->glTexImage3DEXT == NULL) || (ctxInfo->glTexSubImage3DEXT == NULL)) { + ctxInfo->textureExtMask &= ~javax_media_j3d_Canvas3D_TEXTURE_3D; + ctxInfo->texture3DAvailable = JNI_FALSE; + } +#endif + } + + + if(isExtensionSupported(tmpExtensionStr, "GL_EXT_texture_edge_clamp")) { + ctxInfo->texture_clamp_to_edge_enum = GL_CLAMP_TO_EDGE_EXT; + } else if(isExtensionSupported(tmpExtensionStr, "GL_SGIS_texture_edge_clamp")) { + ctxInfo->texture_clamp_to_edge_enum = GL_CLAMP_TO_EDGE_SGIS; + } else { + /* fallback to GL_CLAMP */ + ctxInfo->texture_clamp_to_edge_enum = GL_CLAMP; + } + + + if(isExtensionSupported(tmpExtensionStr, "GL_EXT_blend_color")){ + ctxInfo->blend_color_ext = JNI_TRUE; +#if defined(SOLARIS) || defined(__linux__) + ctxInfo->glBlendColor = (MYPFNGLBLENDCOLOREXTPROC )glBlendColorEXT; +#endif +#ifdef WIN32 + ctxInfo->glBlendColor = (MYPFNGLBLENDCOLOREXTPROC )wglGetProcAddress("glBlendColorEXT"); + if (ctxInfo->glBlendColor == NULL) { + ctxInfo->blend_color_ext = JNI_FALSE; + } +#endif + ctxInfo->blendFunctionTable[7] = GL_CONSTANT_COLOR_EXT; + } + + if(isExtensionSupported(tmpExtensionStr,"GL_EXT_separate_specular_color" )){ + ctxInfo->seperate_specular_color = JNI_TRUE; + ctxInfo->light_model_color_control_enum = GL_LIGHT_MODEL_COLOR_CONTROL_EXT; + ctxInfo->single_color_enum = GL_SINGLE_COLOR_EXT; + ctxInfo->seperate_specular_color_enum = GL_SEPARATE_SPECULAR_COLOR_EXT ; + } + + if (isExtensionSupported(tmpExtensionStr,"GL_SGIS_texture_lod")) { + ctxInfo->textureLodAvailable = JNI_TRUE; + ctxInfo->textureExtMask |= javax_media_j3d_Canvas3D_TEXTURE_LOD_RANGE; + ctxInfo->texture_min_lod_enum = GL_TEXTURE_MIN_LOD_SGIS; + ctxInfo->texture_max_lod_enum = GL_TEXTURE_MAX_LOD_SGIS; + ctxInfo->texture_base_level_enum = GL_TEXTURE_BASE_LEVEL_SGIS; + ctxInfo->texture_max_level_enum = GL_TEXTURE_MAX_LEVEL_SGIS; + } + + + /* ... */ + } + + + + /* check extensions for remaining of 1.1 and 1.2 */ + if(isExtensionSupported(tmpExtensionStr, "GL_EXT_multi_draw_arrays")){ + ctxInfo->multi_draw_arrays_ext = JNI_TRUE; + } + if(isExtensionSupported(tmpExtensionStr, "GL_SUN_multi_draw_arrays")){ + ctxInfo->multi_draw_arrays_sun = JNI_TRUE; + } + + + if (isExtensionSupported(tmpExtensionStr, "GL_EXT_compiled_vertex_array") && + getJavaBoolEnv(env, "isCompliedVertexArray")) { + ctxInfo->compiled_vertex_array_ext = JNI_TRUE; + } + + + if(isExtensionSupported(tmpExtensionStr, "GLX_SUN_video_resize")){ + ctxInfo->videoResizeAvailable = JNI_TRUE; + ctxInfo->extMask |= javax_media_j3d_Canvas3D_SUN_VIDEO_RESIZE; + } + + if(isExtensionSupported(tmpExtensionStr, "GL_SUN_global_alpha")){ + ctxInfo->global_alpha_sun = JNI_TRUE; + } + + if(isExtensionSupported(tmpExtensionStr, "GL_SUNX_constant_data")){ + ctxInfo->constant_data_sun = JNI_TRUE; + } + + if(isExtensionSupported(tmpExtensionStr, "GL_EXT_abgr")) { + ctxInfo->abgr_ext = JNI_TRUE; + } + + if(isExtensionSupported(tmpExtensionStr, "GL_ARB_transpose_matrix")) { + ctxInfo->arb_transpose_matrix = JNI_TRUE; + } + + if(isExtensionSupported(tmpExtensionStr, "GL_SUNX_geometry_compression")) { + ctxInfo->geometry_compression_sunx = JNI_TRUE ; + } + +#if defined(SOLARIS) || defined(__linux__) + /* + * setup ARB_multisample, under windows this is setup in + * NativeConfigTemplate when pixel format is choose + */ + if (isExtensionSupported(tmpExtensionStr, "GL_ARB_multisample")){ + ctxInfo->arb_multisample = JNI_TRUE; + + } +#endif + +#ifdef WIN32 + wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) + wglGetProcAddress("wglGetPixelFormatAttribivARB"); + + if (wglGetPixelFormatAttribivEXT == NULL) { + wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) + wglGetProcAddress("wglGetPixelFormatAttribivEXT"); + } + + ctxInfo->arb_multisample = JNI_FALSE; + if (wglGetPixelFormatAttribivEXT != NULL) { + attr[0] = WGL_SAMPLE_BUFFERS_ARB; + attr[1] = WGL_SAMPLES_ARB; + attr[2] = 0; + + if (wglGetPixelFormatAttribivEXT((HDC) hdc, pixelFormat, 0, 2, attr, piValues)) { + if ((piValues[0] == TRUE) && (piValues[1] > 1)) { + ctxInfo->arb_multisample = JNI_TRUE; + } + } + } +#endif + + /* + * Disable multisample by default since OpenGL will enable + * it by default if the surface is multisample capable. + */ + if (ctxInfo->arb_multisample && !ctxInfo->implicit_multisample) { + glDisable(MULTISAMPLE_ARB); + } + /* + * checking of the texture extensions is done in checkTextureExtensions(), + * so that the same function can be used for queryContext as well + */ + checkTextureExtensions(env, obj, tmpExtensionStr, versionNumbers[1], + ctxInfo); + + + + + /* ... */ + + /* *********************************************************/ + /* Set up rescale_normal if extension supported */ + if (ctxInfo->rescale_normal_ext ) { + ctxInfo->extMask |= javax_media_j3d_Canvas3D_EXT_RESCALE_NORMAL; + } + + /* Setup the multi_draw_array */ + if(ctxInfo->multi_draw_arrays_ext) { + ctxInfo->extMask |= javax_media_j3d_Canvas3D_EXT_MULTI_DRAW_ARRAYS; + } else if (ctxInfo->multi_draw_arrays_sun) { + ctxInfo->extMask |= javax_media_j3d_Canvas3D_SUN_MULTI_DRAW_ARRAYS; + } + if(ctxInfo->compiled_vertex_array_ext) { + ctxInfo->extMask |= javax_media_j3d_Canvas3D_EXT_COMPILED_VERTEX_ARRAYS; + } + + + /* Setup GL_SUN_gloabl_alpha */ + if (ctxInfo->global_alpha_sun) { + ctxInfo->extMask |= javax_media_j3d_Canvas3D_SUN_GLOBAL_ALPHA; + } + + /* Setup GL_SUNX_constant_data */ + if (ctxInfo->constant_data_sun) { + ctxInfo->extMask |= javax_media_j3d_Canvas3D_SUN_CONSTANT_DATA; + } + + /* Setup GL_EXT_abgr */ + if (ctxInfo->abgr_ext) { + ctxInfo->extMask |= javax_media_j3d_Canvas3D_EXT_ABGR; + } + + /* Setup GL_BGR_EXT */ + if (ctxInfo->bgr_ext) { + ctxInfo->extMask |= javax_media_j3d_Canvas3D_EXT_BGR; + } + + /* Setup GL_ARB_transpose_matrix */ + if (ctxInfo->arb_transpose_matrix) { + ctxInfo->extMask |= javax_media_j3d_Canvas3D_ARB_TRANSPOSE_MATRIX; + } + + /* + * Check for compressed geometry extensions and see if hardware + * acceleration is supported in the runtime environment. + */ + if (ctxInfo->geometry_compression_sunx) { + cgHwStr = (char *)glGetString(GL_COMPRESSED_GEOM_ACCELERATED_SUNX) ; + } + + if (cgHwStr == 0 || strstr(cgHwStr, " ")) { + ctxInfo->geometry_compression_accelerated = 0 ; + + } else { + char *tmp = strdup(cgHwStr) ; + + ctxInfo->geometry_compression_accelerated_major_version = + atoi(strtok(tmp, ".")) ; + ctxInfo->geometry_compression_accelerated_minor_version = + atoi(strtok(0, ".")) ; + ctxInfo->geometry_compression_accelerated_subminor_version = + atoi(strtok(0, ".")) ; + + free(tmp) ; + ctxInfo->geometry_compression_accelerated = 1 ; + } + + + /* Setup GL_EXT_separate_specular_color */ + if(ctxInfo->seperate_specular_color) { + ctxInfo->extMask |= javax_media_j3d_Canvas3D_EXT_SEPARATE_SPECULAR_COLOR; + } + + if (ctxInfo->constant_data_sun) { + /* glPixelStorei(GL_UNPACK_CONSTANT_DATA_SUNX, GL_TRUE); */ + } + + if(ctxInfo->arb_multisample) { + ctxInfo->extMask |= javax_media_j3d_Canvas3D_ARB_MULTISAMPLE; + } + + /* setup those functions pointers */ +#ifdef WIN32 + + if (ctxInfo->multi_draw_arrays_ext) { + ctxInfo->glMultiDrawArraysEXT = (MYPFNGLMULTIDRAWARRAYSEXTPROC)wglGetProcAddress("glMultiDrawArraysEXT"); + ctxInfo->glMultiDrawElementsEXT = (MYPFNGLMULTIDRAWELEMENTSEXTPROC)wglGetProcAddress("glMultiDrawElementsEXT"); + if ((ctxInfo->glMultiDrawArraysEXT == NULL) || + (ctxInfo->glMultiDrawElementsEXT == NULL)) { + ctxInfo->multi_draw_arrays_ext = JNI_FALSE; + } + } + else if (ctxInfo->multi_draw_arrays_sun) { + ctxInfo->glMultiDrawArraysEXT = (MYPFNGLMULTIDRAWARRAYSEXTPROC)wglGetProcAddress("glMultiDrawArraysSUN"); + ctxInfo->glMultiDrawElementsEXT = (MYPFNGLMULTIDRAWELEMENTSEXTPROC)wglGetProcAddress("glMultiDrawElementsSUN"); + if ((ctxInfo->glMultiDrawArraysEXT == NULL) || + (ctxInfo->glMultiDrawElementsEXT == NULL)) { + ctxInfo->multi_draw_arrays_sun = JNI_FALSE; + } + + } + if (ctxInfo->compiled_vertex_array_ext) { + ctxInfo->glLockArraysEXT = (MYPFNGLLOCKARRAYSEXTPROC)wglGetProcAddress("glLockArraysEXT"); + ctxInfo->glUnlockArraysEXT = (MYPFNGLUNLOCKARRAYSEXTPROC)wglGetProcAddress("glUnlockArraysEXT"); + if ((ctxInfo->glLockArraysEXT == NULL) || + (ctxInfo->glUnlockArraysEXT == NULL)) { + ctxInfo->compiled_vertex_array_ext = JNI_FALSE; + } + } + + if (ctxInfo->arb_multitexture) { + ctxInfo->glClientActiveTextureARB = (MYPFNGLCLIENTACTIVETEXTUREARBPROC)wglGetProcAddress("glClientActiveTextureARB"); + ctxInfo->glMultiTexCoord2fvARB = (MYPFNGLMULTITEXCOORD2FVARBPROC)wglGetProcAddress("glMultiTexCoord2fvARB"); + ctxInfo->glMultiTexCoord3fvARB = (MYPFNGLMULTITEXCOORD3FVARBPROC)wglGetProcAddress("glMultiTexCoord3fvARB"); + ctxInfo->glMultiTexCoord4fvARB = (MYPFNGLMULTITEXCOORD4FVARBPROC)wglGetProcAddress("glMultiTexCoord4fvARB"); + ctxInfo->glActiveTextureARB = (MYPFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB"); + /* + if (ctxInfo->glClientActiveTextureARB == NULL) { + printf("ctxInfo->glClientActiveTextureARB == NULL\n"); + } + if (ctxInfo->glMultiTexCoord2fvARB == NULL) { + printf("ctxInfo->glMultiTexCoord2fvARB == NULL\n"); + } + if (ctxInfo->glMultiTexCoord3fvARB == NULL) { + printf("ctxInfo->glMultiTexCoord3fvARB == NULL\n"); + } + if (ctxInfo->glMultiTexCoord4fvARB == NULL) { + printf("ctxInfo->glMultiTexCoord4fvARB == NULL\n"); + } + if (ctxInfo->glActiveTextureARB == NULL) { + printf("ctxInfo->glActiveTextureARB == NULL\n"); + } + */ + if ((ctxInfo->glClientActiveTextureARB == NULL) || + (ctxInfo->glMultiTexCoord2fvARB == NULL) || + (ctxInfo->glMultiTexCoord3fvARB == NULL) || + (ctxInfo->glMultiTexCoord4fvARB == NULL) || + (ctxInfo->glActiveTextureARB == NULL)) { + ctxInfo->arb_multitexture = JNI_FALSE; + } + } + + if(ctxInfo->arb_transpose_matrix) { + ctxInfo->glLoadTransposeMatrixdARB = (MYPFNGLLOADTRANSPOSEMATRIXDARBPROC)wglGetProcAddress("glLoadTransposeMatrixdARB"); + ctxInfo->glMultTransposeMatrixdARB = (MYPFNGLMULTTRANSPOSEMATRIXDARBPROC)wglGetProcAddress("glMultTransposeMatrixdARB"); + /* + if (ctxInfo->glLoadTransposeMatrixdARB == NULL) { + printf("ctxInfo->glLoadTransposeMatrixdARB == NULL\n"); + } + if (ctxInfo->glMultTransposeMatrixdARB == NULL) { + printf("ctxInfo->glMultTransposeMatrixdARB == NULL\n"); + } + */ + if ((ctxInfo->glLoadTransposeMatrixdARB == NULL) || + (ctxInfo->glMultTransposeMatrixdARB == NULL)) { + ctxInfo->arb_transpose_matrix = JNI_FALSE; + } + } + + if (ctxInfo->global_alpha_sun) { + ctxInfo->glGlobalAlphaFactorfSUN = (MYPFNGLGLOBALALPHAFACTORFSUNPROC )wglGetProcAddress("glGlobalAlphaFactorfSUN"); + + if (ctxInfo->glGlobalAlphaFactorfSUN == NULL) { + /* printf("ctxInfo->glGlobalAlphaFactorfSUN == NULL\n");*/ + ctxInfo->global_alpha_sun = JNI_FALSE; + } + } + + + DescribePixelFormat((HDC) hdc, pixelFormat, sizeof(pfd), &pfd); + + stencilSize = pfd.cStencilBits; +#endif + +#if defined(SOLARIS) || defined(__linux__) + if(ctxInfo->multi_draw_arrays_ext) { + ctxInfo->glMultiDrawArraysEXT = glMultiDrawArraysEXT; + ctxInfo->glMultiDrawElementsEXT = glMultiDrawElementsEXT; + } + else if (ctxInfo->multi_draw_arrays_sun) { + ctxInfo->glMultiDrawArraysEXT = glMultiDrawArraysSUN; + ctxInfo->glMultiDrawElementsEXT = glMultiDrawElementsSUN; + } + if(ctxInfo->compiled_vertex_array_ext) { + ctxInfo->glLockArraysEXT = glLockArraysEXT; + ctxInfo->glUnlockArraysEXT = glUnlockArraysEXT; + } + + if(ctxInfo->arb_multitexture){ + ctxInfo->glClientActiveTextureARB = glClientActiveTextureARB; + ctxInfo->glMultiTexCoord2fvARB = glMultiTexCoord2fvARB; + ctxInfo->glMultiTexCoord3fvARB = glMultiTexCoord3fvARB; + ctxInfo->glMultiTexCoord4fvARB = glMultiTexCoord4fvARB; + ctxInfo->glActiveTextureARB = glActiveTextureARB; + } + if(ctxInfo->arb_transpose_matrix) { + ctxInfo->glLoadTransposeMatrixdARB = glLoadTransposeMatrixdARB; + ctxInfo->glMultTransposeMatrixdARB = glMultTransposeMatrixdARB; + } + if(ctxInfo->global_alpha_sun) + ctxInfo->glGlobalAlphaFactorfSUN = glGlobalAlphaFactorfSUN; + + + glXGetConfig((Display *) display, (XVisualInfo *) vinfo, GLX_STENCIL_SIZE, &stencilSize); + +#endif + + if (stencilSize > 1) { + ctxInfo->extMask |= javax_media_j3d_Canvas3D_STENCIL_BUFFER; + } + + + /* ... */ + + /* clearing up the memory */ + free(tmpExtensionStr); + free(tmpVersionStr); + return TRUE; +} + + +/* + * put properties to the java side + */ +void setupCanvasProperties( + JNIEnv *env, + jobject obj, + GraphicsContextPropertiesInfo *ctxInfo) +{ + jclass cv_class; + jfieldID rsc_field; + JNIEnv table = *env; + GLint param; + + cv_class = (jclass) (*(table->GetObjectClass))(env, obj); + + /* set the canvas.multiTexAccelerated flag */ + rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "multiTexAccelerated", "Z"); + (*(table->SetBooleanField))(env, obj, rsc_field, ctxInfo->arb_multitexture); + + if (ctxInfo->arb_multitexture) { + rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "numTexUnitSupported", "I"); + (*(table->SetIntField))(env, obj, rsc_field, ctxInfo->textureUnitCount); + rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "numTexCoordSupported", "I"); + (*(table->SetIntField))(env, obj, rsc_field, ctxInfo->textureUnitCount); + } + + rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "extensionsSupported", "I"); + (*(table->SetIntField))(env, obj, rsc_field, ctxInfo->extMask); + + rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "textureExtendedFeatures", "I"); + (*(table->SetIntField))(env, obj, rsc_field, ctxInfo->textureExtMask); + + /* get texture color table size */ + rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "textureColorTableSize", "I"); + (*(table->SetIntField))(env, obj, rsc_field, ctxInfo->textureColorTableSize); + + rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "nativeGraphicsVersion", "Ljava/lang/String;"); + (*(table->SetObjectField))(env, obj, rsc_field, (*env)->NewStringUTF(env, ctxInfo->versionStr)); + + if (ctxInfo->textureAnisotropicFilterAvailable) { + + float degree; + + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, °ree); + rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "anisotropicDegreeMax", "F"); + (*(table->SetFloatField))(env, obj, rsc_field, degree); + } + + rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "textureBoundaryWidthMax", "I"); + (*(table->SetIntField))(env, obj, rsc_field, 1); + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, ¶m); + rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "textureWidthMax", "I"); + (*(table->SetIntField))(env, obj, rsc_field, param); + + rsc_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, "textureHeightMax", "I"); + (*(table->SetIntField))(env, obj, rsc_field, param); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_destroyContext( + JNIEnv *env, + jclass cl, + jlong display, + jint window, + jlong ctxInfo) +{ + GraphicsContextPropertiesInfo* s = (GraphicsContextPropertiesInfo* )ctxInfo; + jlong context = s->context; + +#ifdef WIN32 + /* + * It is possible the window is removed by removeNotify() + * before the following is invoked : + * wglMakeCurrent((HDC)window, NULL); + * This will cause WinMe crash on swapBuffers() + */ + wglDeleteContext((HGLRC)context); +#endif /* WIN32 */ + +#if defined(SOLARIS) || defined(__linux__) + /* + glXMakeCurrent((Display *)display, (GLXDrawable)window, NULL); + */ + glXDestroyContext((Display *)display, (GLXContext)context); +#endif /* SOLARIS */ + /* cleanup CtxInfo and free its memory */ + cleanupCtxInfo(s); + + free(s); + + +} + +/* + * A dummy WndProc for dummy window + */ +#ifdef WIN32 +LONG WINAPI WndProc( HWND hWnd, UINT msg, + WPARAM wParam, LPARAM lParam ) +{ + + /* This function handles any messages that we didn't. */ + /* (Which is most messages) It belongs to the OS. */ + return DefWindowProc( hWnd, msg, wParam, lParam ); +} +#endif /*end of WIN32 */ + + + + +JNIEXPORT +jlong JNICALL Java_javax_media_j3d_Canvas3D_createContext( + JNIEnv *env, + jobject obj, + jlong display, + jint window, + jint vid, + jlong visInfo, + jlong sharedCtxInfo, + jboolean isSharedCtx, + jboolean offScreen) +{ + jlong gctx; + jlong sharedCtx; + + static GLboolean first_time = GL_TRUE; + static GLboolean force_normalize = GL_FALSE; + + GraphicsContextPropertiesInfo *ctxInfo = NULL; + GraphicsContextPropertiesInfo *sharedCtxStructure; + int PixelFormatID=0; + +#if defined(SOLARIS) || defined(__linux__) + GLXContext ctx; + jlong hdc; + + if(sharedCtxInfo == 0) + sharedCtx = 0; + else { + sharedCtxStructure = (GraphicsContextPropertiesInfo *)sharedCtxInfo; + sharedCtx = sharedCtxStructure->context; + } + + if (display == 0) { + fprintf(stderr, "Canvas3D_createContext: display is null\n"); + ctx = NULL; + } + else if (visInfo == 0) { + /* + * visInfo must be a valid pointer to an XVisualInfo struct returned + * by glXChooseVisual() for a physical screen. The visual id in vid + * is not sufficient for handling OpenGL with Xinerama mode disabled: + * it doesn't distinguish between the physical screens making up the + * virtual screen when the X server is running in Xinerama mode. + */ + fprintf(stderr, "Canvas3D_createContext: visual is null\n"); + ctx = NULL; + } + else { + ctx = glXCreateContext((Display *)display, (XVisualInfo *)visInfo, + (GLXContext)sharedCtx, True); + } + + + if (ctx == NULL) { + fprintf(stderr, "Canvas3D_createContext: couldn't create context\n"); + return 0; + } + + if (!glXMakeCurrent((Display *)display, (GLXDrawable)window, + (GLXContext)ctx)) { + fprintf( stderr, "Canvas3D_createContext: couldn't make current\n"); + return 0; + } + + gctx = (jlong)ctx; +#endif /* SOLARIS */ + +#ifdef WIN32 + HGLRC hrc; /* HW Rendering Context */ + HDC hdc; /* HW Device Context */ + jboolean rescale = JNI_FALSE; + JNIEnv table = *env; + DWORD err; + LPTSTR errString; + + + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, /* Version number */ + PFD_DRAW_TO_WINDOW | + PFD_SUPPORT_OPENGL| + PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 24, /* 24 bit color depth */ + 0, 0, 0, /* RGB bits and pixel sizes */ + 0, 0, 0, /* Do not care about them */ + 0, 0, /* no alpha buffer info */ + 0, 0, 0, 0, 0, /* no accumulation buffer */ + 32, /* 16 bit depth buffer */ + 0, /* no stencil buffer */ + 0, /* no auxiliary buffers */ + PFD_MAIN_PLANE, /* layer type */ + 0, /* reserved, must be 0 */ + 0, /* no layer mask */ + 0, /* no visible mask */ + 0 /* no damage mask */ + }; + + jboolean result; + + /* hWnd = (HWND) window; */ + /* or could use: hDC = GetDC(hWnd); */ + + if(sharedCtxInfo == 0) + sharedCtx = 0; + else { + sharedCtxStructure = (GraphicsContextPropertiesInfo *)sharedCtxInfo; + sharedCtx = sharedCtxStructure->context; + } + + + hdc = (HDC) window; + + if (offScreen) { + pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | + PFD_SUPPORT_GDI; + vid = -1; + sharedCtx = 0; + } + + /* vid of -1 means no vid was specified - do the old way */ + if (vid == -1) { + /* choose the "pixel format", terminology is equivalent */ + /* to UNIX "visual" */ + PixelFormatID = ChoosePixelFormat(hdc, &pfd); + + if(PixelFormatID == 0) { + fprintf(stderr,"\nERROR: pixel format ID = 0"); + return 0; + } + } + else { + PixelFormatID = vid; + } + + + SetPixelFormat(hdc, PixelFormatID, &pfd); + + hrc = wglCreateContext( hdc ); + + if (!hrc) { + err = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, err, 0, (LPTSTR)&errString, 0, NULL); + + fprintf(stderr, "wglCreateContext Failed: %s\n", errString); + return 0; + } + + if (sharedCtx != 0) { + wglShareLists( (HGLRC) sharedCtx, hrc ); + } + + result = wglMakeCurrent(hdc, hrc); + + if (!result) { + err = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, err, 0, (LPTSTR)&errString, 0, NULL); + fprintf(stderr, "wglMakeCurrent Failed: %s\n", errString); + return 0; + } + + gctx = (jlong)hrc; +#endif /* WIN32 */ + + /* allocate the structure */ + ctxInfo = (GraphicsContextPropertiesInfo *)malloc(sizeof(GraphicsContextPropertiesInfo)); + + /* initialize the structure */ + initializeCtxInfo(env, ctxInfo); + ctxInfo->context = gctx; + + if (!getPropertiesFromCurrentContext(env, obj, ctxInfo, (jlong) hdc, PixelFormatID, display, (jlong) visInfo)) { + return 0; + } + + + /* setup structure */ + + if(!isSharedCtx){ + /* Setup field in Java side */ + setupCanvasProperties(env, obj, ctxInfo); + } + + /* Set up rescale_normal if extension supported */ + if (first_time && getJavaBoolEnv(env, "isForceNormalized")) { + force_normalize = GL_TRUE; + first_time = GL_FALSE; + } + + if (force_normalize) { + /* Disable rescale normal */ + ctxInfo->rescale_normal_ext = GL_FALSE; + } + + if (ctxInfo->rescale_normal_ext ) { + glEnable(ctxInfo->rescale_normal_ext_enum); + } + else { + glEnable(GL_NORMALIZE); + } + + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glDepthFunc(GL_LEQUAL); + glEnable(GL_COLOR_MATERIAL); + glReadBuffer(GL_FRONT); + return ((jlong)ctxInfo); +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_useCtx( + JNIEnv *env, + jclass cl, + jlong ctxInfo, + jlong display, + jint window) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; +#if defined(SOLARIS) || defined(__linux__) + glXMakeCurrent((Display *)display, (GLXDrawable)window, (GLXContext)ctx); +#endif + +#ifdef WIN32 + wglMakeCurrent((HDC) window, (HGLRC) ctx); +#endif +} + +JNIEXPORT +jint JNICALL Java_javax_media_j3d_Canvas3D_getNumCtxLights( + JNIEnv *env, + jobject obj, + jlong ctxInfo) +{ + GLint nlights; + + glGetIntegerv(GL_MAX_LIGHTS, &nlights); + return((jint)nlights); +} + + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_composite( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jint px, + jint py, + jint minX, + jint minY, + jint maxX, + jint maxY, + jint rasWidth, + jbyteArray imageYdown, + jint winWidth, + jint winHeight) +{ + GLenum gltype; + JNIEnv table; + jbyte *byteData; + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + GLboolean tex3d, texCubeMap; + + table = *env; + +#ifdef VERBOSE + fprintf(stderr, "Canvas3D.composite()\n"); +#endif + /* temporarily disable fragment operations */ + /* TODO: the GL_TEXTURE_BIT may not be necessary */ + glPushAttrib(GL_ENABLE_BIT|GL_TEXTURE_BIT|GL_DEPTH_BUFFER_BIT); + + if(ctxProperties->texture3DAvailable) + tex3d = glIsEnabled(ctxProperties->texture_3D_ext_enum); + + if(ctxProperties->textureCubeMapAvailable) + texCubeMap = glIsEnabled(ctxProperties->texture_cube_map_ext_enum); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + if(ctxProperties->texture3DAvailable) + glDisable(ctxProperties->texture_3D_ext_enum); + if(ctxProperties->textureCubeMapAvailable) + glDisable(ctxProperties->texture_cube_map_ext_enum); + + glEnable(GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + /* loaded identity modelview and projection matrix */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.0, (double)winWidth, 0.0, (double)winHeight, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + /* start from upper left corner */ + glRasterPos2i(px + minX, winHeight-(py + minY)); + + glPixelZoom(1.0, -1.0); + + byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env, + imageYdown, + NULL); + /* if abgr_ext is supported then the data will be in that format */ + if (ctxProperties->abgr_ext) { + gltype = GL_ABGR_EXT; + } else { + gltype = GL_RGBA; + } + + /* + * set the actual width of data which is the width of the canvas + * because what needs to be drawn may be smaller than the canvas + */ + glPixelStorei(GL_UNPACK_ROW_LENGTH, rasWidth); + + /* + * we only need to skip pixels if width of the area to draw is smaller + * than the width of the raster + */ + + /* + * skip this many rows in the data because the size of what + * needs to be drawn may be smaller than the canvas + */ + glPixelStorei(GL_UNPACK_SKIP_ROWS, minY); + /* + * skip this many pixels in the data before drawing because + * the size of what needs to be drawn may be smaller than the + * canvas + */ + glPixelStorei(GL_UNPACK_SKIP_PIXELS, minX); + + + glDrawPixels(maxX - minX, maxY - minY, + gltype, GL_UNSIGNED_BYTE, byteData); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + + glMatrixMode(GL_PROJECTION); + + glLoadIdentity(); + + (*(table->ReleasePrimitiveArrayCritical))(env, imageYdown, byteData, 0); + + /* re-enable fragment operation if necessary */ + if(ctxProperties->texture3DAvailable) + if (tex3d) glEnable(ctxProperties->texture_3D_ext_enum); + + if(ctxProperties->textureCubeMapAvailable) + if (texCubeMap) glEnable(ctxProperties->texture_cube_map_ext_enum); + + /* Java 3D always clears the Z-buffer */ + glDepthMask(GL_TRUE); + glClear(GL_DEPTH_BUFFER_BIT); + + glPopAttrib(); +} + + +JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_Canvas3D_initTexturemapping( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jint texWidth, + jint texHeight, + jint objectId) +{ + GraphicsContextPropertiesInfo *ctxProperties = + (GraphicsContextPropertiesInfo *)ctxInfo; + GLint gltype; + GLint width; + + gltype = (ctxProperties->abgr_ext ? GL_ABGR_EXT : GL_RGBA); + + glBindTexture(GL_TEXTURE_2D, objectId); + + + glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, texWidth, + texHeight, 0, gltype, GL_UNSIGNED_BYTE, NULL); + + glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, + GL_TEXTURE_WIDTH, &width); + + if (width <= 0) { + return JNI_FALSE; + } + + /* init texture size only without filling the pixels */ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, + texHeight, 0, gltype, GL_UNSIGNED_BYTE, NULL); + + + return JNI_TRUE; +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_texturemapping( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jint px, + jint py, + jint minX, + jint minY, + jint maxX, + jint maxY, + jint texWidth, + jint texHeight, + jint rasWidth, + jint format, + jint objectId, + jbyteArray imageYdown, + jint winWidth, + jint winHeight) +{ + JNIEnv table; + GLint gltype; + GLfloat texMinU,texMinV,texMaxU,texMaxV; + GLfloat mapMinX,mapMinY,mapMaxX,mapMaxY; + GLfloat halfWidth,halfHeight; + jbyte *byteData; + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + GLboolean tex3d, texCubeMap; + + table = *env; + gltype = GL_RGBA; + + /* temporary disable fragment operation */ + glPushAttrib(GL_ENABLE_BIT|GL_TEXTURE_BIT|GL_DEPTH_BUFFER_BIT); + + if (ctxProperties->texture3DAvailable) { + tex3d = glIsEnabled(ctxProperties->texture_3D_ext_enum); + } + + if (ctxProperties->textureCubeMapAvailable) { + texCubeMap = glIsEnabled(ctxProperties->texture_cube_map_ext_enum); + } + glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + if (ctxProperties->texture3DAvailable) { + glDisable(ctxProperties->texture_3D_ext_enum); + } + if (ctxProperties->textureCubeMapAvailable) { + glDisable(ctxProperties->texture_cube_map_ext_enum); + } + /* glGetIntegerv(GL_TEXTURE_BINDING_2D,&binding); */ + glDepthMask(GL_FALSE); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glBindTexture(GL_TEXTURE_2D, objectId); + /* set up texture parameter */ + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + +#ifdef VERBOSE + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); +#endif + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_TEXTURE_2D); + + /* glGetIntegerv (GL_VIEWPORT, viewport); */ + + /* loaded identity modelview and projection matrix */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + glOrtho(0.0, (double)winWidth, 0.0, (double)winHeight,0.0, 0.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env, + imageYdown, + NULL); + + if (ctxProperties->abgr_ext) { + gltype = GL_ABGR_EXT; + } else { + switch (format) { + case FORMAT_BYTE_RGBA: + gltype = GL_RGBA; + break; + case FORMAT_BYTE_RGB: + gltype = GL_RGB; + break; + } + } + glPixelStorei(GL_UNPACK_ROW_LENGTH, rasWidth); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, minX); + glPixelStorei(GL_UNPACK_SKIP_ROWS, minY); + glTexSubImage2D(GL_TEXTURE_2D, 0, minX, minY, + maxX - minX, maxY - minY, + gltype, GL_UNSIGNED_BYTE, + byteData); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + + + (*(table->ReleasePrimitiveArrayCritical))(env, imageYdown, byteData, 0); + + texMinU = (float) minX/ (float) texWidth; + texMinV = (float) minY/ (float) texHeight; + texMaxU = (float) maxX/ (float) texWidth; + texMaxV = (float) maxY/ (float) texHeight; + halfWidth = (GLfloat)winWidth/2.0f; + halfHeight = (GLfloat)winHeight/2.0f; + + mapMinX = (float) (((px + minX)- halfWidth)/halfWidth); + mapMinY = (float) ((halfHeight - (py + maxY))/halfHeight); + mapMaxX = (float) ((px + maxX - halfWidth)/halfWidth); + mapMaxY = (float) ((halfHeight - (py + minY))/halfHeight); + +#ifdef VERBOSE + printf("(texMinU,texMinV,texMaxU,texMaxV) = (%3.2f,%3.2f,%3.2f,%3.2f)\n", + texMinU,texMinV,texMaxU,texMaxV); + printf("(mapMinX,mapMinY,mapMaxX,mapMaxY) = (%3.2f,%3.2f,%3.2f,%3.2f)\n", + mapMinX,mapMinY,mapMaxX,mapMaxY); + +#endif + glBegin(GL_QUADS); + + glTexCoord2f(texMinU, texMaxV); glVertex2f(mapMinX,mapMinY); + glTexCoord2f(texMaxU, texMaxV); glVertex2f(mapMaxX,mapMinY); + glTexCoord2f(texMaxU, texMinV); glVertex2f(mapMaxX,mapMaxY); + glTexCoord2f(texMinU, texMinV); glVertex2f(mapMinX,mapMaxY); + glEnd(); + + /* re-enable fragment operation if necessary */ + if (ctxProperties->texture3DAvailable) + if (tex3d) glEnable(ctxProperties->texture_3D_ext_enum); + + if (ctxProperties->textureCubeMapAvailable) + if (texCubeMap) glEnable(ctxProperties->texture_cube_map_ext_enum); + + + /* Java 3D always clears the Z-buffer */ + glDepthMask(GL_TRUE); + glClear(GL_DEPTH_BUFFER_BIT); + glPopAttrib(); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_clear( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jfloat r, + jfloat g, + jfloat b, + jint winWidth, + jint winHeight, + jobject pa2d, + jint imageScaleMode, + jbyteArray pixels_obj) + +{ + jclass pa2d_class; + jfieldID format_field, width_field, height_field; + int format, width, height; + GLubyte * pixels; + JNIEnv table; + GLenum gltype; + float xzoom, yzoom, zoom; + float rasterX, rasterY; + int repeatX, repeatY, i, j; + int row_length, skip_pixels, skip_rows, subwidth, subheight; + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + table = *env; + +#ifdef VERBOSE + fprintf(stderr, "Canvas3D.clear()\n"); +#endif + + if(!pa2d) { + glClearColor((float)r, (float)g, (float)b, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + } + else { + GLboolean tex3d, texCubeMap; + + /* Do a cool image blit */ + pa2d_class = (jclass) (*(table->GetObjectClass))(env, pa2d); + format_field = (jfieldID) (*(table->GetFieldID))(env, pa2d_class, + "storedYdownFormat", "I"); + width_field = (jfieldID) (*(table->GetFieldID))(env, pa2d_class, + "width", "I"); + height_field = (jfieldID) (*(table->GetFieldID))(env, pa2d_class, + "height", "I"); + + format = (int) (*(table->GetIntField))(env, pa2d, format_field); + width = (int) (*(table->GetIntField))(env, pa2d, width_field); + height = (int) (*(table->GetIntField))(env, pa2d, height_field); + + pixels = (GLubyte *) (*(table->GetPrimitiveArrayCritical))(env, + pixels_obj, NULL); + + /* temporarily disable fragment operations */ + /* TODO: the GL_TEXTURE_BIT may not be necessary */ + glPushAttrib(GL_ENABLE_BIT|GL_TEXTURE_BIT); + + if(ctxProperties->texture3DAvailable) + tex3d = glIsEnabled(ctxProperties->texture_3D_ext_enum); + + if(ctxProperties->textureCubeMapAvailable) + texCubeMap = glIsEnabled(ctxProperties->texture_cube_map_ext_enum); + + glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + if(ctxProperties->texture3DAvailable) + glDisable(ctxProperties->texture_3D_ext_enum); + + if(ctxProperties->textureCubeMapAvailable) + glDisable(ctxProperties->texture_cube_map_ext_enum); + + /* loaded identity modelview and projection matrix */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + switch (format) { + case FORMAT_BYTE_RGBA: + gltype = GL_RGBA; + break; + case FORMAT_BYTE_RGB: + gltype = GL_RGB; + break; + + case FORMAT_BYTE_ABGR: + if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */ + gltype = GL_ABGR_EXT; + } + break; + + case FORMAT_BYTE_BGR: + if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */ + gltype = ctxProperties->bgr_ext_enum ; + } + break; + + case FORMAT_BYTE_LA: + gltype = GL_LUMINANCE_ALPHA; + break; + case FORMAT_BYTE_GRAY: + case FORMAT_USHORT_GRAY: + /* TODO: throw exception */ + break; + } + + /* start from upper left corner */ + glRasterPos3f(-1.0, 1.0, 0.0); + + /* setup the pixel zoom */ + xzoom = (float)winWidth/width; + yzoom = (float)winHeight/height; + switch(imageScaleMode){ + case javax_media_j3d_Background_SCALE_NONE: + if(xzoom > 1.0f || yzoom > 1.0f) + { + /* else don't need to clear the background with background color */ + glClearColor((float)r, (float)g, (float)b, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + } + glPixelZoom(1.0, -1.0); + glDrawPixels(width, height, gltype, GL_UNSIGNED_BYTE, + pixels); + + break; + case javax_media_j3d_Background_SCALE_FIT_MIN: + if(xzoom != yzoom ) { + glClearColor((float)r, (float)g, (float)b, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + } + zoom = xzoom < yzoom? xzoom:yzoom; + glPixelZoom(zoom, -zoom); + glDrawPixels(width, height, gltype, GL_UNSIGNED_BYTE, + pixels); + + break; + case javax_media_j3d_Background_SCALE_FIT_MAX: + zoom = xzoom > yzoom? xzoom:yzoom; + glPixelZoom(zoom, -zoom); + glDrawPixels(width, height, gltype, GL_UNSIGNED_BYTE, + pixels); + + break; + case javax_media_j3d_Background_SCALE_FIT_ALL: + glPixelZoom(xzoom, -yzoom); + glDrawPixels(width, height, gltype, GL_UNSIGNED_BYTE, + pixels); + break; + case javax_media_j3d_Background_SCALE_REPEAT: + glPixelZoom(1.0, -1.0); + /* get those raster positions */ + repeatX = winWidth/width; + if(repeatX * width < winWidth) + repeatX++; + repeatY = winHeight/height; + if(repeatY * height < winHeight) + repeatY++; + for(i = 0; i < repeatX; i++) + for(j = 0; j < repeatY; j++) { + rasterX = -1.0f + (float)width/winWidth * i * 2; + rasterY = 1.0f - (float)height/winHeight * j * 2; + glRasterPos3f(rasterX, rasterY, 0.0); + glDrawPixels(width, height, gltype, GL_UNSIGNED_BYTE, + pixels); + } + break; + + case javax_media_j3d_Background_SCALE_NONE_CENTER: + if(xzoom > 1.0f || yzoom > 1.0f){ + glClearColor((float)r, (float)g, (float)b, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + } + if(xzoom >= 1.0f){ + rasterX = -(float)width/winWidth; + subwidth = width; + } + else { + rasterX = -1.0; + row_length = width; + glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length); + skip_pixels = (width-winWidth)/2; + glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels); + subwidth = winWidth; + } + if(yzoom >= 1.0f){ + rasterY = (float)height/winHeight; + subheight = height; + } + else { + rasterY = 1.0f; + skip_rows = (height-winHeight)/2; + glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows); + subheight = winHeight; + } + glRasterPos3f(rasterX, rasterY, 0.0); + glPixelZoom(1.0, -1.0); + glDrawPixels(subwidth, subheight, gltype, GL_UNSIGNED_BYTE, + pixels); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + break; + } + /* re-enable fragment operation if necessary */ + glPopAttrib(); + + if(ctxProperties->texture3DAvailable) + if (tex3d) glEnable(ctxProperties->texture_3D_ext_enum); + + if(ctxProperties->textureCubeMapAvailable) + if (texCubeMap) glEnable(ctxProperties->texture_cube_map_ext_enum); + + (*(table->ReleasePrimitiveArrayCritical))(env, pixels_obj, + (jbyte *)pixels, 0); + } + /* Java 3D always clears the Z-buffer */ + glPushAttrib(GL_DEPTH_BUFFER_BIT); + glDepthMask(GL_TRUE); + glClear(GL_DEPTH_BUFFER_BIT); + glPopAttrib(); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_textureclear(JNIEnv *env, + jobject obj, + jlong ctxInfo, + jint maxX, + jint maxY, + jfloat r, + jfloat g, + jfloat b, + jint winWidth, + jint winHeight, + jint objectId, + jint imageScaleMode, + jobject pa2d, + jboolean update) +{ + jclass pa2d_class; + jfieldID pixels_field, format_field, width_field, height_field; + jbyteArray pixels_obj; + int format, width, height; + GLubyte * pixels; + JNIEnv table; + GLenum gltype; + GLfloat texMinU, texMinV, texMaxU, texMaxV, adjustV; + GLfloat mapMinX, mapMinY, mapMaxX, mapMaxY; + GLfloat halfWidth, halfHeight; + float xzoom, yzoom, zoom; + int i, j; + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + table = *env; + + /* update = 1; */ + +#ifdef VERBOSE + fprintf(stderr, "Canvas3D.textureclear()\n"); +#endif + if(!pa2d){ + glClearColor((float)r, (float)g, (float)b, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + } + /* glPushAttrib(GL_DEPTH_BUFFER_BIT); */ + if (pa2d) { + GLboolean tex3d, texCubeMap; + + + /* Do a cool image blit */ + pa2d_class = (jclass) (*(table->GetObjectClass))(env, pa2d); + + pixels_field = (jfieldID) (*(table->GetFieldID))(env, pa2d_class, + "imageYup", "[B"); + format_field = (jfieldID) (*(table->GetFieldID))(env, pa2d_class, + "storedYupFormat", "I"); + pixels_obj = (jbyteArray)(*(table->GetObjectField))(env, pa2d, + pixels_field); + + width_field = (jfieldID) (*(table->GetFieldID))(env, pa2d_class, + "width", "I"); + height_field = (jfieldID) (*(table->GetFieldID))(env, pa2d_class, + "height", "I"); + + format = (int) (*(table->GetIntField))(env, pa2d, format_field); + width = (int) (*(table->GetIntField))(env, pa2d, width_field); + height = (int) (*(table->GetIntField))(env, pa2d, height_field); + pixels = (GLubyte *) (*(table->GetPrimitiveArrayCritical))(env, + pixels_obj, NULL); + +#ifdef VERBOSE + fprintf(stderr, "width = %d height = %d \n", width, height); +#endif + + /* temporary disable fragment operation */ + glPushAttrib(GL_ENABLE_BIT|GL_TEXTURE_BIT|GL_POLYGON_BIT); + + if(ctxProperties->texture3DAvailable) + tex3d = glIsEnabled(ctxProperties->texture_3D_ext_enum); + if(ctxProperties->textureCubeMapAvailable) + texCubeMap = glIsEnabled(ctxProperties->texture_cube_map_ext_enum); + glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + glDisable(GL_LIGHTING); + + if(ctxProperties->texture3DAvailable) + glDisable(ctxProperties->texture_3D_ext_enum); + + if(ctxProperties->textureCubeMapAvailable) + glDisable(ctxProperties->texture_cube_map_ext_enum); + + Java_javax_media_j3d_Canvas3D_resetTexCoordGeneration(env, obj, ctxInfo); + + glEnable(GL_TEXTURE_2D); + + /* reset the polygon mode */ + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + glDepthMask(GL_FALSE); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glBindTexture(GL_TEXTURE_2D, objectId); + + /* set up texture parameter */ + if(update){ + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } +#ifdef VERBOSE + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); +#endif + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + + + if(update){ + switch (format) { + case FORMAT_BYTE_RGBA: + gltype = GL_RGBA; +#ifdef VERBOSE + fprintf(stderr, "FORMAT_BYTE_RGBA\n"); +#endif + break; + case FORMAT_BYTE_RGB: + gltype = GL_RGB; +#ifdef VERBOSE + fprintf(stderr, "FORMAT_BYTE_RGB\n"); +#endif + break; + + /* GL_ABGR_EXT */ + case FORMAT_BYTE_ABGR: + if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */ + gltype = GL_ABGR_EXT; + } + break; + + /* GL_BGR_EXT or GL_BGR */ + case FORMAT_BYTE_BGR: + if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */ + gltype = ctxProperties->bgr_ext_enum; + } + break; + + case FORMAT_BYTE_LA: + gltype = GL_LUMINANCE_ALPHA; + break; + case FORMAT_BYTE_GRAY: + case FORMAT_USHORT_GRAY: + /* TODO: throw exception */ + break; + } + + /* texture map here! */ + glTexImage2D(GL_TEXTURE_2D, 0, gltype, width, + height, 0, gltype, GL_UNSIGNED_BYTE, + pixels); + } + /* loaded identity modelview and projection matrix */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glLoadIdentity(); + + xzoom = (float)winWidth/maxX; + yzoom = (float)winHeight/maxY; + switch(imageScaleMode) { + case javax_media_j3d_Background_SCALE_NONE: + if(xzoom > 1.0f || yzoom > 1.0f){ + glClearColor((float)r, (float)g, (float)b, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + } + texMinU = 0.0f; + texMinV = 0.0f; + texMaxU = 1.0f; + texMaxV = 1.0f; + halfWidth = (GLfloat)winWidth/2.0f; + halfHeight = (GLfloat)winHeight/2.0f; + mapMinX = (float) ((0 - halfWidth)/halfWidth); + mapMinY = (float) ((0 - halfHeight)/halfHeight); + mapMaxX = (float) ((maxX - halfWidth)/halfWidth); + mapMaxY = (float) ((maxY - halfHeight)/halfHeight); + adjustV = ((float)winHeight - (float)maxY)/halfHeight; + mapMinY += adjustV; + mapMaxY += adjustV; + break; + case javax_media_j3d_Background_SCALE_FIT_MIN: + if(xzoom != yzoom){ + glClearColor((float)r, (float)g, (float)b, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + } + + zoom = xzoom < yzoom? xzoom: yzoom; + texMinU = 0.0f; + texMinV = 0.0f; + texMaxU = 1.0f; + texMaxV = 1.0f; + mapMinX = -1.0f; + mapMaxY = 1.0f; + if(xzoom < yzoom){ + mapMaxX = 1.0f; + mapMinY = -1.0f + 2.0f * ( 1.0f - zoom * (float)maxY/(float) winHeight ); + } else { + mapMaxX = -1.0f + zoom * (float)maxX/winWidth * 2; + mapMinY = -1.0f; + } + break; + case javax_media_j3d_Background_SCALE_FIT_MAX: + zoom = xzoom > yzoom? xzoom: yzoom; + /*fprintf(stderr, "zoom: %f, xzoom: %f, yzoom: %f\n", zoom, xzoom, yzoom);*/ + mapMinX = -1.0f; + mapMinY = -1.0f; + mapMaxX = 1.0f; + mapMaxY = 1.0f; + if(xzoom < yzoom) { + texMinU = 0.0f; + texMinV = 0.0f; + texMaxU = (float)winWidth/maxX/zoom; + texMaxV = 1.0f; + } else { + texMinU = 0.0f; + texMinV = 1.0f - (float)winHeight/maxY/zoom; + texMaxU = 1.0f; + texMaxV = 1.0f; + } + break; + case javax_media_j3d_Background_SCALE_FIT_ALL: + texMinU = 0.0f; + texMinV = 0.0f; + texMaxU = 1.0f; + texMaxV = 1.0f; + mapMinX = -1.0f; + mapMinY = -1.0f; + mapMaxX = 1.0f; + mapMaxY = 1.0f; + break; + case javax_media_j3d_Background_SCALE_REPEAT: + /* glScalef(1.0f, -1.0f, 1.0f); */ + i = winWidth/width; + j = winHeight/height; + texMinU = 0.0f; + texMinV = (float)(j + 1) - yzoom; + texMaxU = xzoom; + texMaxV = (float)(j + 1); + mapMinX = -1.0f; + mapMinY = -1.0f; + mapMaxX = 1.0f; + mapMaxY = 1.0f; + break; + case javax_media_j3d_Background_SCALE_NONE_CENTER: + if(xzoom > 1.0f || yzoom > 1.0f){ + glClearColor((float)r, (float)g, (float)b, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + } + if(xzoom >= 1.0f){ + texMinU = 0.0f; + texMaxU = 1.0f; + mapMinX = -(float)maxX/winWidth; + mapMaxX = (float)maxX/winWidth; + } else { + texMinU = 0.5f - (float)winWidth/maxX/2; + texMaxU = 0.5f + (float)winWidth/maxX/2; + mapMinX = -1.0f; + mapMaxX = 1.0f; + } + if(yzoom >= 1.0f) { + texMinV = 0.0f; + texMaxV = 1.0f; + mapMinY = -(float)maxY/winHeight; + mapMaxY = (float)maxY/winHeight; + }else { + texMinV = 0.5f - (float)winHeight/maxY/2; + texMaxV = 0.5f + (float)winHeight/maxY/2; + mapMinY = -1.0f; + mapMaxY = 1.0f; + } + break; + } +#ifdef VERBOSE + printf("adjustV = %3.2f\n",adjustV); + printf("(texMinU,texMinV,texMaxU,texMaxV) = (%3.2f,%3.2f,%3.2f,%3.2f)\n", + texMinU,texMinV,texMaxU,texMaxV); + printf("(mapMinX,mapMinY,mapMaxX,mapMaxY) = (%3.2f,%3.2f,%3.2f,%3.2f)\n", + mapMinX,mapMinY,mapMaxX,mapMaxY); +#endif + + + glBegin(GL_QUADS); +#ifdef VERBOSE + /* glTexCoord2f(0.2, 0.2); glVertex2f(0.0,0.0); */ + /* glTexCoord2f(0.4, 0.2); glVertex2f(0.2,0.0); */ + /* glTexCoord2f(0.4, 0.4); glVertex2f(0.2,0.2); */ + /* glTexCoord2f(0.2, 0.4); glVertex2f(0.0,0.2); */ + glColor3f(1.0, 0.0, 0.0); +#endif + glTexCoord2f(texMinU, texMinV); glVertex2f(mapMinX,mapMinY); + glTexCoord2f(texMaxU, texMinV); glVertex2f(mapMaxX,mapMinY); + glTexCoord2f(texMaxU, texMaxV); glVertex2f(mapMaxX,mapMaxY); + glTexCoord2f(texMinU, texMaxV); glVertex2f(mapMinX,mapMaxY); + glEnd(); + + /* Restore texture Matrix transform */ + glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + /* re-enable fragment operation if necessary */ + glPopAttrib(); + if(ctxProperties->texture3DAvailable) + if (tex3d) glEnable(ctxProperties->texture_3D_ext_enum); + + if(ctxProperties->textureCubeMapAvailable) + if (texCubeMap) glEnable(ctxProperties->texture_cube_map_ext_enum); + + (*(table->ReleasePrimitiveArrayCritical))(env, pixels_obj, + (jbyte *)pixels, 0); + } + + /* Java 3D always clears the Z-buffer */ + glPushAttrib(GL_DEPTH_BUFFER_BIT); + glDepthMask(GL_TRUE); + glClear(GL_DEPTH_BUFFER_BIT); + glPopAttrib(); + +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setRenderMode( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jint mode, + jboolean dbEnable) +{ + GLint drawBuf; + + if (dbEnable) { + drawBuf = GL_BACK; + switch (mode) { + case 0: /* FIELD_LEFT */ + drawBuf = GL_BACK_LEFT; + break; + case 1: /* FIELD_RIGHT */ + drawBuf = GL_BACK_RIGHT; + break; + case 2: /* FIELD_ALL */ + drawBuf = GL_BACK; + break; + } + } + else { + drawBuf = GL_FRONT; + switch (mode) { + case 0: /* FIELD_LEFT */ + drawBuf = GL_FRONT_LEFT; + break; + case 1: /* FIELD_RIGHT */ + drawBuf = GL_FRONT_RIGHT; + break; + case 2: /* FIELD_ALL */ + drawBuf = GL_FRONT; + break; + } + } + +#ifdef VERBOSE + switch (drawBuf) { + case GL_FRONT_LEFT: + fprintf(stderr, "glDrawBuffer(GL_FRONT_LEFT)\n"); + break; + case GL_FRONT_RIGHT: + fprintf(stderr, "glDrawBuffer(GL_FRONT_RIGHT)\n"); + break; + case GL_FRONT: + fprintf(stderr, "glDrawBuffer(GL_FRONT)\n"); + break; + case GL_BACK_LEFT: + fprintf(stderr, "glDrawBuffer(GL_BACK_LEFT)\n"); + break; + case GL_BACK_RIGHT: + fprintf(stderr, "glDrawBuffer(GL_BACK_RIGHT)\n"); + break; + case GL_BACK: + fprintf(stderr, "glDrawBuffer(GL_BACK)\n"); + break; + default: + fprintf(stderr, "Unknown glDrawBuffer!!!\n"); + break; + } +#endif + + glDrawBuffer(drawBuf); +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_clearAccum( + JNIEnv *env, + jobject obj, + jlong ctxInfo) +{ + + glClear(GL_ACCUM_BUFFER_BIT); + +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_accum( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jfloat value) +{ + + glReadBuffer(GL_BACK); + + glAccum(GL_ACCUM, (float)value); + + glReadBuffer(GL_FRONT); + +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_accumReturn( + JNIEnv *env, + jobject obj, + jlong ctxInfo) +{ + + glAccum(GL_RETURN, 1.0); + +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setDepthBufferWriteEnable( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jboolean mode) +{ + if (mode) + glDepthMask(GL_TRUE); + else + glDepthMask(GL_FALSE); + +} + + +JNIEXPORT +jint JNICALL Java_javax_media_j3d_Canvas3D_swapBuffers( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jlong display, + jint win) +{ + +#if defined(SOLARIS) || defined(__linux__) + glXSwapBuffers((Display *)display, (Window)win); + +#endif + +#ifdef WIN32 + HDC hdc; + + hdc = (HDC) win; + + SwapBuffers(hdc); +#endif + /* + * It would be nice to do a glFinish here, but we can't do this + * in the ViewThread Java thread in MT-aware OGL libraries without + * switching from the ViewThread to the Renderer thread an extra time + * per frame. Instead, we do glFinish after every rendering but before + * swap in the Renderer thread. + */ + /* glFinish(); */ + return 0; +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_syncRender( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jboolean waitFlag) +{ + + if (waitFlag == JNI_TRUE) + glFinish(); + else + glFlush(); +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_newDisplayList( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jint id) +{ + + glNewList(id, GL_COMPILE); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_endDisplayList( + JNIEnv *env, + jobject obj, + jlong ctxInfo) +{ + + glEndList(); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_setGlobalAlpha( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jfloat alpha) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + /* GL_GLOBAL_ALPHA_SUN */ + if(ctxProperties->global_alpha_sun){ + glEnable(GL_GLOBAL_ALPHA_SUN); + ctxProperties->glGlobalAlphaFactorfSUN(alpha); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_disableGlobalAlpha( + JNIEnv *env, + jobject obj, + jlong ctxInfo) +{ + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + /* GL_GLOBAL_ALPHA_SUN */ + if(ctxProperties->global_alpha_sun){ + glDisable(GL_GLOBAL_ALPHA_SUN); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_callDisplayList( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jint id, + jboolean isNonUniformScale) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + /* resale_normal_ext */ + if (ctxProperties->rescale_normal_ext && isNonUniformScale) { + glEnable(GL_NORMALIZE); + } + + glCallList(id); + + if (ctxProperties->rescale_normal_ext && isNonUniformScale) { + glDisable(GL_NORMALIZE); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_freeDisplayList( + JNIEnv *env, + jclass cl, + jlong ctxInfo, + jint id) +{ + + glDeleteLists(id, 1); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_freeTexture( + JNIEnv *env, + jclass cl, + jlong ctxInfo, + jint id) +{ + GLuint texObj; + + if(id > 0) { + texObj = id; + glDeleteTextures(1, &texObj); + } + else + fprintf(stderr, "try to delete tex with texid <= 0. \n"); + +} + + + +JNIEXPORT jint JNICALL Java_javax_media_j3d_Canvas3D_getTextureUnitCount( + JNIEnv *env, + jobject obj, + jlong ctxInfo) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + + return ctxProperties->textureUnitCount; +} + +/* + * Method: getTextureColorTableSize + */ +int getTextureColorTableSize( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + char *extensionStr, + int minorVersion) +{ + GraphicsContextPropertiesInfo* ctxProperties = (GraphicsContextPropertiesInfo* )ctxInfo; + int size; + + if(minorVersion >= 2 && isExtensionSupported(extensionStr, "GL_ARB_imaging")){ + +#ifdef WIN32 + ctxProperties->glColorTable = (MYPFNGLCOLORTABLEPROC)wglGetProcAddress("glColorTable"); + ctxProperties->glGetColorTableParameteriv = + (MYPFNGLGETCOLORTABLEPARAMETERIVPROC)wglGetProcAddress("glGetColorTableParameteriv"); +#endif +#if defined(SOLARIS) || defined(__linux__) + ctxProperties->glColorTable = glColorTable; + ctxProperties->glGetColorTableParameteriv = glGetColorTableParameteriv; +#endif + + } else if(isExtensionSupported(extensionStr, "GL_SGI_color_table")) { +#ifdef WIN32 + ctxProperties->glColorTable = (MYPFNGLCOLORTABLEPROC)wglGetProcAddress("glColorTableSGI"); + ctxProperties->glGetColorTableParameteriv = + (MYPFNGLGETCOLORTABLEPARAMETERIVPROC)wglGetProcAddress("glGetColorTableParameterivSGI"); +#endif +#if defined(SOLARIS) || defined(__linux__) + ctxProperties->glColorTable = glColorTableSGI; + ctxProperties->glGetColorTableParameteriv = glGetColorTableParameterivSGI; +#endif + + } else { + return 0; + } + + if ((ctxProperties->glColorTable == NULL) || + (ctxProperties->glGetColorTableParameteriv == NULL)) { + return 0; + } + + ctxProperties->glColorTable(GL_PROXY_TEXTURE_COLOR_TABLE_SGI, GL_RGBA, 256, GL_RGB, + GL_INT, NULL); + ctxProperties->glGetColorTableParameteriv(GL_PROXY_TEXTURE_COLOR_TABLE_SGI, + GL_COLOR_TABLE_WIDTH_SGI, &size); + return size; +} + +/* we want to use this if available: */ +#define GLX_SGIX_pbuffer 1 + +#ifndef GLX_VERSION_1_3 +#ifdef GLX_SGIX_pbuffer +#ifdef __linux__ +typedef XID GLXPbuffer; +typedef struct __GLXFBConfigRec *GLXFBConfig; +typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; +extern GLXFBConfig * glXChooseFBConfig (Display *dpy, int screen, const int *attrib_list, int *nelements); +extern GLXPbuffer glXCreatePbuffer (Display *dpy, GLXFBConfig config, const int *attrib_list); +extern void glXDestroyPbuffer (Display *dpy, GLXPbuffer pbuf); +extern GLXFBConfigSGIX *glXChooseFBConfigSGIX(Display *dpy, int screen, const int *attribList, int *nitems); +extern GLXPbuffer glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfig config, unsigned int width, unsigned int height, const int *attribList); +extern void glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbuffer pbuf); +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_RGBA_BIT 0x00000001 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_PBUFFER_HEIGHT 0x8040 /* New for GLX 1.3 */ +#define GLX_PBUFFER_WIDTH 0x8041 /* New for GLX 1.3 */ +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_LARGEST_PBUFFER_SGIX GLX_LARGEST_PBUFFER +#else + +#define GLX_DRAWABLE_TYPE GLX_DRAWABLE_TYPE_SGIX +#define GLX_PBUFFER_BIT GLX_PBUFFER_BIT_SGIX +#define GLX_RENDER_TYPE GLX_RENDER_TYPE_SGIX +#define GLX_RGBA_BIT GLX_RGBA_BIT_SGIX +#endif +#endif /* GLX_SGIX_pbuffer */ +#else +#ifdef __linux__ +typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; +#endif /* __linux__ */ +#endif /* GLX_VERSION_1_3 */ + +#if defined(SOLARIS) || defined(__linux__) +#pragma weak glXChooseFBConfig +#pragma weak glXCreatePbuffer +#pragma weak glXDestroyPbuffer +#pragma weak glXChooseFBConfigSGIX +#pragma weak glXCreateGLXPbufferSGIX +#pragma weak glXDestroyGLXPbufferSGIX +#endif /* SOLARIS */ + + + +/* For dvr support */ +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_videoResize( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jlong display, + jint win, + jfloat dvrFactor) +{ + +#if defined(SOLARIS) || defined(__linux__) + /* Not need to do ext. supported checking. This check is done in java. */ + + /* fprintf(stderr, "Canvas3D.c -- glXVideoResize -- %d %f\n", win, dvrFactor); */ + glXVideoResizeSUN((Display *)display, (Window)win, (float) dvrFactor); +#endif + +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_videoResizeCompensation( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jboolean enable) +{ + +#if defined(SOLARIS) || defined(__linux__) + GraphicsContextPropertiesInfo *ctxProperties = + (GraphicsContextPropertiesInfo *)ctxInfo; + + if (ctxProperties->videoResizeAvailable) { + if(enable == JNI_TRUE) { + /* fprintf(stderr, "videoResizeCompensation - glEnable"); */ + glEnable(GL_VIDEO_RESIZE_COMPENSATION_SUN); + } + else { + /* fprintf(stderr, "videoResizeCompensation - glDisable"); */ + glDisable(GL_VIDEO_RESIZE_COMPENSATION_SUN); + } + } + +#endif + +} + +JNIEXPORT +jint JNICALL Java_javax_media_j3d_Canvas3D_createOffScreenBuffer( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jlong display, + jint vid, + jint width, + jint height) +{ + +#if defined(SOLARIS) || defined(__linux__) + XVisualInfo *vinfo, template; + int nitems, depth, redSize; + Display *dpy; + static GLboolean pbufferSupported = GL_FALSE; + static GLboolean pbufferExtSupported = GL_FALSE; + int major, minor; + const char *extStr; + int status; + + dpy = (Display *)display; + + if (dpy == NULL) + dpy = XOpenDisplay(NULL); + + template.visualid = vid; + vinfo = XGetVisualInfo(dpy, VisualIDMask, &template, &nitems); + if (nitems != 1) { + fprintf(stderr, "Warning Canvas3D_createContext got unexpected number of matching visuals %d\n", nitems); + } + + glXGetConfig (dpy, vinfo, GLX_BUFFER_SIZE, &depth); + glXGetConfig (dpy, vinfo, GLX_RED_SIZE, &redSize); + + if (status = glXQueryVersion(dpy, &major, &minor)) { + +#if 0 + /* don't use the 1.3 pbuffer interface for now. */ + if ((major > 1) || (major == 1 && minor >= 3)) + pbufferSupported = GL_TRUE; + else +#endif + { + extStr = glXQueryExtensionsString(dpy, DefaultScreen(dpy)); + if ((extStr != NULL) && (strstr(extStr, "GLX_SGIX_pbuffer"))) { + pbufferExtSupported = GL_TRUE; + } + } + } + +#if defined(GLX_VERSION_1_3) || defined(GLX_SGIX_pbuffer) + if (pbufferExtSupported || pbufferSupported) { + + + int attrCount, configAttr[10], numConfig, val; + GLXPbuffer pbuff; + + /* Initialize the attribute list to be used for choosing FBConfig */ + attrCount = 0; + configAttr[attrCount++] = GLX_DRAWABLE_TYPE; + configAttr[attrCount++] = GLX_PBUFFER_BIT; + configAttr[attrCount++] = GLX_RENDER_TYPE; + configAttr[attrCount++] = GLX_RGBA_BIT; + configAttr[attrCount++] = GLX_RED_SIZE; + configAttr[attrCount++] = redSize; + configAttr[attrCount++] = None; +/* + configAttr[attrCount++] = GLX_DEPTH_SIZE; + configAttr[attrCount++] = depth; +*/ + + +#ifdef GLX_VERSION_1_3 + if (pbufferSupported) { + GLXFBConfig *fbconfiglst; + + fbconfiglst = glXChooseFBConfig(dpy, DefaultScreen(dpy), + configAttr, &numConfig); + + if (numConfig < 1) { + fprintf(stderr, "# of configs returned is %d\n", numConfig); + return None; + } + + attrCount = 0; + configAttr[attrCount++] = GLX_PBUFFER_WIDTH; + configAttr[attrCount++] = width; + configAttr[attrCount++] = GLX_PBUFFER_HEIGHT; + configAttr[attrCount++] = height; + configAttr[attrCount++] = GLX_PRESERVED_CONTENTS; + configAttr[attrCount++] = GL_TRUE; + configAttr[attrCount++] = None; + + + pbuff = glXCreatePbuffer(dpy, fbconfiglst[0], configAttr); + } +#endif /* GLX_VERSION_1_3 */ + +#ifdef GLX_SGIX_pbuffer + if (pbufferExtSupported && !pbufferSupported) { + GLXFBConfigSGIX *fbconfiglst; + + + /* Determine what config to use according to config_attr */ + fbconfiglst = glXChooseFBConfigSGIX(dpy, DefaultScreen(dpy), + configAttr, &numConfig); + + if (numConfig < 1) { + fprintf(stderr, "# of configs returned is %d\n", numConfig); + return None; + } + + attrCount = 0; + configAttr[attrCount++] = GLX_PRESERVED_CONTENTS; + configAttr[attrCount++] = GL_TRUE; + configAttr[attrCount++] = None; + pbuff = glXCreateGLXPbufferSGIX(dpy, fbconfiglst[0], width, height, + configAttr ); + } +#endif /* GLX_SGIX_pbuffer */ + if (pbuff == None) { + fprintf(stderr, "glXCreateGLXPbuffer() returns None\n"); + } + + return pbuff; + + } else +#endif /* GLX_VERSION_1_3 || GLX_SGIX_pbuffer */ + + { + Pixmap pixmap; + GLXPixmap glxpixmap; + + /* fall back to pixmap */ + pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), width, height, + vinfo->depth); + + glxpixmap = glXCreateGLXPixmap(dpy, vinfo, pixmap); + if (glxpixmap == None) { + fprintf(stderr, "glXCreateGLXPixmap() returns None\n"); + } + + return glxpixmap; + } + +#endif /* SOLARIS */ + +#ifdef WIN32 + int PixelFormatID=0; + int dpy = (int)display; + HDC hdc; /* HW Device Context */ + jboolean rescale = JNI_FALSE; + JNIEnv table = *env; + + HBITMAP hbitmap, oldhbitmap; + + BITMAPINFOHEADER bih; + void *ppvBits; + int err; + LPTSTR errString; + HDC hdcMonitor; + + /* create a DIB */ + memset(&bih, 0, sizeof(BITMAPINFOHEADER)); + + bih.biSize = sizeof(BITMAPINFOHEADER); + bih.biWidth = width; + bih.biHeight = height; + bih.biPlanes = 1; + bih.biBitCount = 24; + bih.biCompression = BI_RGB; + + /* create a new device context */ + + if (dpy == 0) { + hdc = CreateCompatibleDC(0); + } else { + /* + * Should be getMonitorDC(screen) + * but display and screen are the same under windows + * They are return from NativeScreenInfo + */ + hdcMonitor = getMonitorDC((int) display); + hdc = CreateCompatibleDC(hdcMonitor); + DeleteDC(hdcMonitor); + + } + hbitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bih, + DIB_PAL_COLORS, &ppvBits, NULL, 0); + + if (!hbitmap) { + err = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, err, 0, (LPTSTR)&errString, 0, NULL); + fprintf(stderr, "CreateDIBSection failed: %s\n", errString); + } + + oldhbitmap = SelectObject(hdc, hbitmap); + + /* Choosing and setting of pixel format is done in createContext */ + + return ((jint)hdc); +#endif /* WIN32 */ +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_destroyOffScreenBuffer( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jlong display, + jint window) +{ +#if defined(SOLARIS) || defined(__linux__) + Display *dpy = (Display*)display; + + GLboolean pbufferSupported = GL_FALSE; + GLboolean pbufferExtSupported = GL_TRUE; + int major, minor; + char *extStr; + + if (glXQueryVersion(dpy, &major, &minor)) { + +#if 0 + /* don't use the 1.3 pbuffer interface for now. */ + if ((major > 1) || (major == 1 && minor >= 3)) + pbufferSupported = GL_TRUE; + else +#endif + { + extStr = (char *)glXQueryExtensionsString(dpy, + DefaultScreen(dpy)); + if ((extStr != NULL) && (strstr(extStr, "GLX_SGIX_pbuffer"))) { + pbufferExtSupported = GL_TRUE; + } + } + } + +#if defined(GLX_VERSION_1_3) || defined(GLX_SGIX_pbuffer) + + if (pbufferSupported) { + glXDestroyPbuffer(dpy, (GLXPbuffer)window); + } else if (pbufferExtSupported) { + glXDestroyGLXPbufferSGIX(dpy, (GLXPbuffer)window); + } else +#endif + + { + glXDestroyGLXPixmap(dpy, (GLXPixmap)window); + } +#endif /* SOLARIS */ + +#ifdef WIN32 + HBITMAP oldhbitmap; + HDC hdc = (HDC) window; + + oldhbitmap = SelectObject(hdc, NULL); + DeleteObject(oldhbitmap); + DeleteDC(hdc); +#endif /* WIN32 */ +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_readOffScreenBuffer( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jint format, + jint width, + jint height) +{ + JNIEnv table = *env; + jclass cv_class; + jfieldID byteData_field; + jbyteArray byteData_array; + jbyte *byteData; + int type; + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + glPixelStorei(GL_PACK_ROW_LENGTH, width); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + cv_class = (jclass) (*(table->GetObjectClass))(env, obj); + byteData_field = (jfieldID) (*(table->GetFieldID))(env, cv_class, + "byteBuffer", "[B"); + byteData_array = (jbyteArray)(*(table->GetObjectField))(env, obj, + byteData_field); + byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env, + byteData_array, NULL); + + + switch (format) { + case FORMAT_BYTE_RGBA: + type = GL_RGBA; + break; + case FORMAT_BYTE_RGB: + type = GL_RGB; + break; + + /* GL_ABGR_EXT */ + case FORMAT_BYTE_ABGR: + if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */ + type = GL_ABGR_EXT; + } + break; + + /* GL_BGR_EXT */ + case FORMAT_BYTE_BGR: + if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */ + type = ctxProperties->bgr_ext_enum; + } + break; + + case FORMAT_BYTE_LA: + type = GL_LUMINANCE_ALPHA; + break; + case FORMAT_BYTE_GRAY: + case FORMAT_USHORT_GRAY: + /* TODO: throw exception */ + break; + } + + + glReadPixels(0, 0, width, height, type, GL_UNSIGNED_BYTE, byteData); + + (*(table->ReleasePrimitiveArrayCritical))(env, byteData_array, + byteData, 0); +} + +void initializeCtxInfo(JNIEnv *env , GraphicsContextPropertiesInfo* ctxInfo){ + ctxInfo->context = 0; + + /* version and extension info */ + ctxInfo->versionStr = NULL; + ctxInfo->extensionStr = NULL; + ctxInfo->versionNumbers[0] = 1; + ctxInfo->versionNumbers[1] = 1; + + /* both in 1.2 core part and 1.1 extensions */ + ctxInfo->rescale_normal_ext = JNI_FALSE; + ctxInfo->bgr_ext = JNI_FALSE; + ctxInfo->texture3DAvailable = JNI_FALSE; + ctxInfo->seperate_specular_color = JNI_FALSE; + + /* 1.2 and GL_ARB_imaging */ + ctxInfo->blend_color_ext = JNI_FALSE; + ctxInfo->color_table_ext = JNI_FALSE; + ctxInfo->blendFunctionTable[0] = GL_ZERO; + ctxInfo->blendFunctionTable[1] = GL_ONE; + ctxInfo->blendFunctionTable[2] = GL_SRC_ALPHA; + ctxInfo->blendFunctionTable[3] = GL_ONE_MINUS_SRC_ALPHA; + ctxInfo->blendFunctionTable[4] = GL_DST_COLOR; + ctxInfo->blendFunctionTable[5] = GL_SRC_COLOR; + ctxInfo->blendFunctionTable[6] = GL_ONE_MINUS_SRC_COLOR; + ctxInfo->blendFunctionTable[7] = GL_SRC_COLOR; + + /* 1.1 extensions or 1.2 extensions */ + /* sun extensions */ + ctxInfo->multi_draw_arrays_sun = JNI_FALSE; + ctxInfo->compiled_vertex_array_ext = JNI_FALSE; + + ctxInfo->videoResizeAvailable = JNI_FALSE; + ctxInfo->global_alpha_sun = JNI_FALSE; + ctxInfo->constant_data_sun = JNI_FALSE; + ctxInfo->geometry_compression_sunx = JNI_FALSE; + + /* EXT extensions */ + ctxInfo->abgr_ext = JNI_FALSE; + + ctxInfo->multi_draw_arrays_ext = JNI_FALSE; + + ctxInfo->implicit_multisample = getJavaBoolEnv(env, "implicitAntialiasing"); + + /* ARB extensions */ + ctxInfo->arb_transpose_matrix = JNI_FALSE; + ctxInfo->arb_multitexture = JNI_FALSE; + + ctxInfo->arb_multisample = JNI_FALSE; + ctxInfo->textureUnitCount = 1; + ctxInfo->textureEnvCombineAvailable = JNI_FALSE; + ctxInfo->textureCombineDot3Available = JNI_FALSE; + ctxInfo->textureCombineSubtractAvailable = JNI_FALSE; + ctxInfo->textureCubeMapAvailable = JNI_FALSE; + + /* NV extensions */ + ctxInfo->textureRegisterCombinersAvailable = JNI_FALSE; + + /* SGI extensions */ + ctxInfo->textureSharpenAvailable = JNI_FALSE; + ctxInfo->textureDetailAvailable = JNI_FALSE; + ctxInfo->textureFilter4Available = JNI_FALSE; + ctxInfo->textureAnisotropicFilterAvailable = JNI_FALSE; + ctxInfo->textureColorTableAvailable = JNI_FALSE; + ctxInfo->textureColorTableSize = 0; + ctxInfo->textureLodAvailable = JNI_FALSE; + ctxInfo->textureLodBiasAvailable = JNI_FALSE; + + ctxInfo->geometry_compression_accelerated = JNI_FALSE; + ctxInfo->geometry_compression_accelerated_major_version = 0; + ctxInfo->geometry_compression_accelerated_minor_version = 0; + ctxInfo->geometry_compression_accelerated_subminor_version = 0; + + /* extension mask */ + ctxInfo->extMask = 0; + ctxInfo->textureExtMask = 0; + + ctxInfo->glBlendColor = NULL; + ctxInfo->glBlendColorEXT = NULL; + ctxInfo->glColorTable = NULL; + ctxInfo->glGetColorTableParameteriv = NULL; + ctxInfo->glTexImage3DEXT = NULL; + ctxInfo->glTexSubImage3DEXT = NULL; + ctxInfo->glClientActiveTextureARB = NULL; + ctxInfo->glMultiDrawArraysEXT = NULL; + ctxInfo->glMultiDrawElementsEXT = NULL; + ctxInfo->glLockArraysEXT = NULL; + ctxInfo->glUnlockArraysEXT = NULL; + ctxInfo->glMultiTexCoord2fvARB = NULL; + ctxInfo->glMultiTexCoord3fvARB = NULL; + ctxInfo->glMultiTexCoord4fvARB = NULL; + ctxInfo->glLoadTransposeMatrixdARB = NULL; + ctxInfo->glMultTransposeMatrixdARB = NULL; + ctxInfo->glActiveTextureARB = NULL; + ctxInfo->glGlobalAlphaFactorfSUN = NULL; + + ctxInfo->glCombinerInputNV = NULL; + ctxInfo->glCombinerOutputNV = NULL; + ctxInfo->glFinalCombinerInputNV = NULL; + ctxInfo->glCombinerParameterfvNV = NULL; + ctxInfo->glCombinerParameterivNV= NULL; + ctxInfo->glCombinerParameterfNV = NULL; + ctxInfo->glCombinerParameteriNV = NULL; + + ctxInfo->glSharpenTexFuncSGIS = NULL; + ctxInfo->glDetailTexFuncSGIS = NULL; + ctxInfo->glTexFilterFuncSGIS = NULL; +} + +void cleanupCtxInfo(GraphicsContextPropertiesInfo* ctxInfo){ + if( ctxInfo->versionStr != NULL) + free(ctxInfo->versionStr); + if( ctxInfo->extensionStr != NULL) + free(ctxInfo->extensionStr); + ctxInfo->versionStr = NULL; + ctxInfo->extensionStr = NULL; +} + +#ifdef WIN32 +HWND createDummyWindow(const char* szAppName) { + static char szTitle[]="A Simple C OpenGL Program"; + WNDCLASS wc; /* windows class sruct */ + + HWND hWnd; + + /* Fill in window class structure with parameters that */ + /* describe the main window. */ + + wc.style = + CS_HREDRAW | CS_VREDRAW;/* Class style(s). */ + wc.lpfnWndProc = + (WNDPROC)WndProc; /* Window Procedure */ + wc.cbClsExtra = 0; /* No per-class extra data. */ + wc.cbWndExtra = 0; /* No per-window extra data. */ + wc.hInstance = + NULL; /* Owner of this class */ + wc.hIcon = NULL; /* Icon name */ + wc.hCursor = + NULL;/* Cursor */ + wc.hbrBackground = + (HBRUSH)(COLOR_WINDOW+1);/* Default color */ + wc.lpszMenuName = NULL; /* Menu from .RC */ + wc.lpszClassName = + szAppName; /* Name to register as + + /* Register the window class */ + + if(RegisterClass( &wc )==0) + fprintf(stdout, "Couldn't register class\n"); + + /* Create a main window for this application instance. */ + + hWnd = CreateWindow( + szAppName, /* app name */ + szTitle, /* Text for window title bar */ + WS_OVERLAPPEDWINDOW/* Window style */ + /* NEED THESE for OpenGL calls to work!*/ + | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, + NULL, /* no parent window */ + NULL, /* Use the window class menu.*/ + NULL, /* This instance owns this window */ + NULL /* We don't use any extra data */ + ); + + /* If window could not be created, return zero */ + if ( !hWnd ){ + fprintf(stdout, "Couldn't Create window\n"); + return NULL; + } + return hWnd; +} +#endif + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_createQueryContext( + JNIEnv *env, + jobject obj, + jlong display, + jint window, + jint vid, + jboolean offScreen, + jint width, + jint height) +{ + JNIEnv table = *env; + jlong gctx; + long newWin; + int PixelFormatID=0; + GraphicsContextPropertiesInfo* ctxInfo = (GraphicsContextPropertiesInfo *)malloc(sizeof(GraphicsContextPropertiesInfo)); + +#if defined(SOLARIS) || defined(__linux__) + XVisualInfo *vinfo, template; + int nitems; + GLXContext ctx; + int result; + Window root; + Window glWin; + XSetWindowAttributes win_attrs; + Colormap cmap; + unsigned long win_mask; + jlong hdc; + + template.visualid = vid; + vinfo = XGetVisualInfo((Display *)display, VisualIDMask, &template, &nitems); + if (nitems != 1) { + fprintf(stderr, "Warning Canvas3D_createQueryContext got unexpected number of matching visuals %d\n", nitems); + } + + ctx = glXCreateContext((Display *)display, vinfo, NULL, True); + if (ctx == NULL) { + fprintf(stderr, "Error Canvas3D_createQueryContext: couldn't create context.\n"); + } + + + /* create window if window == 0 and offscreen == true */ + if(window == 0 && !offScreen) { + + root = RootWindow((Display *)display, vinfo->screen); + + /* Create a colormap */ + cmap = XCreateColormap((Display *)display, root, vinfo->visual, AllocNone); + + /* Create a window */ + win_attrs.colormap = cmap; + win_attrs.border_pixel = 0; + win_attrs.event_mask = KeyPressMask | ExposureMask | StructureNotifyMask; + win_mask = CWColormap | CWBorderPixel | CWEventMask; + glWin = XCreateWindow((Display *)display, root, 0, 0, width, height, 0, vinfo->depth, + InputOutput, vinfo->visual, win_mask, &win_attrs); + newWin = (unsigned long)glWin; + } + else if(window == 0 && offScreen){ + newWin = Java_javax_media_j3d_Canvas3D_createOffScreenBuffer( env, obj, 0, display, vid, width, height); + } + else if(window != 0) { + newWin = window; + } + + result = glXMakeCurrent((Display *)display, (GLXDrawable)newWin, (GLXContext)ctx); + if (result == GL_FALSE) + fprintf(stderr, "glXMakeCurrent fails\n"); + gctx = (jlong)ctx; +#endif + +#ifdef WIN32 + HGLRC hrc; /* HW Rendering Context */ + HDC hdc; /* HW Device Context */ + DWORD err; + LPTSTR errString; + HWND hWnd; + static char szAppName[] = "OpenGL"; + jlong vinfo = 0; + + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, /* Version number */ + PFD_DRAW_TO_WINDOW | + PFD_SUPPORT_OPENGL| + PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 24, /* 24 bit color depth */ + 0, 0, 0, /* RGB bits and pixel sizes */ + 0, 0, 0, /* Donnot care about them */ + 0, 0, /* no alpha buffer info */ + 0, 0, 0, 0, 0, /* no accumulation buffer */ + 32, /* 16 bit depth buffer */ + 0, /* no stencil buffer */ + 0, /* no auxiliary buffers */ + PFD_MAIN_PLANE, /* layer type */ + 0, /* reserved, must be 0 */ + 0, /* no layer mask */ + 0, /* no visible mask */ + 0 /* no damage mask */ + }; + + jboolean result; + + /* onscreen rendering and window is 0 now */ + if(window == 0 && !offScreen){ + hWnd = createDummyWindow((const char *)szAppName); + if (!hWnd) + return; + hdc = GetDC(hWnd); + } + else if(window == 0 && offScreen){ + hdc = (HDC)Java_javax_media_j3d_Canvas3D_createOffScreenBuffer( env, obj, 0, display, vid, width, height); + pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | + PFD_SUPPORT_GDI; + vid = -1; + } + else if(window != 0 && offScreen){ + pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | + PFD_SUPPORT_GDI; + vid = -1; + hdc = (HDC) window; + } + else if(window !=0 && !offScreen){ + hdc = (HDC) window; + } + + newWin = (int)hdc; + + /* vid of -1 means no vid was specified - do the old way */ + if (vid == -1) { + /* + * choose the "pixel format", terminology is equivalent + * to UNIX "visual" + */ + PixelFormatID = ChoosePixelFormat(hdc, &pfd); + + if(PixelFormatID == 0) { + fprintf(stderr,"\nERROR: pixel format ID = 0"); + return; + } + } + else + PixelFormatID = vid; + + SetPixelFormat(hdc, PixelFormatID, &pfd); + + hrc = wglCreateContext( hdc ); + + if (!hrc) { + err = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, err, 0, (LPTSTR)&errString, 0, NULL); + + fprintf(stderr, "wglCreateContext Failed: %s\n", errString); + } + + + result = wglMakeCurrent(hdc, hrc); + + if (!result) { + err = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, err, 0, (LPTSTR)&errString, 0, NULL); + fprintf(stderr, "wglMakeCurrent Failed: %s\n", errString); + } + + gctx = (jlong)hrc; + +#endif + + initializeCtxInfo(env, ctxInfo); + ctxInfo->context = gctx; + + /* get current context properties */ + if (getPropertiesFromCurrentContext(env, obj, ctxInfo, (jlong) hdc, PixelFormatID, display, (jlong) vinfo)) { + /* put the properties to the Java side */ + setupCanvasProperties(env, obj, ctxInfo); + } + + + /* clear up the context , colormap and window if appropriate */ + if(window == 0 && !offScreen){ +#if defined(SOLARIS) || defined(__linux__) + Java_javax_media_j3d_Canvas3D_destroyContext(env, obj, display, newWin, (jlong)ctxInfo); + XDestroyWindow((Display *)display, glWin); + XFreeColormap((Display *)display, cmap); +#endif /* SOLARIS */ +#ifdef WIN32 + /* Release DC */ + ReleaseDC(hWnd, hdc); + /* Destroy context */ + /* This will free ctxInfo also */ + Java_javax_media_j3d_Canvas3D_destroyContext(env, obj, display,newWin, (jlong)ctxInfo); + DestroyWindow(hWnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); +#endif /* WIN32 */ + } + else if(window == 0 && offScreen) { + Java_javax_media_j3d_Canvas3D_destroyOffScreenBuffer(env, obj, gctx, display, newWin); + Java_javax_media_j3d_Canvas3D_destroyContext(env, obj, display, newWin, (jlong)ctxInfo); + } + else if(window != 0){ + Java_javax_media_j3d_Canvas3D_destroyContext(env, obj, display, newWin, (jlong)ctxInfo); + } +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_beginScene( + JNIEnv *env, + jobject obj, + jlong ctxInfo) +{ + /* Not used by OGL version */ +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_Canvas3D_endScene( + JNIEnv *env, + jobject obj, + jlong ctxInfo) +{ + /* This function is a no-op */ + /* + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + */ +} + +/* Setup the multisampling for full scene antialiasing */ +JNIEXPORT void JNICALL Java_javax_media_j3d_Canvas3D_setFullSceneAntialiasing +(JNIEnv *env, jobject obj, jlong ctxInfo, jboolean enable) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + if (ctxProperties->arb_multisample && !ctxProperties->implicit_multisample) { + if(enable == JNI_TRUE) { + glEnable(MULTISAMPLE_ARB); + } + else { + glDisable(MULTISAMPLE_ARB); + + } + } + +} + + +/* + * Return false if <= 8 bit color under windows + */ +JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_Canvas3D_validGraphicsMode( + JNIEnv *env, + jobject obj) +{ +#ifdef WIN32 + DEVMODE devMode; + + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode); + return (devMode.dmBitsPerPel > 8); +#endif + +#if defined(SOLARIS) || defined(__linux__) + return TRUE; +#endif +} diff --git a/src/native/ogl/CompressedGeometryRetained.c b/src/native/ogl/CompressedGeometryRetained.c new file mode 100644 index 0000000..36ca164 --- /dev/null +++ b/src/native/ogl/CompressedGeometryRetained.c @@ -0,0 +1,70 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include +#include +#include "gldefs.h" + +#ifdef SOLARIS +#pragma weak glDrawCompressedGeomSUNX + +#else +static void glDrawCompressedGeomSUNX(GLint size, GLubyte *data) { + fprintf(stderr, "Warning: glDrawCompressedGeomSUNX() not supported\n") ; +} +#endif /* SOLARIS */ + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_CompressedGeometryRetained_execute + (JNIEnv *env, jobject obj, jlong ctxInfo, jint version, jint bufferType, + jint bufferContents, jint renderFlags, jint offset, jint size, + jbyteArray geometry) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + jbyte *cg = (*env)->GetPrimitiveArrayCritical(env, geometry, 0) ; + + /* ignore offset and pass header at 0 along with cg data */ + if(ctxProperties->geometry_compression_sunx) + glDrawCompressedGeomSUNX((GLint)(size + 48), (GLubyte *)cg) ; + + (*env)->ReleasePrimitiveArrayCritical(env, geometry, cg, 0) ; +} + + +JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_CompressedGeometryRetained_decompressByRef + (JNIEnv *env, jobject obj, jlong ctxInfo) +{ + return JNI_FALSE ; +} + +JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_CompressedGeometryRetained_decompressHW + (JNIEnv *env, jobject obj, jlong ctxInfo, jint majorVersion, jint minorVersion) +{ + /* + * Return true if hardware decompression is supported for the given + * version number of the compressed geometry. + */ + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + return + (ctxProperties->geometry_compression_accelerated == 1) && + ((majorVersion < ctxProperties->geometry_compression_accelerated_major_version) || + ((majorVersion == ctxProperties->geometry_compression_accelerated_major_version) && + (minorVersion <= ctxProperties->geometry_compression_accelerated_minor_version))) ; +} diff --git a/src/native/ogl/DrawingSurfaceObjectAWT.c b/src/native/ogl/DrawingSurfaceObjectAWT.c new file mode 100644 index 0000000..71e4376 --- /dev/null +++ b/src/native/ogl/DrawingSurfaceObjectAWT.c @@ -0,0 +1,268 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + * Portions of this code were derived from work done by the Blackdown + * group (www.blackdown.org), who did the initial Linux implementation + * of the Java 3D API. + */ + +#include +#include +#include +#include +#include + +#ifdef DEBUG +/* Uncomment the following for VERBOSE debug messages */ +/* #define VERBOSE */ +#endif /* DEBUG */ + + +#if defined(SOLARIS) || defined(__linux__) +#pragma weak JAWT_GetAWT +#endif + +#ifdef SOLARIS +#pragma weak XDgaGetXineramaInfo + +/* + * The following include file contains the definitions of unsupported, + * undocumented data structures and functions used to implement Xinerama. + * They are also used by the Solaris implementations of OpenGL and AWT. This + * is an interim solution until they are made part of the X Window System + * standard or replaced with a fully supported API. + */ +#include "panoramiXext.h" +#endif /* SOLARIS */ + + +JNIEXPORT jlong JNICALL +Java_javax_media_j3d_MasterControl_getAWT( + JNIEnv *env, jobject obj) +{ + JAWT *awt; + + awt = (JAWT*) malloc(sizeof(JAWT)); + if (awt == NULL) { + fprintf(stderr, "malloc failed\n"); + return 0; + } + + awt->version = JAWT_VERSION_1_4; + + if (JAWT_GetAWT(env, awt) == JNI_FALSE) { + fprintf(stderr, "AWT not found\n"); + return 0; + } + return (jlong)awt; +} + +JNIEXPORT +jlong JNICALL +Java_javax_media_j3d_DrawingSurfaceObjectAWT_getDrawingSurfaceAWT( + JNIEnv *env, + jobject obj, + jobject canvas, + jlong awtObj) +{ + JAWT *awt = (JAWT*) awtObj; + JAWT_DrawingSurface *ds; + + ds = awt->GetDrawingSurface(env, canvas); + if (ds == NULL) { + fprintf(stderr, "NULL drawing surface\n"); + return 0; + } + return (jlong)ds; +} + + +JNIEXPORT +jint JNICALL +Java_javax_media_j3d_DrawingSurfaceObjectAWT_getDrawingSurfaceWindowIdAWT( + JNIEnv *env, + jobject obj, + jobject canvas, + jlong dsObj, + jlong dsiObj, + jlong display, + jint screen, + jboolean xineramaDisabled) +{ + JAWT_DrawingSurface *ds = (JAWT_DrawingSurface*) dsObj; + JAWT_DrawingSurfaceInfo *dsi = (JAWT_DrawingSurfaceInfo *) dsiObj; + jint window; + +#ifdef WIN32 + JAWT_Win32DrawingSurfaceInfo *wds = + (JAWT_Win32DrawingSurfaceInfo*) dsi->platformInfo; + window = (jint)wds->hdc; +#endif /* WIN32 */ + +#ifdef SOLARIS + JAWT_X11DrawingSurfaceInfo *xds = + (JAWT_X11DrawingSurfaceInfo*) dsi->platformInfo; + window = (jint)xds->drawable; + + if (xineramaDisabled) { + XineramaInfo xineramaInfo; + +#ifdef VERBOSE + fprintf(stderr, "getDrawingSurfaceWindowIdAWT: Xinerama disabled\n"); +#endif /* VERBOSE */ + + /* + * The existence of the weak symbol XDgaGetXineramaInfo is checked in + * the native MasterControl.initializeJ3D(); execution will not get + * here if it is unbound. + */ + if (XDgaGetXineramaInfo((Display *)display, + xds->drawable, &xineramaInfo)) { + + /* return Xinerama subwid instead of primary Xinerama wid */ + window = (jint)xineramaInfo.subs[screen].wid; + +#ifdef VERBOSE + fprintf(stderr, + " subwid for display %d screen %d window %d: %d\n", + (Display *)display, screen, xds->drawable, window); +#endif /* VERBOSE */ + } + else { + window = (jint)xds->drawable; + fprintf(stderr, "Get Xinerama subwid, screen %d failed\n", screen); + } + } +#endif /* SOLARIS */ + +#ifdef __linux__ + JAWT_X11DrawingSurfaceInfo *xds = + (JAWT_X11DrawingSurfaceInfo*) dsi->platformInfo; + window = (jint)xds->drawable; +#endif /* __linux__ */ + + /* + * Don't free DrawingSurfaceInfo here, otherwise + * HDC will free in windows JDK1.4 and window + * is invalid. + */ + ds->env = env; + ds->Unlock(ds); + + return window; +} + + + +JNIEXPORT +jlong JNICALL +Java_javax_media_j3d_DrawingSurfaceObjectAWT_getDrawingSurfaceInfo( + JNIEnv *env, + jobject obj, + jlong dsObj) +{ + JAWT_DrawingSurface *ds = (JAWT_DrawingSurface*) dsObj; + JAWT_DrawingSurfaceInfo *dsi; + jint lock; + + ds->env = env; + lock = ds->Lock(ds); + if ((lock & JAWT_LOCK_ERROR) != 0) { + fprintf(stderr, "Error locking surface\n"); + return 0; + } + + dsi = ds->GetDrawingSurfaceInfo(ds); + + if (dsi == NULL) { + fprintf(stderr, "Error GetDrawingSurfaceInfo\n"); + ds->Unlock(ds); + return 0; + } + return (jlong)dsi; +} + +JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_DrawingSurfaceObjectAWT_lockAWT( + JNIEnv *env, + jobject obj, + jlong drawingSurface) +{ + JAWT_DrawingSurface *ds = (JAWT_DrawingSurface*)drawingSurface; + jint lock; + + ds->env = env; + lock = ds->Lock(ds); + + if ((lock & JAWT_LOCK_ERROR) != 0) { + return JNI_FALSE; + } else if ((lock & JAWT_LOCK_SURFACE_CHANGED) != 0) { + ds->Unlock(ds); + return JNI_FALSE; + } else { + return JNI_TRUE; + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_DrawingSurfaceObjectAWT_unlockAWT( + JNIEnv *env, + jobject obj, + jlong drawingSurface) +{ + JAWT_DrawingSurface *ds = (JAWT_DrawingSurface*)drawingSurface; + ds->env = env; + ds->Unlock(ds); +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_DrawingSurfaceObjectAWT_lockGlobal( + JNIEnv *env, + jclass obj, + jlong awt) +{ + ((JAWT *) awt)->Lock(env); +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_DrawingSurfaceObjectAWT_unlockGlobal( + JNIEnv *env, + jclass obj, + jlong awt) +{ + ((JAWT *) awt)->Unlock(env); +} + + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_DrawingSurfaceObjectAWT_freeResource( + JNIEnv *env, + jobject obj, + jlong awtObj, + jlong drawingSurface, + jlong drawingSurfaceInfo) +{ + JAWT *awt = (JAWT*) awtObj; + JAWT_DrawingSurface *ds = (JAWT_DrawingSurface*)drawingSurface; + JAWT_DrawingSurfaceInfo *dsi = (JAWT_DrawingSurfaceInfo *) drawingSurfaceInfo; + + ds->env = env; + ds->FreeDrawingSurfaceInfo(dsi); + awt->FreeDrawingSurface(ds); +} + + + diff --git a/src/native/ogl/GeometryArrayRetained.c b/src/native/ogl/GeometryArrayRetained.c new file mode 100644 index 0000000..ccc0a31 --- /dev/null +++ b/src/native/ogl/GeometryArrayRetained.c @@ -0,0 +1,3599 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include +#include + +#include "gldefs.h" + +#ifdef WIN32 +#include + +#endif /* WIN32 */ + +#ifdef DEBUG +/* Uncomment the following for VERBOSE debug messages */ +/* #define VERBOSE */ +#endif /* DEBUG */ + + +static float EPS = 0.0001f; + +#define INTERLEAVEDARRAYS_TEST() \ + useInterleavedArrays = 1; \ + switch (vformat) { \ + case GA_COORDINATES : \ + iaFormat = GL_V3F; break; \ + case (GA_COORDINATES | GA_NORMALS) : \ + iaFormat = GL_N3F_V3F; break; \ + case (GA_COORDINATES | GA_TEXTURE_COORDINATE_2) :\ + iaFormat = GL_T2F_V3F; break; \ + case (GA_COORDINATES | GA_NORMALS | GA_COLOR) : \ + case (GA_COORDINATES | GA_NORMALS | GA_COLOR | GA_WITH_ALPHA) :\ + iaFormat = GL_C4F_N3F_V3F; break; \ + case (GA_COORDINATES | GA_NORMALS | GA_TEXTURE_COORDINATE_2) :\ + iaFormat = GL_T2F_N3F_V3F; break; \ + case (GA_COORDINATES | GA_NORMALS | GA_COLOR | GA_TEXTURE_COORDINATE_2):\ + case (GA_COORDINATES | GA_NORMALS | GA_COLOR | GA_WITH_ALPHA | GA_TEXTURE_COORDINATE_2):\ + iaFormat = GL_T2F_C4F_N3F_V3F; break;\ + default: \ + useInterleavedArrays = 0; break; \ + } + + + +/* This hardcoded value should be fixed for 1.3 */ +#define NUM_TEXTURE_UNITS 64 + + +extern void enableTexCoordPointer(GraphicsContextPropertiesInfo *, int, int, + int, int, void *); +extern void disableTexCoordPointer(GraphicsContextPropertiesInfo *, int); + +/* + * texUnitIndex < 0 implies send all texture unit state info in one pass + * texUnitIndex >= 0 implies one texture unit state info in one pass using + * the underlying texture unit 0 + */ +void +executeTexture(int texUnitIndex, int texCoordSetMapLen, + int texSize, int bstride, int texCoordoff, + jint texCoordSetMapOffset[], + jint numActiveTexUnit, jint texUnitStateMap[], + float verts[], jlong ctxInfo) +{ + int i; + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + int tus; /* texture unit state index */ + + if (texUnitIndex < 0) { + if(ctxProperties->arb_multitexture) { + + for (i = 0; i < numActiveTexUnit; i++) { + /* + * NULL texUnitStateMap means + * one to one mapping from texture unit to + * texture unit state. It is NULL in build display list, + * when the mapping is according to the texCoordSetMap + */ + if (texUnitStateMap != NULL) { + tus = texUnitStateMap[i]; + } else { + tus = i; + } + /* + * it's possible that texture unit state index (tus) + * is greater than the texCoordSetMapOffsetLen, in this + * case, just disable TexCoordPointer. + */ + if ((tus < texCoordSetMapLen) && + (texCoordSetMapOffset[tus] != -1)) { + enableTexCoordPointer(ctxProperties, i, + texSize, GL_FLOAT, bstride, + &(verts[texCoordoff + texCoordSetMapOffset[tus]])); + + } else { + disableTexCoordPointer(ctxProperties, i); + } + } + }/* GL_ARB_multitexture */ + + else { + +#ifdef VERBOSE + if (numActiveTexUnit > 1) { + fprintf(stderr, "No multi-texture support\n"); + } +#endif /* VERBOSE */ + + if (texUnitStateMap != NULL) { + tus = texUnitStateMap[0]; + } else { + tus = 0; + } + if (texCoordSetMapOffset[tus] != -1) { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(texSize, GL_FLOAT, bstride, + &(verts[texCoordoff + texCoordSetMapOffset[tus]])); + + } else { + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + } + } else { + if ((texUnitIndex < texCoordSetMapLen) && + (texCoordSetMapOffset[texUnitIndex] != -1)) { + enableTexCoordPointer(ctxProperties, 0, + texSize, GL_FLOAT, bstride, + &(verts[texCoordoff + texCoordSetMapOffset[texUnitIndex]])); + } else { + disableTexCoordPointer(ctxProperties, 0); + } + } +} + + +/* + * glLockArrays() is invoked only for indexed geometry, and the + * vertexCount is guarenteed to be >= 0. + */ +static void +lockArray(GraphicsContextPropertiesInfo *ctxProperties, + int vertexCount) { + + if (ctxProperties->compiled_vertex_array_ext) { + ctxProperties->glLockArraysEXT(0, vertexCount); + } +} + +static void +unlockArray(GraphicsContextPropertiesInfo *ctxProperties) +{ + if (ctxProperties->compiled_vertex_array_ext) { + ctxProperties->glUnlockArraysEXT(); + } +} + + +void +executeGeometryArray(JNIEnv *env, + jobject obj, jlong ctxInfo, jobject geo, jint geo_type, + jboolean isNonUniformScale, jboolean useAlpha, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint startVIndex, + jint vcount, jint vformat, + jint texCoordSetCount, + jintArray texCoordSetMap, jint texCoordSetMapLen, + jintArray texUnitOffset, + jint numActiveTexUnit, + jintArray texUnitStateMapArray, + jfloatArray varray, jobject varrayBuffer, jfloatArray carray, + jint texUnitIndex, jint cDirty) +{ + jclass geo_class; + JNIEnv table; + + jfloat *verts, *startVertex, *clrs, *startClrs; + jint i; + size_t bstride, cbstride; + jsize strip_len; + GLsizei *strips; + GLenum iaFormat; + int useInterleavedArrays; + int primType; + jint stride, coordoff, normoff, coloroff, texCoordoff; + int alphaNeedsUpdate = 0; /* used so we can get alpha data from */ + /* JNI before using it so we can use */ + /* GetPrimitiveArrayCritical */ + jfieldID strip_field; + jarray sarray; + + jint texSize, texStride, *texCoordSetMapOffset = NULL, + *texUnitStateMap = NULL; + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + jarray start_array; + jfieldID start_field; + GLint *start; + int cstride = 0; + table = *env; + + geo_class = (jclass) (*(table->GetObjectClass))(env, geo); + + + /* This matches the code in GeometryArrayRetained.java */ + stride = coordoff = normoff = coloroff = texCoordoff = 0; + if ((vformat & GA_COORDINATES) != 0) { + stride += 3; + } + if ((vformat & GA_NORMALS) != 0) { + stride += 3; + coordoff += 3; + } + if ((vformat & GA_COLOR) != 0) { + if ((vformat & GA_WITH_ALPHA) != 0 ) { + stride += 4; + normoff += 4; + coordoff += 4; + } + else { /* Handle the case of executeInterleaved 3f */ + stride += 3; + normoff += 3; + coordoff += 3; + } + } + if ((vformat & GA_TEXTURE_COORDINATE) != 0) { + if ((vformat & GA_TEXTURE_COORDINATE_2) != 0) { + texSize = 2; + texStride = 2 * texCoordSetCount; + } else if ((vformat & GA_TEXTURE_COORDINATE_3) != 0) { + texSize = 3; + texStride = 3 * texCoordSetCount; + } else if ((vformat & GA_TEXTURE_COORDINATE_4) != 0) { + texSize = 4; + texStride = 4 * texCoordSetCount; + } + stride += texStride; + normoff += texStride; + coloroff += texStride; + coordoff += texStride; + } + + bstride = stride*sizeof(float); + + /* + * Call other JNI functions before entering Critical region + * i.e., GetPrimitiveArrayCritical + */ + + if (geo_type == GEO_TYPE_TRI_STRIP_SET || + geo_type == GEO_TYPE_TRI_FAN_SET || + geo_type == GEO_TYPE_LINE_STRIP_SET) { + + strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class, + "stripVertexCounts", "[I"); + sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field); + strip_len = (jsize)(*(table->GetArrayLength))(env, sarray); + + + start_field = (jfieldID) (*(table->GetFieldID))(env, geo_class, + "stripStartOffsetIndices", "[I"); + start_array = (jarray)(*(table->GetObjectField))(env, geo, + start_field); + } + + /* begin critical region */ + if(varray != NULL) { + verts = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, varray, NULL); + if(verts == NULL) + return; + } + else if(varrayBuffer != NULL) { + verts = (jfloat *) (*(table->GetDirectBufferAddress))(env, varrayBuffer ); + if(verts == NULL) + return; + } + + /* using byRef interleaved array and has a separate pointer, then .. */ + cstride = stride; + if (carray != NULL) { + clrs = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, carray, NULL); + cstride = 4; + + } + else { + clrs = &(verts[coloroff]); + } + + + cbstride = cstride * sizeof(float); + if (texCoordSetMapLen >0) { + texCoordSetMapOffset = (jint *) (*(table->GetPrimitiveArrayCritical))(env, texUnitOffset, NULL); + } + + if (texUnitStateMapArray != NULL) { + texUnitStateMap = (jint *) (*(table->GetPrimitiveArrayCritical))(env, texUnitStateMapArray, NULL); + } + + /* Enable normalize for non-uniform scale (which rescale can't handle) */ + if (ctxProperties->rescale_normal_ext && isNonUniformScale) { + glEnable(GL_NORMALIZE); + } + + + startVertex = verts + (stride * startVIndex); + startClrs = clrs + (cstride * startVIndex); + + /*** Handle non-indexed strip GeometryArray first *******/ + if (geo_type == GEO_TYPE_TRI_STRIP_SET || + geo_type == GEO_TYPE_TRI_FAN_SET || + geo_type == GEO_TYPE_LINE_STRIP_SET) { + + + strips = (GLsizei *) (*(table->GetPrimitiveArrayCritical))(env, sarray, + NULL); + + if ((ignoreVertexColors == JNI_TRUE) || (carray != NULL) || + ((vformat & GA_TEXTURE_COORDINATE) && ((texCoordSetMapLen > 1) || + (texCoordSetCount > 1)))) { + useInterleavedArrays = 0; + } else { + INTERLEAVEDARRAYS_TEST() + } + if (useInterleavedArrays) { + glInterleavedArrays(iaFormat, bstride, startVertex); + } else { + if (vformat & GA_NORMALS) { + glNormalPointer(GL_FLOAT, bstride, &(startVertex[normoff])); + } + if (ignoreVertexColors == JNI_FALSE && vformat & GA_COLOR) { + if (vformat & GA_WITH_ALPHA || (useAlpha == GL_TRUE)) { + glColorPointer(4, GL_FLOAT, cbstride, startClrs); + } else { + /* + for (i = 0; i < vcount; i++) { + fprintf(stderr, "r = %f, g = %f, b = %f\n", verts[i*bstride +coloroff], verts[i*bstride +coloroff+1],verts[i*bstride +coloroff+2]); + } + */ + glColorPointer(3, GL_FLOAT, cbstride, startClrs); + } + } + if (vformat & GA_COORDINATES) { + /* + for (i = 0; i < vcount; i++) { + fprintf(stderr, "x = %f, y = %f, z = %f\n", verts[i*bstride +coordoff], verts[i*bstride +coordoff+1],verts[i*bstride +coordoff+2]); + } + */ + glVertexPointer(3, GL_FLOAT, bstride, &(startVertex[coordoff])); + } + + if (vformat & GA_TEXTURE_COORDINATE) { + + executeTexture(texUnitIndex, texCoordSetMapLen, + texSize, bstride, texCoordoff, + texCoordSetMapOffset, + numActiveTexUnit, texUnitStateMap, + startVertex, ctxInfo); + } + } + + switch (geo_type) { + case GEO_TYPE_TRI_STRIP_SET : + primType = GL_TRIANGLE_STRIP; + break; + case GEO_TYPE_TRI_FAN_SET : + primType = GL_TRIANGLE_FAN; + break; + case GEO_TYPE_LINE_STRIP_SET : + primType = GL_LINE_STRIP; + break; + } + /* + fprintf(stderr, "strip_len = %d\n",strip_len); + for (i=0; i < strip_len;i++) { + fprintf(stderr, "strips[i] = %d\n",strips[i]); + } + */ + + + start = (GLint *)(*(table->GetPrimitiveArrayCritical))(env, + start_array, NULL); + + if (ctxProperties->multi_draw_arrays_ext || ctxProperties->multi_draw_arrays_sun) { + /* + * Only used in the "by_copy case, so its ok to + * to temporarily modify + */ + + ctxProperties->glMultiDrawArraysEXT(primType, start, strips, strip_len); + } else { + for (i=0; i < strip_len;i++) { + glDrawArrays(primType, start[i], strips[i]); + } + } + (*(table->ReleasePrimitiveArrayCritical))(env, start_array, start, + 0); + (*(table->ReleasePrimitiveArrayCritical))(env, sarray, strips, 0); + } + /******* Handle non-indexed non-striped GeometryArray now *****/ + else if ((geo_type == GEO_TYPE_QUAD_SET) || + (geo_type == GEO_TYPE_TRI_SET) || + (geo_type == GEO_TYPE_POINT_SET) || + (geo_type == GEO_TYPE_LINE_SET)) + { + + + if ((ignoreVertexColors == JNI_TRUE) || (carray != NULL) || + ((vformat & GA_TEXTURE_COORDINATE) && ((texCoordSetMapLen > 1) || + (texCoordSetCount > 1)))) { + useInterleavedArrays = 0; + } else { + INTERLEAVEDARRAYS_TEST() + } + + if (useInterleavedArrays) { + glInterleavedArrays(iaFormat, bstride, startVertex); + } else { + if (vformat & GA_NORMALS) { + glNormalPointer(GL_FLOAT, bstride, &(startVertex[normoff])); + } + if (ignoreVertexColors == JNI_FALSE && vformat & GA_COLOR) { + if (vformat & GA_WITH_ALPHA || (useAlpha == GL_TRUE)) { + + glColorPointer(4, GL_FLOAT, cbstride, startClrs); + } else { + glColorPointer(3, GL_FLOAT, cbstride, startClrs); + } + } + if (vformat & GA_COORDINATES) { + glVertexPointer(3, GL_FLOAT, bstride, &(startVertex[coordoff])); + } + + if (vformat & GA_TEXTURE_COORDINATE) { + + executeTexture(texUnitIndex, texCoordSetMapLen, + texSize, bstride, texCoordoff, + texCoordSetMapOffset, + numActiveTexUnit, texUnitStateMap, + startVertex, ctxInfo); + } + } + switch (geo_type){ + case GEO_TYPE_QUAD_SET : glDrawArrays(GL_QUADS, 0, vcount);break; + case GEO_TYPE_TRI_SET : glDrawArrays(GL_TRIANGLES, 0, vcount);break; + case GEO_TYPE_POINT_SET : glDrawArrays(GL_POINTS, 0, vcount);break; + case GEO_TYPE_LINE_SET: glDrawArrays(GL_LINES, 0, vcount);break; + } + } + /* clean up if we turned on normalize */ + + if (ctxProperties->rescale_normal_ext && isNonUniformScale) { + glDisable(GL_NORMALIZE); + } + + if (carray != NULL) + (*(table->ReleasePrimitiveArrayCritical))(env, carray, clrs, 0); + + if (texCoordSetMapLen > 0) + (*(table->ReleasePrimitiveArrayCritical))(env, texUnitOffset, + texCoordSetMapOffset, 0); + + if (texUnitStateMap != NULL) + (*(table->ReleasePrimitiveArrayCritical))(env, texUnitStateMapArray, + texUnitStateMap, 0); + if(varray != NULL) + (*(table->ReleasePrimitiveArrayCritical))(env, varray, verts, 0); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_execute(JNIEnv *env, + jobject obj, jlong ctxInfo, jobject geo, jint geo_type, + jboolean isNonUniformScale, jboolean useAlpha, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint startVIndex, + jint vcount, jint vformat, + jint texCoordSetCount, + jintArray texCoordSetMap, jint texCoordSetMapLen, + jintArray texUnitOffset, + jint numActiveTexUnit, + jintArray texUnitStateMapArray, + jfloatArray varray, jfloatArray carray, + jint texUnitIndex, jint cDirty) { + + + /* call executeGeometryArray */ + executeGeometryArray(env, obj, ctxInfo, geo, geo_type, isNonUniformScale, useAlpha, + multiScreen, ignoreVertexColors, startVIndex, vcount, vformat, + texCoordSetCount, texCoordSetMap, texCoordSetMapLen, + texUnitOffset, numActiveTexUnit, texUnitStateMapArray, + varray, NULL, carray, texUnitIndex, cDirty); + +} + +/* interleaved data with nio buffer as data format */ +JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_executeInterleavedBuffer(JNIEnv *env, + jobject obj, jlong ctxInfo, jobject geo, jint geo_type, + jboolean isNonUniformScale, jboolean useAlpha, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint startVIndex, + jint vcount, jint vformat, + jint texCoordSetCount, + jintArray texCoordSetMap, jint texCoordSetMapLen, + jintArray texUnitOffset, + jint numActiveTexUnit, + jintArray texUnitStateMapArray, + jobject varray, jfloatArray carray, + jint texUnitIndex, jint cDirty) { + + /* call executeGeometryArray */ + executeGeometryArray(env, obj, ctxInfo, geo, geo_type, isNonUniformScale, useAlpha, + multiScreen, ignoreVertexColors, startVIndex, vcount, vformat, + texCoordSetCount, texCoordSetMap, texCoordSetMapLen, + texUnitOffset, numActiveTexUnit, texUnitStateMapArray, + NULL, varray, carray, texUnitIndex, cDirty); + +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_buildGA(JNIEnv *env, + jobject obj, jlong ctxInfo, jobject geo, + jint geo_type, + jboolean isNonUniformScale, jboolean updateAlpha, float alpha, + jboolean ignoreVertexColors, + jint startVIndex, + jint vcount, jint vformat, + jint texCoordSetCount, + jintArray texCoordSetMapArray, + jint texCoordSetMapLen, + jintArray texUnitOffset, + jdoubleArray xform, jdoubleArray nxform, + jfloatArray varray) +{ + jclass geo_class; + JNIEnv table; + jboolean useAlpha = JNI_FALSE; + + jfloat *verts; + jint i, j; + size_t bstride; + jint texStride, *texCoordSetMapOffset; + GLsizei *strips; + jfloat vertex[3]; + jfloat normal[3]; + jfloat w, winv; + + jsize strip_len; + int primType; + jint stride, coordoff, normoff, coloroff, texCoordoff; + jfieldID strip_field; + jarray sarray; + jint initialOffset = 0; + jint saveVformat = 0; + float color[4]; + jdouble *xform_ptr = NULL; + jdouble *nxform_ptr = NULL; + + + jint k; + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + table = *env; + geo_class = (jclass) (*(table->GetObjectClass))(env, geo); + + /* This matches the code in GeometryArrayRetained.java */ + stride = coordoff = normoff = coloroff = texCoordoff = 0; + if ((vformat & GA_COORDINATES) != 0) { + stride += 3; + } + if ((vformat & GA_NORMALS) != 0) { + stride += 3; + coordoff += 3; + } + + if ((vformat & GA_COLOR) != 0) { + if ((vformat & GA_BY_REFERENCE) != 0) { + if (vformat & GA_WITH_ALPHA) { + stride += 4; + normoff += 4; + coordoff += 4; + } + else { + stride += 3; + normoff += 3; + coordoff += 3; + } + } + else { + stride += 4; + normoff += 4; + coordoff += 4; + } + } + + if ((vformat & GA_TEXTURE_COORDINATE) != 0) { + if ((vformat & GA_TEXTURE_COORDINATE_2) != 0) { + texStride = 2 * texCoordSetCount; + } else if ((vformat & GA_TEXTURE_COORDINATE_3) != 0) { + texStride = 3 * texCoordSetCount; + } else if ((vformat & GA_TEXTURE_COORDINATE_4) != 0) { + texStride = 4 * texCoordSetCount; + } + stride += texStride; + normoff += texStride; + coloroff += texStride; + coordoff += texStride; + } + + bstride = stride*sizeof(float); + /* Start send down from the startVIndex */ + initialOffset = startVIndex * stride; + normoff += initialOffset; + coloroff += initialOffset; + coordoff += initialOffset; + texCoordoff += initialOffset; + + /* + * process alpha for geometryArray without alpha + */ + if (updateAlpha == JNI_TRUE && ignoreVertexColors == JNI_FALSE) { + useAlpha = JNI_TRUE; + } + + /* + * call other JNI functions before entering Critical region + * i.e., GetPrimitiveArrayCritical + */ + if (geo_type == GEO_TYPE_TRI_STRIP_SET || + geo_type == GEO_TYPE_TRI_FAN_SET || + geo_type == GEO_TYPE_LINE_STRIP_SET) { + + strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class, + "stripVertexCounts", "[I"); + sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field); + strip_len = (jsize)(*(table->GetArrayLength))(env, sarray); + } + + + /* begin critical region */ + verts = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, varray, NULL); + + if (texCoordSetMapLen >0) { + texCoordSetMapOffset = (jint *)(*(table->GetPrimitiveArrayCritical)) + (env, texUnitOffset, NULL); + } + + + /* get the static transform if exists */ + if (xform != NULL) { + xform_ptr = (jdouble *) (*(table->GetPrimitiveArrayCritical))( + env, xform, NULL); + } + + /* get the static normals transform if exists */ + if (nxform != NULL) { + nxform_ptr = (jdouble *) (*(table->GetPrimitiveArrayCritical))( + env, nxform, NULL); + } + + + if (geo_type == GEO_TYPE_TRI_STRIP_SET || + geo_type == GEO_TYPE_TRI_FAN_SET || + geo_type == GEO_TYPE_LINE_STRIP_SET) { + + + switch (geo_type) { + case GEO_TYPE_TRI_STRIP_SET : + primType = GL_TRIANGLE_STRIP; + break; + case GEO_TYPE_TRI_FAN_SET : + primType = GL_TRIANGLE_FAN; + break; + case GEO_TYPE_LINE_STRIP_SET : + primType = GL_LINE_STRIP; + break; + } + + + strips = (GLsizei *) (*(table->GetPrimitiveArrayCritical))(env, sarray, NULL); + saveVformat = vformat; + if (ignoreVertexColors == JNI_TRUE) { + vformat &= ~GA_COLOR; + } + for (i = 0; i < strip_len; i++) { + glBegin(primType); + for (j = 0; j < strips[i]; j++) { + if (vformat & GA_NORMALS) { + if (nxform_ptr != NULL) { + normal[0] = (float) (nxform_ptr[0] * verts[normoff] + + nxform_ptr[1] * verts[normoff+1] + + nxform_ptr[2] * verts[normoff+2]); + normal[1] = (float ) (nxform_ptr[4] * verts[normoff] + + nxform_ptr[5] * verts[normoff+1] + + nxform_ptr[6] * verts[normoff+2]); + normal[2] = (float) (nxform_ptr[8] * verts[normoff] + + nxform_ptr[9] * verts[normoff+1] + + nxform_ptr[10] * verts[normoff+2]); +/* +printf("orig: < %g %g %g > transformed: < %g %g %g >\n", + verts[normoff], verts[normoff+1], verts[normoff+2], + normal[0], normal[1], normal[2]); +*/ + glNormal3fv(normal); + } else { + glNormal3fv(&verts[normoff]); + } + } + if (vformat & GA_COLOR) { + if (useAlpha ) { + color[0] = verts[coloroff]; + color[1] = verts[coloroff+1]; + color[2] = verts[coloroff+2]; + color[3] = verts[coloroff+3] * alpha; + glColor4fv(&color[0]); + } + else { + if (vformat & GA_WITH_ALPHA) { /* alpha is present */ + glColor4fv(&verts[coloroff]); + } + else { + glColor3fv(&verts[coloroff]); + } + } + } + + if (vformat & GA_TEXTURE_COORDINATE) { + + if (texCoordSetMapLen > 0) { + + if (ctxProperties->arb_multitexture) { + if (vformat & GA_TEXTURE_COORDINATE_2) { + for (k = 0; k < texCoordSetMapLen; k++) { + if (texCoordSetMapOffset[k] != -1) { + ctxProperties->glMultiTexCoord2fvARB( + GL_TEXTURE0_ARB + k, + &verts[texCoordoff + + texCoordSetMapOffset[k]]); + } + } + } else if (vformat & GA_TEXTURE_COORDINATE_3) { + for (k = 0; k < texCoordSetMapLen; k++) { + if (texCoordSetMapOffset[k] != -1) { + ctxProperties->glMultiTexCoord3fvARB( + GL_TEXTURE0_ARB + k, + &verts[texCoordoff + + texCoordSetMapOffset[k]]); + } + } + } else { + for (k = 0; k < texCoordSetMapLen; k++) { + if (texCoordSetMapOffset[k] != -1) { + ctxProperties->glMultiTexCoord4fvARB( + GL_TEXTURE0_ARB + k, + &verts[texCoordoff + + texCoordSetMapOffset[k]]); + } + } + } + } + else { /* GL_ARB_multitexture */ + + if (texCoordSetMapOffset[0] != -1) { + if (vformat & GA_TEXTURE_COORDINATE_2) { + glTexCoord2fv(&verts[texCoordoff + + texCoordSetMapOffset[0]]); + } else if (vformat & GA_TEXTURE_COORDINATE_3) { + glTexCoord3fv(&verts[texCoordoff + + texCoordSetMapOffset[0]]); + } else { + glTexCoord4fv(&verts[texCoordoff + + texCoordSetMapOffset[0]]); + } + } + } /* GL_ARB_multitexture */ + } + /* + * texCoordSetMapLen can't be 0 if texture coordinates + * is to be specified + */ + } + if (vformat & GA_COORDINATES) { + if (xform_ptr != NULL) { + + /* + * transform the vertex data with the + * static transform + */ + w = (float ) (xform_ptr[12] * verts[coordoff] + + xform_ptr[13] * verts[coordoff+1] + + xform_ptr[14] * verts[coordoff+2] + + xform_ptr[15]); + winv = 1.0f/w; + vertex[0] = (float ) (xform_ptr[0] * verts[coordoff] + + xform_ptr[1] * verts[coordoff+1] + + xform_ptr[2] * verts[coordoff+2] + + xform_ptr[3]) * winv; + vertex[1] = (float) (xform_ptr[4] * verts[coordoff] + + xform_ptr[5] * verts[coordoff+1] + + xform_ptr[6] * verts[coordoff+2] + + xform_ptr[7]) * winv; + vertex[2] = (float) (xform_ptr[8] * verts[coordoff] + + xform_ptr[9] * verts[coordoff+1] + + xform_ptr[10] * verts[coordoff+2] + + xform_ptr[11]) * winv; +/* +printf("orig: < %g %g %g > transformed: < %g %g %g >\n", + verts[coordoff], verts[coordoff+1], verts[coordoff+2], + vertex[0], vertex[1], vertex[2]); +*/ + glVertex3fv(vertex); + } else { + glVertex3fv(&verts[coordoff]); + } + } + normoff += stride; + coloroff += stride; + coordoff += stride; + texCoordoff += stride; + } + glEnd(); + } + /* Restore the vertex format */ + vformat = saveVformat; + (*(table->ReleasePrimitiveArrayCritical))(env, sarray, strips, + 0); + + } + else if ((geo_type == GEO_TYPE_QUAD_SET) || + (geo_type == GEO_TYPE_TRI_SET) || + (geo_type == GEO_TYPE_POINT_SET) || + (geo_type == GEO_TYPE_LINE_SET)) { + + switch (geo_type) { + case GEO_TYPE_QUAD_SET : + primType = GL_QUADS; + break; + case GEO_TYPE_TRI_SET : + primType = GL_TRIANGLES; + break; + case GEO_TYPE_POINT_SET : + primType = GL_POINTS; + break; + case GEO_TYPE_LINE_SET : + primType = GL_LINES; + break; + + } + + saveVformat = vformat; + if (ignoreVertexColors == JNI_TRUE) { + vformat &= ~GA_COLOR; + } + glBegin(primType); + for (j = 0; j < vcount; j++) { + if (vformat & GA_NORMALS) { + if (nxform_ptr != NULL) { + normal[0] = (float) (nxform_ptr[0] * verts[normoff] + + nxform_ptr[1] * verts[normoff+1] + + nxform_ptr[2] * verts[normoff+2]); + normal[1] = (float) (nxform_ptr[4] * verts[normoff] + + nxform_ptr[5] * verts[normoff+1] + + nxform_ptr[6] * verts[normoff+2]); + normal[2] = (float) (nxform_ptr[8] * verts[normoff] + + nxform_ptr[9] * verts[normoff+1] + + nxform_ptr[10] * verts[normoff+2]); +/* +printf("orig: < %g %g %g > transformed: < %g %g %g >\n", + verts[normoff], verts[normoff+1], verts[normoff+2], + normal[0], normal[1], normal[2]); +*/ + glNormal3fv(normal); + } else { + glNormal3fv(&verts[normoff]); + } + } + if (vformat & GA_COLOR) { + if (useAlpha ) { + if (vformat & GA_WITH_ALPHA) { + color[0] = verts[coloroff]; + color[1] = verts[coloroff+1]; + color[2] = verts[coloroff+2]; + color[3] = verts[coloroff+3] * alpha; + } + else { + color[0] = verts[coloroff]; + color[1] = verts[coloroff+1]; + color[2] = verts[coloroff+2]; + color[3] = alpha; + } + glColor4fv(&color[0]); + + } + else { + if (vformat & GA_WITH_ALPHA) { /* alpha is present */ + glColor4fv(&verts[coloroff]); + } + else { + glColor3fv(&verts[coloroff]); + } + } + } + + if (vformat & GA_TEXTURE_COORDINATE) { + + if (texCoordSetMapLen > 0) { + + if(ctxProperties->arb_multitexture) { + if (vformat & GA_TEXTURE_COORDINATE_2) { + for (k = 0; k < texCoordSetMapLen; k++) { + if (texCoordSetMapOffset[k] != -1) { + ctxProperties->glMultiTexCoord2fvARB( + GL_TEXTURE0_ARB + k, + &verts[texCoordoff + + texCoordSetMapOffset[k]]); + } + } + } else if (vformat & GA_TEXTURE_COORDINATE_3) { + for (k = 0; k < texCoordSetMapLen; k++) { + if (texCoordSetMapOffset[k] != -1) { + ctxProperties->glMultiTexCoord3fvARB( + GL_TEXTURE0_ARB + k, + &verts[texCoordoff + + texCoordSetMapOffset[k]]); + } + } + } else { + for (k = 0; k < texCoordSetMapLen; k++) { + if (texCoordSetMapOffset[k] != -1) { + ctxProperties->glMultiTexCoord4fvARB( + GL_TEXTURE0_ARB + k, + &verts[texCoordoff + + texCoordSetMapOffset[k]]); + } + } + } + } + else { /* GL_ARB_multitexture */ + + if (texCoordSetMapOffset[0] != -1) { + if (vformat & GA_TEXTURE_COORDINATE_2) { + glTexCoord2fv(&verts[texCoordoff + + texCoordSetMapOffset[0]]); + } else if (vformat & GA_TEXTURE_COORDINATE_3) { + glTexCoord3fv(&verts[texCoordoff + + texCoordSetMapOffset[0]]); + } else { + glTexCoord4fv(&verts[texCoordoff + + texCoordSetMapOffset[0]]); + } + } + } /* GL_ARB_multitexture */ + } + + /* + * texCoordSetMapLen can't be 0 if texture coordinates + * is to be specified + */ + } + + if (vformat & GA_COORDINATES) { + if (xform_ptr != NULL) { + + /* + * transform the vertex data with the + * static transform + */ + w = (float) (xform_ptr[12] * verts[coordoff] + + xform_ptr[13] * verts[coordoff+1] + + xform_ptr[14] * verts[coordoff+2] + + xform_ptr[15]); + winv = 1.0f/w; + vertex[0] = (float) (xform_ptr[0] * verts[coordoff] + + xform_ptr[1] * verts[coordoff+1] + + xform_ptr[2] * verts[coordoff+2] + + xform_ptr[3]) * winv; + vertex[1] = (float) (xform_ptr[4] * verts[coordoff] + + xform_ptr[5] * verts[coordoff+1] + + xform_ptr[6] * verts[coordoff+2] + + xform_ptr[7]) * winv; + vertex[2] = (float) (xform_ptr[8] * verts[coordoff] + + xform_ptr[9] * verts[coordoff+1] + + xform_ptr[10] * verts[coordoff+2] + + xform_ptr[11]) * winv; +/* +printf("orig: < %g %g %g > transformed: < %g %g %g >\n", + verts[coordoff], verts[coordoff+1], verts[coordoff+2], + vertex[0], vertex[1], vertex[2]); +*/ + glVertex3fv(vertex); + } else { + glVertex3fv(&verts[coordoff]); + } + } + normoff += stride; + coloroff += stride; + coordoff += stride; + texCoordoff += stride; + } + glEnd(); + } + /* Restore the vertex format */ + vformat = saveVformat; + + + (*(table->ReleasePrimitiveArrayCritical))(env, varray, verts, 0); + + if (texCoordSetMapLen > 0) + (*(table->ReleasePrimitiveArrayCritical))(env, texUnitOffset, + texCoordSetMapOffset, 0); + + if (xform_ptr != NULL) + (*(table->ReleasePrimitiveArrayCritical))(env, xform, xform_ptr, 0); + + if (nxform_ptr != NULL) + (*(table->ReleasePrimitiveArrayCritical))(env, nxform, nxform_ptr, 0); +} + +void enableTexCoordPointer( + GraphicsContextPropertiesInfo *ctxProperties, + int texUnit, + int texSize, + int texDataType, + int stride, + void *pointer) { + + if (ctxProperties->arb_multitexture) { + ctxProperties->glClientActiveTextureARB(texUnit + GL_TEXTURE0_ARB); + } + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(texSize, texDataType, stride, pointer); +} + + +void disableTexCoordPointer( + GraphicsContextPropertiesInfo *ctxProperties, + int texUnit) { + + if (ctxProperties->glClientActiveTextureARB != NULL) { + ctxProperties->glClientActiveTextureARB(texUnit + GL_TEXTURE0_ARB); + } + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + +void executeGeometryArrayVA( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jobject geo, + jint geo_type, + jboolean isNonUniformScale, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint vcount, + jint vformat, + jint vdefined, + jint initialCoordIndex, + jfloat* fverts, + jdouble* dverts, + jint initialColorIndex, + jfloat* fclrs, + jbyte* bclrs, + jint initialNormalIndex, + jfloat* norms, + jint pass, + jint texCoordMapLength, + jintArray tcoordsetmap, + jint numActiveTexUnit, + jint* texUnitStateMap, + jintArray texindices, + jint texStride, + jfloat** texCoordPointer, + jint cdirty, + jarray sarray, + jsize strip_len, + jarray start_array) +{ + int primType; + JNIEnv table; + jint i; + GLsizei *strips; + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + GLint *start; + + jint coordoff, coloroff, normoff; + int texSet; + jint *texCoordSetMap; + jint* initialTexIndices; + + jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0); + jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0); + jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0); + jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0); + jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0); + jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0); + + table = *env; + + /* Enable normalize for non-uniform scale (which rescale can't handle) */ + if (ctxProperties->rescale_normal_ext && isNonUniformScale) { + glEnable(GL_NORMALIZE); + } + + coordoff = 3 * initialCoordIndex; + /* Define the data pointers */ + if (floatCoordDefined) { + glVertexPointer(3, GL_FLOAT, 0, &(fverts[coordoff])); + } else if (doubleCoordDefined){ + glVertexPointer(3, GL_DOUBLE, 0, &(dverts[coordoff])); + } + + if (floatColorsDefined) { + if (vformat & GA_WITH_ALPHA) { + coloroff = 4 * initialColorIndex; + glColorPointer(4, GL_FLOAT, 0, &(fclrs[coloroff])); + } else { + coloroff = 3 * initialColorIndex; + glColorPointer(3, GL_FLOAT, 0, &(fclrs[coloroff])); + } + } else if (byteColorsDefined) { + if (vformat & GA_WITH_ALPHA) { + coloroff = 4 * initialColorIndex; + glColorPointer(4, GL_UNSIGNED_BYTE, 0, &(bclrs[coloroff])); + } else { + coloroff = 3 * initialColorIndex; + glColorPointer(3, GL_UNSIGNED_BYTE, 0, &(bclrs[coloroff])); + } + } + if (normalsDefined) { + normoff = 3 * initialNormalIndex; + glNormalPointer(GL_FLOAT, 0, &(norms[normoff])); + } + + if (textureDefined) { + + int j = 0, tus = 0; + float *ptexCoords; + + initialTexIndices = (jint *) (*(table->GetPrimitiveArrayCritical))(env,texindices, NULL); + + texCoordSetMap = (jint *) (*(table->GetPrimitiveArrayCritical))(env,tcoordsetmap, NULL); + if (pass < 0) { + for (i = 0; i < numActiveTexUnit; i++) { + tus = texUnitStateMap[i]; + if ((tus < texCoordMapLength) && ( + ((texSet=texCoordSetMap[tus]) != -1))) { + + ptexCoords = texCoordPointer[texSet]; + + enableTexCoordPointer(ctxProperties, i, texStride, + GL_FLOAT, 0, + &ptexCoords[texStride * initialTexIndices[texSet]]); + + } else { + disableTexCoordPointer(ctxProperties, i); + } + } + } + else { + texUnitStateMap = NULL; + texSet = texCoordSetMap[pass]; + if (texSet != -1) { + ptexCoords = texCoordPointer[texSet]; + enableTexCoordPointer(ctxProperties, 0, texStride, + GL_FLOAT, 0, + &ptexCoords[texStride * initialTexIndices[texSet]]); + + /* + * in a non-multitexturing case, only the first texture + * unit is used, it will be the core library responsibility + * to disable all texture units before enabling "the" + * texture unit for multi-pass purpose + */ + } else { + disableTexCoordPointer(ctxProperties, 0); + } + } + } + + if (geo_type == GEO_TYPE_TRI_STRIP_SET || + geo_type == GEO_TYPE_TRI_FAN_SET || + geo_type == GEO_TYPE_LINE_STRIP_SET) { + + strips = (GLint *) (*(table->GetPrimitiveArrayCritical))(env, sarray, + NULL); + + switch (geo_type) { + case GEO_TYPE_TRI_STRIP_SET : + primType = GL_TRIANGLE_STRIP; + break; + case GEO_TYPE_TRI_FAN_SET : + primType = GL_TRIANGLE_FAN; + break; + case GEO_TYPE_LINE_STRIP_SET : + primType = GL_LINE_STRIP; + break; + } + + start = (GLint *)(*(table->GetPrimitiveArrayCritical))(env, + start_array, NULL); + if (ctxProperties->multi_draw_arrays_ext || ctxProperties->multi_draw_arrays_sun) { + + /* + fprintf(stderr, "strip_len = %d \n",strip_len); + for (i=0; i < strip_len;i++) { + fprintf(stderr, "numVertices = %d\n",strips[i]); + fprintf(stderr, "start = %d \n",start[i]); + } + */ + ctxProperties->glMultiDrawArraysEXT(primType, start, strips, strip_len); + } else { + for (i=0; i < strip_len;i++) { + glDrawArrays(primType, start[i], strips[i]); + } + } + (*(table->ReleasePrimitiveArrayCritical))(env, start_array, start, + 0); + (*(table->ReleasePrimitiveArrayCritical))(env, sarray, strips, 0); + } + else { + switch (geo_type){ + case GEO_TYPE_QUAD_SET : glDrawArrays(GL_QUADS, 0, vcount);break; + case GEO_TYPE_TRI_SET : glDrawArrays(GL_TRIANGLES, 0, vcount);break; + case GEO_TYPE_POINT_SET : glDrawArrays(GL_POINTS, 0, vcount);break; + case GEO_TYPE_LINE_SET: glDrawArrays(GL_LINES, 0, vcount);break; + } + } + /* clean up if we turned on normalize */ + if (ctxProperties->rescale_normal_ext && isNonUniformScale) { + glDisable(GL_NORMALIZE); + } + + + if (textureDefined) { + (*(table->ReleasePrimitiveArrayCritical))(env, tcoordsetmap, texCoordSetMap, 0); + (*(table->ReleasePrimitiveArrayCritical))(env, texindices, initialTexIndices, 0); + } +} + +/* execute geometry array with java array format */ +JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_executeVA( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jobject geo, + jint geo_type, + jboolean isNonUniformScale, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint vcount, + jint vformat, + jint vdefined, + jint initialCoordIndex, + jfloatArray vfcoords, + jdoubleArray vdcoords, + jint initialColorIndex, + jfloatArray cfdata, + jbyteArray cbdata, + jint initialNormalIndex, + jfloatArray ndata, + jint pass, + jint texCoordMapLength, + jintArray tcoordsetmap, + jint numActiveTexUnit, + jintArray tunitstatemap, + jintArray texindices, + jint texStride, + jobjectArray texCoords, + jint cdirty) +{ + + jfieldID strip_field; + jarray sarray; + jsize strip_len; + jclass geo_class; + + jarray start_array; + jfieldID start_field; + + JNIEnv table = *env; + jfloat *fverts = NULL; + jdouble *dverts = NULL; + jbyte *bclrs = NULL; + jfloat *fclrs = NULL, *norms = NULL; + jfloat* texCoordPointer[NUM_TEXTURE_UNITS]; + jarray texobjs[NUM_TEXTURE_UNITS]; + jint* texUnitStateMap = NULL; + int i; + + + jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0); + jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0); + jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0); + jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0); + jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0); + jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0); + + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + texobjs[i] = (*(table->GetObjectArrayElement))(env, texCoords, i); + } + } + geo_class = (jclass) (*(table->GetObjectClass))(env, geo); + + if (geo_type == GEO_TYPE_TRI_STRIP_SET || + geo_type == GEO_TYPE_TRI_FAN_SET || + geo_type == GEO_TYPE_LINE_STRIP_SET) { + + strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class, + "stripVertexCounts", "[I"); + sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field); + strip_len = (jsize)(*(table->GetArrayLength))(env, sarray); + + start_field = (jfieldID) (*(table->GetFieldID))(env, geo_class, + "stripStartOffsetIndices", "[I"); + start_array = (jarray)(*(table->GetObjectField))(env, geo, + start_field); + } + + /* get texture arrays */ + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + if (texobjs[i] != NULL) + texCoordPointer[i] = (jfloat*)(*(table->GetPrimitiveArrayCritical))(env,texobjs[i], NULL); + else + texCoordPointer[i] = NULL; + } + if (pass < 0) { + texUnitStateMap = (jint *) (*(table->GetPrimitiveArrayCritical))(env,tunitstatemap, NULL); + } + } + + /* get coordinate array */ + if (floatCoordDefined) { + fverts= (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, vfcoords, NULL); + } else if (doubleCoordDefined) { + dverts= (jdouble *) (*(table->GetPrimitiveArrayCritical))(env, vdcoords, NULL); + } + + /* get color array */ + if (floatColorsDefined) { + fclrs = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, cfdata, NULL); + } else if (byteColorsDefined) { + bclrs = (jbyte *) (*(table->GetPrimitiveArrayCritical))(env, cbdata, NULL); + } + + /* get normal array */ + if (normalsDefined) { + norms = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env,ndata, NULL); + } + + executeGeometryArrayVA(env, obj, ctxInfo, geo, geo_type, + isNonUniformScale, multiScreen, ignoreVertexColors, + vcount, vformat, vdefined, initialCoordIndex, + fverts, dverts, initialColorIndex, + fclrs, bclrs, initialNormalIndex, + norms, pass, texCoordMapLength, + tcoordsetmap,numActiveTexUnit, texUnitStateMap, + texindices,texStride,texCoordPointer,cdirty, sarray, strip_len, start_array); + + + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + if (texCoordPointer[i] != NULL) { + (*(table->ReleasePrimitiveArrayCritical))(env, texobjs[i], texCoordPointer[i], 0); + } + } + if (texUnitStateMap != NULL) { + (*(table->ReleasePrimitiveArrayCritical))(env, tunitstatemap, texUnitStateMap, 0); + } + } + + if (normalsDefined) { + (*env)->ReleasePrimitiveArrayCritical(env, ndata, norms, 0); + } + + + if (floatColorsDefined) { + (*env)->ReleasePrimitiveArrayCritical(env, cfdata, fclrs, 0); + } + else if (byteColorsDefined) { + (*env)->ReleasePrimitiveArrayCritical(env, cbdata, bclrs, 0); + } + + + if (floatCoordDefined) { + (*env)->ReleasePrimitiveArrayCritical(env, vfcoords, fverts, 0); + } + else if (doubleCoordDefined) { + (*env)->ReleasePrimitiveArrayCritical(env, vdcoords, dverts, 0); + } + +} + +/* execute geometry array with java array format */ +JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_executeVABuffer( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jobject geo, + jint geo_type, + jboolean isNonUniformScale, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint vcount, + jint vformat, + jint vdefined, + jint initialCoordIndex, + jobject vcoords, + jint initialColorIndex, + jobject cdataBuffer, + jfloatArray cfdata, + jbyteArray cbdata, + jint initialNormalIndex, + jobject ndata, + jint pass, + jint texCoordMapLength, + jintArray tcoordsetmap, + jint numActiveTexUnit, + jintArray tunitstatemap, + jintArray texindices, + jint texStride, + jobjectArray texCoords, + jint cdirty) +{ + jfieldID strip_field; + jarray sarray; + jsize strip_len; + jclass geo_class; + + jarray start_array; + jfieldID start_field; + + JNIEnv table = *env; + jfloat *fverts = NULL; + jdouble *dverts = NULL ; + jbyte *bclrs = NULL; + jfloat *fclrs = NULL, *norms = NULL; + jfloat* texCoordPointer[NUM_TEXTURE_UNITS]; + jarray texobjs[NUM_TEXTURE_UNITS]; + jint* texUnitStateMap = NULL; + int i; + + jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0); + jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0); + jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0); + jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0); + jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0); + jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0); + + + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + texobjs[i] = (*(table->GetObjectArrayElement))(env, texCoords, i); + } + } + geo_class = (jclass) (*(table->GetObjectClass))(env, geo); + + if (geo_type == GEO_TYPE_TRI_STRIP_SET || + geo_type == GEO_TYPE_TRI_FAN_SET || + geo_type == GEO_TYPE_LINE_STRIP_SET) { + + strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class, + "stripVertexCounts", "[I"); + sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field); + strip_len = (jsize)(*(table->GetArrayLength))(env, sarray); + + start_field = (jfieldID) (*(table->GetFieldID))(env, geo_class, + "stripStartOffsetIndices", "[I"); + start_array = (jarray)(*(table->GetObjectField))(env, geo, + start_field); + } + + /* get coordinate array */ + if (floatCoordDefined) { + fverts= (jfloat *)(*(table->GetDirectBufferAddress))(env, vcoords ); + } else if (doubleCoordDefined) { + dverts= (jdouble *)(*(table->GetDirectBufferAddress))(env, vcoords ); + } + + if(fverts == NULL && dverts == NULL) { + return; + } + + + /* get color array */ + if (floatColorsDefined) { + if(cfdata != NULL) + fclrs = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, cfdata, NULL); + else + fclrs = (jfloat *)(*(table->GetDirectBufferAddress))(env, cdataBuffer); + } + else if (byteColorsDefined) { + if(cbdata != NULL) + bclrs = (jbyte *) (*(table->GetPrimitiveArrayCritical))(env, cbdata, NULL); + else + bclrs = (jbyte *)(*(table->GetDirectBufferAddress))(env, cdataBuffer); + } + + /* get normal array */ + if (normalsDefined) { + norms = (jfloat *)(*(table->GetDirectBufferAddress))(env, ndata); + } + + /* get texture arrays */ + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + if (texobjs[i] != NULL) + texCoordPointer[i] = (jfloat*)(*(table->GetDirectBufferAddress))(env,texobjs[i]); + else + texCoordPointer[i] = NULL; + } + if (pass < 0) { + texUnitStateMap = (jint *) (*(table->GetPrimitiveArrayCritical))(env,tunitstatemap, NULL); + } + } + + + executeGeometryArrayVA(env, obj, ctxInfo, geo, geo_type, + isNonUniformScale, multiScreen, ignoreVertexColors, + vcount, vformat, vdefined, initialCoordIndex, + fverts, dverts, initialColorIndex, + fclrs, bclrs, initialNormalIndex, + norms, pass, texCoordMapLength, + tcoordsetmap,numActiveTexUnit, texUnitStateMap, + texindices,texStride,texCoordPointer,cdirty, sarray, strip_len, start_array); + + if (textureDefined) { + if (texUnitStateMap != NULL) { + (*(table->ReleasePrimitiveArrayCritical))(env, tunitstatemap, texUnitStateMap, 0); + } + } + + if(floatColorsDefined && cfdata != NULL) + (*(table->ReleasePrimitiveArrayCritical))(env, cfdata, fclrs, 0); + else if(byteColorsDefined && cbdata != NULL) + (*(table->ReleasePrimitiveArrayCritical))(env, cbdata, bclrs, 0); +} + + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_disableGlobalAlpha( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jint vformat, + jboolean useAlpha, + jboolean ignoreVertexColors) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + if(ctxProperties->global_alpha_sun){ + if (ignoreVertexColors == JNI_FALSE && vformat & 0x04) { + if (useAlpha && ctxProperties->global_alpha_sun ) { + glDisable(GL_GLOBAL_ALPHA_SUN); + } + } + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_setVertexFormat( + JNIEnv *env, + jobject obj, + jint vformat, + jboolean useAlpha, + jboolean ignoreVertexColors, + jlong ctxInfo) { + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + /* Enable and disable the appropriate pointers */ + if (vformat & GA_NORMALS) { + glEnableClientState(GL_NORMAL_ARRAY); + } + else { + glDisableClientState(GL_NORMAL_ARRAY); + } + if (ignoreVertexColors == JNI_FALSE && vformat & GA_COLOR) { + glEnableClientState(GL_COLOR_ARRAY); + } + else { + glDisableClientState(GL_COLOR_ARRAY); + + } + + if (ctxProperties->global_alpha_sun) { + if (useAlpha) { + glEnable(GL_GLOBAL_ALPHA_SUN); + } + else { + glDisable(GL_GLOBAL_ALPHA_SUN); + } + } + + + if (vformat & GA_COORDINATES) { + glEnableClientState(GL_VERTEX_ARRAY); + } + else { + glDisableClientState(GL_VERTEX_ARRAY); + } +} + +JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_GeometryArrayRetained_globalAlphaSUN + (JNIEnv *env, jobject obj, jlong ctxInfo) +{ + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + if (ctxProperties->global_alpha_sun == 1) + return JNI_TRUE ; + else + return JNI_FALSE ; +} + + + +void executeIndexedGeometryArray(JNIEnv *env, + jobject obj, jlong ctxInfo, jobject geo, jint geo_type, + jboolean isNonUniformScale, jboolean useAlpha, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint initialIndexIndex, + jint indexCount, + jint vertexCount, + jint vformat, + jint texCoordSetCount, + jintArray texCoordSetMap, jint texCoordSetMapLen, + jintArray texUnitOffset, + jint numActiveTexUnit, + jintArray texUnitStateMapArray, + jfloatArray varray, jobject varrayBuffer, jfloatArray carray, + jint texUnitIndex, jint cDirty, + jintArray indexCoord) +{ + jclass geo_class; + JNIEnv table; + + jfloat *verts,*clrs; + jint *indices; + jint i; + size_t bstride, cbstride; + jsize strip_len; + GLsizei *countArray; + int offset; + GLenum iaFormat; + int useInterleavedArrays; + int primType; + jint stride, coordoff, normoff, coloroff, texCoordoff; + int alphaNeedsUpdate = 0; /* used so we can get alpha data from */ + /* JNI before using it so we can use */ + /* GetPrimitiveArrayCritical */ + jfieldID strip_field; + jarray sarray; + jint* tmpDrawElementsIndices[100]; + + jint** multiDrawElementsIndices = NULL; + jint allocated = 0; + + jint texSize, texStride, *texCoordSetMapOffset = NULL, + *texUnitStateMap = NULL; + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + int cstride = 0; + table = *env; + + /* fprintf(stderr, "Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometry \n");*/ + geo_class = (jclass) (*(table->GetObjectClass))(env, geo); + + /* This matches the code in GeometryArrayRetained.java */ + stride = coordoff = normoff = coloroff = texCoordoff = 0; + if ((vformat & GA_COORDINATES) != 0) { + stride += 3; + } + if ((vformat & GA_NORMALS) != 0) { + stride += 3; + coordoff += 3; + } + if ((vformat & GA_COLOR) != 0) { + if ((vformat & GA_WITH_ALPHA) != 0 ) { + stride += 4; + normoff += 4; + coordoff += 4; + } + else { /* Handle the case of executeInterleaved 3f */ + stride += 3; + normoff += 3; + coordoff += 3; + } + } + if ((vformat & GA_TEXTURE_COORDINATE) != 0) { + if ((vformat & GA_TEXTURE_COORDINATE_2) != 0) { + texSize = 2; + texStride = 2 * texCoordSetCount; + } else if ((vformat & GA_TEXTURE_COORDINATE_3) != 0) { + texSize = 3; + texStride = 3 * texCoordSetCount; + } else if ((vformat & GA_TEXTURE_COORDINATE_4) != 0) { + texSize = 4; + texStride = 4 * texCoordSetCount; + } + stride += texStride; + normoff += texStride; + coloroff += texStride; + coordoff += texStride; + } + + bstride = stride*sizeof(float); + + /* + * call other JNI functions before entering Critical region + * i.e., GetPrimitiveArrayCritical + */ + + + if (geo_type == GEO_TYPE_INDEXED_TRI_STRIP_SET || + geo_type == GEO_TYPE_INDEXED_TRI_FAN_SET || + geo_type == GEO_TYPE_INDEXED_LINE_STRIP_SET) { + + strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class, + "stripIndexCounts", "[I"); + sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field); + strip_len = (jsize)(*(table->GetArrayLength))(env, sarray); + + + } + + /* begin critical region */ + if(varray != NULL) + verts = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, varray, NULL); + else if(varrayBuffer != NULL) + verts = (jfloat *) (*(table->GetDirectBufferAddress))(env, varrayBuffer); + + indices = (jint *) (*(table->GetPrimitiveArrayCritical))(env, indexCoord, NULL); + + + /* using byRef interleaved array and has a separate pointer, then .. */ + cstride = stride; + if (carray != NULL) { + clrs = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, carray, NULL); + cstride = 4; + + } + else { + clrs = &(verts[coloroff]); + } + cbstride = cstride * sizeof(float); + if (texCoordSetMapLen >0) { + texCoordSetMapOffset = (jint *) (*(table->GetPrimitiveArrayCritical))(env, texUnitOffset, NULL); + } + + if (texUnitStateMapArray != NULL) { + texUnitStateMap = (jint *) (*(table->GetPrimitiveArrayCritical))(env, texUnitStateMapArray, NULL); + } + + /* Enable normalize for non-uniform scale (which rescale can't handle) */ + if (ctxProperties->rescale_normal_ext && isNonUniformScale) { + glEnable(GL_NORMALIZE); + } + + /*** Handle non-indexed strip GeometryArray first *******/ + if (geo_type == GEO_TYPE_INDEXED_TRI_STRIP_SET || + geo_type == GEO_TYPE_INDEXED_TRI_FAN_SET || + geo_type == GEO_TYPE_INDEXED_LINE_STRIP_SET) { + + + countArray = (GLsizei *) (*(table->GetPrimitiveArrayCritical))(env, sarray, + NULL); + + if ((ignoreVertexColors == JNI_TRUE) || (carray != NULL) || + ((vformat & GA_TEXTURE_COORDINATE) && ((texCoordSetMapLen > 1) || + (texCoordSetCount > 1)))) { + useInterleavedArrays = 0; + } else { + INTERLEAVEDARRAYS_TEST() + } + if (useInterleavedArrays) { + glInterleavedArrays(iaFormat, bstride, verts); + } else { + if (vformat & GA_NORMALS) { + glNormalPointer(GL_FLOAT, bstride, &(verts[normoff])); + } + if (ignoreVertexColors == JNI_FALSE && vformat & GA_COLOR) { + if (vformat & GA_WITH_ALPHA || (useAlpha == GL_TRUE)) { + glColorPointer(4, GL_FLOAT, cbstride, clrs); + } else { + /* + for (i = 0; i < 4; i++) { + fprintf(stderr, "r = %f, g = %f, b = %f\n", verts[i*stride +coloroff], verts[i*stride +coloroff+1],verts[i*stride +coloroff+2]); + } + */ + glColorPointer(3, GL_FLOAT, cbstride, clrs); + } + } + if (vformat & GA_COORDINATES) { + /* + for (i = 0; i < 4; i++) { + fprintf(stderr, "x = %f, y = %f, z = %f\n", verts[i*stride +coordoff], verts[i*stride +coordoff+1],verts[i*stride +coordoff+2]); + } + */ + glVertexPointer(3, GL_FLOAT, bstride, &(verts[coordoff])); + } + + if (vformat & GA_TEXTURE_COORDINATE) { + +/* TODO: texCoordoff == 0 ???*/ + executeTexture(texUnitIndex, texCoordSetMapLen, + texSize, bstride, texCoordoff, + texCoordSetMapOffset, + numActiveTexUnit, texUnitStateMap, + verts, ctxInfo); + } + } + + switch (geo_type) { + case GEO_TYPE_INDEXED_TRI_STRIP_SET : + primType = GL_TRIANGLE_STRIP; + break; + case GEO_TYPE_INDEXED_TRI_FAN_SET : + primType = GL_TRIANGLE_FAN; + break; + case GEO_TYPE_INDEXED_LINE_STRIP_SET : + primType = GL_LINE_STRIP; + break; + } + /* + fprintf(stderr, "strip_len = %d\n",strip_len); + for (i=0; i < strip_len;i++) { + fprintf(stderr, "strips[i] = %d\n",strips[i]); + } + */ + + lockArray(ctxProperties, vertexCount); + + if (ctxProperties->multi_draw_arrays_ext || ctxProperties->multi_draw_arrays_sun) { + if (strip_len > 100) { + multiDrawElementsIndices = (jint**)malloc(strip_len * sizeof(int*)); + allocated = 1; + } + else { + multiDrawElementsIndices =(jint**) &tmpDrawElementsIndices; + } + + offset = initialIndexIndex; + for (i=0; i < strip_len;i++) { + multiDrawElementsIndices[i] = &indices[offset]; + offset += countArray[i]; + } + ctxProperties->glMultiDrawElementsEXT(primType, countArray, GL_UNSIGNED_INT,(const void **)multiDrawElementsIndices, strip_len); + + } else { + offset = initialIndexIndex; + for (i=0; i < strip_len;i++) { + + glDrawElements(primType, countArray[i], GL_UNSIGNED_INT, &indices[offset]); + offset += countArray[i]; + } + } + (*(table->ReleasePrimitiveArrayCritical))(env, sarray, countArray, 0); + if (allocated) { + free(multiDrawElementsIndices); + } + + } + /******* Handle non-indexed non-striped GeometryArray now *****/ + else if ((geo_type == GEO_TYPE_INDEXED_QUAD_SET) || + (geo_type == GEO_TYPE_INDEXED_TRI_SET) || + (geo_type == GEO_TYPE_INDEXED_POINT_SET) || + (geo_type == GEO_TYPE_INDEXED_LINE_SET)) + { + if ((ignoreVertexColors == JNI_TRUE) || (carray != NULL) || + ((vformat & GA_TEXTURE_COORDINATE) && ((texCoordSetMapLen > 1) || + (texCoordSetCount > 1)))) { + useInterleavedArrays = 0; + } else { + INTERLEAVEDARRAYS_TEST() + } + if (useInterleavedArrays) { + glInterleavedArrays(iaFormat, bstride, verts); + } else { + if (vformat & GA_NORMALS) { + glNormalPointer(GL_FLOAT, bstride, &(verts[normoff])); + } + if (ignoreVertexColors == JNI_FALSE && vformat & GA_COLOR) { + if (vformat & GA_WITH_ALPHA || (useAlpha == GL_TRUE)) { + + glColorPointer(4, GL_FLOAT, cbstride, clrs); + } else { + glColorPointer(3, GL_FLOAT, cbstride, clrs); + } + } + if (vformat & GA_COORDINATES) { + glVertexPointer(3, GL_FLOAT, bstride, &(verts[coordoff])); + } + + if (vformat & GA_TEXTURE_COORDINATE) { + +/* TODO: texCoordoff == 0 ???*/ + executeTexture(texUnitIndex, texCoordSetMapLen, + texSize, bstride, texCoordoff, + texCoordSetMapOffset, + numActiveTexUnit, texUnitStateMap, + verts, ctxInfo); + } + } + + + lockArray(ctxProperties, vertexCount); + + switch (geo_type){ + case GEO_TYPE_INDEXED_QUAD_SET : glDrawElements(GL_QUADS,indexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break; + case GEO_TYPE_INDEXED_TRI_SET : glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break; + case GEO_TYPE_INDEXED_POINT_SET : glDrawElements(GL_POINTS, indexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break; + case GEO_TYPE_INDEXED_LINE_SET: glDrawElements(GL_LINES, indexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break; + } + } + + unlockArray(ctxProperties); + + /* clean up if we turned on normalize */ + + if (ctxProperties->rescale_normal_ext && isNonUniformScale) { + glDisable(GL_NORMALIZE); + } + if(varray != NULL) + (*(table->ReleasePrimitiveArrayCritical))(env, varray, verts, 0); + + (*(table->ReleasePrimitiveArrayCritical))(env, indexCoord, indices, 0); + + if (carray != NULL) + (*(table->ReleasePrimitiveArrayCritical))(env, carray, clrs, 0); + + if (texCoordSetMapLen > 0) + (*(table->ReleasePrimitiveArrayCritical))(env, texUnitOffset, + texCoordSetMapOffset, 0); + + if (texUnitStateMap != NULL) + (*(table->ReleasePrimitiveArrayCritical))(env, texUnitStateMapArray, + texUnitStateMap, 0); +} +JNIEXPORT +void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometry(JNIEnv *env, + jobject obj, jlong ctxInfo, jobject geo, jint geo_type, + jboolean isNonUniformScale, jboolean useAlpha, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint initialIndexIndex, + jint indexCount, + jint vertexCount, + jint vformat, + jint texCoordSetCount, + jintArray texCoordSetMap, jint texCoordSetMapLen, + jintArray texUnitOffset, + jint numActiveTexUnit, + jintArray texUnitStateMapArray, + jfloatArray varray, jfloatArray carray, + jint texUnitIndex, jint cDirty, + jintArray indexCoord) +{ + executeIndexedGeometryArray(env, obj, ctxInfo, geo, geo_type, + isNonUniformScale, useAlpha, multiScreen, + ignoreVertexColors, + initialIndexIndex, + indexCount, + vertexCount, + vformat, + texCoordSetCount, + texCoordSetMap, texCoordSetMapLen, + texUnitOffset, + numActiveTexUnit, + texUnitStateMapArray, + varray, NULL, carray, + texUnitIndex, cDirty, + indexCoord); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometryBuffer(JNIEnv *env, + jobject obj, jlong ctxInfo, jobject geo, jint geo_type, + jboolean isNonUniformScale, jboolean useAlpha, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint initialIndexIndex, + jint indexCount, + jint vertexCount, + jint vformat, + jint texCoordSetCount, + jintArray texCoordSetMap, jint texCoordSetMapLen, + jintArray texUnitOffset, + jint numActiveTexUnit, + jintArray texUnitStateMapArray, + jobject varray, jfloatArray carray, + jint texUnitIndex, jint cDirty, + jintArray indexCoord) +{ + executeIndexedGeometryArray(env, obj, ctxInfo, geo, geo_type, + isNonUniformScale, useAlpha, multiScreen, + ignoreVertexColors, + initialIndexIndex, + indexCount, + vertexCount, + vformat, + texCoordSetCount, + texCoordSetMap, texCoordSetMapLen, + texUnitOffset, + numActiveTexUnit, + texUnitStateMapArray, + NULL, varray, carray, + texUnitIndex, cDirty, + indexCoord); +} + + +void executeIndexedGeometryArrayVA( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jobject geo, + jint geo_type, + jboolean isNonUniformScale, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint initialIndexIndex, + jint validIndexCount, + jint vertexCount, + jint vformat, + jint vdefined, + jfloat* fverts, + jdouble* dverts, + jfloat* fclrs, + jbyte* bclrs, + jfloat* norms, + jint pass, + jint texCoordMapLength, + jintArray tcoordsetmap, + jint numActiveTexUnit, + jintArray tunitstatemap, + jint texStride, + jfloat** texCoordPointer, + jint cdirty, + jintArray indexCoord, + jarray sarray, + jsize strip_len) + { + int primType; + JNIEnv table; + jint i; + jint* tmpDrawElementsIndices[100]; + jint** multiDrawElementsIndices = NULL; + jint allocated = 0; + jint *indices; + + jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0); + jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0); + jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0); + jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0); + jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0); + jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0); + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + int texSet; + jint *texCoordSetMap, *texUnitStateMap; + GLsizei *countArray; + jint offset = 0; + table = *env; + + /* Enable normalize for non-uniform scale (which rescale can't handle) */ + if (ctxProperties->rescale_normal_ext && isNonUniformScale) { + glEnable(GL_NORMALIZE); + } + + /* Define the data pointers */ + if (floatCoordDefined) { + glVertexPointer(3, GL_FLOAT, 0, fverts); + } else if (doubleCoordDefined){ + glVertexPointer(3, GL_DOUBLE, 0, dverts); + } + if (floatColorsDefined) { + if (vformat & GA_WITH_ALPHA) { + glColorPointer(4, GL_FLOAT, 0, fclrs); + } else { + glColorPointer(3, GL_FLOAT, 0, fclrs); + } + } else if (byteColorsDefined) { + if (vformat & GA_WITH_ALPHA) { + glColorPointer(4, GL_UNSIGNED_BYTE, 0, bclrs); + } else { + glColorPointer(3, GL_UNSIGNED_BYTE, 0, bclrs); + } + } + if (normalsDefined) { + glNormalPointer(GL_FLOAT, 0, norms); + } + + if (textureDefined) { + + int j = 0, tus = 0; + float *ptexCoords; + + texCoordSetMap = (jint *) (*(table->GetPrimitiveArrayCritical))(env,tcoordsetmap, NULL); + if (pass < 0) { + texUnitStateMap = (jint *) (*(table->GetPrimitiveArrayCritical))(env,tunitstatemap, NULL); + for (i = 0; i < numActiveTexUnit; i++) { + tus = texUnitStateMap[i]; + if ((tus < texCoordMapLength) && ( + ((texSet=texCoordSetMap[tus]) != -1))) { + + ptexCoords = texCoordPointer[texSet]; + + enableTexCoordPointer(ctxProperties, i, texStride, + GL_FLOAT, 0, + ptexCoords); + + } else { + + disableTexCoordPointer(ctxProperties, i); + } + } + } + else { + texUnitStateMap = NULL; + texSet = texCoordSetMap[pass]; + if (texSet != -1) { + ptexCoords = texCoordPointer[texSet]; + enableTexCoordPointer(ctxProperties, 0, texStride, + GL_FLOAT, 0, + ptexCoords); + + /* + * in a non-multitexturing case, only the first texture + * unit is used, it will be the core library responsibility + * to disable all texture units before enabling "the" + * texture unit for multi-pass purpose + */ + } + } + } + indices = (jint *) (*(table->GetPrimitiveArrayCritical))(env, indexCoord, NULL); + + lockArray(ctxProperties, vertexCount); + + if (geo_type == GEO_TYPE_INDEXED_TRI_STRIP_SET || + geo_type == GEO_TYPE_INDEXED_TRI_FAN_SET || + geo_type == GEO_TYPE_INDEXED_LINE_STRIP_SET) { + + countArray = (GLint *) (*(table->GetPrimitiveArrayCritical))(env, sarray, + NULL); + + switch (geo_type) { + case GEO_TYPE_INDEXED_TRI_STRIP_SET : + primType = GL_TRIANGLE_STRIP; + break; + case GEO_TYPE_INDEXED_TRI_FAN_SET : + primType = GL_TRIANGLE_FAN; + break; + case GEO_TYPE_INDEXED_LINE_STRIP_SET : + primType = GL_LINE_STRIP; + break; + } + + + + if (ctxProperties->multi_draw_arrays_ext || ctxProperties->multi_draw_arrays_sun) { + if (strip_len > 100) { + multiDrawElementsIndices = (jint**)malloc(strip_len * sizeof(int*)); + allocated = 1; + } + else { + multiDrawElementsIndices = (jint**)&tmpDrawElementsIndices; + } + + offset = initialIndexIndex; + for (i=0; i < strip_len;i++) { + multiDrawElementsIndices[i] = &indices[offset]; + offset += countArray[i]; + } + ctxProperties->glMultiDrawElementsEXT(primType, countArray, GL_UNSIGNED_INT,(const void **)multiDrawElementsIndices, strip_len); + + } else { + offset = initialIndexIndex; + for (i=0; i < strip_len;i++) { + glDrawElements(primType, countArray[i], GL_UNSIGNED_INT, &indices[offset]); + offset += countArray[i]; + } + } + + (*(table->ReleasePrimitiveArrayCritical))(env, sarray, countArray, 0); + if (allocated) { + free(multiDrawElementsIndices); + } + } + else { + switch (geo_type){ + case GEO_TYPE_INDEXED_QUAD_SET : glDrawElements(GL_QUADS,validIndexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break; + case GEO_TYPE_INDEXED_TRI_SET : glDrawElements(GL_TRIANGLES, validIndexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break; + case GEO_TYPE_INDEXED_POINT_SET : glDrawElements(GL_POINTS, validIndexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break; + case GEO_TYPE_INDEXED_LINE_SET: glDrawElements(GL_LINES, validIndexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break; + } + } + + unlockArray(ctxProperties); + + /* clean up if we turned on normalize */ + if (ctxProperties->rescale_normal_ext && isNonUniformScale) { + glDisable(GL_NORMALIZE); + } + + (*(table->ReleasePrimitiveArrayCritical))(env, indexCoord, indices, 0); + + if (textureDefined) { + (*(table->ReleasePrimitiveArrayCritical))(env, tcoordsetmap, texCoordSetMap, 0); + if (texUnitStateMap != NULL) + (*(table->ReleasePrimitiveArrayCritical))(env, tunitstatemap, texUnitStateMap, 0); + } +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometryVA( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jobject geo, + jint geo_type, + jboolean isNonUniformScale, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint initialIndexIndex, + jint validIndexCount, + jint vertexCount, + jint vformat, + jint vdefined, + jfloatArray vfcoords, + jdoubleArray vdcoords, + jfloatArray cfdata, + jbyteArray cbdata, + jfloatArray ndata, + jint pass, + jint texCoordMapLength, + jintArray tcoordsetmap, + jint numActiveTexUnit, + jintArray tunitstatemap, + jint texStride, + jobjectArray texCoords, + jint cdirty, + jintArray indexCoord) +{ + jfieldID strip_field; + jarray sarray; + jsize strip_len; + JNIEnv table; + jint i; + jclass geo_class; + + jfloat *fverts = NULL; + jdouble *dverts = NULL; + jbyte *bclrs = NULL; + jfloat *fclrs = NULL, *norms = NULL; + jfloat* texCoordPointer[NUM_TEXTURE_UNITS]; + jarray texobjs[NUM_TEXTURE_UNITS]; + + jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0); + jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0); + jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0); + jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0); + jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0); + jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0); + table = *env; + geo_class = (jclass) (*(table->GetObjectClass))(env, geo); + + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + texobjs[i] = (jarray)(*(table->GetObjectArrayElement))(env, texCoords, i); + } + } + if (geo_type == GEO_TYPE_INDEXED_TRI_STRIP_SET || + geo_type == GEO_TYPE_INDEXED_TRI_FAN_SET || + geo_type == GEO_TYPE_INDEXED_LINE_STRIP_SET) { + + strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class, + "stripIndexCounts", "[I"); + sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field); + strip_len = (jsize)(*(table->GetArrayLength))(env, sarray); + + } + /* get texture arrays */ + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + if (texobjs[i] != NULL) + texCoordPointer[i] = (jfloat*)(*(table->GetPrimitiveArrayCritical))(env,texobjs[i], NULL); + else + texCoordPointer[i] = NULL; + + } + } + + /* get coordinate array */ + if (floatCoordDefined) { + fverts= (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, vfcoords, NULL); + } else if (doubleCoordDefined) { + dverts= (jdouble *) (*(table->GetPrimitiveArrayCritical))(env, vdcoords, NULL); + } + + /* get color array */ + if (floatColorsDefined) { + fclrs = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, cfdata, NULL); + } else if (byteColorsDefined) { + bclrs = (jbyte *) (*(table->GetPrimitiveArrayCritical))(env, cbdata, NULL); + } + + /* get normal array */ + if (normalsDefined) { + norms = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env,ndata, NULL); + } + + executeIndexedGeometryArrayVA(env, + obj, + ctxInfo, + geo, + geo_type, + isNonUniformScale, + multiScreen, + ignoreVertexColors, + initialIndexIndex, + validIndexCount, + vertexCount, + vformat, + vdefined, + fverts, + dverts, + fclrs, + bclrs, + norms, + pass, + texCoordMapLength, + tcoordsetmap, + numActiveTexUnit, + tunitstatemap, + texStride, + texCoordPointer, + cdirty, + indexCoord, + sarray, + strip_len); + + if (floatCoordDefined) { + (*(table->ReleasePrimitiveArrayCritical))(env, vfcoords, fverts, 0); + } + else if (doubleCoordDefined) { + (*(table->ReleasePrimitiveArrayCritical))(env, vdcoords, dverts, 0); + } + + if (floatColorsDefined) { + (*(table->ReleasePrimitiveArrayCritical))(env, cfdata, fclrs, 0); + } + else if (byteColorsDefined) { + (*(table->ReleasePrimitiveArrayCritical))(env, cbdata, bclrs, 0); + } + + if (normalsDefined) { + (*(table->ReleasePrimitiveArrayCritical))(env, ndata, norms, 0); + } + + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + if (texCoordPointer[i] != NULL) { + (*(table->ReleasePrimitiveArrayCritical))(env, texobjs[i], texCoordPointer[i], 0); + } + } + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_executeIndexedGeometryVABuffer( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jobject geo, + jint geo_type, + jboolean isNonUniformScale, + jboolean multiScreen, + jboolean ignoreVertexColors, + jint initialIndexIndex, + jint validIndexCount, + jint vertexCount, + jint vformat, + jint vdefined, + jobject vcoords, + jobject cdataBuffer, + jfloatArray cfdata, + jbyteArray cbdata, + jobject ndata, + jint pass, + jint texCoordMapLength, + jintArray tcoordsetmap, + jint numActiveTexUnit, + jintArray tunitstatemap, + jint texStride, + jobjectArray texCoords, + jint cdirty, + jintArray indexCoord) +{ + jfieldID strip_field; + jarray sarray; + jsize strip_len; + JNIEnv table; + jint i; + jclass geo_class; + + jfloat *fverts = NULL; + jdouble *dverts = NULL; + jbyte *bclrs = NULL; + jfloat *fclrs = NULL, *norms = NULL; + jfloat* texCoordPointer[NUM_TEXTURE_UNITS]; + jarray texobjs[NUM_TEXTURE_UNITS]; + + jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0); + jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0); + jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0); + jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0); + jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0); + jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0); + table = *env; + geo_class = (jclass) (*(table->GetObjectClass))(env, geo); + + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + texobjs[i] = (jarray)(*(table->GetObjectArrayElement))(env, texCoords, i); + } + } + if (geo_type == GEO_TYPE_INDEXED_TRI_STRIP_SET || + geo_type == GEO_TYPE_INDEXED_TRI_FAN_SET || + geo_type == GEO_TYPE_INDEXED_LINE_STRIP_SET) { + + strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class, + "stripIndexCounts", "[I"); + sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field); + strip_len = (jsize)(*(table->GetArrayLength))(env, sarray); + + } + /* get texture arrays */ + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + if (texobjs[i] != NULL) + texCoordPointer[i] = (jfloat*)(*(table->GetDirectBufferAddress))(env,texobjs[i]); + else + texCoordPointer[i] = NULL; + + } + } + + /* get coordinate array */ + if (floatCoordDefined) { + fverts= (jfloat *)(*(table->GetDirectBufferAddress))(env, vcoords ); + } else if (doubleCoordDefined) { + dverts= (jdouble *)(*(table->GetDirectBufferAddress))(env, vcoords ); + } + + /* get color array */ + if (floatColorsDefined) { + if(cfdata != NULL) + fclrs = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, cfdata, NULL); + else + fclrs = (jfloat *)(*(table->GetDirectBufferAddress))(env, cdataBuffer); + } + else if (byteColorsDefined) { + if(cbdata != NULL) + bclrs = (jbyte *) (*(table->GetPrimitiveArrayCritical))(env, cbdata, NULL); + else + bclrs = (jbyte *)(*(table->GetDirectBufferAddress))(env, cdataBuffer); + } + + /* get normal array */ + if (normalsDefined) { + norms = (jfloat *)(*(table->GetDirectBufferAddress))(env, ndata); + } + + executeIndexedGeometryArrayVA(env, + obj, + ctxInfo, + geo, + geo_type, + isNonUniformScale, + multiScreen, + ignoreVertexColors, + initialIndexIndex, + validIndexCount, + vertexCount, + vformat, + vdefined, + fverts, + dverts, + fclrs, + bclrs, + norms, + pass, + texCoordMapLength, + tcoordsetmap, + numActiveTexUnit, + tunitstatemap, + texStride, + texCoordPointer, + cdirty, + indexCoord, + sarray, + strip_len); + + if(floatColorsDefined && cfdata != NULL) + (*(table->ReleasePrimitiveArrayCritical))(env, cfdata, fclrs, 0); + else if(byteColorsDefined && cbdata != NULL) + (*(table->ReleasePrimitiveArrayCritical))(env, cbdata, bclrs, 0); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_IndexedGeometryArrayRetained_buildIndexedGeometry(JNIEnv *env, + jobject obj, jlong ctxInfo, jobject geo, + jint geo_type, + jboolean isNonUniformScale, jboolean updateAlpha, float alpha, + jboolean ignoreVertexColors, + jint initialIndexIndex, + jint validIndexCount, + jint vertexCount, + jint vformat, + jint texCoordSetCount, + jintArray texCoordSetMapArray, + jint texCoordSetMapLen, + jintArray texUnitOffset, + jdoubleArray xform, jdoubleArray nxform, + jfloatArray varray, jintArray indexCoord) +{ + + jclass geo_class; + JNIEnv table; + jboolean useAlpha = JNI_FALSE; + + jfloat *verts; + jint *indices; + jint i; + size_t bstride; + jint texStride, *texCoordSetMapOffset, texSize; + GLsizei *countArray; + GLenum iaFormat; + int useInterleavedArrays; + jsize strip_len; + int primType; + jint stride, coordoff, normoff, coloroff, texCoordoff; + jfieldID strip_field; + jarray sarray; + jdouble *xform_ptr = NULL; + jdouble *nxform_ptr = NULL; + jfloat *tmpCoordArray = NULL, *tmpNormalArray = NULL; + jint* tmpDrawElementsIndices[100]; + + jint** multiDrawElementsIndices = NULL; + jint allocated = 0; + int offset = 0; + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + table = *env; + geo_class = (jclass) (*(table->GetObjectClass))(env, geo); + + /* This matches the code in GeometryArrayRetained.java */ + stride = coordoff = normoff = coloroff = texCoordoff = 0; + if ((vformat & GA_COORDINATES) != 0) { + glEnableClientState(GL_VERTEX_ARRAY); + stride += 3; + } + else { + glDisableClientState(GL_VERTEX_ARRAY); + } + if ((vformat & GA_NORMALS) != 0) { + glEnableClientState(GL_NORMAL_ARRAY); + stride += 3; + coordoff += 3; + } + else { + glDisableClientState(GL_NORMAL_ARRAY); + } + + if ((vformat & GA_COLOR) != 0) { + glEnableClientState(GL_COLOR_ARRAY); + stride += 4; + normoff += 4; + coordoff += 4; + } + else { + glDisableClientState(GL_COLOR_ARRAY); + } + if ((vformat & GA_TEXTURE_COORDINATE) != 0) { + if ((vformat & GA_TEXTURE_COORDINATE_2) != 0) { + texSize = 2; + texStride = 2 * texCoordSetCount; + } else if ((vformat & GA_TEXTURE_COORDINATE_3) != 0) { + texSize = 3; + texStride = 3 * texCoordSetCount; + } else if ((vformat & GA_TEXTURE_COORDINATE_4) != 0) { + texSize = 4; + texStride = 4 * texCoordSetCount; + } + stride += texStride; + normoff += texStride; + coloroff += texStride; + coordoff += texStride; + } + + bstride = stride*sizeof(float); + + /* + * process alpha for geometryArray without alpha + */ + if (updateAlpha == JNI_TRUE && ignoreVertexColors == JNI_FALSE) { + useAlpha = JNI_TRUE; + } + + /* + * call other JNI functions before entering Critical region + * i.e., GetPrimitiveArrayCritical + */ + if (geo_type == GEO_TYPE_INDEXED_TRI_STRIP_SET || + geo_type == GEO_TYPE_INDEXED_TRI_FAN_SET || + geo_type == GEO_TYPE_INDEXED_LINE_STRIP_SET) { + + strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class, + "stripIndexCounts", "[I"); + sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field); + strip_len = (jsize)(*(table->GetArrayLength))(env, sarray); + } + + + + /* begin critical region */ + verts = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, varray, NULL); + + indices = (jint *) (*(table->GetPrimitiveArrayCritical))(env, indexCoord, NULL); + + if (texCoordSetMapLen >0) { + texCoordSetMapOffset = (jint *)(*(table->GetPrimitiveArrayCritical)) + (env, texUnitOffset, NULL); + } + + + /* get the static transform if exists */ + if (xform != NULL) { + xform_ptr = (jdouble *) (*(table->GetPrimitiveArrayCritical))( + env, xform, NULL); + + } + + + /* get the static normals transform if exists */ + if (nxform != NULL) { + nxform_ptr = (jdouble *) (*(table->GetPrimitiveArrayCritical))( + env, nxform, NULL); + } + + + /* + * Check if normal is present and nxform_ptr id non-null, if yes, + * create a new normal array and apply the xform + */ + if ((vformat & GA_NORMALS) != 0 && (nxform_ptr != NULL)) { + /* create a temporary array for normals */ + tmpNormalArray = (jfloat*) malloc(vertexCount * sizeof(float) * 3); + for (i = 0; i < vertexCount*3; i+=3) { + tmpNormalArray[i] = (float) (nxform_ptr[0] * verts[normoff] + + nxform_ptr[1] * verts[normoff+1] + + nxform_ptr[2] * verts[normoff+2]); + tmpNormalArray[i+1] = (float) (nxform_ptr[4] * verts[normoff] + + nxform_ptr[5] * verts[normoff+1] + + nxform_ptr[6] * verts[normoff+2]); + tmpNormalArray[i+2] = (float) (nxform_ptr[8] * verts[normoff] + + nxform_ptr[9] * verts[normoff+1] + + nxform_ptr[10] * verts[normoff+2]); + normoff += stride; + } + } + + if ((vformat & GA_COORDINATES) != 0 && xform_ptr != NULL) { + /* create a temporary array for normals */ + tmpCoordArray = (jfloat*) malloc(vertexCount * sizeof(float) * 3); + for (i = 0; i < vertexCount*3; i+=3) { + tmpCoordArray[i] = (float) (xform_ptr[0] * verts[coordoff] + + xform_ptr[1] * verts[coordoff+1] + + xform_ptr[2] * verts[coordoff+2]); + tmpCoordArray[i+1] = (float) (xform_ptr[4] * verts[coordoff] + + xform_ptr[5] * verts[coordoff+1] + + xform_ptr[6] * verts[coordoff+2]); + tmpCoordArray[i+2] = (float) (xform_ptr[8] * verts[coordoff] + + xform_ptr[9] * verts[coordoff+1] + + xform_ptr[10] * verts[coordoff+2]); + coordoff += stride; + } + } + + + if (geo_type == GEO_TYPE_INDEXED_TRI_STRIP_SET || + geo_type == GEO_TYPE_INDEXED_TRI_FAN_SET || + geo_type == GEO_TYPE_INDEXED_LINE_STRIP_SET) { + + + switch (geo_type) { + case GEO_TYPE_INDEXED_TRI_STRIP_SET : + primType = GL_TRIANGLE_STRIP; + break; + case GEO_TYPE_INDEXED_TRI_FAN_SET : + primType = GL_TRIANGLE_FAN; + break; + case GEO_TYPE_INDEXED_LINE_STRIP_SET : + primType = GL_LINE_STRIP; + break; + } + + + countArray = (GLsizei *) (*(table->GetPrimitiveArrayCritical))(env, sarray, + NULL); + + if ((ignoreVertexColors == JNI_TRUE) || (xform_ptr != NULL) || + ((vformat & GA_TEXTURE_COORDINATE) && ((texCoordSetMapLen > 1) || + (texCoordSetCount > 1)))) { + useInterleavedArrays = 0; + } else { + INTERLEAVEDARRAYS_TEST() + } + + if (useInterleavedArrays) { + glInterleavedArrays(iaFormat, bstride, verts); + } else { + if (vformat & GA_NORMALS) { + if (nxform_ptr == NULL) { + glNormalPointer(GL_FLOAT, bstride, &(verts[normoff])); + } + else { + glNormalPointer(GL_FLOAT, 3 * sizeof(float), tmpNormalArray); + } + } + if (ignoreVertexColors == JNI_FALSE && vformat & GA_COLOR) { + if (vformat & GA_WITH_ALPHA || (useAlpha == GL_TRUE)) { + glColorPointer(4, GL_FLOAT, bstride, &(verts[coloroff])); + } else { + /* + for (i = 0; i < vcount; i++) { + fprintf(stderr, "r = %f, g = %f, b = %f\n", verts[i*bstride +coloroff], verts[i*bstride +coloroff+1],verts[i*bstride +coloroff+2]); + } + */ + glColorPointer(3, GL_FLOAT, bstride, &(verts[coloroff])); + } + } + if (vformat & GA_COORDINATES) { + if (xform_ptr == NULL) { + /* + for (i = 0; i < vcount; i++) { + fprintf(stderr, "x = %f, y = %f, z = %f\n", verts[i*bstride +coordoff], verts[i*bstride +coordoff+1],verts[i*bstride +coordoff+2]); + } + */ + glVertexPointer(3, GL_FLOAT, bstride, &(verts[coordoff])); + } + else { + glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), tmpCoordArray); + } + } + + if (vformat & GA_TEXTURE_COORDINATE) { + + executeTexture(-1, texCoordSetMapLen, + texSize, bstride, texCoordoff, + texCoordSetMapOffset, + texCoordSetMapLen, NULL, + verts, ctxInfo); + } + } + + switch (geo_type) { + case GEO_TYPE_INDEXED_TRI_STRIP_SET : + primType = GL_TRIANGLE_STRIP; + break; + case GEO_TYPE_INDEXED_TRI_FAN_SET : + primType = GL_TRIANGLE_FAN; + break; + case GEO_TYPE_INDEXED_LINE_STRIP_SET : + primType = GL_LINE_STRIP; + break; + } + + lockArray(ctxProperties, vertexCount); + + if (ctxProperties->multi_draw_arrays_ext || ctxProperties->multi_draw_arrays_sun) { + if (strip_len > 100) { + multiDrawElementsIndices = (jint**)malloc(strip_len * sizeof(int*)); + allocated = 1; + } + else { + multiDrawElementsIndices =(jint**) &tmpDrawElementsIndices; + } + + offset = initialIndexIndex; + for (i=0; i < strip_len;i++) { + multiDrawElementsIndices[i] = &indices[offset]; + offset += countArray[i]; + } + ctxProperties->glMultiDrawElementsEXT(primType, countArray, GL_UNSIGNED_INT,(const void **)multiDrawElementsIndices, strip_len); + + } else { + offset = initialIndexIndex; + for (i=0; i < strip_len;i++) { + glDrawElements(primType, countArray[i], GL_UNSIGNED_INT, &indices[offset]); + offset += countArray[i]; + } + } + (*(table->ReleasePrimitiveArrayCritical))(env, sarray, countArray, 0); + if (allocated) { + free(multiDrawElementsIndices); + } + + + } + else if ((geo_type == GEO_TYPE_INDEXED_QUAD_SET) || + (geo_type == GEO_TYPE_INDEXED_TRI_SET) || + (geo_type == GEO_TYPE_INDEXED_POINT_SET) || + (geo_type == GEO_TYPE_INDEXED_LINE_SET)) { + + switch (geo_type) { + case GEO_TYPE_INDEXED_QUAD_SET : + primType = GL_QUADS; + break; + case GEO_TYPE_INDEXED_TRI_SET : + primType = GL_TRIANGLES; + break; + case GEO_TYPE_INDEXED_POINT_SET : + primType = GL_POINTS; + break; + case GEO_TYPE_INDEXED_LINE_SET : + primType = GL_LINES; + break; + + } + + if ((ignoreVertexColors == JNI_TRUE) || (xform_ptr != NULL) || + ((vformat & GA_TEXTURE_COORDINATE) && ((texCoordSetMapLen > 1) || + (texCoordSetCount > 1)))) { + useInterleavedArrays = 0; + } else { + INTERLEAVEDARRAYS_TEST() + } + + if (useInterleavedArrays) { + glInterleavedArrays(iaFormat, bstride, verts); + } else { + if (vformat & GA_NORMALS) { + + if (nxform_ptr == NULL) { + glNormalPointer(GL_FLOAT, bstride, &(verts[normoff])); + } + else { + glNormalPointer(GL_FLOAT, 3 * sizeof(float), tmpNormalArray); + } + } + if (ignoreVertexColors == JNI_FALSE && vformat & GA_COLOR) { + if (vformat & GA_WITH_ALPHA || (useAlpha == GL_TRUE)) { + glColorPointer(4, GL_FLOAT, bstride, &(verts[coloroff])); + } else { + glColorPointer(3, GL_FLOAT, bstride, &(verts[coloroff])); + } + } + if (vformat & GA_COORDINATES) { + + if (xform_ptr == NULL) { + glVertexPointer(3, GL_FLOAT, bstride, &(verts[coordoff])); + } + else { + glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), tmpCoordArray); + } + } + + if (vformat & GA_TEXTURE_COORDINATE) { + executeTexture(-1, texCoordSetMapLen, + texSize, bstride, texCoordoff, + texCoordSetMapOffset, + texCoordSetMapLen, NULL, + verts, ctxInfo); + } + } + lockArray(ctxProperties, vertexCount); + switch (geo_type){ + case GEO_TYPE_INDEXED_QUAD_SET : glDrawElements(GL_QUADS,validIndexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break; + case GEO_TYPE_INDEXED_TRI_SET : glDrawElements(GL_TRIANGLES, validIndexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break; + case GEO_TYPE_INDEXED_POINT_SET : glDrawElements(GL_POINTS, validIndexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break; + case GEO_TYPE_INDEXED_LINE_SET: glDrawElements(GL_LINES, validIndexCount, GL_UNSIGNED_INT, &indices[initialIndexIndex]);break; + } + } + + unlockArray(ctxProperties); + + if (tmpNormalArray != NULL) { + free(tmpNormalArray); + } + if (tmpCoordArray != NULL) { + free(tmpCoordArray); + } + + (*(table->ReleasePrimitiveArrayCritical))(env, varray, verts, 0); + + (*(table->ReleasePrimitiveArrayCritical))(env, indexCoord, indices, 0); + + + if (texCoordSetMapLen > 0) + (*(table->ReleasePrimitiveArrayCritical))(env, texUnitOffset, + texCoordSetMapOffset, 0); + + if (xform_ptr != NULL) + (*(table->ReleasePrimitiveArrayCritical))(env, xform, xform_ptr, 0); + + if (nxform_ptr != NULL) + (*(table->ReleasePrimitiveArrayCritical))(env, nxform, nxform_ptr, 0); +} + + +/* execute geometry array with java array format */ +JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_buildGAForByRef( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jobject geo, + jint geo_type, + jboolean isNonUniformScale, + jboolean updateAlpha, + jfloat alpha, + jboolean ignoreVertexColors, + jint vcount, + jint vformat, + jint vdefined, + jint initialCoordIndex, + jfloatArray vfcoords, + jdoubleArray vdcoords, + jint initialColorIndex, + jfloatArray cfdata, + jbyteArray cbdata, + jint initialNormalIndex, + jfloatArray ndata, + jint texCoordMapLength, + jintArray tcoordsetmap, + jintArray texindices, + jint texStride, + jobjectArray texCoords, + jdoubleArray xform, + jdoubleArray nxform) +{ + jclass geo_class; + JNIEnv table; + jboolean useAlpha = JNI_FALSE; + jfieldID strip_field; + jarray sarray; + jint i; + jsize strip_len; + jarray start_array; + jfieldID start_field; + jfloat *fverts = NULL; + jdouble *dverts = NULL; + jbyte *bclrs = NULL; + jfloat *fclrs = NULL, *norms = NULL; + jdouble *xform_ptr = NULL; + jdouble *nxform_ptr = NULL; + jfloat *tmpFloatCoordArray = NULL, *tmpNormalArray = NULL, *tmpFloatColors = NULL; + jdouble *tmpDoubleCoordArray = NULL; + jbyte* tmpByteColors= NULL; + jfloat* fvptr = NULL, *nptr = NULL, *fcptr = NULL; + jdouble* dvptr = NULL; + jbyte* bcptr = NULL; + jfloat* texCoordPointer[NUM_TEXTURE_UNITS]; + jarray texobjs[NUM_TEXTURE_UNITS]; + jint *tunitstatemap = NULL; + jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0); + jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0); + jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0); + jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0); + jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0); + jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0); + int offset = 0; + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + table = *env; + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + texobjs[i] = (*(table->GetObjectArrayElement))(env, texCoords, i); + } + } + + geo_class = (jclass) (*(table->GetObjectClass))(env, geo); + + /* + * process alpha for geometryArray without alpha + */ + if (updateAlpha == JNI_TRUE && ignoreVertexColors== JNI_FALSE) { + useAlpha = JNI_TRUE; + } + + /* + * call other JNI functions before entering Critical region + * i.e., GetPrimitiveArrayCritical + */ + if (geo_type == GEO_TYPE_TRI_STRIP_SET || + geo_type == GEO_TYPE_TRI_FAN_SET || + geo_type == GEO_TYPE_LINE_STRIP_SET) { + + strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class, + "stripVertexCounts", "[I"); + sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field); + strip_len = (jsize)(*(table->GetArrayLength))(env, sarray); + start_field = (jfieldID) (*(table->GetFieldID))(env, geo_class, + "stripStartOffsetIndices", "[I"); + start_array = (jarray)(*(table->GetObjectField))(env, geo, + start_field); + } + + if (ignoreVertexColors == JNI_TRUE) { + vformat &= ~GA_COLOR; + floatColorsDefined = JNI_FALSE; + byteColorsDefined = JNI_FALSE; + } + /* get texture arrays */ + if (textureDefined) { + tunitstatemap = (int *)malloc(texCoordMapLength * sizeof(int)); + for (i = 0; i < texCoordMapLength; i++) { + tunitstatemap[i] = i; + if (texobjs[i] != NULL) + texCoordPointer[i] = (jfloat*)(*(table->GetPrimitiveArrayCritical))(env,texobjs[i], NULL); + else + texCoordPointer[i] = NULL; + + } + } + + /* get coordinate array */ + if (floatCoordDefined) { + glEnableClientState(GL_VERTEX_ARRAY); + fverts= (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, vfcoords, NULL); + fvptr = fverts; + } else if (doubleCoordDefined) { + glEnableClientState(GL_VERTEX_ARRAY); + dverts= (jdouble *) (*(table->GetPrimitiveArrayCritical))(env, vdcoords, NULL); + dvptr = dverts; + } + else { + glDisableClientState(GL_VERTEX_ARRAY); + } + + + /* get color array */ + if (floatColorsDefined) { + glEnableClientState(GL_COLOR_ARRAY); + fclrs = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env, cfdata, NULL); + fcptr = fclrs; + } else if (byteColorsDefined) { + glEnableClientState(GL_COLOR_ARRAY); + bclrs = (jbyte *) (*(table->GetPrimitiveArrayCritical))(env, cbdata, NULL); + bcptr = bclrs; + } + else { + glDisableClientState(GL_COLOR_ARRAY); + } + /* get normal array */ + if (normalsDefined) { + glEnableClientState(GL_NORMAL_ARRAY); + norms = (jfloat *) (*(table->GetPrimitiveArrayCritical))(env,ndata, NULL); + nptr = norms; + } + else { + glDisableClientState(GL_NORMAL_ARRAY); + } + + /* get the static transform if exists */ + if (xform != NULL) { + xform_ptr = (jdouble *) (*(table->GetPrimitiveArrayCritical))( + env, xform, NULL); + + } + + + /* get the static normals transform if exists */ + if (nxform != NULL) { + nxform_ptr = (jdouble *) (*(table->GetPrimitiveArrayCritical))( + env, nxform, NULL); + } + + /* + * Check if normal is present and nxform_ptr id non-null, if yes, + * create a new normal array and apply the xform + */ + if (normalsDefined) { + if(nxform_ptr != NULL) { + /* create a temporary array for normals */ + tmpNormalArray = (jfloat*) malloc(vcount * sizeof(float) * 3); + for (i = initialNormalIndex; i < vcount*3; i+=3) { + tmpNormalArray[i] = (float) (nxform_ptr[0] * norms[i] + + nxform_ptr[1] * norms[i+1] + + nxform_ptr[2] * norms[i+2]); + tmpNormalArray[i+1] = (float) (nxform_ptr[4] * norms[i] + + nxform_ptr[5] * norms[i+1] + + nxform_ptr[6] * norms[i+2]); + tmpNormalArray[i+2] = (float) (nxform_ptr[8] * norms[i] + + nxform_ptr[9] * norms[i+1] + + nxform_ptr[10] * norms[i+2]); + } + nptr = tmpNormalArray; + } + + } + + if (xform_ptr != NULL) { + if (floatCoordDefined) { + /* create a temporary array for normals */ + tmpFloatCoordArray = (jfloat*) malloc(vcount * sizeof(float) * 3); + for (i = initialCoordIndex; i < vcount*3; i+=3) { + tmpFloatCoordArray[i] = (float) (xform_ptr[0] * fverts[i] + + xform_ptr[1] * fverts[i+1] + + xform_ptr[2] * fverts[i+2]); + tmpFloatCoordArray[i+1] = (float) (xform_ptr[4] * fverts[i] + + xform_ptr[5] * fverts[i+1] + + xform_ptr[6] * fverts[i+2]); + tmpFloatCoordArray[i+2] = (float) (xform_ptr[8] * fverts[i] + + xform_ptr[9] * fverts[i+1] + + xform_ptr[10] * fverts[i+2]); + } + fvptr = tmpFloatCoordArray; + } + else { + tmpDoubleCoordArray = (jdouble*) malloc(vcount * sizeof(double) * 3); + for (i = initialCoordIndex; i < vcount*3; i+=3) { + tmpDoubleCoordArray[i] = (double) (xform_ptr[0] * dverts[i] + + xform_ptr[1] * dverts[i+1] + + xform_ptr[2] * dverts[i+2]); + tmpDoubleCoordArray[i+1] = (double) (xform_ptr[4] * dverts[i] + + xform_ptr[5] * dverts[i+1] + + xform_ptr[6] * dverts[i+2]); + tmpDoubleCoordArray[i+2] = (double) (xform_ptr[8] * dverts[i] + + xform_ptr[9] * dverts[i+1] + + xform_ptr[10] * dverts[i+2]); + } + dvptr = tmpDoubleCoordArray; + } + + } + /* + fprintf(stderr, "floatColorsDefined = %d, useAlpha = %d\n", + floatColorsDefined,useAlpha); + */ + if (floatColorsDefined && useAlpha) { + tmpFloatColors = (jfloat*)malloc(vcount*sizeof(float) * 4); + if ((vformat & GA_WITH_ALPHA) != 0) { + /* fprintf(stderr, "with Alpha\n") */ + for (i = initialColorIndex; i < vcount*4; i+=4) { + tmpFloatColors[i] = fclrs[i]; + tmpFloatColors[i+1] = fclrs[i+1]; + tmpFloatColors[i+2] = fclrs[i+2]; + tmpFloatColors[i+3] = (float)(alpha* fclrs[i+3]); + } + } + else { + /* fprintf(stderr, "without Alpha\n") */ + int k = 0; + for (i = initialColorIndex; i < vcount*4; i+=4) { + tmpFloatColors[i] = fclrs[k++]; + tmpFloatColors[i+1] = fclrs[k++]; + tmpFloatColors[i+2] = fclrs[k++]; + tmpFloatColors[i+3] = (float)(alpha); + } + } + fcptr = tmpFloatColors; + vformat |= GA_WITH_ALPHA; + } + else if (byteColorsDefined && useAlpha) { + tmpByteColors = (jbyte*)malloc(vcount*sizeof(jbyte) * 4); + if ((vformat & GA_WITH_ALPHA) != 0) { + for (i = initialColorIndex; i < vcount*4; i+=4) { + tmpByteColors[i] = bclrs[i]; + tmpByteColors[i+1] = bclrs[i+1]; + tmpByteColors[i+2] =bclrs[i+2]; + tmpByteColors[i+3] = (jbyte) (alpha * ((int)bclrs[i+3] & 0xff)); + } + } + else { + int k = 0; + for (i = initialColorIndex; i < vcount*4; i+=4) { + tmpByteColors[i] = bclrs[k++]; + tmpByteColors[i+1] = bclrs[k++]; + tmpByteColors[i+2] =bclrs[k++]; + tmpByteColors[i+3] = (jbyte) (alpha * 255.0); + } + } + bcptr = tmpByteColors; + vformat |= GA_WITH_ALPHA; + + } + executeGeometryArrayVA(env, obj, ctxInfo, geo, geo_type, + isNonUniformScale, JNI_FALSE, ignoreVertexColors, + vcount, vformat, vdefined, initialCoordIndex, + fvptr, dvptr, initialColorIndex, + fcptr, bcptr, initialNormalIndex, + nptr, -1, texCoordMapLength, + tcoordsetmap, texCoordMapLength, tunitstatemap, + texindices,texStride,texCoordPointer,0, sarray, + strip_len, start_array); + if (textureDefined) { + if (tunitstatemap != NULL) { + free(tunitstatemap); + } + for (i = 0; i < texCoordMapLength; i++) { + if (texCoordPointer[i] != NULL) { + (*(table->ReleasePrimitiveArrayCritical))(env, texobjs[i], texCoordPointer[i], 0); + } + } + } + + if (normalsDefined) { + (*env)->ReleasePrimitiveArrayCritical(env, ndata, norms, 0); + if (tmpNormalArray != NULL) { + free(tmpNormalArray); + } + } + + + if (floatColorsDefined) { + (*env)->ReleasePrimitiveArrayCritical(env, cfdata, fclrs, 0); + if (tmpFloatColors != NULL) { + free(tmpFloatColors); + } + } + else if (byteColorsDefined) { + (*env)->ReleasePrimitiveArrayCritical(env, cbdata, bclrs, 0); + if (tmpByteColors != NULL) { + free(tmpByteColors); + } + } + + + if (floatCoordDefined) { + (*env)->ReleasePrimitiveArrayCritical(env, vfcoords, fverts, 0); + if (tmpFloatCoordArray != NULL) { + free(tmpFloatCoordArray); + } + } + else if (doubleCoordDefined) { + (*env)->ReleasePrimitiveArrayCritical(env, vdcoords, dverts, 0); + if (tmpDoubleCoordArray != NULL) { + free(tmpFloatCoordArray); + } + } +} + + +/* execute geometry array with java array format */ +JNIEXPORT +void JNICALL Java_javax_media_j3d_GeometryArrayRetained_buildGAForBuffer( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jobject geo, + jint geo_type, + jboolean isNonUniformScale, + jboolean updateAlpha, + jfloat alpha, + jboolean ignoreVertexColors, + jint vcount, + jint vformat, + jint vdefined, + jint initialCoordIndex, + jobject vcoords, + jint initialColorIndex, + jobject cdataBuffer, + jint initialNormalIndex, + jobject ndata, + jint texCoordMapLength, + jintArray tcoordsetmap, + jintArray texindices, + jint texStride, + jobjectArray texCoords, + jdoubleArray xform, + jdoubleArray nxform) +{ + jclass geo_class; + JNIEnv table; + jboolean useAlpha = JNI_FALSE; + jfieldID strip_field; + jarray sarray; + jint i; + jsize strip_len; + jarray start_array; + jfieldID start_field; + jfloat *fverts = NULL; + jdouble *dverts = NULL; + jbyte *bclrs = NULL; + jfloat *fclrs = NULL, *norms = NULL; + jdouble *xform_ptr = NULL; + jdouble *nxform_ptr = NULL; + jfloat *tmpFloatCoordArray = NULL, *tmpNormalArray = NULL, *tmpFloatColors = NULL; + jdouble *tmpDoubleCoordArray = NULL; + jbyte* tmpByteColors= NULL; + jfloat* fvptr = NULL, *nptr = NULL, *fcptr = NULL; + jdouble* dvptr = NULL; + jbyte* bcptr = NULL; + jfloat* texCoordPointer[NUM_TEXTURE_UNITS]; + jarray texobjs[NUM_TEXTURE_UNITS]; + jint *tunitstatemap = NULL; + jboolean floatCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_FLOAT) != 0); + jboolean doubleCoordDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE) != 0); + jboolean floatColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT) != 0); + jboolean byteColorsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_COLOR_BYTE) != 0); + jboolean normalsDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT) != 0); + jboolean textureDefined = ((vdefined & javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT) != 0); + int offset = 0; + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + table = *env; + if (textureDefined) { + for (i = 0; i < texCoordMapLength; i++) { + texobjs[i] = (*(table->GetObjectArrayElement))(env, texCoords, i); + } + } + + geo_class = (jclass) (*(table->GetObjectClass))(env, geo); + + + /* + * process alpha for geometryArray without alpha + */ + if (updateAlpha == JNI_TRUE && ignoreVertexColors== JNI_FALSE) { + useAlpha = JNI_TRUE; + } + + /* + * call other JNI functions before entering Critical region + * i.e., GetPrimitiveArrayCritical + */ + if (geo_type == GEO_TYPE_TRI_STRIP_SET || + geo_type == GEO_TYPE_TRI_FAN_SET || + geo_type == GEO_TYPE_LINE_STRIP_SET) { + + strip_field = (jfieldID) (*(table->GetFieldID))(env, geo_class, + "stripVertexCounts", "[I"); + sarray = (jarray)(*(table->GetObjectField))(env, geo, strip_field); + strip_len = (jsize)(*(table->GetArrayLength))(env, sarray); + start_field = (jfieldID) (*(table->GetFieldID))(env, geo_class, + "stripStartOffsetIndices", "[I"); + start_array = (jarray)(*(table->GetObjectField))(env, geo, + start_field); + } + + if (ignoreVertexColors == JNI_TRUE) { + vformat &= ~GA_COLOR; + floatColorsDefined = JNI_FALSE; + byteColorsDefined = JNI_FALSE; + } + /* get texture arrays */ + if (textureDefined) { + tunitstatemap = (int *)malloc( texCoordMapLength * sizeof(int)); + for (i = 0; i < texCoordMapLength; i++) { + tunitstatemap[i] = i; + if (texobjs[i] != NULL) + texCoordPointer[i] = (jfloat*)(*(table->GetPrimitiveArrayCritical))(env,texobjs[i], NULL); + else + texCoordPointer[i] = NULL; + + } + } + + /* get coordinate array */ + if (floatCoordDefined) { + glEnableClientState(GL_VERTEX_ARRAY); + fverts= (jfloat *)(*(table->GetDirectBufferAddress))(env, vcoords ); + fvptr = fverts; + } else if (doubleCoordDefined) { + glEnableClientState(GL_VERTEX_ARRAY); + dverts= (jdouble *)(*(table->GetDirectBufferAddress))(env, vcoords ); + dvptr = dverts; + } + else { + glDisableClientState(GL_VERTEX_ARRAY); + } + + if(fverts == NULL && dverts == NULL) { + return; + } + /* get color array */ + if (floatColorsDefined) { + glEnableClientState(GL_COLOR_ARRAY); + fclrs = (jfloat *)(*(table->GetDirectBufferAddress))(env, cdataBuffer); + fcptr = fclrs; + } else if (byteColorsDefined) { + glEnableClientState(GL_COLOR_ARRAY); + bclrs = (jbyte *)(*(table->GetDirectBufferAddress))(env, cdataBuffer); + bcptr = bclrs; + } + else { + glDisableClientState(GL_COLOR_ARRAY); + } + /* get normal array */ + if (normalsDefined) { + glEnableClientState(GL_NORMAL_ARRAY); + norms = (jfloat *)(*(table->GetDirectBufferAddress))(env, ndata); + nptr = norms; + } + else { + glDisableClientState(GL_NORMAL_ARRAY); + } + /* get the static transform if exists */ + if (xform != NULL) { + xform_ptr = (jdouble *) (*(table->GetPrimitiveArrayCritical))( + env, xform, NULL); + + } + + + /* get the static normals transform if exists */ + if (nxform != NULL) { + nxform_ptr = (jdouble *) (*(table->GetPrimitiveArrayCritical))( + env, nxform, NULL); + } + + + /* + * Check if normal is present and nxform_ptr id non-null, if yes, + * create a new normal array and apply the xform + */ + if (normalsDefined) { + if(nxform_ptr != NULL) { + /* create a temporary array for normals */ + tmpNormalArray = (jfloat*) malloc(vcount * sizeof(float) * 3); + for (i = initialNormalIndex; i < vcount*3; i+=3) { + tmpNormalArray[i] = (float) (nxform_ptr[0] * norms[i] + + nxform_ptr[1] * norms[i+1] + + nxform_ptr[2] * norms[i+2]); + tmpNormalArray[i+1] = (float) (nxform_ptr[4] * norms[i] + + nxform_ptr[5] * norms[i+1] + + nxform_ptr[6] * norms[i+2]); + tmpNormalArray[i+2] = (float) (nxform_ptr[8] * norms[i] + + nxform_ptr[9] * norms[i+1] + + nxform_ptr[10] * norms[i+2]); + } + nptr = tmpNormalArray; + } + + } + + if (xform_ptr != NULL) { + if (floatCoordDefined) { + /* create a temporary array for normals */ + tmpFloatCoordArray = (jfloat*) malloc(vcount * sizeof(float) * 3); + for (i = initialCoordIndex; i < vcount*3; i+=3) { + tmpFloatCoordArray[i] = (float) (xform_ptr[0] * fverts[i] + + xform_ptr[1] * fverts[i+1] + + xform_ptr[2] * fverts[i+2]); + tmpFloatCoordArray[i+1] = (float) (xform_ptr[4] * fverts[i] + + xform_ptr[5] * fverts[i+1] + + xform_ptr[6] * fverts[i+2]); + tmpFloatCoordArray[i+2] = (float) (xform_ptr[8] * fverts[i] + + xform_ptr[9] * fverts[i+1] + + xform_ptr[10] * fverts[i+2]); + } + fvptr = tmpFloatCoordArray; + } + else { + tmpDoubleCoordArray = (jdouble*) malloc(vcount * sizeof(double) * 3); + for (i = initialCoordIndex; i < vcount*3; i+=3) { + tmpDoubleCoordArray[i] = (double) (xform_ptr[0] * dverts[i] + + xform_ptr[1] * dverts[i+1] + + xform_ptr[2] * dverts[i+2]); + tmpDoubleCoordArray[i+1] = (double) (xform_ptr[4] * dverts[i] + + xform_ptr[5] * dverts[i+1] + + xform_ptr[6] * dverts[i+2]); + tmpDoubleCoordArray[i+2] = (double) (xform_ptr[8] * dverts[i] + + xform_ptr[9] * dverts[i+1] + + xform_ptr[10] * dverts[i+2]); + } + dvptr = tmpDoubleCoordArray; + } + + } + if (floatColorsDefined && useAlpha) { + tmpFloatColors = (jfloat*)malloc(vcount*sizeof(float) * 4); + if ((vformat & GA_WITH_ALPHA) != 0) { + for (i = initialColorIndex; i < vcount*4; i+=4) { + tmpFloatColors[i] = fclrs[i]; + tmpFloatColors[i+1] = fclrs[i+1]; + tmpFloatColors[i+2] = fclrs[i+2]; + tmpFloatColors[i+3] = (float)(alpha* fclrs[i+3]); + } + } + else { + int k = 0; + for (i = initialColorIndex; i < vcount*4; i+=4) { + tmpFloatColors[i] = fclrs[k++]; + tmpFloatColors[i+1] = fclrs[k++]; + tmpFloatColors[i+2] = fclrs[k++]; + tmpFloatColors[i+3] = (float)(alpha); + } + } + fcptr = tmpFloatColors; + vformat |= GA_WITH_ALPHA; + } + else if (byteColorsDefined && useAlpha) { + tmpByteColors = (jbyte*)malloc(vcount*sizeof(jbyte) * 4); + if ((vformat & GA_WITH_ALPHA) != 0) { + for (i = initialColorIndex; i < vcount*4; i+=4) { + tmpByteColors[i] = bclrs[i]; + tmpByteColors[i+1] = bclrs[i+1]; + tmpByteColors[i+2] =bclrs[i+2]; + tmpByteColors[i+3] = (jbyte) (alpha * ((int)bclrs[i+3] & 0xff)); + } + } + else { + int k = 0; + for (i = initialColorIndex; i < vcount*4; i+=4) { + tmpByteColors[i] = bclrs[k++]; + tmpByteColors[i+1] = bclrs[k++]; + tmpByteColors[i+2] =bclrs[k++]; + tmpByteColors[i+3] = (jbyte) (alpha * 255.0); + } + } + bcptr = tmpByteColors; + vformat |= GA_WITH_ALPHA; + + } + executeGeometryArrayVA(env, obj, ctxInfo, geo, geo_type, + isNonUniformScale, JNI_FALSE, ignoreVertexColors, + vcount, vformat, vdefined, initialCoordIndex, + fvptr, dvptr, initialColorIndex, + fcptr, bcptr, initialNormalIndex, + nptr, -1, texCoordMapLength, + tcoordsetmap, texCoordMapLength, tunitstatemap, + texindices,texStride,texCoordPointer,0, sarray, strip_len, start_array); + if (textureDefined) { + if (tunitstatemap != NULL) { + free(tunitstatemap); + } + for (i = 0; i < texCoordMapLength; i++) { + if (texCoordPointer[i] != NULL) { + (*(table->ReleasePrimitiveArrayCritical))(env, texobjs[i], texCoordPointer[i], 0); + } + } + } + + if (tmpNormalArray != NULL) { + free(tmpNormalArray); + } + + + if (tmpFloatColors != NULL) { + free(tmpFloatColors); + } + else if (tmpByteColors != NULL) { + free(tmpByteColors); + } + + + if (tmpFloatCoordArray != NULL) { + free(tmpFloatCoordArray); + } + else if (tmpDoubleCoordArray != NULL) { + free(tmpFloatCoordArray); + } +} + + diff --git a/src/native/ogl/GraphicsContext3D.c b/src/native/ogl/GraphicsContext3D.c new file mode 100644 index 0000000..9d800f8 --- /dev/null +++ b/src/native/ogl/GraphicsContext3D.c @@ -0,0 +1,171 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include +#include + +#include "gldefs.h" + +JNIEXPORT +void JNICALL Java_javax_media_j3d_GraphicsContext3D_readRasterNative( + JNIEnv *env, jobject obj, jlong ctxInfo, + jint type, jint xOffset, jint yOffset, + jint wRaster, jint hRaster, jint hCanvas, + jint format, jobject image, jobject depth, jobject ctx) +{ + JNIEnv table; + int yAdjusted; + jclass ctx_class; + GLenum gltype; + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong d3dctx = ctxProperties->context; + + table = *env; + + glPixelStorei(GL_PACK_ROW_LENGTH, wRaster); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + yAdjusted = hCanvas - hRaster - yOffset; + + ctx_class = (jclass) (*(table->GetObjectClass))(env, ctx); + + if ((type & javax_media_j3d_Raster_RASTER_COLOR) != 0) { + + jclass image_class; + + jfieldID byteData_field; + jarray byteData_array; + jbyte *byteData; + + byteData_field = (jfieldID)(*(table->GetFieldID))(env, + ctx_class, "byteBuffer","[B"); + byteData_array = (jarray)(*(table->GetObjectField))(env, ctx, + byteData_field); + + image_class = (jclass) (*(table->GetObjectClass))(env, image); + + if (image_class == NULL) { + return; + } + + switch (format) { + case FORMAT_BYTE_RGBA: + gltype = GL_RGBA; + break; + case FORMAT_BYTE_RGB: + gltype = GL_RGB; + break; + + case FORMAT_BYTE_ABGR: + if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */ + gltype = GL_ABGR_EXT; + } + break; + + case FORMAT_BYTE_BGR: + if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */ + gltype = ctxProperties->bgr_ext_enum; + } + break; + case FORMAT_BYTE_LA: + gltype = GL_LUMINANCE_ALPHA; + break; + case FORMAT_BYTE_GRAY: + case FORMAT_USHORT_GRAY: + /* TODO: throw exception */ + break; + } + byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env, + byteData_array, NULL); + glReadPixels(xOffset, yAdjusted, wRaster, hRaster, + gltype, GL_UNSIGNED_BYTE, byteData); + + /* + { + int i, j , *intData; + fprintf(stderr, "format = %d, wRaster = %d, hRaster = %d\n\n", format, wRaster, hRaster); + intData = (int*)byteData; + for (i = 0; i < wRaster; i++) { + for (j = 0; j < hRaster; j++, intData++) { + fprintf(stderr, " 0x%x", *intData); + } + fprintf(stderr, "\n"); + } + } + */ + (*(table->ReleasePrimitiveArrayCritical))(env, byteData_array, + byteData, 0); + } + + + if ((type & javax_media_j3d_Raster_RASTER_DEPTH) != 0) { + + jclass depth_class; + jfieldID wDepth_field, depth_type_field; + jint depth_type, wDepth; + + depth_class = (jclass) (*(table->GetObjectClass))(env, depth); + + if (depth_class == NULL) { + return; + } + + wDepth_field = (jfieldID) (*(table->GetFieldID))(env, depth_class, + "width", "I"); + wDepth = (jint)(*(table->GetIntField))(env, depth, wDepth_field); + + depth_type_field = (jfieldID) (*(table->GetFieldID))(env, + depth_class, "type", "I"); + depth_type = (jint)(*(table->GetIntField))(env, depth, + depth_type_field); + + if (depth_type == javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_INT) { + jfieldID intData_field; + jarray intData_array; + jint *intData; + + intData_field = (jfieldID)(*(table->GetFieldID))(env, + ctx_class, "intBuffer","[I"); + intData_array = (jarray)(*(table->GetObjectField))(env, ctx, + intData_field); + + intData = (jint *)(*(table->GetPrimitiveArrayCritical))(env, + intData_array, NULL); + + /* yOffset is adjusted for OpenGL - Y upward */ + glReadPixels(xOffset, yAdjusted, wRaster, hRaster, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, intData); + + (*(table->ReleasePrimitiveArrayCritical))(env, intData_array, + intData, 0); + } else { /* javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_FLOAT */ + jfieldID floatData_field; + jarray floatData_array; + jfloat *floatData; + + floatData_field = (jfieldID)(*(table->GetFieldID))(env, + ctx_class, "floatBuffer","[F"); + floatData_array = (jarray)(*(table->GetObjectField))(env, ctx, + floatData_field); + floatData = (jfloat *)(*(table->GetPrimitiveArrayCritical))(env, + floatData_array, NULL); + + /* yOffset is adjusted for OpenGL - Y upward */ + glReadPixels(xOffset, yAdjusted, wRaster, hRaster, + GL_DEPTH_COMPONENT, GL_FLOAT, floatData); + + (*(table->ReleasePrimitiveArrayCritical))(env, floatData_array, + floatData, 0); + } + } +} + diff --git a/src/native/ogl/Lights.c b/src/native/ogl/Lights.c new file mode 100644 index 0000000..89ab98e --- /dev/null +++ b/src/native/ogl/Lights.c @@ -0,0 +1,168 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include +#include +#include +#include +#include + +#include "gldefs.h" + +#ifdef DEBUG +/* Uncomment the following for VERBOSE debug messages */ +/* #define VERBOSE */ +#endif /* DEBUG */ + + +const float black[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + +JNIEXPORT +void JNICALL Java_javax_media_j3d_DirectionalLightRetained_updateLight( + JNIEnv *env, + jobject light, + jlong ctxInfo, + jint lightSlot, + jfloat red, + jfloat green, + jfloat blue, + jfloat dirx, + jfloat diry, + jfloat dirz) +{ + int lightNum; + float values[4]; + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + +#ifdef VERBOSE + fprintf(stderr, + "Directional Light %d: %f %f %f direction, %f %f %f color\n", + lightSlot, dirx, diry, dirz, red, green, blue); +#endif + lightNum = GL_LIGHT0 + lightSlot; + values[0] = red; + values[1] = green; + values[2] = blue; + values[3] = 1.0f; + glLightfv(lightNum, GL_DIFFUSE, values); + glLightfv(lightNum, GL_SPECULAR, values); + values[0] = -dirx; + values[1] = -diry; + values[2] = -dirz; + values[3] = 0.0f; + glLightfv(lightNum, GL_POSITION, values); + glLightfv(lightNum, GL_AMBIENT, black); + glLightf(lightNum, GL_CONSTANT_ATTENUATION, 1.0f); + glLightf(lightNum, GL_LINEAR_ATTENUATION, 0.0f); + glLightf(lightNum, GL_QUADRATIC_ATTENUATION, 0.0f); + glLightf(lightNum, GL_SPOT_EXPONENT, 0.0f); + glLightf(lightNum, GL_SPOT_CUTOFF, 180.0f); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_PointLightRetained_updateLight( + JNIEnv *env, + jobject light, + jlong ctxInfo, + jint lightSlot, + jfloat red, + jfloat green, + jfloat blue, + jfloat attenx, + jfloat atteny, + jfloat attenz, + jfloat posx, + jfloat posy, + jfloat posz) +{ + int lightNum; + float values[4]; + +#ifdef VERBOSE + fprintf(stderr, "Positional Light %d: %f %f %f position, %f %f %f color\n\t %f %f %f attenuation\n", + lightSlot, posx, posy, posz, red, green, blue, + attenx, atteny, attenz); +#endif + + lightNum = GL_LIGHT0 + lightSlot; + values[0] = red; + values[1] = green; + values[2] = blue; + values[3] = 1.0f; + glLightfv(lightNum, GL_DIFFUSE, values); + glLightfv(lightNum, GL_SPECULAR, values); + glLightfv(lightNum, GL_AMBIENT, black); + values[0] = posx; + values[1] = posy; + values[2] = posz; + glLightfv(lightNum, GL_POSITION, values); + glLightf(lightNum, GL_CONSTANT_ATTENUATION, attenx); + glLightf(lightNum, GL_LINEAR_ATTENUATION, atteny); + glLightf(lightNum, GL_QUADRATIC_ATTENUATION, attenz); + glLightf(lightNum, GL_SPOT_EXPONENT, 0.0f); + glLightf(lightNum, GL_SPOT_CUTOFF, 180.0f); +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_SpotLightRetained_updateLight( + JNIEnv *env, + jobject light, + jlong ctxInfo, + jint lightSlot, + jfloat red, + jfloat green, + jfloat blue, + jfloat attenx, + jfloat atteny, + jfloat attenz, + jfloat posx, + jfloat posy, + jfloat posz, + jfloat spreadAngle, + jfloat concentration, + jfloat dirx, + jfloat diry, + jfloat dirz) +{ + int lightNum; + float values[4]; + +#ifdef VERBOSE + fprintf(stderr, "Spot Light %d: %f %f %f position, %f %f %f color\n\t %f %f %f attenuation\n\t %f %f %f direction, %f spreadAngle, %f concentration\n", + lightSlot, posx, posy, posz, red, green, blue, + attenx, atteny, attenz, dirx, diry, dirz, + spreadAngle*180.0 / M_PI, concentration); +#endif + lightNum = GL_LIGHT0 + lightSlot; + values[0] = red; + values[1] = green; + values[2] = blue; + values[3] = 1.0f; + glLightfv(lightNum, GL_DIFFUSE, values); + glLightfv(lightNum, GL_SPECULAR, values); + glLightfv(lightNum, GL_AMBIENT, black); + values[0] = posx; + values[1] = posy; + values[2] = posz; + glLightfv(lightNum, GL_POSITION, values); + glLightf(lightNum, GL_CONSTANT_ATTENUATION, attenx); + glLightf(lightNum, GL_LINEAR_ATTENUATION, atteny); + glLightf(lightNum, GL_QUADRATIC_ATTENUATION, attenz); + values[0] = dirx; + values[1] = diry; + values[2] = dirz; + glLightfv(lightNum, GL_SPOT_DIRECTION, values); + glLightf(lightNum, GL_SPOT_EXPONENT, concentration); + glLightf(lightNum, GL_SPOT_CUTOFF, (float) (spreadAngle * 180.0f / M_PI)); +} + diff --git a/src/native/ogl/MasterControl.c b/src/native/ogl/MasterControl.c new file mode 100644 index 0000000..3f8dcc5 --- /dev/null +++ b/src/native/ogl/MasterControl.c @@ -0,0 +1,261 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + * Portions of this code were derived from work done by the Blackdown + * group (www.blackdown.org), who did the initial Linux implementation + * of the Java 3D API. + */ + +#ifdef DEBUG +#define DPRINT(args) fprintf args +#else +#define DPRINT(args) +#endif /* DEBUG */ + +#include +#include +#include +#include "gldefs.h" + +#ifdef WIN32 +#include +#include +#endif /* WIN32 */ + +#if defined(SOLARIS) || defined(__linux__) +#include +#ifdef SOLARIS +#include +#else +#include +#endif +#include +#include +#include +#include + +#pragma weak glXInitThreadsSUN +#pragma weak glXDisableXineramaSUN +#pragma weak XPanoramiXQueryExtension + +#ifdef SOLARIS +extern int glXInitThreadsSUN(); +extern int glXDisableXineramaSUN(Display *dpy); + + +/* + * The following is currently an unsupported, undocumented function to query + * whether the X server is running with Xinerama support. This is an interim + * solution until it is made part of the X Window System standard or replaced + * with a fully supported API. It is currently available in the libXext + * shipped with Solaris 9 and patched versions of Solaris 7 and 8. dlsym() is + * used to check for its existence. + */ +extern Bool XPanoramiXQueryExtension(Display *dpy, + int *event_base, int *error_base); +#endif /* SOLARIS */ +#endif /* SOLARIS || __linux__ */ + +/* defined in Canvas3D.c */ +extern int isExtensionSupported(const char *allExtensions, + const char *extension); + +JNIEXPORT jboolean JNICALL +Java_javax_media_j3d_MasterControl_initializeJ3D( + JNIEnv *env, jobject obj, jboolean disableXinerama) +{ + jboolean glIsMTSafe = JNI_FALSE; + +#ifdef WIN32 + glIsMTSafe = JNI_TRUE; + return glIsMTSafe; +#endif /* WIN32 */ + +#ifdef __linux__ + glIsMTSafe = JNI_TRUE; + return glIsMTSafe; +#endif /* __linux__ */ + +#ifdef SOLARIS + Display* dpy; + int event_base, error_base; + const char *glxExtStr = NULL; + + dpy = XOpenDisplay(NULL); + glxExtStr = glXGetClientString((Display*)dpy, GLX_EXTENSIONS); + +#ifdef GLX_SUN_init_threads + if(isExtensionSupported(glxExtStr, "GLX_SUN_init_threads")) { + if (glXInitThreadsSUN()) { + glIsMTSafe = JNI_TRUE; + } + else { + DPRINT((stderr, "Failed initializing OpenGL for MT rendering.\n")); + DPRINT((stderr, "glXInitThreadsSUN returned false.\n")); + } + } + else { + DPRINT((stderr, "Failed to initialize OpenGL for MT rendering.\n")); + DPRINT((stderr, "GLX_SUN_init_threads not available.\n")); + } +#endif /* GLX_SUN_init_threads */ + + if (disableXinerama) { + DPRINT((stderr, "Property j3d.disableXinerama true ")); + + if ((! dlsym(RTLD_DEFAULT, "XPanoramiXQueryExtension")) || + (! dlsym(RTLD_DEFAULT, "XDgaGetXineramaInfo"))) { + + DPRINT((stderr, "but required API not available.\n")); + return glIsMTSafe; + } + + if (XPanoramiXQueryExtension(dpy, &event_base, &error_base)) { + DPRINT((stderr, "and Xinerama is in use.\n")); +#ifdef GLX_SUN_disable_xinerama + if(isExtensionSupported(glxExtStr, "GLX_SUN_disable_xinerama")) { + + if (glXDisableXineramaSUN((Display *)dpy)) { + jclass cls = (*env)->GetObjectClass(env, obj); + jfieldID disabledField = + (*env)->GetFieldID(env, cls, "xineramaDisabled", "Z"); + + (*env)->SetBooleanField(env, obj, disabledField, JNI_TRUE); + DPRINT((stderr, "Successfully disabled Xinerama.\n")); + } + else { + DPRINT((stderr, "Failed to disable Xinerama: ")); + DPRINT((stderr, "glXDisableXineramaSUN returns false.\n")); + } + } else { + DPRINT((stderr, "Failed to disable Xinerama: ")); + DPRINT((stderr, "GLX_SUN_disable_xinerama not available.\n")); + } +#endif /* GLX_SUN_disable_xinerama */ + } else { + DPRINT((stderr, "but Xinerama is not in use.\n")); + } + } +#endif /* SOLARIS */ + + return glIsMTSafe; +} + + +#ifdef WIN32 +DWORD countBits(DWORD mask) +{ + DWORD count = 0; + int i; + + for (i=sizeof(DWORD)*8-1; i >=0 ; i--) { + if ((mask & 0x01) > 0) { + count++; + } + mask >>= 1; + } + return count; +} + +#endif /* WIN32 */ + +/* + * Class: javax_media_j3d_MasterControl + * Method: getNumberOfProcessor + * Signature: ()I + * + * This function get the number of active processor in the system + */ +JNIEXPORT jint JNICALL Java_javax_media_j3d_MasterControl_getNumberOfProcessor + (JNIEnv *env, jobject obj) +{ +#if defined(SOLARIS) || defined(__linux__) + return sysconf(_SC_NPROCESSORS_ONLN); +#endif /* SOLARIS || __linux__ */ + +#ifdef WIN32 + SYSTEM_INFO sysInfo; + + GetSystemInfo(&sysInfo); + return countBits(sysInfo.dwActiveProcessorMask); +#endif /* WIN32 */ +} + + +/* + * Class: javax_media_j3d_MasterControl + * Method: getThreadConcurrency + * Signature: ()I + */ +JNIEXPORT jint JNICALL +Java_javax_media_j3d_MasterControl_getThreadConcurrency(JNIEnv *env, + jobject obj) +{ + /* + * Return the number of concurrent threads that can be run, + * -1 if unknown. + */ + +#ifdef SOLARIS + return (jint) thr_getconcurrency(); +#endif /* SOLARIS */ + +#ifdef WIN32 + return -1; +#endif /* WIN32 */ +} + + +/* + * Class: javax_media_j3d_MasterControl + * Method: setThreadConcurrency + * Signature: (I)V + */ +JNIEXPORT void JNICALL +Java_javax_media_j3d_MasterControl_setThreadConcurrency(JNIEnv *env, + jobject obj, + jint newLevel) +{ +#ifdef SOLARIS + thr_setconcurrency((int)newLevel); +#endif /* SOLARIS */ + +#ifdef WIN32 + /* No-op on windows */ +#endif /* WIN32 */ + +#ifdef __linux__ + /* No-op on linux */ +#endif /* __linux__ */ +} + + + +JNIEXPORT +jint JNICALL Java_javax_media_j3d_MasterControl_getMaximumLights( + JNIEnv *env, + jobject obj + ) { + +#ifdef SOLARIS + return 32; +#endif /* SOLARIS */ + +#ifdef WIN32 + return 8; +#endif /* WIN32 */ + +#ifdef __linux__ + return 8; +#endif /* __linux__ */ +} diff --git a/src/native/ogl/NativeAPIInfo.c b/src/native/ogl/NativeAPIInfo.c new file mode 100644 index 0000000..8cd0841 --- /dev/null +++ b/src/native/ogl/NativeAPIInfo.c @@ -0,0 +1,38 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + * Portions of this code were derived from work done by the Blackdown + * group (www.blackdown.org), who did the initial Linux implementation + * of the Java 3D API. + */ + +#include + +#include "javax_media_j3d_MasterControl.h" + +JNIEXPORT +jint JNICALL Java_javax_media_j3d_NativeAPIInfo_getRenderingAPI( + JNIEnv *env, jobject obj) +{ +#ifdef WIN32 + return (jint)javax_media_j3d_MasterControl_RENDER_OPENGL_WIN32; +#endif /* WIN32 */ + +#ifdef SOLARIS + return (jint)javax_media_j3d_MasterControl_RENDER_OPENGL_SOLARIS; +#endif /* SOLARIS */ + +#ifdef __linux__ + return (jint)javax_media_j3d_MasterControl_RENDER_OPENGL_LINUX; +#endif /* __linux__ */ +} diff --git a/src/native/ogl/NativeConfigTemplate3D.c b/src/native/ogl/NativeConfigTemplate3D.c new file mode 100644 index 0000000..66a5324 --- /dev/null +++ b/src/native/ogl/NativeConfigTemplate3D.c @@ -0,0 +1,1277 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + * Portions of this code were derived from work done by the Blackdown + * group (www.blackdown.org), who did the initial Linux implementation + * of the Java 3D API. + */ + +#include +#include +#include + +#include "gldefs.h" + +#if defined(SOLARIS) || defined(__linux__) +#include +#include +#include +#endif + +#ifdef WIN32 +#include +#endif + +/* check if the extension is supported */ +extern int isExtensionSupported(const char *allExtensions, const char *extension); + +#if defined(SOLARIS) || defined(__linux__) + +XVisualInfo *findVisualInfoSwitchDoubleBufferAndStereo(jlong display, + jint screen, + int* glxAttrs, + int sVal, int sIndex, + int dbVal, int dbIndex ) { + int stereoLoop; + int doubleBufferLoop; + XVisualInfo *vis_info = NULL; + + int i, j; + /* + * set all "enums" to user's preferred state + */ + if (dbVal == REQUIRED || dbVal == PREFERRED) + glxAttrs[dbIndex] = GLX_DOUBLEBUFFER; + else + glxAttrs[dbIndex] = GLX_USE_GL; + + if (sVal == REQUIRED || sVal == PREFERRED) + glxAttrs[sIndex] = GLX_STEREO; + else + glxAttrs[sIndex] = GLX_USE_GL; + + vis_info = glXChooseVisual((Display*)display, screen, glxAttrs); + if (vis_info == NULL) { + /* + * coudn't match visual with default values - try + * enabling UNNECESSARY attributes. + */ + if(sVal == UNNECESSARY) + stereoLoop = 1; + else + stereoLoop = 0; + + if(dbVal == UNNECESSARY) + doubleBufferLoop = 1; + else + doubleBufferLoop = 0; + + i = 0; + while(i <= stereoLoop && vis_info == NULL ) { + if (sVal == UNNECESSARY) + glxAttrs[sIndex] = i? GLX_STEREO : GLX_USE_GL; + j = 0; + while(j <= doubleBufferLoop && vis_info == NULL) { + if(dbVal == UNNECESSARY) { + glxAttrs[dbIndex] = j? GLX_USE_GL: GLX_DOUBLEBUFFER; + } + vis_info = glXChooseVisual((Display*)display, screen, glxAttrs); + j++; + } /* end of doubleBufferLoop */ + i++; + } /* end of stereoLoop */ + } + + if (vis_info == NULL) { + /* + * still coudn't match visual with default values - try + * disabling PREFERRED attributes. + */ + /* restore default values */ + if (sVal == REQUIRED || sVal == PREFERRED) + glxAttrs[sIndex] = GLX_STEREO; + else + glxAttrs[sIndex] = GLX_USE_GL; + + if (dbVal == REQUIRED || dbVal == PREFERRED) + glxAttrs[dbIndex] = GLX_DOUBLEBUFFER; + else + glxAttrs[dbIndex] = GLX_USE_GL; + + if(sVal == PREFERRED) + stereoLoop = 1; + else + stereoLoop = 0; + + if(dbVal == PREFERRED) + doubleBufferLoop = 1; + else + doubleBufferLoop = 0; + + i = 0; + while(i <= stereoLoop && vis_info == NULL ) { + if (sVal == PREFERRED) + glxAttrs[sIndex] = i? GLX_USE_GL : GLX_STEREO ; + j = 0; + while(j <= doubleBufferLoop && vis_info == NULL) { + if(dbVal == PREFERRED) { + glxAttrs[dbIndex] = j? GLX_DOUBLEBUFFER : GLX_USE_GL; + } + vis_info = glXChooseVisual((Display*)display, screen, glxAttrs); + j++; + } /* end of doubleBufferLoop */ + i++; + } /* end of stereoLoop */ + } + + if (vis_info == NULL) { + + /* + * STILL coudn't match visual with default values - try + * disabling PREFERRED attributes and enabling UNNECESSARY. + */ + + /* restore default values */ + if (sVal == REQUIRED || sVal == PREFERRED) + glxAttrs[sIndex] = GLX_STEREO; + else + glxAttrs[sIndex] = GLX_USE_GL; + + if (dbVal == REQUIRED || dbVal == PREFERRED) + glxAttrs[dbIndex] = GLX_DOUBLEBUFFER; + else + glxAttrs[dbIndex] = GLX_USE_GL; + + if(sVal != REQUIRED) + stereoLoop = 1; + else + stereoLoop = 0; + + if(dbVal != REQUIRED) + doubleBufferLoop = 1; + else + doubleBufferLoop = 0; + + i = 0; + while(i <= stereoLoop && vis_info == NULL ) { + if (sVal == PREFERRED || sVal == UNNECESSARY) + glxAttrs[sIndex] = i? GLX_USE_GL : GLX_STEREO ; + j = 0; + while(j <= doubleBufferLoop && vis_info == NULL) { + if(dbVal == PREFERRED || dbVal == UNNECESSARY) { + glxAttrs[dbIndex] = j? GLX_DOUBLEBUFFER : GLX_USE_GL; + } + vis_info = glXChooseVisual((Display*)display, screen, glxAttrs); + j++; + } /* end of doubleBufferLoop */ + i++; + } /* end of stereoLoop */ + } + return vis_info; +} + +/* + * Uses the past in array to choose the best OpenGL visual. + * When the "best" visual cannot be used, the "enums" (three + * state attributes) are looped through setting/resetting in all + * combinations in hopes of finding an valid visual. + */ +JNIEXPORT +jint JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_chooseOglVisual( + JNIEnv *env, + jobject obj, + jlong display, + jint screen, + jintArray attrList, + jlongArray vInfArray) +{ + VisualID vis_id = 0; + jint *mx_ptr; + int glxAttrs[256]; /* value, attr pair plus a None */ + int index; + XVisualInfo *vis_info = NULL; + + /* use to cycle through when attr is not REQUIRED */ + int sVal; + int sIndex; + + int dbVal; + int dbIndex; + + int antialiasVal; + int antialiasIndex; + + const char *glxExtensions = NULL; + jlong *visInfo = (*env)->GetLongArrayElements(env, vInfArray, NULL); + + mx_ptr = (jint *)(*env)->GetPrimitiveArrayCritical(env, attrList, NULL); + + /* + * convert Java 3D values to GLX + */ + index = 0; + glxAttrs[index++] = GLX_RGBA; /* only interested in RGB visuals */ + glxAttrs[index++] = GLX_RED_SIZE; + glxAttrs[index++] = mx_ptr[RED_SIZE]; + glxAttrs[index++] = GLX_GREEN_SIZE; + glxAttrs[index++] = mx_ptr[GREEN_SIZE]; + glxAttrs[index++] = GLX_BLUE_SIZE; + glxAttrs[index++] = mx_ptr[BLUE_SIZE]; + glxAttrs[index++] = GLX_DEPTH_SIZE; + glxAttrs[index++] = mx_ptr[DEPTH_SIZE]; + + + dbIndex = index++; + dbVal = mx_ptr[DOUBLEBUFFER]; + + sIndex = index++; + sVal = mx_ptr[STEREO]; + + antialiasIndex = index++; + antialiasVal = mx_ptr[ANTIALIASING]; + + /* glxAttrs[index] = None; */ + + (*env)->ReleasePrimitiveArrayCritical(env, attrList, mx_ptr, 0); + + + if(antialiasVal == REQUIRED || antialiasVal== PREFERRED) { + /* try GLX_ARB_multisample */ + glxExtensions = (const char *)glXGetClientString((Display*)display, GLX_EXTENSIONS); + + + if(isExtensionSupported(glxExtensions, "GLX_ARB_multisample")){ + /* path 1: */ + /* Query the visual with mulitsamples */ + + index = antialiasIndex; + glxAttrs[index++] = GLX_SAMPLE_BUFFERS_ARB; + glxAttrs[index++] = 1; + glxAttrs[index++] = GLX_SAMPLES_ARB; + glxAttrs[index++] = 1; + glxAttrs[index++] = None; + vis_info = findVisualInfoSwitchDoubleBufferAndStereo(display, screen, glxAttrs, sVal, sIndex, + dbVal, dbIndex); + + if(vis_info != NULL) { + vis_id = XVisualIDFromVisual(vis_info->visual); + visInfo[0] = (jlong)vis_info; + (*env)->ReleaseLongArrayElements(env, vInfArray, visInfo, 0); + return vis_id; + } + } + } + + /* normal path */ + if ( antialiasVal == REQUIRED || antialiasVal == PREFERRED) { + /* step 1 : enable antialiasing */ + index = antialiasIndex; + glxAttrs[index++] = GLX_ACCUM_RED_SIZE; + glxAttrs[index++] = 8; + glxAttrs[index++] = GLX_ACCUM_GREEN_SIZE; + glxAttrs[index++] = 8; + glxAttrs[index++] = GLX_ACCUM_BLUE_SIZE; + glxAttrs[index++] = 8; + glxAttrs[index++] = None; + vis_info = findVisualInfoSwitchDoubleBufferAndStereo(display, screen, glxAttrs, sVal, sIndex, + dbVal, dbIndex); + + if( vis_info == NULL) { + /* try disable antialiasing if it is PREFERRED */ + if(antialiasVal == PREFERRED) { + glxAttrs[antialiasIndex] = None; + vis_info = findVisualInfoSwitchDoubleBufferAndStereo(display, screen, glxAttrs, sVal, sIndex, + dbVal, dbIndex); + } + } + + visInfo[0] = (jlong)vis_info; + (*env)->ReleaseLongArrayElements(env, vInfArray, visInfo, 0); + + if( vis_info != NULL) { + vis_id = XVisualIDFromVisual(vis_info->visual); + return vis_id; + } else { + return 0; + } + } + + + glxAttrs[antialiasIndex] = None; + vis_info = findVisualInfoSwitchDoubleBufferAndStereo(display, screen, glxAttrs, sVal, sIndex, + dbVal, dbIndex); + + visInfo[0] = (jlong)vis_info; + (*env)->ReleaseLongArrayElements(env, vInfArray, visInfo, 0); + + if( vis_info != NULL) { + vis_id = XVisualIDFromVisual(vis_info->visual); + return vis_id; + } else { + return 0; + } +} + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_freeVisual( + JNIEnv *env, + jclass class, /* this is a static native method */ + jlong visInfo) +{ + XFree((XVisualInfo *)visInfo); +} + + +JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isStereoAvailable( + JNIEnv *env, + jobject obj, + jlong display, + jint screen, + jint vid) +{ + Display *dpy = (Display*) display; + XVisualInfo *vinfo, template; + int nitems; + int stereoFlag; + static GLboolean first_time = GL_TRUE; + static GLboolean force_no_stereo = GL_FALSE; + + if (first_time) { + if (getenv("J3D_NO_STEREO") != NULL) { + fprintf(stderr, "Java 3D: stereo mode disabled\n"); + force_no_stereo = GL_TRUE; + } + first_time = GL_FALSE; + } + + if (force_no_stereo) + return JNI_FALSE; + + template.visualid = vid; + vinfo = XGetVisualInfo(dpy, VisualIDMask, &template, &nitems); + if (nitems != 1) { + fprintf(stderr, "Warning Canvas3D_isStereoAvailable got unexpected number of matching visuals %d\n", nitems); + } + + glXGetConfig(dpy, vinfo, GLX_STEREO, &stereoFlag); + + return (stereoFlag ? JNI_TRUE : JNI_FALSE); +} + +JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isDoubleBufferAvailable( + JNIEnv *env, + jobject obj, + jlong display, + jint screen, + jint vid) +{ + Display *dpy = (Display*) display; + XVisualInfo *vinfo, template; + int nitems; + int doubleBufferFlag; + + template.visualid = vid; + vinfo = XGetVisualInfo(dpy, VisualIDMask, &template, &nitems); + if (nitems != 1) { + fprintf(stderr, "Warning Canvas3D_isDoubleBufferAvailable got unexpected number of matching visuals %d\n", nitems); + } + + glXGetConfig(dpy, vinfo, GLX_DOUBLEBUFFER, &doubleBufferFlag); + + return (doubleBufferFlag ? JNI_TRUE : JNI_FALSE); +} + +JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isSceneAntialiasingAccumAvailable( + JNIEnv *env, + jobject obj, + jlong display, + jint screen, + jint vid) +{ + Display *dpy = (Display*) display; + XVisualInfo *vinfo, template; + int nitems; + int numAccumRedBits; + + template.visualid = vid; + vinfo = XGetVisualInfo(dpy, VisualIDMask, &template, &nitems); + if (nitems != 1) { + fprintf(stderr, "Warning Canvas3D_isSceneAntialiasingAvailable got unexpected number of matching visuals %d\n", nitems); + } + + glXGetConfig(dpy, vinfo, GLX_ACCUM_RED_SIZE, &numAccumRedBits); + + return (numAccumRedBits > 0 ? JNI_TRUE : JNI_FALSE); +} + +JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isSceneAntialiasingMultiSamplesAvailable( + JNIEnv *env, + jobject obj, + jlong display, + jint screen, + jint vid) +{ + Display *dpy = (Display*) display; + XVisualInfo *vinfo, template; + int nitems; + + const char *glxExtensions; + int numSampleBuffers; + int numSamples; + + template.visualid = vid; + vinfo = XGetVisualInfo(dpy, VisualIDMask, &template, &nitems); + if (nitems != 1) { + fprintf(stderr, "Warning Canvas3D_isSceneAntialiasingAvailable got unexpected number of matching visuals %d\n", nitems); + } + /* try GLX_ARB_multisample */ + glxExtensions = (const char *)glXGetClientString((Display*)display, GLX_EXTENSIONS); + + if(isExtensionSupported(glxExtensions, "GLX_ARB_multisample")){ + glXGetConfig(dpy, vinfo, GLX_SAMPLE_BUFFERS_ARB, &numSampleBuffers); + glXGetConfig(dpy, vinfo, GLX_SAMPLES_ARB, &numSamples); + if(numSampleBuffers > 0 && numSamples > 1){ + return JNI_TRUE; + } + } + + return JNI_FALSE; +} + + +JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_J3dGraphicsConfig_isValidVisualID( + JNIEnv *env, + jclass cls, + jlong display, + jint vid) +{ + XVisualInfo template; + int nitems; + + template.visualid = vid; + XGetVisualInfo((Display *)display, VisualIDMask, &template, &nitems); + return (nitems == 1); + +} +#endif /* SOLARIS || __linux__ */ + + +#ifdef WIN32 + +extern HWND createDummyWindow(const char* szAppName); + +/* +void printPixelDescriptor(PIXELFORMATDESCRIPTOR *pfd) +{ + + printf("color : r=%d, g=%d, b=%d, a=%d, shift r=%d, g=%d, b=%d, a=%d\n", + pfd->cRedBits, pfd->cGreenBits, pfd->cBlueBits, pfd->cAlphaBits, + pfd->cRedShift, pfd->cGreenShift, pfd->cBlueShift, pfd->cAlphaShift); + printf("Accum r=%d, g=%d, b=%d, a=%d, depth %d, stencil %d, AuxBuffers %d\n", + pfd->cAccumRedBits, pfd->cAccumGreenBits, pfd->cAccumBlueBits, + pfd->cAccumAlphaBits, pfd->cDepthBits, pfd->cStencilBits, pfd->cAuxBuffers); + printf("iLayerType %x, bReserved %x, dwLayerMask %x, dwVisibleMask %x, dwDamageMask %x\n", + pfd->iLayerType, pfd->bReserved, pfd->dwLayerMask, pfd->dwVisibleMask, pfd->dwDamageMask); + if (pfd->dwFlags & PFD_SUPPORT_OPENGL) { + printf("SUPPORT_OPENGL "); + } + if (pfd->dwFlags & PFD_DRAW_TO_WINDOW) { + printf("DRAW_TO_WINDOW "); + } + if (pfd->dwFlags & PFD_DRAW_TO_BITMAP) { + printf("DRAW_TO_BITMAP "); + } + if (pfd->dwFlags & PFD_SUPPORT_GDI) { + printf("SUPPORT_GDI "); + } + if (pfd->dwFlags & PFD_SUPPORT_GDI) { + printf("NEED_PALETTE "); + } + if (pfd->dwFlags & PFD_SUPPORT_GDI) { + printf("NEED_SYSTEM_PALETTE "); + } + if (pfd->dwFlags & PFD_STEREO) { + printf("STEREO "); + } + if (pfd->dwFlags & PFD_SUPPORT_GDI) { + printf("SWAP_LAYER_BUFFERS "); + } + if (pfd->dwFlags & PFD_GENERIC_FORMAT) { + printf("PFD_GENERIC_FORMAT "); + } + if (pfd->dwFlags & PFD_GENERIC_ACCELERATED) { + printf("PFD_GENERIC_FORMAT "); + } + if (pfd->dwFlags & PFD_DOUBLEBUFFER) { + printf("PFD_DOUBLEBUFFER "); + } + printf("\n"); + +} + +*/ + +BOOL isSupportedWGL(const char * extensions, const char *extension_string) { + /* get the list of supported extensions */ + const char *p = extensions; + + /* search for extension_string in the list */ + while(p = strstr(p, extension_string)){ + const char *q = p + strlen(extension_string); + + /* must be terminated by or */ + if(*q == ' ' || *q == '\0') { + return TRUE; + } + + /* try to find another match */ + p = q; + } + return FALSE; +} + +HDC getMonitorDC(int screen) +{ + return CreateDC("DISPLAY", NULL, NULL, NULL); +} + +int findPixelFormatSwitchDoubleBufferAndStereo (PIXELFORMATDESCRIPTOR* pfd, HDC hdc, int *mx_ptr) +{ + + int pf; + + pf = ChoosePixelFormat(hdc, pfd); + + /* Check if pixel format support min. requirement */ + DescribePixelFormat(hdc, pf, sizeof(*pfd), pfd); + + if ((pfd->cRedBits < (unsigned char) mx_ptr[RED_SIZE]) || + (pfd->cGreenBits < (unsigned char) mx_ptr[GREEN_SIZE]) || + (pfd->cBlueBits < (unsigned char) mx_ptr[BLUE_SIZE]) || + (pfd->cDepthBits < (unsigned char) mx_ptr[DEPTH_SIZE]) || + ((mx_ptr[DOUBLEBUFFER] == REQUIRED) && ((pfd->dwFlags & PFD_DOUBLEBUFFER) == 0)) || + ((mx_ptr[STEREO] == REQUIRED) && ((pfd->dwFlags & PFD_STEREO) == 0))) + { + return -1; + } + + if ((mx_ptr[ANTIALIASING] == REQUIRED) && + ((pfd->cAccumRedBits <= 0) || + (pfd->cAccumGreenBits <= 0) || + (pfd->cAccumBlueBits <= 0))) + { + return -1; + } + return pf; +} + + +void printErrorMessage(char *message) +{ + DWORD err; + char * errString; + + err = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, err, 0, (LPTSTR)&errString, 0, NULL); + fprintf(stderr, "%s - %s\n", message, errString); + LocalFree(errString); +} + +/* Prefer multiSample in following order + 4, 5, 6, 3, 7, 8, 2, 9, 10, 11, ... +*/ +int getMultiSampleScore(int s) +{ + static int multiSampleScore[9] = {9999, 9999, 6, 3, 0, 1, 2, 4, 5}; + + if (s < 9) { + return multiSampleScore[s]; + } + return s-2; +} + + +/* Max no of format wglChoosePixelFormatEXT can return */ +#define NFORMAT 100 + +int getExtPixelFormat(int *nativeConfigAttrs) +{ + static const BOOL debug = FALSE; + static char szAppName[] = "Choose Pixel Format"; + + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, /* Version number */ + PFD_DRAW_TO_WINDOW | + PFD_SUPPORT_OPENGL, + PFD_TYPE_RGBA, + 16, /* 16 bit color depth */ + 0, 0, 0, /* RGB bits and pixel sizes */ + 0, 0, 0, /* Do not care about them */ + 0, 0, /* no alpha buffer info */ + 0, 0, 0, 0, 0, /* no accumulation buffer */ + 8, /* 8 bit depth buffer */ + 0, /* no stencil buffer */ + 0, /* no auxiliary buffers */ + PFD_MAIN_PLANE, /* layer type */ + 0, /* reserved, must be 0 */ + 0, /* no layer mask */ + 0, /* no visible mask */ + 0 /* no damage mask */ + }; + + HWND hwnd; + HGLRC hrc; + HDC hdc; + int attr[22]; + int piValues[12]; + int i, idx; + int pNumFormats[NFORMAT], nAvailableFormat; + const char* supportedExtensions; + int score; + int highestScore, highestScorePF; + int highestScoreAlpha, lowestScoreMultiSample; + + /* declare function pointers for WGL functions */ + PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsStringEXT = NULL; + PFNWGLCHOOSEPIXELFORMATEXTPROC wglChoosePixelFormatEXT = NULL; + PFNWGLGETPIXELFORMATATTRIBIVEXTPROC wglGetPixelFormatAttribivEXT = NULL; + + /* + * Select any pixel format and bound current context to + * it so that we can get the wglChoosePixelFormatARB entry point. + * Otherwise wglxxx entry point will always return null. + * That's why we need to create a dummy window also. + */ + hwnd = createDummyWindow((const char *)szAppName); + + if (!hwnd) { + return -1; + } + hdc = GetDC(hwnd); + + pNumFormats[0] = ChoosePixelFormat(hdc, &pfd); + if (!pNumFormats[0]) { + printErrorMessage("Failed in ChoosePixelFormat"); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); + return -1; + } + + SetPixelFormat(hdc, pNumFormats[0], &pfd); + + hrc = wglCreateContext(hdc); + if (!hrc) { + printErrorMessage("Failed in wglCreateContext"); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); + return -1; + } + + if (!wglMakeCurrent(hdc, hrc)) { + printErrorMessage("Failed in wglMakeCurrent"); + ReleaseDC(hwnd, hdc); + wglDeleteContext(hrc); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); + return -1; + } + + wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) + wglGetProcAddress("wglGetExtensionsStringARB"); + + if (wglGetExtensionsStringEXT == NULL) { + wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) + wglGetProcAddress("wglGetExtensionsStringEXT"); + if (wglGetExtensionsStringEXT == NULL) { + if (debug) { + printf("wglGetExtensionsStringEXT/ARB not support !\n"); + } + ReleaseDC(hwnd, hdc); + wglDeleteContext(hrc); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); + return -1; + } + if (debug) { + printf("Support wglGetExtensionsStringEXT\n"); + } + } else { + if (debug) { + printf("Support wglGetExtensionsStringARB\n"); + } + } + + /* get the list of supported extensions */ + supportedExtensions = (const char *)wglGetExtensionsStringEXT(hdc); + + if (debug) { + fprintf(stderr, "WGL Supported extensions: %s.\n", supportedExtensions); + } + + if (!isSupportedWGL(supportedExtensions, "WGL_ARB_multisample") && + !isSupportedWGL(supportedExtensions, "WGL_EXT_multisample") && + !isSupportedWGL(supportedExtensions, "WGL_SGIS_multisample")) { + + /* Under Wildcat III it doesn't use wglGetExtensionString */ + supportedExtensions = (char *) glGetString(GL_EXTENSIONS); + + if (debug) { + fprintf(stderr, "GL Supported extensions: %s.\n", supportedExtensions); + } + + if (!isSupportedWGL(supportedExtensions, "GL_ARB_multisample") && + !isSupportedWGL(supportedExtensions, "GL_EXT_multisample") && + !isSupportedWGL(supportedExtensions, "GL_SGIS_multisample")) { + ReleaseDC(hwnd, hdc); + wglDeleteContext(hrc); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); + return -1; + } + } + + wglChoosePixelFormatEXT = (PFNWGLCHOOSEPIXELFORMATEXTPROC) + wglGetProcAddress("wglChoosePixelFormatARB"); + + if (wglChoosePixelFormatEXT == NULL) { + wglChoosePixelFormatEXT = (PFNWGLCHOOSEPIXELFORMATEXTPROC) + wglGetProcAddress("wglChoosePixelFormatEXT"); + if (wglChoosePixelFormatEXT == NULL) { + if (debug) { + printf("wglChoosePixelFormatARB/EXT not support !\n"); + } + ReleaseDC(hwnd, hdc); + wglDeleteContext(hrc); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); + return -1; + } + if (debug) { + printf("Support wglChoosePixelFormatEXT\n"); + } + } else { + if (debug) { + printf("Support wglChoosePixelFormatARB\n"); + } + } + + idx = 0; + attr[idx++] = WGL_SUPPORT_OPENGL_EXT; + attr[idx++] = TRUE; + attr[idx++] = WGL_DRAW_TO_WINDOW_EXT; + attr[idx++] = TRUE; + attr[idx++] = WGL_RED_BITS_EXT; + attr[idx++] = nativeConfigAttrs[RED_SIZE]; + attr[idx++] = WGL_GREEN_BITS_EXT; + attr[idx++] = nativeConfigAttrs[GREEN_SIZE]; + attr[idx++] = WGL_BLUE_BITS_EXT; + attr[idx++] = nativeConfigAttrs[BLUE_SIZE]; + attr[idx++] = WGL_DEPTH_BITS_EXT; + attr[idx++] = nativeConfigAttrs[DEPTH_SIZE]; + + if (nativeConfigAttrs[DOUBLEBUFFER] == REQUIRED) { + attr[idx++] = WGL_DOUBLE_BUFFER_EXT; + attr[idx++] = TRUE; + } + if (nativeConfigAttrs[STEREO] == REQUIRED) { + attr[idx++] = WGL_STEREO_EXT; + attr[idx++] = TRUE; + } + + if (nativeConfigAttrs[ANTIALIASING] == REQUIRED) { + attr[idx++] = WGL_SAMPLE_BUFFERS_ARB; + attr[idx++] = TRUE; + attr[idx++] = WGL_SAMPLES_ARB; + attr[idx++] = 2; + } + + /* + * Terminate by 2 zeros to avoid driver bugs + * that assume attributes always come in pairs. + */ + attr[idx++] = 0; + attr[idx++] = 0; + + if (!wglChoosePixelFormatEXT(hdc, (const int *)attr, NULL, NFORMAT, + pNumFormats, &nAvailableFormat)) { + printErrorMessage("Failed in wglChoosePixelFormatEXT"); + ReleaseDC(hwnd, hdc); + wglDeleteContext(hrc); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); + return -1; + } + + if (debug) { + printf("No. of available pixel format is: %d\n", nAvailableFormat); + } + + if (nAvailableFormat <= 0) { + ReleaseDC(hwnd, hdc); + wglDeleteContext(hrc); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); + return -1; + } + + wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) + wglGetProcAddress("wglGetPixelFormatAttribivARB"); + + if (wglGetPixelFormatAttribivEXT == NULL) { + wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) + wglGetProcAddress("wglGetPixelFormatAttribivEXT"); + + if (wglGetPixelFormatAttribivEXT == NULL) { + if (debug) { + printf("wglGetPixelFormatAttribivEXT/ARB not support !\n"); + } + ReleaseDC(hwnd, hdc); + wglDeleteContext(hrc); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); + return -1; + } + if (debug) { + printf("Support wglGetPixelFormatAttribivEXT\n"); + } + } else { + if (debug) { + printf("Support wglGetPixelFormatAttribivARB\n"); + } + } + + idx = 0; + attr[idx++] = WGL_ACCELERATION_EXT; + attr[idx++] = WGL_RED_BITS_EXT; + attr[idx++] = WGL_GREEN_BITS_EXT; + attr[idx++] = WGL_BLUE_BITS_EXT; + attr[idx++] = WGL_ALPHA_BITS_EXT; + attr[idx++] = WGL_DEPTH_BITS_EXT; + attr[idx++] = WGL_STENCIL_BITS_EXT; + attr[idx++] = WGL_SAMPLE_BUFFERS_ARB; + attr[idx++] = WGL_SAMPLES_ARB; + attr[idx++] = WGL_DOUBLE_BUFFER_EXT; + attr[idx++] = WGL_STEREO_EXT; + attr[idx] = 0; + + /* Select the best pixel format based on score */ + highestScore = 0; + highestScorePF = -1; + highestScoreAlpha = 0; + lowestScoreMultiSample = 9999; + + for (i=0; i < nAvailableFormat; i++) { + if (!wglGetPixelFormatAttribivEXT(hdc, pNumFormats[i], 0, idx, attr, piValues)) { + printErrorMessage("Failed in wglGetPixelFormatAttribivEXT"); + ReleaseDC(hwnd, hdc); + wglDeleteContext(hrc); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); + return -1; + } + if (debug) { + printf("Format %d\n", pNumFormats[i]); + + if (piValues[0] == WGL_FULL_ACCELERATION_EXT) { + printf("WGL_FULL_ACCELERATION_EXT"); + } else if (piValues[0] == WGL_GENERIC_ACCELERATION_EXT) { + printf("WGL_GENERIC_ACCELERATION_EXT"); + } else { + printf("WGL_NO_ACCELERATION_EXT"); + } + + printf(" R %d, G %d, B %d, A %d, Depth %d, Stencil %d", + piValues[1], piValues[2], piValues[3], piValues[4], + piValues[5], piValues[6]); + + if (piValues[7] == TRUE) { + printf(" MultiSample %d", piValues[8]); + } + + if (piValues[9] == TRUE) { + printf(" DoubleBuffer"); + } + + if (piValues[10] == TRUE) { + printf(" Stereo"); + } + printf("\n"); + } + + /* Red, Green, Blue are fixed under windows so they are not checked */ + score = 0; + + if (piValues[0] == WGL_FULL_ACCELERATION_EXT) { + score += 20000; + } else if (piValues[0] == WGL_GENERIC_ACCELERATION_EXT) { + score += 10000; + } + if ((nativeConfigAttrs[DOUBLEBUFFER] == PREFERRED) && + (piValues[9] == TRUE)) { + score += 5000; + } + if (piValues[4] > 0) { /* Alpha */ + score += 2500; + } + if ((nativeConfigAttrs[STEREO] == PREFERRED) && + (piValues[10] == TRUE)) { + score += 1250; + } + if ((nativeConfigAttrs[ANTIALIASING] == PREFERRED) && + (piValues[7] == TRUE)) { + score += 624; + } + + /* Stencil bit * 10 + Depth bit */ + score += piValues[6]*10 + piValues[5]; + + if (score > highestScore) { + highestScore = score; + highestScorePF = i; + highestScoreAlpha = piValues[4]; + lowestScoreMultiSample = getMultiSampleScore(piValues[8]); + } else if (score == highestScore) { + if (piValues[4] > highestScoreAlpha) { + highestScore = score; + highestScorePF = i; + highestScoreAlpha = piValues[4]; + lowestScoreMultiSample = getMultiSampleScore(piValues[8]); + } else if (piValues[4] == highestScoreAlpha) { + if (getMultiSampleScore(piValues[8]) < lowestScoreMultiSample) { + highestScore = score; + highestScorePF = i; + highestScoreAlpha = piValues[4]; + lowestScoreMultiSample = getMultiSampleScore(piValues[8]); + } + } + } + + } + + if (debug) { + printf("Select Pixel Format %d\n", pNumFormats[highestScorePF]); + } + + ReleaseDC(hwnd, hdc); + wglDeleteContext(hrc); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); + return pNumFormats[highestScorePF]; +} + + +JNIEXPORT +jint JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_choosePixelFormat( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jint screen, + jintArray attrList) +{ + int *mx_ptr; + int dbVal; /* value for double buffering */ + int sVal; /* value for stereo */ + HDC hdc; + int pf; /* PixelFormat */ + PIXELFORMATDESCRIPTOR pfd; + + mx_ptr = (int *)(*env)->GetIntArrayElements(env, attrList, NULL); + + if (mx_ptr[ANTIALIASING] != UNNECESSARY) { + pf = getExtPixelFormat(mx_ptr); + if (pf > 0) { + return pf; + } + + /* fallback to use standard ChoosePixelFormat and accumulation buffer */ + } + + hdc = getMonitorDC(screen); + + ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; /*TODO: when would this change? */ + pfd.iPixelType = PFD_TYPE_RGBA; + + /* + * Convert Java 3D values to PixelFormat + */ + + pfd.cRedBits = (unsigned char) mx_ptr[RED_SIZE]; + pfd.cGreenBits = (unsigned char) mx_ptr[GREEN_SIZE]; + pfd.cBlueBits = (unsigned char) mx_ptr[BLUE_SIZE]; + pfd.cDepthBits = (unsigned char) mx_ptr[DEPTH_SIZE]; + + if (mx_ptr[DOUBLEBUFFER] == REQUIRED || mx_ptr[DOUBLEBUFFER] == PREFERRED) + dbVal = PFD_DOUBLEBUFFER; + else + dbVal = PFD_DOUBLEBUFFER_DONTCARE; + + sVal = 0; + if (mx_ptr[STEREO] == REQUIRED || mx_ptr[STEREO] == PREFERRED) { + sVal = PFD_STEREO; + } else { + sVal = 0; + } + + pfd.dwFlags = dbVal | sVal | PFD_SUPPORT_OPENGL; + pfd.cStencilBits = 2; + + if (mx_ptr[ANTIALIASING] == REQUIRED || mx_ptr[ANTIALIASING] == PREFERRED) { + pfd.cAccumRedBits = 8; + pfd.cAccumGreenBits = 8; + pfd.cAccumBlueBits = 8; + } + + pf = findPixelFormatSwitchDoubleBufferAndStereo(&pfd, hdc, mx_ptr); + + if (pf == -1) { + /* try disable stencil buffer */ + pfd.cStencilBits = 0; + pf = findPixelFormatSwitchDoubleBufferAndStereo(&pfd, hdc, mx_ptr); + + if (pf == -1) { + /* try disable accumulate buffer */ + if (mx_ptr[ANTIALIASING] == PREFERRED) { + pfd.cStencilBits = 2; + pfd.cAccumRedBits = 0; + pfd.cAccumGreenBits = 0; + pfd.cAccumBlueBits = 0; + pf = findPixelFormatSwitchDoubleBufferAndStereo(&pfd, hdc, mx_ptr); + + if (pf == -1) { + /* try disable stencil buffer */ + pfd.cStencilBits = 0; + pf = findPixelFormatSwitchDoubleBufferAndStereo(&pfd, hdc, mx_ptr); + } + } + } + } + + DeleteDC(hdc); + + (*env)->ReleaseIntArrayElements(env, attrList, mx_ptr, JNI_ABORT); + return pf; +} + + +JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isStereoAvailable( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jlong display, + jint screen, + jint pixelFormat) +{ + HDC hdc; /* HW Device Context */ + + PIXELFORMATDESCRIPTOR pfd; + + static GLboolean first_time = GL_TRUE; + static GLboolean force_no_stereo = GL_FALSE; + + if (first_time) { + if (getenv("J3D_NO_STEREO") != NULL) { + fprintf(stderr, "Java 3D: stereo mode disabled\n"); + force_no_stereo = GL_TRUE; + } + first_time = GL_FALSE; + } + + if (force_no_stereo) + return JNI_FALSE; + + hdc = getMonitorDC(screen); + + /* Check the chosen PixelFormat to see if it is stereo capable */ + DescribePixelFormat(hdc, pixelFormat, sizeof(pfd), &pfd); + + DeleteDC(hdc); + if (pfd.dwFlags & PFD_STEREO) + return JNI_TRUE; + else + return JNI_FALSE; + + return JNI_TRUE; +} + + +JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isDoubleBufferAvailable( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jlong display, + jint screen, + jint pixelFormat) +{ + HDC hdc; /* HW Device Context */ + + PIXELFORMATDESCRIPTOR pfd; + + hdc = getMonitorDC(screen); + + /* Check the chosen PixelFormat to see if it is doubleBuffer capable */ + DescribePixelFormat(hdc, pixelFormat, sizeof(pfd), &pfd); + + DeleteDC(hdc); + if (pfd.dwFlags & PFD_DOUBLEBUFFER) + return JNI_TRUE; + else + return JNI_FALSE; +} + + + +JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isSceneAntialiasingAccumAvailable( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jlong display, + jint screen, + jint pixelFormat) +{ + HDC hdc; /* HW Device Context */ + PIXELFORMATDESCRIPTOR pfd; + + hdc = getMonitorDC(screen); + /* Check the chosen PixelFormat to see if it is sceneAntialiasing capable */ + DescribePixelFormat(hdc, pixelFormat, sizeof(pfd), &pfd); + + DeleteDC(hdc); + if (pfd.cAccumRedBits > 0) + return JNI_TRUE; + else + return JNI_FALSE; +} + +JNIEXPORT +jboolean JNICALL Java_javax_media_j3d_NativeConfigTemplate3D_isSceneAntialiasingMultiSamplesAvailable( + JNIEnv *env, + jobject obj, + jlong ctxInfo, + jlong display, + jint screen, + jint pixelFormat) +{ + static char szAppName[] = "Choose Pixel Format"; + HWND hwnd; + HGLRC hrc; + HDC hdc; + int attr[3]; + int piValues[2]; + int pf; + BOOL support; + + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, /* Version number */ + PFD_DRAW_TO_WINDOW | + PFD_SUPPORT_OPENGL, + PFD_TYPE_RGBA, + 16, /* 16 bit color depth */ + 0, 0, 0, /* RGB bits and pixel sizes */ + 0, 0, 0, /* Do not care about them */ + 0, 0, /* no alpha buffer info */ + 0, 0, 0, 0, 0, /* no accumulation buffer */ + 8, /* 8 bit depth buffer */ + 0, /* no stencil buffer */ + 0, /* no auxiliary buffers */ + PFD_MAIN_PLANE, /* layer type */ + 0, /* reserved, must be 0 */ + 0, /* no layer mask */ + 0, /* no visible mask */ + 0 /* no damage mask */ + }; + + PFNWGLGETPIXELFORMATATTRIBIVEXTPROC wglGetPixelFormatAttribivEXT = NULL; + + hwnd = createDummyWindow((const char *)szAppName); + + if (!hwnd) { + return -1; + } + hdc = GetDC(hwnd); + + pf = ChoosePixelFormat(hdc, &pfd); + if (!pf) { + printErrorMessage("Failed in ChoosePixelFormat"); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); + return -1; + } + + SetPixelFormat(hdc, pf, &pfd); + + hrc = wglCreateContext(hdc); + if (!hrc) { + printErrorMessage("Failed in wglCreateContext"); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); + return -1; + } + + if (!wglMakeCurrent(hdc, hrc)) { + printErrorMessage("Failed in wglMakeCurrent"); + ReleaseDC(hwnd, hdc); + wglDeleteContext(hrc); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); + return -1; + } + + wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) + wglGetProcAddress("wglGetPixelFormatAttribivARB"); + + if (wglGetPixelFormatAttribivEXT == NULL) { + wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) + wglGetProcAddress("wglGetPixelFormatAttribivEXT"); + + if (wglGetPixelFormatAttribivEXT == NULL) { + ReleaseDC(hwnd, hdc); + wglDeleteContext(hrc); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); + return FALSE; + } + } + + attr[0] = WGL_SAMPLE_BUFFERS_ARB; + attr[1] = WGL_SAMPLES_ARB; + attr[2] = 0; + support = FALSE; + + if (wglGetPixelFormatAttribivEXT(hdc, pixelFormat, 0, 2, attr, piValues)) { + if ((piValues[0] == TRUE) && (piValues[1] > 1)) { + support = TRUE; + } + } + + ReleaseDC(hwnd, hdc); + wglDeleteContext(hrc); + DestroyWindow(hwnd); + UnregisterClass(szAppName, (HINSTANCE)NULL); + return support; +} +#endif /* WIN32 */ diff --git a/src/native/ogl/NativeScreenInfo.c b/src/native/ogl/NativeScreenInfo.c new file mode 100644 index 0000000..c92900c --- /dev/null +++ b/src/native/ogl/NativeScreenInfo.c @@ -0,0 +1,65 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + * Portions of this code were derived from work done by the Blackdown + * group (www.blackdown.org), who did the initial Linux implementation + * of the Java 3D API. + */ + +#include +#include + +#include "gldefs.h" + +#if defined(SOLARIS) || defined(__linux__) +#include +#include +#include +#endif + +#ifdef WIN32 +#include +#endif + +#if defined(SOLARIS) || defined(__linux__) +/* + * Class: javax_media_j3d_NativeScreenInfo + * Method: openDisplay + * Signature: ()J + */ +JNIEXPORT jlong JNICALL +Java_javax_media_j3d_NativeScreenInfo_openDisplay( + JNIEnv *env, + jobject obj) +{ + Display* dpy; + dpy = XOpenDisplay(NULL); + return (jlong)dpy; +} + + +/* + * Class: javax_media_j3d_NativeScreenInfo + * Method: getDefaultScreen + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_javax_media_j3d_NativeScreenInfo_getDefaultScreen( + JNIEnv *env, + jobject obj, + jlong display) +{ + Display* dpy = (Display*)display; + return (jint)DefaultScreen(dpy); +} +#endif diff --git a/src/native/ogl/NativeWSInfo.c b/src/native/ogl/NativeWSInfo.c new file mode 100644 index 0000000..be1a1fc --- /dev/null +++ b/src/native/ogl/NativeWSInfo.c @@ -0,0 +1,78 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + * Portions of this code were derived from work done by the Blackdown + * group (www.blackdown.org), who did the initial Linux implementation + * of the Java 3D API. + */ + +#include +#include + +#include "gldefs.h" + +#if defined(SOLARIS) || defined(__linux__) +#include +#include +#include +#endif + +#ifdef WIN32 +#include +#endif + +#ifdef WIN32 + +/* + * Workaround for bug 4169320: Resizing a Java 3D canvas + * on Win95 crashes the application + */ + +#ifdef STRICT +static WNDPROC g_lpDefWindowProc; +#else +static FARPROC g_lpDefWindowProc; +#endif + +static +LRESULT CALLBACK canvas3dWndProc( + HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam) +{ + switch (message) { + case WM_WINDOWPOSCHANGED: + return 0; + default: + return CallWindowProc(g_lpDefWindowProc, hWnd, message, + wParam, lParam); + } +} + +JNIEXPORT +void JNICALL Java_javax_media_j3d_NativeWSInfo_subclass( + JNIEnv * env, + jobject obj, + jint hWnd) +{ +#ifdef STRICT + g_lpDefWindowProc = (WNDPROC) SetWindowLong((HWND) hWnd, GWL_WNDPROC, + (LONG) canvas3dWndProc); +#else + g_lpDefWindowProc = (FARPROC) SetWindowLong((HWND) hWnd, GWL_WNDPROC, + (LONG) canvas3dWndProc); +#endif +} + +#endif diff --git a/src/native/ogl/RasterRetained.c b/src/native/ogl/RasterRetained.c new file mode 100644 index 0000000..775bb2f --- /dev/null +++ b/src/native/ogl/RasterRetained.c @@ -0,0 +1,392 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#include +#include + +#include "gldefs.h" + +#ifdef DEBUG +/* Uncomment the following for VERBOSE debug messages */ +/* #define VERBOSE */ +#endif /* DEBUG */ + + +JNIEXPORT +void JNICALL Java_javax_media_j3d_RasterRetained_execute(JNIEnv *env, + jobject obj, jlong ctxInfo, jobject geo, + jboolean updateAlpha, jfloat alpha, + jint type, jint w_raster, jint h_raster, + jint x_offset, jint y_offset, jfloat x, jfloat y, jfloat z, jbyteArray imageYdown) + + +{ + jclass geo_class; + JNIEnv table; + + jfieldID w_field, h_field; + int width, height; + + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + table = *env; + + geo_class = (jclass) (*(table->GetObjectClass))(env, geo); + +#ifdef VERBOSE + fprintf(stderr, + "x %g ,y %g ,z %g ,w_raster %d,h_raster %d, x_offset %d, y_offset %d\n", + x,y,z,w_raster,h_raster,x_offset,y_offset); +#endif + + if ((type == javax_media_j3d_Raster_RASTER_COLOR) || + (type == javax_media_j3d_Raster_RASTER_COLOR_DEPTH)) { + jobject image; + jclass image_class; + jfieldID image_field, format_field; + jbyte *byteData; + int format; + int glformat; + + image_field = (jfieldID)(*(table->GetFieldID))(env, geo_class, + "image","Ljavax/media/j3d/ImageComponent2DRetained;"); + image = (jobject) (*(table->GetObjectField))(env, geo, image_field); + + if (image == NULL) { + return; + } + image_class = (jclass) (*(table->GetObjectClass))(env, image); + + format_field = (jfieldID) (*(table->GetFieldID))(env, image_class, + "storedYdownFormat", "I"); + format = (jint)(*(table->GetIntField))(env, image, format_field); + w_field = (jfieldID) (*(table->GetFieldID))(env, image_class, + "width", "I"); + width = (jint)(*(table->GetIntField))(env, image, w_field); + h_field = (jfieldID)(*(table->GetFieldID))(env, image_class, + "height", "I"); + height = (jint)(*(table->GetIntField))(env, image, h_field); + + + /* + * raster position is upper left corner, default for Java3D + * ImageComponent currently has the data reverse in Y + */ + glPixelZoom(1.0, -1.0); + glPixelStorei(GL_UNPACK_ROW_LENGTH, width); + if (x_offset >= 0) { + glPixelStorei(GL_UNPACK_SKIP_PIXELS, x_offset); + if (x_offset + w_raster > width) { + w_raster = width - x_offset; + } + } else { + w_raster += x_offset; + if (w_raster > width) { + w_raster = width; + } + } + if (y_offset >= 0) { + glPixelStorei(GL_UNPACK_SKIP_ROWS, y_offset); + if (y_offset + h_raster > height) { + h_raster = height - y_offset; + } + } else { + h_raster += y_offset; + if (h_raster > height) { + h_raster = height; + } + } + + + + glRasterPos3f(x, y, z); + + byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env, + imageYdown, NULL); + +/* + { + int i, j, *intData; + + fprintf(stderr, "format = %d, w_raster = %d, h_raster = %d\n\n", format, w_raster, h_raster); + intData = (int*)byteData; + for (i = 0; i < w_raster; i++) { + for (j = 0; j < h_raster; j++, intData++) { + fprintf(stderr, " 0x%x", *intData); + } + fprintf(stderr, "\n"); + } + } + */ + switch (format) { + case FORMAT_BYTE_RGBA: + glformat = GL_RGBA; + break; + case FORMAT_BYTE_RGB: + glformat = GL_RGB; + break; + + case FORMAT_BYTE_ABGR: + if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */ + glformat = GL_ABGR_EXT; + } + break; + case FORMAT_BYTE_BGR: + if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */ + glformat = ctxProperties->bgr_ext_enum; + } + break; + case FORMAT_BYTE_LA: + glformat = GL_LUMINANCE_ALPHA; + break; + case FORMAT_BYTE_GRAY: + case FORMAT_USHORT_GRAY: + /* TODO: throw exception */ + break; + } + glDrawPixels(w_raster, h_raster, glformat, GL_UNSIGNED_BYTE, + byteData); + + (*(table->ReleasePrimitiveArrayCritical))(env, + imageYdown, byteData, 0); + } + + if ((type == javax_media_j3d_Raster_RASTER_DEPTH) || + (type == javax_media_j3d_Raster_RASTER_COLOR_DEPTH)) { + GLint draw_buf; + jobject depth; + jclass depth_class; + jfieldID depth_field, depth_type_field; + int depth_type; + + depth_field = (jfieldID)(*(table->GetFieldID))(env, geo_class, + "depthComponent","Ljavax/media/j3d/DepthComponentRetained;"); + + depth = (jobject) (*(table->GetObjectField))(env, geo, depth_field); + if (depth == NULL) { + return; + } + depth_class = (jclass) (*(table->GetObjectClass))(env, depth); + + depth_type_field = (jfieldID) (*(table->GetFieldID))(env, + depth_class, "type", "I"); + depth_type = (jint)(*(table->GetIntField))(env, depth, + depth_type_field); + + w_field = (jfieldID) (*(table->GetFieldID))(env, depth_class, + "width", "I"); + width = (jint)(*(table->GetIntField))(env, depth, w_field); + h_field = (jfieldID)(*(table->GetFieldID))(env, depth_class, + "height", "I"); + height = (jint)(*(table->GetIntField))(env, depth, h_field); + + + glGetIntegerv(GL_DRAW_BUFFER, &draw_buf); + /* disable draw buffer */ + glDrawBuffer(GL_NONE); + /* glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); */ + + /* + * raster position is upper left corner, default for Java3D + * ImageComponent currently has the data reverse in Y + */ + glPixelStorei(GL_UNPACK_ROW_LENGTH, width); + if (x_offset >= 0) { + glPixelStorei(GL_UNPACK_SKIP_PIXELS, x_offset); + if (x_offset + w_raster > width) { + w_raster = width - x_offset; + } + } else { + w_raster += x_offset; + if (w_raster > width) { + w_raster = width; + } + } + if (y_offset >= 0) { + glPixelStorei(GL_UNPACK_SKIP_ROWS, y_offset); + if (y_offset + h_raster > height) { + h_raster = height - y_offset; + } + } else { + h_raster += y_offset; + if (h_raster > height) { + h_raster = height; + } + } + + + if (depth_type == javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_INT) { + jfieldID intData_field; + jintArray intData_array; + jint *intData; + + intData_field = (jfieldID)(*(table->GetFieldID))(env, + depth_class, "depthData","[I"); + + intData_array = (jintArray)(*(table->GetObjectField))(env, depth, + intData_field); + intData = (jint *)(*(table->GetPrimitiveArrayCritical))(env, + intData_array, NULL); + glDrawPixels(w_raster, h_raster, GL_DEPTH_COMPONENT, + GL_UNSIGNED_INT, intData); + (*(table->ReleasePrimitiveArrayCritical))(env, intData_array, + intData, 0); + } else { /* javax_media_j3d_DepthComponentRetained_DEPTH_COMPONENT_TYPE_FLOAT */ + jfieldID floatData_field; + jfloatArray floatData_array; + jfloat *floatData; + + floatData_field = (jfieldID)(*(table->GetFieldID))(env, + depth_class, "depthData","[F"); + floatData_array = (jfloatArray)(*(table->GetObjectField))(env, depth, + floatData_field); + floatData = (jfloat *)(*(table->GetPrimitiveArrayCritical))(env, + floatData_array, NULL); + glDrawPixels(w_raster, h_raster, GL_DEPTH_COMPONENT, + GL_FLOAT, floatData); + (*(table->ReleasePrimitiveArrayCritical))(env, floatData_array, + floatData, 0); + } + + /* re-enable draw buffer */ + glDrawBuffer(draw_buf); + + } + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + +} + + +#if 0 + +JNIEXPORT +void JNICALL Java_javax_media_j3d_RasterRetained_executeTiled(JNIEnv *env, + jobject obj, jlong ctxInfo, jobject geo, + jint format, jint w_raster, jint h_raster, + jint x_offset, jint y_offset, jint deltaw, jint deltah, jfloat x, jfloat y, jfloat z, jbyteArray tile) + + +{ + jclass geo_class; + JNIEnv table; + jint j; + int alphaChanged = 0; /* used so we can get alpha data from */ + /* JNI before using it so we can use */ + /* GetPrimitiveArrayCritical */ + jobject image; + jclass image_class; + jfieldID byteData_field, image_field, format_field; + jbyteArray byteData_array; + jbyte *byteData; + int glformat; + float rasterPos[3]; + GraphicsContextPropertiesInfo *ctxProperties = (GraphicsContextPropertiesInfo *)ctxInfo; + jlong ctx = ctxProperties->context; + + table = *env; + + +#ifdef VERBOSE + fprintf(stderr, + "x %g ,y %g ,z %g ,w_raster %d,h_raster %d, x_offset %d, y_offset %d\n", + x,y,z,w_raster,h_raster,x_offset,y_offset); +#endif + + + /* + * raster position is upper left corner, default for Java3D + * ImageComponent currently has the data reverse in Y + */ + glPixelZoom(1.0, -1.0); + /* glPixelStorei(GL_UNPACK_ROW_LENGTH, width);*/ + if (x_offset >= 0) { + glPixelStorei(GL_UNPACK_SKIP_PIXELS, x_offset); + if (x_offset + w_raster > width) { + w_raster = width - x_offset; + } + } else { + w_raster += x_offset; + if (w_raster > width) { + w_raster = width; + } + } + if (y_offset >= 0) { + glPixelStorei(GL_UNPACK_SKIP_ROWS, y_offset); + if (y_offset + h_raster > height) { + h_raster = height - y_offset; + } + } else { + h_raster += y_offset; + if (h_raster > height) { + h_raster = height; + } + } + + if (deltaw == 0 && deltah == 0) { + glRasterPos3f(x, y, z); + } + else { + glGetFloatv(GL_CURRENT_RASTER_POSITION,rasterPos); + rasterPos[0] += (float)deltaw; + rasterPos[1] += (float)deltah; + glRasterPos3f(rasterPos[0], rasterPos[1], rasterPos[2]); + } + + + + byteData = (jbyte *)(*(table->GetPrimitiveArrayCritical))(env, + tile, NULL); + switch (format) { + case FORMAT_BYTE_RGBA: + glformat = GL_RGBA; + break; + case FORMAT_BYTE_RGB: + glformat = GL_RGB; + break; + + case FORMAT_BYTE_ABGR: + if (ctxProperties->abgr_ext) { /* If its zero, should never come here! */ + glformat = GL_ABGR_EXT; + } + break; + + + case FORMAT_BYTE_BGR: + if (ctxProperties->bgr_ext) { /* If its zero, should never come here! */ + glformat = ctxProperties->bgr_ext_enum; + } + break; + + case FORMAT_BYTE_LA: + glformat = GL_LUMINANCE_ALPHA; + break; + case FORMAT_BYTE_GRAY: + case FORMAT_USHORT_GRAY: + /* TODO: throw exception */ + break; + } + fprintf(stderr, "w_raster = %d, h_raster = %d, glformat = %d\n",w_raster, h_raster, glformat); + glDrawPixels(w_raster, h_raster, glformat, GL_UNSIGNED_BYTE, + byteData); + + (*(table->ReleasePrimitiveArrayCritical))(env, + tile, byteData, 0); + + /* glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);*/ + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + +} +#endif diff --git a/src/native/ogl/build-linux-i586.xml b/src/native/ogl/build-linux-i586.xml new file mode 100644 index 0000000..1148118 --- /dev/null +++ b/src/native/ogl/build-linux-i586.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/native/ogl/build-solaris-sparc-forte.xml b/src/native/ogl/build-solaris-sparc-forte.xml new file mode 100644 index 0000000..86d46d7 --- /dev/null +++ b/src/native/ogl/build-solaris-sparc-forte.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/native/ogl/build-solaris-sparc-gcc.xml b/src/native/ogl/build-solaris-sparc-gcc.xml new file mode 100644 index 0000000..33f8ebe --- /dev/null +++ b/src/native/ogl/build-solaris-sparc-gcc.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/native/ogl/build-windows-i586-gcc.xml b/src/native/ogl/build-windows-i586-gcc.xml new file mode 100644 index 0000000..95d768e --- /dev/null +++ b/src/native/ogl/build-windows-i586-gcc.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/native/ogl/build-windows-i586-vc.xml b/src/native/ogl/build-windows-i586-vc.xml new file mode 100644 index 0000000..1890d8a --- /dev/null +++ b/src/native/ogl/build-windows-i586-vc.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/native/ogl/gl_1_2.h b/src/native/ogl/gl_1_2.h new file mode 100644 index 0000000..b540d3e --- /dev/null +++ b/src/native/ogl/gl_1_2.h @@ -0,0 +1,191 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#ifndef __gl_1_2_h_ +#define __gl_1_2_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Portions of this code were derived from work done by the Blackdown + * group (www.blackdown.org), who did the initial Linux implementation + * of the Java 3D API. + */ + +#ifndef GL_VERSION_1_2 + +#ifndef GL_BGR +#define GL_BGR 0x80E0 +#endif + +#ifndef GL_BGRA +#define GL_BGRA 0x80E1 +#endif + + +#ifndef GL_LIGHT_MODEL_COLOR_CONTROL +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#endif + +#ifndef GL_SEPARATE_SPECULAR_COLOR +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#endif + +#ifndef GL_SINGLE_COLOR +#define GL_SINGLE_COLOR 0x81F9 +#endif + +#endif /* GL_VERSION_1_2 */ + + +#ifndef GL_ARB_texture_env_combine +#define GL_COMBINE_ARB 0x8570 +#define GL_COMBINE_RGB_ARB 0x8571 +#define GL_COMBINE_ALPHA_ARB 0x8572 +#define GL_RGB_SCALE_ARB 0x8573 +#define GL_ADD_SIGNED_ARB 0x8574 +#define GL_INTERPOLATE_ARB 0x8575 +#define GL_SUBTRACT_ARB 0x84E7 +#define GL_CONSTANT_ARB 0x8576 +#define GL_PRIMARY_COLOR_ARB 0x8577 +#define GL_PREVIOUS_ARB 0x8578 +#define GL_SOURCE0_RGB_ARB 0x8580 +#define GL_SOURCE1_RGB_ARB 0x8581 +#define GL_SOURCE2_RGB_ARB 0x8582 +#define GL_SOURCE0_ALPHA_ARB 0x8588 +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_OPERAND0_RGB_ARB 0x8590 +#define GL_OPERAND1_RGB_ARB 0x8591 +#define GL_OPERAND2_RGB_ARB 0x8592 +#define GL_OPERAND0_ALPHA_ARB 0x8598 +#define GL_OPERAND1_ALPHA_ARB 0x8599 +#define GL_OPERAND2_ALPHA_ARB 0x859A +#endif /* GL_ARB_texture_env_combine */ + + +#ifndef GL_ARB_texture_env_dot3 +#define GL_DOT3_RGB_ARB 0x86AE +#define GL_DOT3_RGBA_ARB 0x86AF +#endif /* GL_ARB_texture_env_dot3 */ + + +#ifndef GL_EXT_texture_env_dot3 +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 +#endif /* GL_EXT_texture_env_dot3 */ + +#ifndef GL_EXT_texture_edge_clamp +#define GL_CLAMP_TO_EDGE_EXT 0x812F +#endif + +#ifndef GL_ARB_texture_border_clamp +#define GL_CLAMP_TO_BORDER_ARB 0x812D +#endif + +#ifndef GL_ARB_multisample +#if defined(SOLARIS) || defined(__linux__) +#define GLX_SAMPLE_BUFFERS_ARB 100000 +#define GLX_SAMPLES_ARB 100001 +#endif +#ifdef WIN32 +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif +#define MULTISAMPLE_ARB 0x809D +#define SAMPLE_ALPHA_TO_COVERATE_ARB 0x809E +#define SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define SAMPLE_COVERAGE_ARB 0x80A0 +#define MULTISAMPLE_BIT_ARB 0x20000000 +#define SAMPLE_BUFFERS_ARB 0x80A8 +#define SAMPLES_ARB 0x80A9 +#define SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#endif /* GL_ARB_multisample */ + +#ifndef MULTISAMPLE_ARB +#define MULTISAMPLE_ARB 0x809D +#endif + +#ifdef WIN32 + +/* define those EXT_pixel_format enums from 3DLabs register developer web site */ +#ifndef WGL_SUPPORT_OPENGL_EXT +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C +#endif /* WGL_SUPPORT_OPENGL_EXT */ + +/* define those ARB_pixel_format enums */ +#ifndef WGL_SUPPORT_OPENGL_ARB +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_DEPTH_BITS_ARB 0x2022 +#endif /* WGL_SUPPORT_OPENGL_ARB */ + +#endif /* WIN32 */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/native/ogl/gldefs.h b/src/native/ogl/gldefs.h new file mode 100644 index 0000000..6658201 --- /dev/null +++ b/src/native/ogl/gldefs.h @@ -0,0 +1,645 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#ifndef _Java3D_gldefs_h_ +#define _Java3D_gldefs_h_ + +/* + * Portions of this code were derived from work done by the Blackdown + * group (www.blackdown.org), who did the initial Linux implementation + * of the Java 3D API. + */ + +#include +#include +#include + +#if defined(SOLARIS) || defined(__linux__) +#define GLX_GLEXT_PROTOTYPES +#define GLX_GLXEXT_PROTOTYPES +#include +#include +#include +#include +#include +#include "gl_1_2.h" +#include "glext.h" +#endif + +#ifdef WIN32 +#include + +#ifndef _WIN32 +#define _WIN32 +#endif + +#define M_PI 3.14159265358979323846 + +/* Some constant defined in those javax_media_j3d_*.h */ +/* TODO: remove those constant when D3D automatically include those *.h files */ +#ifdef D3D + +/* used in GeometryArrayRetained, execute geometry in by REFERENCE case */ +#ifndef javax_media_j3d_GeometryArrayRetained_COORD_FLOAT +#define javax_media_j3d_GeometryArrayRetained_COORD_FLOAT 1L +#endif +#ifndef javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE +#define javax_media_j3d_GeometryArrayRetained_COORD_DOUBLE 2L +#endif +#ifndef javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT +#define javax_media_j3d_GeometryArrayRetained_COLOR_FLOAT 4L +#endif +#ifndef javax_media_j3d_GeometryArrayRetained_COLOR_BYTE +#define javax_media_j3d_GeometryArrayRetained_COLOR_BYTE 8L +#endif +#ifndef javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT +#define javax_media_j3d_GeometryArrayRetained_NORMAL_FLOAT 16L +#endif +#ifndef javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT +#define javax_media_j3d_GeometryArrayRetained_TEXCOORD_FLOAT 32L +#endif + +#endif /* end of ifdef D3D */ + +#ifndef D3D +#include +#include "gl_1_2.h" +#include "glext.h" +#endif + +#endif /* WIN32 */ + +/* include those .h files generated by javah */ +#include "javax_media_j3d_Background.h" +#include "javax_media_j3d_Canvas3D.h" +#include "javax_media_j3d_ColoringAttributes.h" +#include "javax_media_j3d_ColoringAttributesRetained.h" +#include "javax_media_j3d_CompressedGeometryRetained.h" +#include "javax_media_j3d_DepthComponentRetained.h" +#include "javax_media_j3d_DetailTextureImage.h" +#include "javax_media_j3d_DirectionalLightRetained.h" +#include "javax_media_j3d_DisplayListRenderMethod.h" +#include "javax_media_j3d_DrawingSurfaceObjectAWT.h" +#include "javax_media_j3d_ExponentialFogRetained.h" +#include "javax_media_j3d_GeometryRetained.h" +#include "javax_media_j3d_GeometryArray.h" +#include "javax_media_j3d_GeometryArrayRetained.h" +#include "javax_media_j3d_GraphicsContext3D.h" +#include "javax_media_j3d_ImageComponent.h" +#include "javax_media_j3d_ImageComponentRetained.h" +#include "javax_media_j3d_ImageComponent2DRetained.h" +#include "javax_media_j3d_IndexedGeometryArrayRetained.h" +#include "javax_media_j3d_LineAttributes.h" +#include "javax_media_j3d_LineAttributesRetained.h" +#include "javax_media_j3d_LinearFogRetained.h" +#include "javax_media_j3d_MasterControl.h" +#include "javax_media_j3d_Material.h" +#include "javax_media_j3d_MaterialRetained.h" +#include "javax_media_j3d_ModelClipRetained.h" +#include "javax_media_j3d_NativeConfigTemplate3D.h" +#include "javax_media_j3d_NodeRetained.h" +#include "javax_media_j3d_PointAttributesRetained.h" +#include "javax_media_j3d_PointLightRetained.h" +#include "javax_media_j3d_PolygonAttributes.h" +#include "javax_media_j3d_PolygonAttributesRetained.h" +#include "javax_media_j3d_Raster.h" +#include "javax_media_j3d_RasterRetained.h" +#include "javax_media_j3d_Renderer.h" +#include "javax_media_j3d_RenderingAttributes.h" +#include "javax_media_j3d_RenderingAttributesRetained.h" +#include "javax_media_j3d_RenderMolecule.h" +#include "javax_media_j3d_SpotLightRetained.h" +#include "javax_media_j3d_TexCoordGeneration.h" +#include "javax_media_j3d_TexCoordGenerationRetained.h" +#include "javax_media_j3d_Texture.h" +#include "javax_media_j3d_Texture2D.h" +#include "javax_media_j3d_Texture2DRetained.h" +#include "javax_media_j3d_Texture3DRetained.h" +#include "javax_media_j3d_TextureAttributes.h" +#include "javax_media_j3d_TextureAttributesRetained.h" +#include "javax_media_j3d_TextureCubeMapRetained.h" +#include "javax_media_j3d_TextureRetained.h" +#include "javax_media_j3d_TextureUnitStateRetained.h" +#include "javax_media_j3d_TransparencyAttributes.h" +#include "javax_media_j3d_TransparencyAttributesRetained.h" + +#ifndef GL_SUNX_geometry_compression +#define GL_COMPRESSED_GEOM_ACCELERATED_SUNX 0x81D0 +#endif /* GL_SUNX_geometry_compression */ + +/* + * Define these constants here as a workaround for conflicting + * glext.h files between Mesa and Solaris + */ + +#ifndef GL_CLAMP_TO_BORDER_SGIS +#define GL_CLAMP_TO_BORDER_SGIS 0x812D +#endif + +#ifndef GL_VIDEO_RESIZE_COMPENSATION_SUN +#define GL_VIDEO_RESIZE_COMPENSATION_SUN 0x85CD +#endif + +/* + * End constant workaround + */ + + +/* Used to compare floating point values close to 0.0 */ +#define J3D_SMALL_FLOAT 0.00001f + +/* + * General purpose assertion macro + */ +#define J3D_ASSERT(expr) \ + if (!(expr)) { \ + fprintf(stderr, \ + "\nAssertion failed in module '%s' at line %d\n", \ + __FILE__, __LINE__); \ + fprintf(stderr, "\t%s\n\n", #expr); \ + } + +#define EPSILON 1e-2 +#define J3D_FNE(a,b) ((a)>((b)+EPSILON)||(a)<((b)-EPSILON)) + + +/* + * Macro to copy and transpose one matrix to another. + * + * NOTE: the source and dest must not be the same (no aliasing check + * is performed). + */ +#define COPY_TRANSPOSE(src,dst) { \ + (dst)[0] = (src)[0]; \ + (dst)[1] = (src)[4]; \ + (dst)[2] = (src)[8]; \ + (dst)[3] = (src)[12]; \ + (dst)[4] = (src)[1]; \ + (dst)[5] = (src)[5]; \ + (dst)[6] = (src)[9]; \ + (dst)[7] = (src)[13]; \ + (dst)[8] = (src)[2]; \ + (dst)[9] = (src)[6]; \ + (dst)[10] = (src)[10]; \ + (dst)[11] = (src)[14]; \ + (dst)[12] = (src)[3]; \ + (dst)[13] = (src)[7]; \ + (dst)[14] = (src)[11]; \ + (dst)[15] = (src)[15]; \ +} + + +/* + * These match the constants in GeometryRetained + */ + +#define GEO_TYPE_NONE javax_media_j3d_GeometryRetained_GEO_TYPE_NONE +#define GEO_TYPE_QUAD_SET javax_media_j3d_GeometryRetained_GEO_TYPE_QUAD_SET +#define GEO_TYPE_TRI_SET javax_media_j3d_GeometryRetained_GEO_TYPE_TRI_SET +#define GEO_TYPE_POINT_SET javax_media_j3d_GeometryRetained_GEO_TYPE_POINT_SET +#define GEO_TYPE_LINE_SET javax_media_j3d_GeometryRetained_GEO_TYPE_LINE_SET +#define GEO_TYPE_TRI_STRIP_SET javax_media_j3d_GeometryRetained_GEO_TYPE_TRI_STRIP_SET +#define GEO_TYPE_TRI_FAN_SET javax_media_j3d_GeometryRetained_GEO_TYPE_TRI_FAN_SET +#define GEO_TYPE_LINE_STRIP_SET javax_media_j3d_GeometryRetained_GEO_TYPE_LINE_STRIP_SET +#define GEO_TYPE_INDEXED_QUAD_SET javax_media_j3d_GeometryRetained_GEO_TYPE_INDEXED_QUAD_SET +#define GEO_TYPE_INDEXED_TRI_SET javax_media_j3d_GeometryRetained_GEO_TYPE_INDEXED_TRI_SET +#define GEO_TYPE_INDEXED_POINT_SET javax_media_j3d_GeometryRetained_GEO_TYPE_INDEXED_POINT_SET +#define GEO_TYPE_INDEXED_LINE_SET javax_media_j3d_GeometryRetained_GEO_TYPE_INDEXED_LINE_SET +#define GEO_TYPE_INDEXED_TRI_STRIP_SET javax_media_j3d_GeometryRetained_GEO_TYPE_INDEXED_TRI_STRIP_SET +#define GEO_TYPE_INDEXED_TRI_FAN_SET javax_media_j3d_GeometryRetained_GEO_TYPE_INDEXED_TRI_FAN_SET +#define GEO_TYPE_INDEXED_LINE_STRIP_SET javax_media_j3d_GeometryRetained_GEO_TYPE_INDEXED_LINE_STRIP_SET +#define GEO_TYPE_RASTER javax_media_j3d_GeometryRetained_GEO_TYPE_RASTER +#define GEO_TYPE_TEXT3D javax_media_j3d_GeometryRetained_GEO_TYPE_TEXT3D +#define GEO_TYPE_COMPRESSED javax_media_j3d_GeometryRetained_GEO_TYPE_COMPRESSED +#define GEO_TYPE_TOTAL javax_media_j3d_GeometryRetained_GEO_TYPE_TOTAL + +/* + * These match the constants in ImageComponent + */ + +#define FORMAT_RGB javax_media_j3d_ImageComponent_FORMAT_RGB +#define FORMAT_RGBA javax_media_j3d_ImageComponent_FORMAT_RGBA +#define FORMAT_RGB5 javax_media_j3d_ImageComponent_FORMAT_RGB5 +#define FORMAT_RGB5_A1 javax_media_j3d_ImageComponent_FORMAT_RGB5_A1 +#define FORMAT_RGB4 javax_media_j3d_ImageComponent_FORMAT_RGB4 +#define FORMAT_RGBA4 javax_media_j3d_ImageComponent_FORMAT_RGBA4 +#define FORMAT_LUM4_ALPHA4 javax_media_j3d_ImageComponent_FORMAT_LUM4_ALPHA4 +#define FORMAT_LUM8_ALPHA8 javax_media_j3d_ImageComponent_FORMAT_LUM8_ALPHA8 +#define FORMAT_R3_G3_B2 javax_media_j3d_ImageComponent_FORMAT_R3_G3_B2 +#define FORMAT_CHANNEL8 javax_media_j3d_ImageComponent_FORMAT_CHANNEL8 + + +/* now the imagecomponent formats are reduced the ones below */ +#define FORMAT_BYTE_RGBA javax_media_j3d_ImageComponentRetained_BYTE_RGBA +#define FORMAT_BYTE_ABGR javax_media_j3d_ImageComponentRetained_BYTE_ABGR +#define FORMAT_BYTE_GRAY javax_media_j3d_ImageComponentRetained_BYTE_GRAY +#define FORMAT_USHORT_GRAY javax_media_j3d_ImageComponentRetained_USHORT_GRAY +#define FORMAT_BYTE_LA javax_media_j3d_ImageComponentRetained_BYTE_LA +#define FORMAT_BYTE_BGR javax_media_j3d_ImageComponentRetained_BYTE_BGR +#define FORMAT_BYTE_RGB javax_media_j3d_ImageComponentRetained_BYTE_RGB + + +/* These match the definitions in GeometryArray.java */ +/* These have a GA prefix to avoid confusion with TEXTURE_COORDINATE_2 above */ +#define GA_COORDINATES javax_media_j3d_GeometryArray_COORDINATES +#define GA_NORMALS javax_media_j3d_GeometryArray_NORMALS +#define GA_COLOR javax_media_j3d_GeometryArray_COLOR +#define GA_WITH_ALPHA javax_media_j3d_GeometryArray_WITH_ALPHA +#define GA_TEXTURE_COORDINATE_2 javax_media_j3d_GeometryArray_TEXTURE_COORDINATE_2 +#define GA_TEXTURE_COORDINATE_3 javax_media_j3d_GeometryArray_TEXTURE_COORDINATE_3 +#define GA_TEXTURE_COORDINATE_4 javax_media_j3d_GeometryArray_TEXTURE_COORDINATE_4 +#define GA_TEXTURE_COORDINATE javax_media_j3d_GeometryArray_TEXTURE_COORDINATE +#define GA_BY_REFERENCE javax_media_j3d_GeometryArray_BY_REFERENCE + + + +/* + * These match the constants in NativeConfigTemplate3D + */ + +#define RED_SIZE javax_media_j3d_NativeConfigTemplate3D_RED_SIZE +#define GREEN_SIZE javax_media_j3d_NativeConfigTemplate3D_GREEN_SIZE +#define BLUE_SIZE javax_media_j3d_NativeConfigTemplate3D_BLUE_SIZE +#define ALPHA_SIZE javax_media_j3d_NativeConfigTemplate3D_ALPHA_SIZE +#define ACCUM_BUFFER javax_media_j3d_NativeConfigTemplate3D_ACCUM_BUFFER +#define DEPTH_SIZE javax_media_j3d_NativeConfigTemplate3D_DEPTH_SIZE + /* this maps to GLX_ACCUM_RED, */ + /* GLX_ACCUM_GREEN and */ + /* GLX_ACCUM_BLUE so NUM_ITEMS */ + /* must be incremented by 3 for */ + /* this attribute. */ +#define DOUBLEBUFFER javax_media_j3d_NativeConfigTemplate3D_DOUBLEBUFFER +#define STEREO javax_media_j3d_NativeConfigTemplate3D_STEREO +#define ANTIALIASING javax_media_j3d_NativeConfigTemplate3D_ANTIALIASING + + +/* set this to the number of indices (from above) */ +#define NUM_ITEMS (javax_media_j3d_NativeConfigTemplate3D_NUM_ITEMS + 2) + /* total + 2 beacause of */ + /* DEPTH_SIZE */ + +/* values for "enum" entries for GraphicsConfiguration */ +#define REQUIRED 1 +#define PREFERRED 2 +#define UNNECESSARY 3 + + + +#define INTENSITY javax_media_j3d_Texture_INTENSITY +#define LUMINANCE javax_media_j3d_Texture_LUMINANCE +#define ALPHA javax_media_j3d_Texture_ALPHA +#define LUMINANCE_ALPHA javax_media_j3d_Texture_LUMINANCE_ALPHA +#define J3D_RGB javax_media_j3d_Texture_RGB +#define J3D_RGBA javax_media_j3d_Texture_RGBA + +#ifndef D3D +#if defined(SOLARIS) || defined(__linux__) +extern void APIENTRY glBlendColor (GLclampf, GLclampf, GLclampf, GLclampf); +extern void APIENTRY glBlendColorEXT (GLclampf, GLclampf, GLclampf, GLclampf); +extern void APIENTRY glColorTable (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glColorTableSGI (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glGetColorTableParameterivSGI (GLenum, GLenum, GLint *); +extern void APIENTRY glGetColorTableParameterfv (GLenum, GLenum, GLfloat *); +extern void APIENTRY glMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei); +extern void APIENTRY glMultiDrawArraysSUN (GLenum, GLint *, GLsizei *, GLsizei); +extern void APIENTRY glMultiDrawElementsEXT (GLenum, GLsizei *, GLenum, const GLvoid**, GLsizei); +extern void APIENTRY glMultiDrawElementsSUN (GLenum, GLsizei *, GLenum, const GLvoid**, GLsizei); +extern void APIENTRY glLockArraysEXT (GLint first, GLsizei count); +extern void APIENTRY glUnlockArraysEXT (void); + + +extern void APIENTRY glClientActiveTextureARB (GLenum); +extern void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *); +extern void APIENTRY glGlobalAlphaFactorfSUN (GLfloat); +extern void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *); +extern void APIENTRY glMultTransposeMatrixdARB (const GLdouble *); +extern void APIENTRY glActiveTextureARB (GLenum); +extern void APIENTRY glSharpenTexFuncSGIS(GLenum, GLsizei, const GLfloat *); +extern void APIENTRY glDetailTexFuncSGIS(GLenum, GLsizei, const GLfloat *); +extern void APIENTRY glTexFilterFuncSGIS(GLenum, GLenum, GLsizei, const GLfloat *); +extern void APIENTRY glCombinerInputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum); +extern void APIENTRY glCombinerOutputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean); +extern void APIENTRY glFinalCombinerInputNV (GLenum, GLenum, GLenum, GLenum); +extern void APIENTRY glCombinerParameterfvNV (GLenum, const GLfloat *); +extern void APIENTRY glCombinerParameterivNV (GLenum, const GLint *); +extern void APIENTRY glCombinerParameterfNV (GLenum, GLfloat); +extern void APIENTRY glCombinerParameteriNV (GLenum, GLint); + +extern void APIENTRY glTexImage3DEXT (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); + + + +#ifndef GLX_SUN_video_resize +#define GLX_SUN_video_resize 1 +extern int glXVideoResizeSUN( Display *, GLXDrawable, float); +extern int glXgetVideoResizeSUN( Display *, GLXDrawable, float *); +#endif + +#pragma weak glXVideoResizeSUN +#pragma weak glBlendColor +#pragma weak glBlendColorEXT +#pragma weak glColorTable +#pragma weak glColorTableSGI +#pragma weak glGetColorTableParameterivSGI +#pragma weak glGetColorTableParameteriv +#pragma weak glMultiDrawArraysSUN +#pragma weak glMultiDrawArraysEXT +#pragma weak glMultiDrawElementsSUN +#pragma weak glMultiDrawElementsEXT +#pragma weak glLockArraysEXT +#pragma weak glUnlockArraysEXT +#pragma weak glClientActiveTextureARB +#pragma weak glMultiTexCoord2fvARB +#pragma weak glMultiTexCoord3fvARB +#pragma weak glMultiTexCoord4fvARB +#pragma weak glGlobalAlphaFactorfSUN +#pragma weak glLoadTransposeMatrixdARB +#pragma weak glMultTransposeMatrixdARB +#pragma weak glActiveTextureARB +#pragma weak glCombinerInputNV +#pragma weak glCombinerOutputNV +#pragma weak glFinalCombinerInputNV +#pragma weak glCombinerParameterfvNV +#pragma weak glCombinerParameterivNV +#pragma weak glCombinerParameterfNV +#pragma weak glCombinerParameteriNV +#pragma weak glSharpenTexFuncSGIS +#pragma weak glDetailTexFuncSGIS +#pragma weak glTexFilterFuncSGIS +/* [jk] mostly needed by older NVIDIA drivers */ +#pragma weak glTexImage3DEXT +#pragma weak glTexSubImage3DEXT +#pragma weak glTexImage3D +#pragma weak glTexSubImage3D +#endif /* SOLARIS */ + +#ifndef APIENTRY +#define APIENTRY +#endif + +#ifdef WIN32 + +/* declare function prototype for WGL related functions*/ +typedef const char * (APIENTRY * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (HDC hdc); +typedef BOOL (APIENTRY * PFNWGLCHOOSEPIXELFORMATEXTPROC)(HDC hdc, + const int *piAttribIList, + const FLOAT *pfAttriFList, + UINT nMaxFormats, + int *piFormats, + UINT *nNumFormats); +typedef BOOL (APIENTRY * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC)(HDC hdc, + int iPixelFormat, + int iLayerPlane, + UINT nAttributes, + const int *piAttributes, + int *piValues); + + + +#endif /* WIN32 */ + +/* define function prototypes */ +typedef void (APIENTRY * MYPFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, + GLclampf blue, GLclampf alpha); +typedef void (APIENTRY * MYPFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, + GLclampf blue, GLclampf alpha); +typedef void (APIENTRY * MYPFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRY * MYPFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * MYPFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (APIENTRY * MYPFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRY * MYPFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (APIENTRY * MYPFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum, GLsizei *, GLenum, const GLvoid**, GLsizei); +typedef void (APIENTRY * MYPFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (APIENTRY * MYPFNGLUNLOCKARRAYSEXTPROC) (void); + +typedef void (APIENTRY * MYPFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * MYPFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * MYPFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * MYPFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +typedef void (APIENTRY * MYPFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +typedef void (APIENTRY * MYPFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRY * MYPFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * MYPFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); + +typedef void (APIENTRY * MYPFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); + +typedef void (APIENTRY * MYPFNGLCOMBINERINPUTNV) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRY * MYPFNGLFINALCOMBINERINPUTNV) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRY * MYPFNGLCOMBINEROUTPUTNV) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (APIENTRY * MYPFNGLCOMBINERPARAMETERFVNV) (GLenum pname, const GLfloat *params); +typedef void (APIENTRY * MYPFNGLCOMBINERPARAMETERIVNV) (GLenum pname, const GLint *params); +typedef void (APIENTRY * MYPFNGLCOMBINERPARAMETERFNV) (GLenum pname, GLfloat param); +typedef void (APIENTRY * MYPFNGLCOMBINERPARAMETERINV) (GLenum pname, GLint param); +typedef void (APIENTRY * MYPFNGLSHARPENTEXFUNCSGI) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRY * MYPFNGLDETAILTEXFUNCSGI) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRY * MYPFNGLTEXFILTERFUNCSGI) (GLenum target, GLenum filter, GLsizei n, const GLfloat *points); + +/* define the structure to hold the properties of graphics context */ +typedef struct { + jlong context; + + /* version and extension info */ + char *versionStr; + char *extensionStr; + int versionNumbers[2]; + + /* both in 1.2 core part and 1.1 extensions */ + /* GL_EXT_rescale_normal or GL_RESCALE_NORMAL */ + jboolean rescale_normal_ext; + GLenum rescale_normal_ext_enum; + + /* GL_BGR_EXT or GL_BGR */ + jboolean bgr_ext; + GLenum bgr_ext_enum; + + /* GL_EXT_texture3D or GL_TEXTURE3D */ + jboolean texture3DAvailable; + GLenum texture_3D_ext_enum; + GLenum texture_wrap_r_ext_enum; + + /* GL_ARB_imaging subset */ + /* GL_EXT_blend_color or GL_BLEND_COLOR */ + jboolean blend_color_ext; + GLenum blendFunctionTable[8]; + /* GL_SGI_color_table or GL_COLOR_TABLE */ + jboolean color_table_ext; + + /* GL_EXT_separate_specular_color */ + jboolean seperate_specular_color; + GLenum light_model_color_control_enum; + GLenum single_color_enum; + GLenum seperate_specular_color_enum; + + /* GL_CLAMP_TO_EDGE or GL_EXT_texture_edge_clamp or + GL_SGIS_texture_edge_clamp */ + GLenum texture_clamp_to_edge_enum; + + + /* GL_SGIS_texture_lod */ + jboolean textureLodAvailable; + GLenum texture_min_lod_enum; + GLenum texture_max_lod_enum; + GLenum texture_base_level_enum; + GLenum texture_max_level_enum; + + + /* ***********1.1 extension or 1.2 extensions ********************/ + + /* GL_ARB_texture_border_clamp or GL_SGIS_texture_border_clamp */ + GLenum texture_clamp_to_border_enum; + + /* GL_SUN_multi_draw_arrays */ + jboolean multi_draw_arrays_sun; + + /* GLX_SUN_video_resize */ + jboolean videoResizeAvailable; + + /* GL_SUN_global_alpha */ + jboolean global_alpha_sun; + /* GL_SUNX_constant_data */ + jboolean constant_data_sun; + /* GL_SUNX_geometry_compression */ + jboolean geometry_compression_sunx; + + /* GL_EXT_abgr */ + jboolean abgr_ext; + /* GL_EXT_multi_draw_arrays */ + jboolean multi_draw_arrays_ext; + + /* GL_EXT_compiled_vertex_array */ + jboolean compiled_vertex_array_ext; + + /* GL_ARB_transpose_matrix */ + jboolean arb_transpose_matrix; + + /* GL_ARB_multitexture */ + jboolean arb_multitexture; + int textureUnitCount; + + /* GL_SGI_texture_color_table */ + jboolean textureColorTableAvailable; + int textureColorTableSize; + + /* GL_ARB_texture_env_combine */ + /* GL_EXT_texture_env_combine */ + jboolean textureEnvCombineAvailable; + jboolean textureCombineDot3Available; + jboolean textureCombineSubtractAvailable; + + /* GL_NV_register_combiners */ + jboolean textureRegisterCombinersAvailable; + GLenum currentTextureUnit; + GLenum currentCombinerUnit; + + /* save the enum for the combine modes since the enums between + ARB & EXT might be different. + */ + GLenum combine_enum; + GLenum combine_add_signed_enum; + GLenum combine_interpolate_enum; + GLenum combine_subtract_enum; + GLenum combine_dot3_rgb_enum; + GLenum combine_dot3_rgba_enum; + + /* GL_ARB_texture_cube_map */ + /* GL_EXT_texture_cube_map */ + jboolean textureCubeMapAvailable; + GLenum texture_cube_map_ext_enum; + + /* GL_ARB_mulitsample */ + jboolean arb_multisample; + + /* + By default, full scene antialiasing is disable if + multisampling pixel format (or visual) is chosen. + To honor display driver multisampling antialiasing + setting (e.g. force scene antialiasing), set the + implicit multisample flag to true in this case. + This cause Java3D not to invoke any native + multisampling API to enable/disable scene antialiasing. + */ + jboolean implicit_multisample; + + /* GL_SGIS_sharpen_texture */ + jboolean textureSharpenAvailable; + GLenum linear_sharpen_enum; + GLenum linear_sharpen_rgb_enum; + GLenum linear_sharpen_alpha_enum; + + /* GL_SGIS_detail_texture */ + jboolean textureDetailAvailable; + GLenum texture_detail_ext_enum; + GLenum linear_detail_enum; + GLenum linear_detail_rgb_enum; + GLenum linear_detail_alpha_enum; + GLenum texture_detail_mode_enum; + GLenum texture_detail_level_enum; + + /* GL_SGIS_texture_filter4 */ + jboolean textureFilter4Available; + GLenum filter4_enum; + + /* GL_EXT_texture_filter_anisotropic */ + jboolean textureAnisotropicFilterAvailable; + GLenum texture_filter_anisotropic_ext_enum; + GLenum max_texture_filter_anisotropy_enum; + + /* GL_SGIX_texture_lod_bias */ + jboolean textureLodBiasAvailable; + + jboolean geometry_compression_accelerated; + int geometry_compression_accelerated_major_version; + int geometry_compression_accelerated_minor_version; + int geometry_compression_accelerated_subminor_version; + + /* extension mask */ + jint extMask; + jint textureExtMask; + + /* function pointers */ + MYPFNGLBLENDCOLORPROC glBlendColor; + MYPFNGLBLENDCOLOREXTPROC glBlendColorEXT; + MYPFNGLCOLORTABLEPROC glColorTable; + MYPFNGLGETCOLORTABLEPARAMETERIVPROC glGetColorTableParameteriv; + MYPFNGLTEXIMAGE3DPROC glTexImage3DEXT; + MYPFNGLTEXSUBIMAGE3DPROC glTexSubImage3DEXT; + MYPFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB; + MYPFNGLACTIVETEXTUREARBPROC glActiveTextureARB; + MYPFNGLMULTIDRAWARRAYSEXTPROC glMultiDrawArraysEXT; + MYPFNGLMULTIDRAWELEMENTSEXTPROC glMultiDrawElementsEXT; + MYPFNGLLOCKARRAYSEXTPROC glLockArraysEXT; + MYPFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT; + MYPFNGLMULTITEXCOORD2FVARBPROC glMultiTexCoord2fvARB; + MYPFNGLMULTITEXCOORD3FVARBPROC glMultiTexCoord3fvARB; + MYPFNGLMULTITEXCOORD4FVARBPROC glMultiTexCoord4fvARB; + MYPFNGLLOADTRANSPOSEMATRIXDARBPROC glLoadTransposeMatrixdARB; + MYPFNGLMULTTRANSPOSEMATRIXDARBPROC glMultTransposeMatrixdARB; + MYPFNGLGLOBALALPHAFACTORFSUNPROC glGlobalAlphaFactorfSUN; + + MYPFNGLCOMBINERINPUTNV glCombinerInputNV; + MYPFNGLCOMBINEROUTPUTNV glCombinerOutputNV; + MYPFNGLFINALCOMBINERINPUTNV glFinalCombinerInputNV; + MYPFNGLCOMBINERPARAMETERFVNV glCombinerParameterfvNV; + MYPFNGLCOMBINERPARAMETERIVNV glCombinerParameterivNV; + MYPFNGLCOMBINERPARAMETERFNV glCombinerParameterfNV; + MYPFNGLCOMBINERPARAMETERINV glCombinerParameteriNV; + + MYPFNGLSHARPENTEXFUNCSGI glSharpenTexFuncSGIS; + MYPFNGLDETAILTEXFUNCSGI glDetailTexFuncSGIS; + MYPFNGLTEXFILTERFUNCSGI glTexFilterFuncSGIS; +} GraphicsContextPropertiesInfo; + +#endif /* J3D_BUILDVERTICES */ +#endif /* _Java3D_gldefs_h_ */ diff --git a/src/native/ogl/glext.h b/src/native/ogl/glext.h new file mode 100644 index 0000000..1a5b8b9 --- /dev/null +++ b/src/native/ogl/glext.h @@ -0,0 +1,3063 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +#ifndef __glext_h_ +#define __glext_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Portions of this code were derived from work done by the Blackdown + * group (www.blackdown.org), who did the initial Linux implementation + * of the Java 3D API. + */ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif + +/*************************************************************/ + +/* Header file version number, required by OpenGL ABI for Linux */ +#define GL_GLEXT_VERSION 7 + +#ifndef GL_VERSION_1_2 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_RESCALE_NORMAL 0x803A +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#endif + +#ifndef GL_ARB_multitexture +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 +#endif + +#ifndef GL_ARB_transpose_matrix +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 +#endif + +#ifndef GL_ARB_multisample +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 +#endif + +#ifndef GL_ARB_texture_cube_map +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C +#endif + +#ifndef GL_ARB_texture_compression +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 +#endif + +#ifndef GL_ARB_vertex_blend +#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 +#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 +#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 +#define GL_VERTEX_BLEND_ARB 0x86A7 +#define GL_CURRENT_WEIGHT_ARB 0x86A8 +#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 +#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA +#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB +#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC +#define GL_WEIGHT_ARRAY_ARB 0x86AD +#define GL_MODELVIEW0_ARB 0x1700 +#define GL_MODELVIEW1_ARB 0x850A +#define GL_MODELVIEW2_ARB 0x8722 +#define GL_MODELVIEW3_ARB 0x8723 +#define GL_MODELVIEW4_ARB 0x8724 +#define GL_MODELVIEW5_ARB 0x8725 +#define GL_MODELVIEW6_ARB 0x8726 +#define GL_MODELVIEW7_ARB 0x8727 +#define GL_MODELVIEW8_ARB 0x8728 +#define GL_MODELVIEW9_ARB 0x8729 +#define GL_MODELVIEW10_ARB 0x872A +#define GL_MODELVIEW11_ARB 0x872B +#define GL_MODELVIEW12_ARB 0x872C +#define GL_MODELVIEW13_ARB 0x872D +#define GL_MODELVIEW14_ARB 0x872E +#define GL_MODELVIEW15_ARB 0x872F +#define GL_MODELVIEW16_ARB 0x8730 +#define GL_MODELVIEW17_ARB 0x8731 +#define GL_MODELVIEW18_ARB 0x8732 +#define GL_MODELVIEW19_ARB 0x8733 +#define GL_MODELVIEW20_ARB 0x8734 +#define GL_MODELVIEW21_ARB 0x8735 +#define GL_MODELVIEW22_ARB 0x8736 +#define GL_MODELVIEW23_ARB 0x8737 +#define GL_MODELVIEW24_ARB 0x8738 +#define GL_MODELVIEW25_ARB 0x8739 +#define GL_MODELVIEW26_ARB 0x873A +#define GL_MODELVIEW27_ARB 0x873B +#define GL_MODELVIEW28_ARB 0x873C +#define GL_MODELVIEW29_ARB 0x873D +#define GL_MODELVIEW30_ARB 0x873E +#define GL_MODELVIEW31_ARB 0x873F +#endif + +#ifndef GL_EXT_abgr +#define GL_ABGR_EXT 0x8000 +#endif + +#ifndef GL_EXT_blend_color +#define GL_CONSTANT_COLOR_EXT 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 +#define GL_CONSTANT_ALPHA_EXT 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 +#define GL_BLEND_COLOR_EXT 0x8005 +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_POLYGON_OFFSET_EXT 0x8037 +#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 +#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 +#endif + +#ifndef GL_EXT_texture +#define GL_ALPHA4_EXT 0x803B +#define GL_ALPHA8_EXT 0x803C +#define GL_ALPHA12_EXT 0x803D +#define GL_ALPHA16_EXT 0x803E +#define GL_LUMINANCE4_EXT 0x803F +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE12_EXT 0x8041 +#define GL_LUMINANCE16_EXT 0x8042 +#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 +#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 +#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 +#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 +#define GL_INTENSITY_EXT 0x8049 +#define GL_INTENSITY4_EXT 0x804A +#define GL_INTENSITY8_EXT 0x804B +#define GL_INTENSITY12_EXT 0x804C +#define GL_INTENSITY16_EXT 0x804D +#define GL_RGB2_EXT 0x804E +#define GL_RGB4_EXT 0x804F +#define GL_RGB5_EXT 0x8050 +#define GL_RGB8_EXT 0x8051 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB12_EXT 0x8053 +#define GL_RGB16_EXT 0x8054 +#define GL_RGBA2_EXT 0x8055 +#define GL_RGBA4_EXT 0x8056 +#define GL_RGB5_A1_EXT 0x8057 +#define GL_RGBA8_EXT 0x8058 +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGBA12_EXT 0x805A +#define GL_RGBA16_EXT 0x805B +#define GL_TEXTURE_RED_SIZE_EXT 0x805C +#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D +#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E +#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 +#define GL_REPLACE_EXT 0x8062 +#define GL_PROXY_TEXTURE_1D_EXT 0x8063 +#define GL_PROXY_TEXTURE_2D_EXT 0x8064 +#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 +#endif + +#ifndef GL_EXT_texture3D +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_SKIP_IMAGES_EXT 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_3D_EXT 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_PROXY_TEXTURE_3D_EXT 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_DEPTH_EXT 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_TEXTURE_WRAP_R_EXT 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 +#endif + +#ifndef GL_SGIS_texture_filter4 +#define GL_FILTER4_SGIS 0x8146 +#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 +#endif + +#ifndef GL_EXT_subtexture +#endif + +#ifndef GL_EXT_copy_texture +#endif + +#ifndef GL_EXT_histogram +#define GL_HISTOGRAM_EXT 0x8024 +#define GL_PROXY_HISTOGRAM_EXT 0x8025 +#define GL_HISTOGRAM_WIDTH_EXT 0x8026 +#define GL_HISTOGRAM_FORMAT_EXT 0x8027 +#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C +#define GL_HISTOGRAM_SINK_EXT 0x802D +#define GL_MINMAX_EXT 0x802E +#define GL_MINMAX_FORMAT_EXT 0x802F +#define GL_MINMAX_SINK_EXT 0x8030 +#define GL_TABLE_TOO_LARGE_EXT 0x8031 +#endif + +#ifndef GL_EXT_convolution +#define GL_CONVOLUTION_1D_EXT 0x8010 +#define GL_CONVOLUTION_2D_EXT 0x8011 +#define GL_SEPARABLE_2D_EXT 0x8012 +#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 +#define GL_REDUCE_EXT 0x8016 +#define GL_CONVOLUTION_FORMAT_EXT 0x8017 +#define GL_CONVOLUTION_WIDTH_EXT 0x8018 +#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 +#endif + +#ifndef GL_SGI_color_matrix +#define GL_COLOR_MATRIX_SGI 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB +#endif + +#ifndef GL_SGI_color_table +#define GL_COLOR_TABLE_SGI 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 +#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 +#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 +#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 +#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 +#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF +#endif + +#ifndef GL_SGIS_pixel_texture +#define GL_PIXEL_TEXTURE_SGIS 0x8353 +#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 +#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 +#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 +#endif + +#ifndef GL_SGIX_pixel_texture +#define GL_PIXEL_TEX_GEN_SGIX 0x8139 +#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B +#endif + +#ifndef GL_SGIS_texture4D +#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 +#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 +#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 +#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 +#define GL_TEXTURE_4D_SGIS 0x8134 +#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 +#define GL_TEXTURE_4DSIZE_SGIS 0x8136 +#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 +#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 +#define GL_TEXTURE_4D_BINDING_SGIS 0x814F +#endif + +#ifndef GL_SGI_texture_color_table +#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC +#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD +#endif + +#ifndef GL_EXT_cmyka +#define GL_CMYK_EXT 0x800C +#define GL_CMYKA_EXT 0x800D +#define GL_PACK_CMYK_HINT_EXT 0x800E +#define GL_UNPACK_CMYK_HINT_EXT 0x800F +#endif + +#ifndef GL_EXT_texture_object +#define GL_TEXTURE_PRIORITY_EXT 0x8066 +#define GL_TEXTURE_RESIDENT_EXT 0x8067 +#define GL_TEXTURE_1D_BINDING_EXT 0x8068 +#define GL_TEXTURE_2D_BINDING_EXT 0x8069 +#define GL_TEXTURE_3D_BINDING_EXT 0x806A +#endif + +#ifndef GL_SGIS_detail_texture +#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 +#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 +#define GL_LINEAR_DETAIL_SGIS 0x8097 +#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 +#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 +#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A +#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B +#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C +#endif + +#ifndef GL_SGIS_sharpen_texture +#define GL_LINEAR_SHARPEN_SGIS 0x80AD +#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE +#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF +#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 +#endif + +#ifndef GL_EXT_packed_pixels +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#endif + +#ifndef GL_SGIS_texture_lod +#define GL_TEXTURE_MIN_LOD_SGIS 0x813A +#define GL_TEXTURE_MAX_LOD_SGIS 0x813B +#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C +#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D +#endif + +#ifndef GL_SGIS_multisample +#define GL_MULTISAMPLE_SGIS 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F +#define GL_SAMPLE_MASK_SGIS 0x80A0 +#define GL_1PASS_SGIS 0x80A1 +#define GL_2PASS_0_SGIS 0x80A2 +#define GL_2PASS_1_SGIS 0x80A3 +#define GL_4PASS_0_SGIS 0x80A4 +#define GL_4PASS_1_SGIS 0x80A5 +#define GL_4PASS_2_SGIS 0x80A6 +#define GL_4PASS_3_SGIS 0x80A7 +#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 +#define GL_SAMPLES_SGIS 0x80A9 +#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA +#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB +#define GL_SAMPLE_PATTERN_SGIS 0x80AC +#endif + +#ifndef GL_EXT_rescale_normal +#define GL_RESCALE_NORMAL_EXT 0x803A +#endif + +#ifndef GL_EXT_vertex_array +#define GL_VERTEX_ARRAY_EXT 0x8074 +#define GL_NORMAL_ARRAY_EXT 0x8075 +#define GL_COLOR_ARRAY_EXT 0x8076 +#define GL_INDEX_ARRAY_EXT 0x8077 +#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 +#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 +#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A +#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B +#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C +#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D +#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E +#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F +#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 +#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 +#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 +#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 +#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 +#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 +#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 +#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 +#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A +#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B +#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C +#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D +#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E +#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F +#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 +#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 +#endif + +#ifndef GL_EXT_misc_attribute +#endif + +#ifndef GL_SGIS_generate_mipmap +#define GL_GENERATE_MIPMAP_SGIS 0x8191 +#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 +#endif + +#ifndef GL_SGIX_clipmap +#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 +#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 +#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 +#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 +#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 +#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 +#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 +#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 +#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 +#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D +#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E +#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F +#endif + +#ifndef GL_SGIX_shadow +#define GL_TEXTURE_COMPARE_SGIX 0x819A +#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B +#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C +#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D +#endif + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_CLAMP_TO_EDGE_SGIS 0x812F +#endif + +#ifndef GL_SGIS_texture_border_clamp +#define GL_CLAMP_TO_BORDER_SGIS 0x812D +#endif + +#ifndef GL_EXT_blend_minmax +#define GL_FUNC_ADD_EXT 0x8006 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#define GL_BLEND_EQUATION_EXT 0x8009 +#endif + +#ifndef GL_EXT_blend_subtract +#define GL_FUNC_SUBTRACT_EXT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B +#endif + +#ifndef GL_EXT_blend_logic_op +#endif + +#ifndef GL_SGIX_interlace +#define GL_INTERLACE_SGIX 0x8094 +#endif + +#ifndef GL_SGIX_pixel_tiles +#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E +#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F +#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 +#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 +#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 +#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 +#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 +#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 +#endif + +#ifndef GL_SGIS_texture_select +#define GL_DUAL_ALPHA4_SGIS 0x8110 +#define GL_DUAL_ALPHA8_SGIS 0x8111 +#define GL_DUAL_ALPHA12_SGIS 0x8112 +#define GL_DUAL_ALPHA16_SGIS 0x8113 +#define GL_DUAL_LUMINANCE4_SGIS 0x8114 +#define GL_DUAL_LUMINANCE8_SGIS 0x8115 +#define GL_DUAL_LUMINANCE12_SGIS 0x8116 +#define GL_DUAL_LUMINANCE16_SGIS 0x8117 +#define GL_DUAL_INTENSITY4_SGIS 0x8118 +#define GL_DUAL_INTENSITY8_SGIS 0x8119 +#define GL_DUAL_INTENSITY12_SGIS 0x811A +#define GL_DUAL_INTENSITY16_SGIS 0x811B +#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C +#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D +#define GL_QUAD_ALPHA4_SGIS 0x811E +#define GL_QUAD_ALPHA8_SGIS 0x811F +#define GL_QUAD_LUMINANCE4_SGIS 0x8120 +#define GL_QUAD_LUMINANCE8_SGIS 0x8121 +#define GL_QUAD_INTENSITY4_SGIS 0x8122 +#define GL_QUAD_INTENSITY8_SGIS 0x8123 +#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 +#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 +#endif + +#ifndef GL_SGIX_sprite +#define GL_SPRITE_SGIX 0x8148 +#define GL_SPRITE_MODE_SGIX 0x8149 +#define GL_SPRITE_AXIS_SGIX 0x814A +#define GL_SPRITE_TRANSLATION_SGIX 0x814B +#define GL_SPRITE_AXIAL_SGIX 0x814C +#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D +#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E +#endif + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E +#endif + +#ifndef GL_SGIS_point_parameters +#define GL_POINT_SIZE_MIN_EXT 0x8126 +#define GL_POINT_SIZE_MIN_SGIS 0x8126 +#define GL_POINT_SIZE_MAX_EXT 0x8127 +#define GL_POINT_SIZE_MAX_SGIS 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 +#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 +#define GL_DISTANCE_ATTENUATION_EXT 0x8129 +#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 +#endif + +#ifndef GL_SGIX_instruments +#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 +#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 +#endif + +#ifndef GL_SGIX_texture_scale_bias +#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 +#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A +#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B +#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C +#endif + +#ifndef GL_SGIX_framezoom +#define GL_FRAMEZOOM_SGIX 0x818B +#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C +#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D +#endif + +#ifndef GL_SGIX_tag_sample_buffer +#endif + +#ifndef GL_FfdMaskSGIX +#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 +#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 +#endif + +#ifndef GL_SGIX_polynomial_ffd +#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 +#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 +#define GL_DEFORMATIONS_MASK_SGIX 0x8196 +#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 +#endif + +#ifndef GL_SGIX_reference_plane +#define GL_REFERENCE_PLANE_SGIX 0x817D +#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E +#endif + +#ifndef GL_SGIX_flush_raster +#endif + +#ifndef GL_SGIX_depth_texture +#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 +#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 +#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 +#endif + +#ifndef GL_SGIS_fog_function +#define GL_FOG_FUNC_SGIS 0x812A +#define GL_FOG_FUNC_POINTS_SGIS 0x812B +#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C +#endif + +#ifndef GL_SGIX_fog_offset +#define GL_FOG_OFFSET_SGIX 0x8198 +#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 +#endif + +#ifndef GL_HP_image_transform +#define GL_IMAGE_SCALE_X_HP 0x8155 +#define GL_IMAGE_SCALE_Y_HP 0x8156 +#define GL_IMAGE_TRANSLATE_X_HP 0x8157 +#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 +#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 +#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A +#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B +#define GL_IMAGE_MAG_FILTER_HP 0x815C +#define GL_IMAGE_MIN_FILTER_HP 0x815D +#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E +#define GL_CUBIC_HP 0x815F +#define GL_AVERAGE_HP 0x8160 +#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 +#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 +#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 +#endif + +#ifndef GL_HP_convolution_border_modes +#define GL_IGNORE_BORDER_HP 0x8150 +#define GL_CONSTANT_BORDER_HP 0x8151 +#define GL_REPLICATE_BORDER_HP 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 +#endif + +#ifndef GL_INGR_palette_buffer +#endif + +#ifndef GL_SGIX_texture_add_env +#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE +#endif + +#ifndef GL_EXT_color_subtable +#endif + +#ifndef GL_PGI_vertex_hints +#define GL_VERTEX_DATA_HINT_PGI 0x1A22A +#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B +#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C +#define GL_MAX_VERTEX_HINT_PGI 0x1A22D +#define GL_COLOR3_BIT_PGI 0x00010000 +#define GL_COLOR4_BIT_PGI 0x00020000 +#define GL_EDGEFLAG_BIT_PGI 0x00040000 +#define GL_INDEX_BIT_PGI 0x00080000 +#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 +#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 +#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 +#define GL_MAT_EMISSION_BIT_PGI 0x00800000 +#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 +#define GL_MAT_SHININESS_BIT_PGI 0x02000000 +#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 +#define GL_NORMAL_BIT_PGI 0x08000000 +#define GL_TEXCOORD1_BIT_PGI 0x10000000 +#define GL_TEXCOORD2_BIT_PGI 0x20000000 +#define GL_TEXCOORD3_BIT_PGI 0x40000000 +#define GL_TEXCOORD4_BIT_PGI 0x80000000 +#define GL_VERTEX23_BIT_PGI 0x00000004 +#define GL_VERTEX4_BIT_PGI 0x00000008 +#endif + +#ifndef GL_PGI_misc_hints +#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 +#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD +#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE +#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 +#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 +#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 +#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C +#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D +#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E +#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F +#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 +#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 +#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 +#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 +#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 +#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 +#define GL_CLIP_NEAR_HINT_PGI 0x1A220 +#define GL_CLIP_FAR_HINT_PGI 0x1A221 +#define GL_WIDE_LINE_HINT_PGI 0x1A222 +#define GL_BACK_NORMALS_HINT_PGI 0x1A223 +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#endif + +#ifndef GL_EXT_clip_volume_hint +#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 +#endif + +#ifndef GL_SGIX_list_priority +#define GL_LIST_PRIORITY_SGIX 0x8182 +#endif + +#ifndef GL_SGIX_ir_instrument1 +#define GL_IR_INSTRUMENT1_SGIX 0x817F +#endif + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 +#endif + +#ifndef GL_SGIX_texture_lod_bias +#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E +#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F +#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 +#endif + +#ifndef GL_SGIX_shadow_ambient +#define GL_SHADOW_AMBIENT_SGIX 0x80BF +#endif + +#ifndef GL_EXT_index_texture +#endif + +#ifndef GL_EXT_index_material +#define GL_INDEX_MATERIAL_EXT 0x81B8 +#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 +#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA +#endif + +#ifndef GL_EXT_index_func +#define GL_INDEX_TEST_EXT 0x81B5 +#define GL_INDEX_TEST_FUNC_EXT 0x81B6 +#define GL_INDEX_TEST_REF_EXT 0x81B7 +#endif + +#ifndef GL_EXT_index_array_formats +#define GL_IUI_V2F_EXT 0x81AD +#define GL_IUI_V3F_EXT 0x81AE +#define GL_IUI_N3F_V2F_EXT 0x81AF +#define GL_IUI_N3F_V3F_EXT 0x81B0 +#define GL_T2F_IUI_V2F_EXT 0x81B1 +#define GL_T2F_IUI_V3F_EXT 0x81B2 +#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 +#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 +#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_CULL_VERTEX_EXT 0x81AA +#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB +#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC +#endif + +#ifndef GL_SGIX_ycrcb +#define GL_YCRCB_422_SGIX 0x81BB +#define GL_YCRCB_444_SGIX 0x81BC +#endif + +#ifndef GL_SGIX_fragment_lighting +#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 +#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 +#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 +#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 +#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 +#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 +#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 +#define GL_LIGHT_ENV_MODE_SGIX 0x8407 +#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 +#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 +#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A +#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B +#define GL_FRAGMENT_LIGHT0_SGIX 0x840C +#define GL_FRAGMENT_LIGHT1_SGIX 0x840D +#define GL_FRAGMENT_LIGHT2_SGIX 0x840E +#define GL_FRAGMENT_LIGHT3_SGIX 0x840F +#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 +#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 +#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 +#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 +#endif + +#ifndef GL_IBM_rasterpos_clip +#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 +#endif + +#ifndef GL_HP_texture_lighting +#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 +#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 +#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 +#endif + +#ifndef GL_EXT_draw_range_elements +#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 +#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 +#endif + +#ifndef GL_WIN_phong_shading +#define GL_PHONG_WIN 0x80EA +#define GL_PHONG_HINT_WIN 0x80EB +#endif + +#ifndef GL_WIN_specular_fog +#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC +#endif + +#ifndef GL_EXT_light_texture +#define GL_FRAGMENT_MATERIAL_EXT 0x8349 +#define GL_FRAGMENT_NORMAL_EXT 0x834A +#define GL_FRAGMENT_COLOR_EXT 0x834C +#define GL_ATTENUATION_EXT 0x834D +#define GL_SHADOW_ATTENUATION_EXT 0x834E +#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F +#define GL_TEXTURE_LIGHT_EXT 0x8350 +#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 +#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 +/* reuse GL_FRAGMENT_DEPTH_EXT */ +#endif + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_ALPHA_MIN_SGIX 0x8320 +#define GL_ALPHA_MAX_SGIX 0x8321 +#endif + +#ifndef GL_EXT_bgra +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 +#endif + +#ifndef GL_SGIX_async +#define GL_ASYNC_MARKER_SGIX 0x8329 +#endif + +#ifndef GL_SGIX_async_pixel +#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C +#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D +#define GL_ASYNC_READ_PIXELS_SGIX 0x835E +#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F +#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 +#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 +#endif + +#ifndef GL_SGIX_async_histogram +#define GL_ASYNC_HISTOGRAM_SGIX 0x832C +#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D +#endif + +#ifndef GL_INTEL_texture_scissor +#endif + +#ifndef GL_INTEL_parallel_arrays +#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 +#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 +#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 +#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 +#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 +#endif + +#ifndef GL_HP_occlusion_test +#define GL_OCCLUSION_TEST_HP 0x8165 +#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 +#endif + +#ifndef GL_EXT_pixel_transform +#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 +#define GL_PIXEL_MAG_FILTER_EXT 0x8331 +#define GL_PIXEL_MIN_FILTER_EXT 0x8332 +#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 +#define GL_CUBIC_EXT 0x8334 +#define GL_AVERAGE_EXT 0x8335 +#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 +#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 +#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 +#endif + +#ifndef GL_EXT_pixel_transform_color_table +#endif + +#ifndef GL_EXT_shared_texture_palette +#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB +#endif + +#ifndef GL_EXT_separate_specular_color +#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 +#define GL_SINGLE_COLOR_EXT 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA +#endif + +#ifndef GL_EXT_secondary_color +#define GL_COLOR_SUM_EXT 0x8458 +#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D +#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E +#endif + +#ifndef GL_EXT_texture_perturb_normal +#define GL_PERTURB_EXT 0x85AE +#define GL_TEXTURE_NORMAL_EXT 0x85AF +#endif + +#ifndef GL_EXT_multi_draw_arrays +#endif + +#ifndef GL_EXT_fog_coord +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 +#endif + +#ifndef GL_REND_screen_coordinates +#define GL_SCREEN_COORDINATES_REND 0x8490 +#define GL_INVERTED_SCREEN_W_REND 0x8491 +#endif + +#ifndef GL_EXT_coordinate_frame +#define GL_TANGENT_ARRAY_EXT 0x8439 +#define GL_BINORMAL_ARRAY_EXT 0x843A +#define GL_CURRENT_TANGENT_EXT 0x843B +#define GL_CURRENT_BINORMAL_EXT 0x843C +#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E +#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F +#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 +#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 +#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 +#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 +#define GL_MAP1_TANGENT_EXT 0x8444 +#define GL_MAP2_TANGENT_EXT 0x8445 +#define GL_MAP1_BINORMAL_EXT 0x8446 +#define GL_MAP2_BINORMAL_EXT 0x8447 +#endif + +#ifndef GL_EXT_texture_env_combine +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE3_RGB_EXT 0x8583 +#define GL_SOURCE4_RGB_EXT 0x8584 +#define GL_SOURCE5_RGB_EXT 0x8585 +#define GL_SOURCE6_RGB_EXT 0x8586 +#define GL_SOURCE7_RGB_EXT 0x8587 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_SOURCE3_ALPHA_EXT 0x858B +#define GL_SOURCE4_ALPHA_EXT 0x858C +#define GL_SOURCE5_ALPHA_EXT 0x858D +#define GL_SOURCE6_ALPHA_EXT 0x858E +#define GL_SOURCE7_ALPHA_EXT 0x858F +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND3_RGB_EXT 0x8593 +#define GL_OPERAND4_RGB_EXT 0x8594 +#define GL_OPERAND5_RGB_EXT 0x8595 +#define GL_OPERAND6_RGB_EXT 0x8596 +#define GL_OPERAND7_RGB_EXT 0x8597 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A +#define GL_OPERAND3_ALPHA_EXT 0x859B +#define GL_OPERAND4_ALPHA_EXT 0x859C +#define GL_OPERAND5_ALPHA_EXT 0x859D +#define GL_OPERAND6_ALPHA_EXT 0x859E +#define GL_OPERAND7_ALPHA_EXT 0x859F +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_TRANSFORM_HINT_APPLE 0x85B1 +#endif + +#ifndef GL_SGIX_fog_scale +#define GL_FOG_SCALE_SGIX 0x81FC +#define GL_FOG_SCALE_VALUE_SGIX 0x81FD +#endif + +#ifndef GL_SUNX_constant_data +#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 +#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 +#endif + +#ifndef GL_SUN_global_alpha +#define GL_GLOBAL_ALPHA_SUN 0x81D9 +#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA +#endif + +#ifndef GL_SUN_triangle_list +#define GL_RESTART_SUN 0x01 +#define GL_REPLACE_MIDDLE_SUN 0x02 +#define GL_REPLACE_OLDEST_SUN 0x03 +#define GL_TRIANGLE_LIST_SUN 0x81D7 +#define GL_REPLACEMENT_CODE_SUN 0x81D8 +#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 +#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 +#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 +#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 +#define GL_R1UI_V3F_SUN 0x85C4 +#define GL_R1UI_C4UB_V3F_SUN 0x85C5 +#define GL_R1UI_C3F_V3F_SUN 0x85C6 +#define GL_R1UI_N3F_V3F_SUN 0x85C7 +#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 +#define GL_R1UI_T2F_V3F_SUN 0x85C9 +#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA +#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB +#endif + + /* DVR support --This is a temporary solution. Hopefully the new + glext.h from ARB will have GL_SUN_video_resize_compensation + defined. */ +#ifndef GL_SUN_video_resize_compensation +#define GL_VIDEO_RESIZE_COMPENSATION_SUN 0x85CD +#endif + +#ifndef GL_SUN_vertex +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_BLEND_DST_RGB_EXT 0x80C8 +#define GL_BLEND_SRC_RGB_EXT 0x80C9 +#define GL_BLEND_DST_ALPHA_EXT 0x80CA +#define GL_BLEND_SRC_ALPHA_EXT 0x80CB +#endif + +#ifndef GL_INGR_color_clamp +#define GL_RED_MIN_CLAMP_INGR 0x8560 +#define GL_GREEN_MIN_CLAMP_INGR 0x8561 +#define GL_BLUE_MIN_CLAMP_INGR 0x8562 +#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 +#define GL_RED_MAX_CLAMP_INGR 0x8564 +#define GL_GREEN_MAX_CLAMP_INGR 0x8565 +#define GL_BLUE_MAX_CLAMP_INGR 0x8566 +#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 +#endif + +#ifndef GL_INGR_interlace_read +#define GL_INTERLACE_READ_INGR 0x8568 +#endif + +#ifndef GL_EXT_stencil_wrap +#define GL_INCR_WRAP_EXT 0x8507 +#define GL_DECR_WRAP_EXT 0x8508 +#endif + +#ifndef GL_EXT_422_pixels +#define GL_422_EXT 0x80CC +#define GL_422_REV_EXT 0x80CD +#define GL_422_AVERAGE_EXT 0x80CE +#define GL_422_REV_AVERAGE_EXT 0x80CF +#endif + +#ifndef GL_NV_texgen_reflection +#define GL_NORMAL_MAP_NV 0x8511 +#define GL_REFLECTION_MAP_NV 0x8512 +#endif + +#ifndef GL_EXT_texture_cube_map +#define GL_NORMAL_MAP_EXT 0x8511 +#define GL_REFLECTION_MAP_EXT 0x8512 +#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C +#endif + +#ifndef GL_SUN_convolution_border_modes +#define GL_WRAP_BORDER_SUN 0x81D4 +#endif + +#ifndef GL_EXT_texture_env_add +#endif + +#ifndef GL_EXT_texture_lod_bias +#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD +#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 +#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + +#ifndef GL_EXT_vertex_weighting +#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH +#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 +#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX +#define GL_MODELVIEW_MATRIX1_EXT 0x8506 +#define GL_VERTEX_WEIGHTING_EXT 0x8509 +#define GL_MODELVIEW0_EXT GL_MODELVIEW +#define GL_MODELVIEW1_EXT 0x850A +#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B +#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C +#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D +#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E +#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F +#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 +#endif + +#ifndef GL_NV_light_max_exponent +#define GL_MAX_SHININESS_NV 0x8504 +#define GL_MAX_SPOT_EXPONENT_NV 0x8505 +#endif + +#ifndef GL_NV_vertex_array_range +#define GL_VERTEX_ARRAY_RANGE_NV 0x851D +#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E +#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F +#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 +#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 +#endif + +#ifndef GL_NV_register_combiners +#define GL_REGISTER_COMBINERS_NV 0x8522 +#define GL_VARIABLE_A_NV 0x8523 +#define GL_VARIABLE_B_NV 0x8524 +#define GL_VARIABLE_C_NV 0x8525 +#define GL_VARIABLE_D_NV 0x8526 +#define GL_VARIABLE_E_NV 0x8527 +#define GL_VARIABLE_F_NV 0x8528 +#define GL_VARIABLE_G_NV 0x8529 +#define GL_CONSTANT_COLOR0_NV 0x852A +#define GL_CONSTANT_COLOR1_NV 0x852B +#define GL_PRIMARY_COLOR_NV 0x852C +#define GL_SECONDARY_COLOR_NV 0x852D +#define GL_SPARE0_NV 0x852E +#define GL_SPARE1_NV 0x852F +#define GL_DISCARD_NV 0x8530 +#define GL_E_TIMES_F_NV 0x8531 +#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 +#define GL_UNSIGNED_IDENTITY_NV 0x8536 +#define GL_UNSIGNED_INVERT_NV 0x8537 +#define GL_EXPAND_NORMAL_NV 0x8538 +#define GL_EXPAND_NEGATE_NV 0x8539 +#define GL_HALF_BIAS_NORMAL_NV 0x853A +#define GL_HALF_BIAS_NEGATE_NV 0x853B +#define GL_SIGNED_IDENTITY_NV 0x853C +#define GL_SIGNED_NEGATE_NV 0x853D +#define GL_SCALE_BY_TWO_NV 0x853E +#define GL_SCALE_BY_FOUR_NV 0x853F +#define GL_SCALE_BY_ONE_HALF_NV 0x8540 +#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 +#define GL_COMBINER_INPUT_NV 0x8542 +#define GL_COMBINER_MAPPING_NV 0x8543 +#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 +#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 +#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 +#define GL_COMBINER_MUX_SUM_NV 0x8547 +#define GL_COMBINER_SCALE_NV 0x8548 +#define GL_COMBINER_BIAS_NV 0x8549 +#define GL_COMBINER_AB_OUTPUT_NV 0x854A +#define GL_COMBINER_CD_OUTPUT_NV 0x854B +#define GL_COMBINER_SUM_OUTPUT_NV 0x854C +#define GL_MAX_GENERAL_COMBINERS_NV 0x854D +#define GL_NUM_GENERAL_COMBINERS_NV 0x854E +#define GL_COLOR_SUM_CLAMP_NV 0x854F +#define GL_COMBINER0_NV 0x8550 +#define GL_COMBINER1_NV 0x8551 +#define GL_COMBINER2_NV 0x8552 +#define GL_COMBINER3_NV 0x8553 +#define GL_COMBINER4_NV 0x8554 +#define GL_COMBINER5_NV 0x8555 +#define GL_COMBINER6_NV 0x8556 +#define GL_COMBINER7_NV 0x8557 +/* reuse GL_TEXTURE0_ARB */ +/* reuse GL_TEXTURE1_ARB */ +/* reuse GL_ZERO */ +/* reuse GL_NONE */ +/* reuse GL_FOG */ +#endif + +#ifndef GL_NV_fog_distance +#define GL_FOG_DISTANCE_MODE_NV 0x855A +#define GL_EYE_RADIAL_NV 0x855B +#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C +/* reuse GL_EYE_PLANE */ +#endif + +#ifndef GL_NV_texgen_emboss +#define GL_EMBOSS_LIGHT_NV 0x855D +#define GL_EMBOSS_CONSTANT_NV 0x855E +#define GL_EMBOSS_MAP_NV 0x855F +#endif + +#ifndef GL_NV_blend_square +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_COMBINE4_NV 0x8503 +#define GL_SOURCE3_RGB_NV 0x8583 +#define GL_SOURCE3_ALPHA_NV 0x858B +#define GL_OPERAND3_RGB_NV 0x8593 +#define GL_OPERAND3_ALPHA_NV 0x859B +#endif + +#ifndef GL_MESA_resize_buffers +#endif + +#ifndef GL_MESA_window_pos +#endif + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif + +#ifndef GL_IBM_cull_vertex +#define GL_CULL_VERTEX_IBM 103050 +#endif + +#ifndef GL_IBM_multimode_draw_arrays +#endif + +#ifndef GL_IBM_vertex_array_lists +#define GL_VERTEX_ARRAY_LIST_IBM 103070 +#define GL_NORMAL_ARRAY_LIST_IBM 103071 +#define GL_COLOR_ARRAY_LIST_IBM 103072 +#define GL_INDEX_ARRAY_LIST_IBM 103073 +#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 +#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 +#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 +#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 +#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 +#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 +#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 +#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 +#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 +#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 +#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 +#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 +#endif + +#ifndef GL_SGIX_subsample +#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 +#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 +#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 +#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 +#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 +#endif + +#ifndef GL_SGIX_ycrcb_subsample +#endif + +#ifndef GL_SGIX_ycrcba +#define GL_YCRCB_SGIX 0x8318 +#define GL_YCRCBA_SGIX 0x8319 +#endif + +#ifndef GL_SGI_depth_pass_instrument +#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 +#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 +#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 +#endif + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 +#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 +#endif + +#ifndef GL_3DFX_multisample +#define GL_MULTISAMPLE_3DFX 0x86B2 +#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 +#define GL_SAMPLES_3DFX 0x86B4 +#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 +#endif + +#ifndef GL_3DFX_tbuffer +#endif + +#ifndef GL_EXT_multisample +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#define GL_SAMPLE_MASK_EXT 0x80A0 +#define GL_1PASS_EXT 0x80A1 +#define GL_2PASS_0_EXT 0x80A2 +#define GL_2PASS_1_EXT 0x80A3 +#define GL_4PASS_0_EXT 0x80A4 +#define GL_4PASS_1_EXT 0x80A5 +#define GL_4PASS_2_EXT 0x80A6 +#define GL_4PASS_3_EXT 0x80A7 +#define GL_SAMPLE_BUFFERS_EXT 0x80A8 +#define GL_SAMPLES_EXT 0x80A9 +#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA +#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB +#define GL_SAMPLE_PATTERN_EXT 0x80AC +#endif + +#ifndef GL_SGIX_vertex_preclip +#define GL_VERTEX_PRECLIP_SGIX 0x83EE +#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF +#endif + +#ifndef GL_SGIX_convolution_accuracy +#define GL_CONVOLUTION_HINT_SGIX 0x8316 +#endif + +#ifndef GL_SGIX_resample +#define GL_PACK_RESAMPLE_SGIX 0x842C +#define GL_UNPACK_RESAMPLE_SGIX 0x842D +#define GL_RESAMPLE_REPLICATE_SGIX 0x842E +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F +#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 +#endif + +#ifndef GL_SGIS_point_line_texgen +#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 +#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 +#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 +#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 +#define GL_EYE_POINT_SGIS 0x81F4 +#define GL_OBJECT_POINT_SGIS 0x81F5 +#define GL_EYE_LINE_SGIS 0x81F6 +#define GL_OBJECT_LINE_SGIS 0x81F7 +#endif + +#ifndef GL_SGIS_texture_color_mask +#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF +#endif + + +/*************************************************************/ + +#ifndef GL_VERSION_1_2 + /* #define GL_VERSION_1_2 1, I am not sure about this one */ + +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlendColor (GLclampf, GLclampf, GLclampf, GLclampf); +extern void APIENTRY glBlendEquation (GLenum); +extern void APIENTRY glDrawRangeElements (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); +extern void APIENTRY glColorTable (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glColorTableParameterfv (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glColorTableParameteriv (GLenum, GLenum, const GLint *); +extern void APIENTRY glCopyColorTable (GLenum, GLenum, GLint, GLint, GLsizei); +extern void APIENTRY glGetColorTable (GLenum, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetColorTableParameterfv (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetColorTableParameteriv (GLenum, GLenum, GLint *); +extern void APIENTRY glColorSubTable (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glCopyColorSubTable (GLenum, GLsizei, GLint, GLint, GLsizei); +extern void APIENTRY glConvolutionFilter1D (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glConvolutionFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glConvolutionParameterf (GLenum, GLenum, GLfloat); +extern void APIENTRY glConvolutionParameterfv (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glConvolutionParameteri (GLenum, GLenum, GLint); +extern void APIENTRY glConvolutionParameteriv (GLenum, GLenum, const GLint *); +extern void APIENTRY glCopyConvolutionFilter1D (GLenum, GLenum, GLint, GLint, GLsizei); +extern void APIENTRY glCopyConvolutionFilter2D (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); +extern void APIENTRY glGetConvolutionFilter (GLenum, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetConvolutionParameterfv (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetConvolutionParameteriv (GLenum, GLenum, GLint *); +extern void APIENTRY glGetSeparableFilter (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); +extern void APIENTRY glSeparableFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); +extern void APIENTRY glGetHistogram (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetHistogramParameterfv (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetHistogramParameteriv (GLenum, GLenum, GLint *); +extern void APIENTRY glGetMinmax (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetMinmaxParameterfv (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetMinmaxParameteriv (GLenum, GLenum, GLint *); +extern void APIENTRY glHistogram (GLenum, GLsizei, GLenum, GLboolean); +extern void APIENTRY glMinmax (GLenum, GLenum, GLboolean); +extern void APIENTRY glResetHistogram (GLenum); +extern void APIENTRY glResetMinmax (GLenum); +extern void APIENTRY glTexImage3D (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glCopyTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (APIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (APIENTRY * PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (APIENTRY * PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRY * PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRY * PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (APIENTRY * PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +typedef void (APIENTRY * PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRY * PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRY * PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRY * PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRY * PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (APIENTRY * PFNGLRESETMINMAXPROC) (GLenum target); +typedef void (APIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_ARB_multitexture +#define GL_ARB_multitexture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glActiveTextureARB (GLenum); +extern void APIENTRY glClientActiveTextureARB (GLenum); +extern void APIENTRY glMultiTexCoord1dARB (GLenum, GLdouble); +extern void APIENTRY glMultiTexCoord1dvARB (GLenum, const GLdouble *); +extern void APIENTRY glMultiTexCoord1fARB (GLenum, GLfloat); +extern void APIENTRY glMultiTexCoord1fvARB (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord1iARB (GLenum, GLint); +extern void APIENTRY glMultiTexCoord1ivARB (GLenum, const GLint *); +extern void APIENTRY glMultiTexCoord1sARB (GLenum, GLshort); +extern void APIENTRY glMultiTexCoord1svARB (GLenum, const GLshort *); +extern void APIENTRY glMultiTexCoord2dARB (GLenum, GLdouble, GLdouble); +extern void APIENTRY glMultiTexCoord2dvARB (GLenum, const GLdouble *); +extern void APIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat); +extern void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord2iARB (GLenum, GLint, GLint); +extern void APIENTRY glMultiTexCoord2ivARB (GLenum, const GLint *); +extern void APIENTRY glMultiTexCoord2sARB (GLenum, GLshort, GLshort); +extern void APIENTRY glMultiTexCoord2svARB (GLenum, const GLshort *); +extern void APIENTRY glMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glMultiTexCoord3dvARB (GLenum, const GLdouble *); +extern void APIENTRY glMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord3iARB (GLenum, GLint, GLint, GLint); +extern void APIENTRY glMultiTexCoord3ivARB (GLenum, const GLint *); +extern void APIENTRY glMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort); +extern void APIENTRY glMultiTexCoord3svARB (GLenum, const GLshort *); +extern void APIENTRY glMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glMultiTexCoord4dvARB (GLenum, const GLdouble *); +extern void APIENTRY glMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *); +extern void APIENTRY glMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint); +extern void APIENTRY glMultiTexCoord4ivARB (GLenum, const GLint *); +extern void APIENTRY glMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort); +extern void APIENTRY glMultiTexCoord4svARB (GLenum, const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (APIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (APIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (APIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (APIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); +#endif + +#ifndef GL_ARB_transpose_matrix +#define GL_ARB_transpose_matrix 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *); +extern void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *); +extern void APIENTRY glMultTransposeMatrixfARB (const GLfloat *); +extern void APIENTRY glMultTransposeMatrixdARB (const GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRY * PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +typedef void (APIENTRY * PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); +typedef void (APIENTRY * PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); +#endif + +#ifndef GL_ARB_multisample +#define GL_ARB_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSampleCoverageARB (GLclampf, GLboolean); +extern void APIENTRY glSamplePassARB (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRY * PFNGLSAMPLEPASSARBPROC) (GLenum pass); +#endif + +#ifndef GL_ARB_texture_env_add +#define GL_ARB_texture_env_add 1 +#endif + +#ifndef GL_ARB_texture_cube_map +#define GL_ARB_texture_cube_map 1 +#endif + +#ifndef GL_ARB_texture_compression +#define GL_ARB_texture_compression 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glCompressedTexImage3DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexImage2DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexImage1DARB (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexSubImage3DARB (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexSubImage2DARB (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glCompressedTexSubImage1DARB (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glGetCompressedTexImageARB (GLenum, GLint, void *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, void *img); +#endif + +#ifndef GL_EXT_abgr +#define GL_EXT_abgr 1 +#endif + +#ifndef GL_EXT_blend_color +#define GL_EXT_blend_color 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlendColorEXT (GLclampf, GLclampf, GLclampf, GLclampf); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPolygonOffsetEXT (GLfloat, GLfloat); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); +#endif + +#ifndef GL_EXT_texture +#define GL_EXT_texture 1 +#endif + +#ifndef GL_EXT_texture3D +#define GL_EXT_texture3D 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTexImage3DEXT (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_SGIS_texture_filter4 +#define GL_SGIS_texture_filter4 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGetTexFilterFuncSGIS (GLenum, GLenum, GLfloat *); +extern void APIENTRY glTexFilterFuncSGIS (GLenum, GLenum, GLsizei, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); +typedef void (APIENTRY * PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); +#endif + +#ifndef GL_EXT_subtexture +#define GL_EXT_subtexture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTexSubImage1DEXT (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_EXT_copy_texture +#define GL_EXT_copy_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glCopyTexImage1DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); +extern void APIENTRY glCopyTexImage2DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); +extern void APIENTRY glCopyTexSubImage1DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei); +extern void APIENTRY glCopyTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +extern void APIENTRY glCopyTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (APIENTRY * PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (APIENTRY * PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRY * PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_EXT_histogram +#define GL_EXT_histogram 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGetHistogramEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetHistogramParameterfvEXT (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetHistogramParameterivEXT (GLenum, GLenum, GLint *); +extern void APIENTRY glGetMinmaxEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetMinmaxParameterfvEXT (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetMinmaxParameterivEXT (GLenum, GLenum, GLint *); +extern void APIENTRY glHistogramEXT (GLenum, GLsizei, GLenum, GLboolean); +extern void APIENTRY glMinmaxEXT (GLenum, GLenum, GLboolean); +extern void APIENTRY glResetHistogramEXT (GLenum); +extern void APIENTRY glResetMinmaxEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRY * PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (APIENTRY * PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (APIENTRY * PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (APIENTRY * PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); +typedef void (APIENTRY * PFNGLRESETMINMAXEXTPROC) (GLenum target); +#endif + +#ifndef GL_EXT_convolution +#define GL_EXT_convolution 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glConvolutionFilter1DEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glConvolutionFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glConvolutionParameterfEXT (GLenum, GLenum, GLfloat); +extern void APIENTRY glConvolutionParameterfvEXT (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glConvolutionParameteriEXT (GLenum, GLenum, GLint); +extern void APIENTRY glConvolutionParameterivEXT (GLenum, GLenum, const GLint *); +extern void APIENTRY glCopyConvolutionFilter1DEXT (GLenum, GLenum, GLint, GLint, GLsizei); +extern void APIENTRY glCopyConvolutionFilter2DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); +extern void APIENTRY glGetConvolutionFilterEXT (GLenum, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetConvolutionParameterfvEXT (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetConvolutionParameterivEXT (GLenum, GLenum, GLint *); +extern void APIENTRY glGetSeparableFilterEXT (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); +extern void APIENTRY glSeparableFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRY * PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); +typedef void (APIENTRY * PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef void (APIENTRY * PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +#endif + +#ifndef GL_EXT_color_matrix +#define GL_EXT_color_matrix 1 +#endif + +#ifndef GL_SGI_color_table +#define GL_SGI_color_table 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glColorTableSGI (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glColorTableParameterfvSGI (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glColorTableParameterivSGI (GLenum, GLenum, const GLint *); +extern void APIENTRY glCopyColorTableSGI (GLenum, GLenum, GLint, GLint, GLsizei); +extern void APIENTRY glGetColorTableSGI (GLenum, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetColorTableParameterfvSGI (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetColorTableParameterivSGI (GLenum, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRY * PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (APIENTRY * PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); +#endif + +#ifndef GL_SGIX_pixel_texture +#define GL_SGIX_pixel_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPixelTexGenSGIX (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); +#endif + +#ifndef GL_SGIS_pixel_texture +#define GL_SGIS_pixel_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPixelTexGenParameteriSGIS (GLenum, GLint); +extern void APIENTRY glPixelTexGenParameterivSGIS (GLenum, const GLint *); +extern void APIENTRY glPixelTexGenParameterfSGIS (GLenum, GLfloat); +extern void APIENTRY glPixelTexGenParameterfvSGIS (GLenum, const GLfloat *); +extern void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum, GLint *); +extern void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); +#endif + +#ifndef GL_SGIS_texture4D +#define GL_SGIS_texture4D 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTexImage4DSGIS (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glTexSubImage4DSGIS (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRY * PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); +#endif + +#ifndef GL_SGI_texture_color_table +#define GL_SGI_texture_color_table 1 +#endif + +#ifndef GL_EXT_cmyka +#define GL_EXT_cmyka 1 +#endif + +#ifndef GL_EXT_texture_object +#define GL_EXT_texture_object 1 +#ifdef GL_GLEXT_PROTOTYPES +extern GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei, const GLuint *, GLboolean *); +extern void APIENTRY glBindTextureEXT (GLenum, GLuint); +extern void APIENTRY glDeleteTexturesEXT (GLsizei, const GLuint *); +extern void APIENTRY glGenTexturesEXT (GLsizei, GLuint *); +extern GLboolean APIENTRY glIsTextureEXT (GLuint); +extern void APIENTRY glPrioritizeTexturesEXT (GLsizei, const GLuint *, const GLclampf *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLboolean (APIENTRY * PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); +typedef void (APIENTRY * PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (APIENTRY * PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); +typedef void (APIENTRY * PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); +typedef GLboolean (APIENTRY * PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef void (APIENTRY * PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); +#endif + +#ifndef GL_SGIS_detail_texture +#define GL_SGIS_detail_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glDetailTexFuncSGIS (GLenum, GLsizei, const GLfloat *); +extern void APIENTRY glGetDetailTexFuncSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRY * PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#endif + +#ifndef GL_SGIS_sharpen_texture +#define GL_SGIS_sharpen_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSharpenTexFuncSGIS (GLenum, GLsizei, const GLfloat *); +extern void APIENTRY glGetSharpenTexFuncSGIS (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); +typedef void (APIENTRY * PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); +#endif + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 +#endif + +#ifndef GL_SGIS_texture_lod +#define GL_SGIS_texture_lod 1 +#endif + +#ifndef GL_SGIS_multisample +#define GL_SGIS_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSampleMaskSGIS (GLclampf, GLboolean); +extern void APIENTRY glSamplePatternSGIS (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRY * PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); +#endif + +#ifndef GL_EXT_rescale_normal +#define GL_EXT_rescale_normal 1 +#endif + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glArrayElementEXT (GLint); +extern void APIENTRY glColorPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +extern void APIENTRY glDrawArraysEXT (GLenum, GLint, GLsizei); +extern void APIENTRY glEdgeFlagPointerEXT (GLsizei, GLsizei, const GLboolean *); +extern void APIENTRY glGetPointervEXT (GLenum, GLvoid* *); +extern void APIENTRY glIndexPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); +extern void APIENTRY glNormalPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); +extern void APIENTRY glTexCoordPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +extern void APIENTRY glVertexPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (APIENTRY * PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRY * PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); +typedef void (APIENTRY * PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params); +typedef void (APIENTRY * PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_misc_attribute +#define GL_EXT_misc_attribute 1 +#endif + +#ifndef GL_SGIS_generate_mipmap +#define GL_SGIS_generate_mipmap 1 +#endif + +#ifndef GL_SGIX_clipmap +#define GL_SGIX_clipmap 1 +#endif + +#ifndef GL_SGIX_shadow +#define GL_SGIX_shadow 1 +#endif + +#ifndef GL_SGIS_texture_edge_clamp +#define GL_SGIS_texture_edge_clamp 1 +#endif + +#ifndef GL_SGIS_texture_border_clamp +#define GL_SGIS_texture_border_clamp 1 +#endif + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlendEquationEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); +#endif + +#ifndef GL_EXT_blend_subtract +#define GL_EXT_blend_subtract 1 +#endif + +#ifndef GL_EXT_blend_logic_op +#define GL_EXT_blend_logic_op 1 +#endif + +#ifndef GL_SGIX_interlace +#define GL_SGIX_interlace 1 +#endif + +#ifndef GL_SGIX_pixel_tiles +#define GL_SGIX_pixel_tiles 1 +#endif + +#ifndef GL_SGIX_texture_select +#define GL_SGIX_texture_select 1 +#endif + +#ifndef GL_SGIX_sprite +#define GL_SGIX_sprite 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSpriteParameterfSGIX (GLenum, GLfloat); +extern void APIENTRY glSpriteParameterfvSGIX (GLenum, const GLfloat *); +extern void APIENTRY glSpriteParameteriSGIX (GLenum, GLint); +extern void APIENTRY glSpriteParameterivSGIX (GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); +#endif + +#ifndef GL_SGIX_texture_multi_buffer +#define GL_SGIX_texture_multi_buffer 1 +#endif + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPointParameterfEXT (GLenum, GLfloat); +extern void APIENTRY glPointParameterfvEXT (GLenum, const GLfloat *); +extern void APIENTRY glPointParameterfSGIS (GLenum, GLfloat); +extern void APIENTRY glPointParameterfvSGIS (GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_SGIX_instruments +#define GL_SGIX_instruments 1 +#ifdef GL_GLEXT_PROTOTYPES +extern GLint APIENTRY glGetInstrumentsSGIX (void); +extern void APIENTRY glInstrumentsBufferSGIX (GLsizei, GLint *); +extern GLint APIENTRY glPollInstrumentsSGIX (GLint *); +extern void APIENTRY glReadInstrumentsSGIX (GLint); +extern void APIENTRY glStartInstrumentsSGIX (void); +extern void APIENTRY glStopInstrumentsSGIX (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef GLint (APIENTRY * PFNGLGETINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRY * PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); +typedef GLint (APIENTRY * PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); +typedef void (APIENTRY * PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); +typedef void (APIENTRY * PFNGLSTARTINSTRUMENTSSGIXPROC) (void); +typedef void (APIENTRY * PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); +#endif + +#ifndef GL_SGIX_texture_scale_bias +#define GL_SGIX_texture_scale_bias 1 +#endif + +#ifndef GL_SGIX_framezoom +#define GL_SGIX_framezoom 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFrameZoomSGIX (GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFRAMEZOOMSGIXPROC) (GLint factor); +#endif + +#ifndef GL_SGIX_tag_sample_buffer +#define GL_SGIX_tag_sample_buffer 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTagSampleBufferSGIX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); +#endif + +#ifndef GL_SGIX_polynomial_ffd +#define GL_SGIX_polynomial_ffd 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glDeformationMap3dSGIX (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *); +extern void APIENTRY glDeformationMap3fSGIX (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *); +extern void APIENTRY glDeformSGIX (GLbitfield); +extern void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); +typedef void (APIENTRY * PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); +typedef void (APIENTRY * PFNGLDEFORMSGIXPROC) (GLbitfield mask); +typedef void (APIENTRY * PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); +#endif + +#ifndef GL_SGIX_reference_plane +#define GL_SGIX_reference_plane 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glReferencePlaneSGIX (const GLdouble *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); +#endif + +#ifndef GL_SGIX_flush_raster +#define GL_SGIX_flush_raster 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFlushRasterSGIX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFLUSHRASTERSGIXPROC) (void); +#endif + +#ifndef GL_SGIX_depth_texture +#define GL_SGIX_depth_texture 1 +#endif + +#ifndef GL_SGIS_fog_function +#define GL_SGIS_fog_function 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFogFuncSGIS (GLsizei, const GLfloat *); +extern void APIENTRY glGetFogFuncSGIS (const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); +typedef void (APIENTRY * PFNGLGETFOGFUNCSGISPROC) (const GLfloat *points); +#endif + +#ifndef GL_SGIX_fog_offset +#define GL_SGIX_fog_offset 1 +#endif + +#ifndef GL_HP_image_transform +#define GL_HP_image_transform 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glImageTransformParameteriHP (GLenum, GLenum, GLint); +extern void APIENTRY glImageTransformParameterfHP (GLenum, GLenum, GLfloat); +extern void APIENTRY glImageTransformParameterivHP (GLenum, GLenum, const GLint *); +extern void APIENTRY glImageTransformParameterfvHP (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glGetImageTransformParameterivHP (GLenum, GLenum, GLint *); +extern void APIENTRY glGetImageTransformParameterfvHP (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_HP_convolution_border_modes +#define GL_HP_convolution_border_modes 1 +#endif + +#ifndef GL_SGIX_texture_add_env +#define GL_SGIX_texture_add_env 1 +#endif + +#ifndef GL_EXT_color_subtable +#define GL_EXT_color_subtable 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glColorSubTableEXT (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glCopyColorSubTableEXT (GLenum, GLsizei, GLint, GLint, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (APIENTRY * PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +#endif + +#ifndef GL_PGI_vertex_hints +#define GL_PGI_vertex_hints 1 +#endif + +#ifndef GL_PGI_misc_hints +#define GL_PGI_misc_hints 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glHintPGI (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLHINTPGIPROC) (GLenum target, GLint mode); +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_EXT_paletted_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glColorTableEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); +extern void APIENTRY glGetColorTableEXT (GLenum, GLenum, GLenum, GLvoid *); +extern void APIENTRY glGetColorTableParameterivEXT (GLenum, GLenum, GLint *); +extern void APIENTRY glGetColorTableParameterfvEXT (GLenum, GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (APIENTRY * PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); +#endif + +#ifndef GL_EXT_clip_volume_hint +#define GL_EXT_clip_volume_hint 1 +#endif + +#ifndef GL_SGIX_list_priority +#define GL_SGIX_list_priority 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGetListParameterfvSGIX (GLuint, GLenum, GLfloat *); +extern void APIENTRY glGetListParameterivSGIX (GLuint, GLenum, GLint *); +extern void APIENTRY glListParameterfSGIX (GLuint, GLenum, GLfloat); +extern void APIENTRY glListParameterfvSGIX (GLuint, GLenum, const GLfloat *); +extern void APIENTRY glListParameteriSGIX (GLuint, GLenum, GLint); +extern void APIENTRY glListParameterivSGIX (GLuint, GLenum, const GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); +#endif + +#ifndef GL_SGIX_ir_instrument1 +#define GL_SGIX_ir_instrument1 1 +#endif + +#ifndef GL_SGIX_calligraphic_fragment +#define GL_SGIX_calligraphic_fragment 1 +#endif + +#ifndef GL_SGIX_texture_lod_bias +#define GL_SGIX_texture_lod_bias 1 +#endif + +#ifndef GL_SGIX_shadow_ambient +#define GL_SGIX_shadow_ambient 1 +#endif + +#ifndef GL_EXT_index_texture +#define GL_EXT_index_texture 1 +#endif + +#ifndef GL_EXT_index_material +#define GL_EXT_index_material 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glIndexMaterialEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); +#endif + +#ifndef GL_EXT_index_func +#define GL_EXT_index_func 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glIndexFuncEXT (GLenum, GLclampf); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); +#endif + +#ifndef GL_EXT_index_array_formats +#define GL_EXT_index_array_formats 1 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glLockArraysEXT (GLint, GLsizei); +extern void APIENTRY glUnlockArraysEXT (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void); +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glCullParameterdvEXT (GLenum, GLdouble *); +extern void APIENTRY glCullParameterfvEXT (GLenum, GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); +typedef void (APIENTRY * PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); +#endif + +#ifndef GL_SGIX_ycrcb +#define GL_SGIX_ycrcb 1 +#endif + +#ifndef GL_SGIX_fragment_lighting +#define GL_SGIX_fragment_lighting 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFragmentColorMaterialSGIX (GLenum, GLenum); +extern void APIENTRY glFragmentLightfSGIX (GLenum, GLenum, GLfloat); +extern void APIENTRY glFragmentLightfvSGIX (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glFragmentLightiSGIX (GLenum, GLenum, GLint); +extern void APIENTRY glFragmentLightivSGIX (GLenum, GLenum, const GLint *); +extern void APIENTRY glFragmentLightModelfSGIX (GLenum, GLfloat); +extern void APIENTRY glFragmentLightModelfvSGIX (GLenum, const GLfloat *); +extern void APIENTRY glFragmentLightModeliSGIX (GLenum, GLint); +extern void APIENTRY glFragmentLightModelivSGIX (GLenum, const GLint *); +extern void APIENTRY glFragmentMaterialfSGIX (GLenum, GLenum, GLfloat); +extern void APIENTRY glFragmentMaterialfvSGIX (GLenum, GLenum, const GLfloat *); +extern void APIENTRY glFragmentMaterialiSGIX (GLenum, GLenum, GLint); +extern void APIENTRY glFragmentMaterialivSGIX (GLenum, GLenum, const GLint *); +extern void APIENTRY glGetFragmentLightfvSGIX (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetFragmentLightivSGIX (GLenum, GLenum, GLint *); +extern void APIENTRY glGetFragmentMaterialfvSGIX (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetFragmentMaterialivSGIX (GLenum, GLenum, GLint *); +extern void APIENTRY glLightEnviSGIX (GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); +#endif + +#ifndef GL_IBM_rasterpos_clip +#define GL_IBM_rasterpos_clip 1 +#endif + +#ifndef GL_HP_texture_lighting +#define GL_HP_texture_lighting 1 +#endif + +#ifndef GL_EXT_draw_range_elements +#define GL_EXT_draw_range_elements 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glDrawRangeElementsEXT (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +#endif + +#ifndef GL_WIN_phong_shading +#define GL_WIN_phong_shading 1 +#endif + +#ifndef GL_WIN_specular_fog +#define GL_WIN_specular_fog 1 +#endif + +#ifndef GL_EXT_light_texture +#define GL_EXT_light_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glApplyTextureEXT (GLenum); +extern void APIENTRY glTextureLightEXT (GLenum); +extern void APIENTRY glTextureMaterialEXT (GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); +typedef void (APIENTRY * PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); +typedef void (APIENTRY * PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); +#endif + +#ifndef GL_SGIX_blend_alpha_minmax +#define GL_SGIX_blend_alpha_minmax 1 +#endif + +#ifndef GL_EXT_bgra +#define GL_EXT_bgra 1 +#endif + +#ifndef GL_SGIX_async +#define GL_SGIX_async 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glAsyncMarkerSGIX (GLuint); +extern GLint APIENTRY glFinishAsyncSGIX (GLuint *); +extern GLint APIENTRY glPollAsyncSGIX (GLuint *); +extern GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei); +extern void APIENTRY glDeleteAsyncMarkersSGIX (GLuint, GLsizei); +extern GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLASYNCMARKERSGIXPROC) (GLuint marker); +typedef GLint (APIENTRY * PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); +typedef GLint (APIENTRY * PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); +typedef GLuint (APIENTRY * PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); +typedef void (APIENTRY * PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); +typedef GLboolean (APIENTRY * PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); +#endif + +#ifndef GL_SGIX_async_pixel +#define GL_SGIX_async_pixel 1 +#endif + +#ifndef GL_SGIX_async_histogram +#define GL_SGIX_async_histogram 1 +#endif + +#ifndef GL_INTEL_parallel_arrays +#define GL_INTEL_parallel_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glVertexPointervINTEL (GLint, GLenum, const GLvoid* *); +extern void APIENTRY glNormalPointervINTEL (GLenum, const GLvoid* *); +extern void APIENTRY glColorPointervINTEL (GLint, GLenum, const GLvoid* *); +extern void APIENTRY glTexCoordPointervINTEL (GLint, GLenum, const GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +typedef void (APIENTRY * PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer); +typedef void (APIENTRY * PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +typedef void (APIENTRY * PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); +#endif + +#ifndef GL_HP_occlusion_test +#define GL_HP_occlusion_test 1 +#endif + +#ifndef GL_EXT_pixel_transform +#define GL_EXT_pixel_transform 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glPixelTransformParameteriEXT (GLenum, GLenum, GLint); +extern void APIENTRY glPixelTransformParameterfEXT (GLenum, GLenum, GLfloat); +extern void APIENTRY glPixelTransformParameterivEXT (GLenum, GLenum, const GLint *); +extern void APIENTRY glPixelTransformParameterfvEXT (GLenum, GLenum, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); +#endif + +#ifndef GL_EXT_pixel_transform_color_table +#define GL_EXT_pixel_transform_color_table 1 +#endif + +#ifndef GL_EXT_shared_texture_palette +#define GL_EXT_shared_texture_palette 1 +#endif + +#ifndef GL_EXT_separate_specular_color +#define GL_EXT_separate_specular_color 1 +#endif + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSecondaryColor3bEXT (GLbyte, GLbyte, GLbyte); +extern void APIENTRY glSecondaryColor3bvEXT (const GLbyte *); +extern void APIENTRY glSecondaryColor3dEXT (GLdouble, GLdouble, GLdouble); +extern void APIENTRY glSecondaryColor3dvEXT (const GLdouble *); +extern void APIENTRY glSecondaryColor3fEXT (GLfloat, GLfloat, GLfloat); +extern void APIENTRY glSecondaryColor3fvEXT (const GLfloat *); +extern void APIENTRY glSecondaryColor3iEXT (GLint, GLint, GLint); +extern void APIENTRY glSecondaryColor3ivEXT (const GLint *); +extern void APIENTRY glSecondaryColor3sEXT (GLshort, GLshort, GLshort); +extern void APIENTRY glSecondaryColor3svEXT (const GLshort *); +extern void APIENTRY glSecondaryColor3ubEXT (GLubyte, GLubyte, GLubyte); +extern void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *); +extern void APIENTRY glSecondaryColor3uiEXT (GLuint, GLuint, GLuint); +extern void APIENTRY glSecondaryColor3uivEXT (const GLuint *); +extern void APIENTRY glSecondaryColor3usEXT (GLushort, GLushort, GLushort); +extern void APIENTRY glSecondaryColor3usvEXT (const GLushort *); +extern void APIENTRY glSecondaryColorPointerEXT (GLint, GLenum, GLsizei, GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (APIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); +typedef void (APIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer); +#endif + +#ifndef GL_EXT_texture_perturb_normal +#define GL_EXT_texture_perturb_normal 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTextureNormalEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTEXTURENORMALEXTPROC) (GLenum mode); +#endif + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei); +extern void APIENTRY glMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); +typedef void (APIENTRY * PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); +#endif + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFogCoordfEXT (GLfloat); +extern void APIENTRY glFogCoordfvEXT (const GLfloat *); +extern void APIENTRY glFogCoorddEXT (GLdouble); +extern void APIENTRY glFogCoorddvEXT (const GLdouble *); +extern void APIENTRY glFogCoordPointerEXT (GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (APIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); +typedef void (APIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (APIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); +typedef void (APIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_REND_screen_coordinates +#define GL_REND_screen_coordinates 1 +#endif + +#ifndef GL_EXT_coordinate_frame +#define GL_EXT_coordinate_frame 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTangent3bEXT (GLbyte, GLbyte, GLbyte); +extern void APIENTRY glTangent3bvEXT (const GLbyte *); +extern void APIENTRY glTangent3dEXT (GLdouble, GLdouble, GLdouble); +extern void APIENTRY glTangent3dvEXT (const GLdouble *); +extern void APIENTRY glTangent3fEXT (GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTangent3fvEXT (const GLfloat *); +extern void APIENTRY glTangent3iEXT (GLint, GLint, GLint); +extern void APIENTRY glTangent3ivEXT (const GLint *); +extern void APIENTRY glTangent3sEXT (GLshort, GLshort, GLshort); +extern void APIENTRY glTangent3svEXT (const GLshort *); +extern void APIENTRY glBinormal3bEXT (GLbyte, GLbyte, GLbyte); +extern void APIENTRY glBinormal3bvEXT (const GLbyte *); +extern void APIENTRY glBinormal3dEXT (GLdouble, GLdouble, GLdouble); +extern void APIENTRY glBinormal3dvEXT (const GLdouble *); +extern void APIENTRY glBinormal3fEXT (GLfloat, GLfloat, GLfloat); +extern void APIENTRY glBinormal3fvEXT (const GLfloat *); +extern void APIENTRY glBinormal3iEXT (GLint, GLint, GLint); +extern void APIENTRY glBinormal3ivEXT (const GLint *); +extern void APIENTRY glBinormal3sEXT (GLshort, GLshort, GLshort); +extern void APIENTRY glBinormal3svEXT (const GLshort *); +extern void APIENTRY glTangentPointerEXT (GLenum, GLsizei, const GLvoid *); +extern void APIENTRY glBinormalPointerEXT (GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); +typedef void (APIENTRY * PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRY * PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); +typedef void (APIENTRY * PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); +typedef void (APIENTRY * PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); +typedef void (APIENTRY * PFNGLTANGENT3IVEXTPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); +typedef void (APIENTRY * PFNGLTANGENT3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); +typedef void (APIENTRY * PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); +typedef void (APIENTRY * PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); +typedef void (APIENTRY * PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); +typedef void (APIENTRY * PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); +typedef void (APIENTRY * PFNGLBINORMAL3IVEXTPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); +typedef void (APIENTRY * PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRY * PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_EXT_texture_env_combine +#define GL_EXT_texture_env_combine 1 +#endif + +#ifndef GL_APPLE_specular_vector +#define GL_APPLE_specular_vector 1 +#endif + +#ifndef GL_APPLE_transform_hint +#define GL_APPLE_transform_hint 1 +#endif + +#ifndef GL_SGIX_fog_scale +#define GL_SGIX_fog_scale 1 +#endif + +#ifndef GL_SUNX_constant_data +#define GL_SUNX_constant_data 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFinishTextureSUNX (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFINISHTEXTURESUNXPROC) (void); +#endif + +#ifndef GL_SUN_global_alpha +#define GL_SUN_global_alpha 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glGlobalAlphaFactorbSUN (GLbyte); +extern void APIENTRY glGlobalAlphaFactorsSUN (GLshort); +extern void APIENTRY glGlobalAlphaFactoriSUN (GLint); +extern void APIENTRY glGlobalAlphaFactorfSUN (GLfloat); +extern void APIENTRY glGlobalAlphaFactordSUN (GLdouble); +extern void APIENTRY glGlobalAlphaFactorubSUN (GLubyte); +extern void APIENTRY glGlobalAlphaFactorusSUN (GLushort); +extern void APIENTRY glGlobalAlphaFactoruiSUN (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); +typedef void (APIENTRY * PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); +#endif + +#ifndef GL_SUN_triangle_list +#define GL_SUN_triangle_list 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glReplacementCodeuiSUN (GLuint); +extern void APIENTRY glReplacementCodeusSUN (GLushort); +extern void APIENTRY glReplacementCodeubSUN (GLubyte); +extern void APIENTRY glReplacementCodeuivSUN (const GLuint *); +extern void APIENTRY glReplacementCodeusvSUN (const GLushort *); +extern void APIENTRY glReplacementCodeubvSUN (const GLubyte *); +extern void APIENTRY glReplacementCodePointerSUN (GLenum, GLsizei, const GLvoid* *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer); +#endif + +#ifndef GL_SUN_vertex +#define GL_SUN_vertex 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glColor4ubVertex2fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat); +extern void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *, const GLfloat *); +extern void APIENTRY glColor4ubVertex3fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *, const GLfloat *); +extern void APIENTRY glColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glColor3fVertex3fvSUN (const GLfloat *, const GLfloat *); +extern void APIENTRY glNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *); +extern void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord2fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord4fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *, const GLubyte *, const GLfloat *); +extern void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLenum *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLenum, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLenum *, const GLubyte *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *, const GLfloat *); +extern void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLenum, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLenum *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); +typedef void (APIENTRY * PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLenum rc, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLenum rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLenum *rc, const GLubyte *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLenum rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *c, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLenum rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLenum rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLenum rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *tc, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLenum rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLenum rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLenum *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glBlendFuncSeparateEXT (GLenum, GLenum, GLenum, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +#endif + +#ifndef GL_INGR_color_clamp +#define GL_INGR_color_clamp 1 +#endif + +#ifndef GL_INGR_interlace_read +#define GL_INGR_interlace_read 1 +#endif + +#ifndef GL_EXT_stencil_wrap +#define GL_EXT_stencil_wrap 1 +#endif + +#ifndef GL_EXT_422_pixels +#define GL_EXT_422_pixels 1 +#endif + +#ifndef GL_NV_texgen_reflection +#define GL_NV_texgen_reflection 1 +#endif + +#ifndef GL_SUN_convolution_border_modes +#define GL_SUN_convolution_border_modes 1 +#endif + +#ifndef GL_EXT_texture_env_add +#define GL_EXT_texture_env_add 1 +#endif + +#ifndef GL_EXT_texture_lod_bias +#define GL_EXT_texture_lod_bias 1 +#endif + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#endif + +#ifndef GL_EXT_vertex_weighting +#define GL_EXT_vertex_weighting 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glVertexWeightfEXT (GLfloat); +extern void APIENTRY glVertexWeightfvEXT (const GLfloat *); +extern void APIENTRY glVertexWeightPointerEXT (GLsizei, GLenum, GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); +typedef void (APIENTRY * PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); +typedef void (APIENTRY * PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_NV_light_max_exponent +#define GL_NV_light_max_exponent 1 +#endif + +#ifndef GL_NV_vertex_array_range +#define GL_NV_vertex_array_range 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glFlushVertexArrayRangeNV (void); +extern void APIENTRY glVertexArrayRangeNV (GLsizei, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); +typedef void (APIENTRY * PFNGLVERTEXARRAYRANGENVPROC) (GLsizei size, const GLvoid *pointer); +#endif + +#ifndef GL_NV_register_combiners +#define GL_NV_register_combiners 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glCombinerParameterfvNV (GLenum, const GLfloat *); +extern void APIENTRY glCombinerParameterfNV (GLenum, GLfloat); +extern void APIENTRY glCombinerParameterivNV (GLenum, const GLint *); +extern void APIENTRY glCombinerParameteriNV (GLenum, GLint); +extern void APIENTRY glCombinerInputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum); +extern void APIENTRY glCombinerOutputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean); +extern void APIENTRY glFinalCombinerInputNV (GLenum, GLenum, GLenum, GLenum); +extern void APIENTRY glGetCombinerInputParameterfvNV (GLenum, GLenum, GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetCombinerInputParameterivNV (GLenum, GLenum, GLenum, GLenum, GLint *); +extern void APIENTRY glGetCombinerOutputParameterfvNV (GLenum, GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetCombinerOutputParameterivNV (GLenum, GLenum, GLenum, GLint *); +extern void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum, GLenum, GLfloat *); +extern void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum, GLenum, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRY * PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRY * PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); +typedef void (APIENTRY * PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (APIENTRY * PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRY * PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (APIENTRY * PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (APIENTRY * PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); +typedef void (APIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); +typedef void (APIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); +#endif + +#ifndef GL_NV_fog_distance +#define GL_NV_fog_distance 1 +#endif + +#ifndef GL_NV_texgen_emboss +#define GL_NV_texgen_emboss 1 +#endif + +#ifndef GL_NV_blend_square +#define GL_NV_blend_square 1 +#endif + +#ifndef GL_NV_texture_env_combine4 +#define GL_NV_texture_env_combine4 1 +#endif + +#ifndef GL_MESA_resize_buffers +#define GL_MESA_resize_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glResizeBuffersMESA (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLRESIZEBUFFERSMESAPROC) (void); +#endif + +#ifndef GL_MESA_window_pos +#define GL_MESA_window_pos 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glWindowPos2dMESA (GLdouble, GLdouble); +extern void APIENTRY glWindowPos2dvMESA (const GLdouble *); +extern void APIENTRY glWindowPos2fMESA (GLfloat, GLfloat); +extern void APIENTRY glWindowPos2fvMESA (const GLfloat *); +extern void APIENTRY glWindowPos2iMESA (GLint, GLint); +extern void APIENTRY glWindowPos2ivMESA (const GLint *); +extern void APIENTRY glWindowPos2sMESA (GLshort, GLshort); +extern void APIENTRY glWindowPos2svMESA (const GLshort *); +extern void APIENTRY glWindowPos3dMESA (GLdouble, GLdouble, GLdouble); +extern void APIENTRY glWindowPos3dvMESA (const GLdouble *); +extern void APIENTRY glWindowPos3fMESA (GLfloat, GLfloat, GLfloat); +extern void APIENTRY glWindowPos3fvMESA (const GLfloat *); +extern void APIENTRY glWindowPos3iMESA (GLint, GLint, GLint); +extern void APIENTRY glWindowPos3ivMESA (const GLint *); +extern void APIENTRY glWindowPos3sMESA (GLshort, GLshort, GLshort); +extern void APIENTRY glWindowPos3svMESA (const GLshort *); +extern void APIENTRY glWindowPos4dMESA (GLdouble, GLdouble, GLdouble, GLdouble); +extern void APIENTRY glWindowPos4dvMESA (const GLdouble *); +extern void APIENTRY glWindowPos4fMESA (GLfloat, GLfloat, GLfloat, GLfloat); +extern void APIENTRY glWindowPos4fvMESA (const GLfloat *); +extern void APIENTRY glWindowPos4iMESA (GLint, GLint, GLint, GLint); +extern void APIENTRY glWindowPos4ivMESA (const GLint *); +extern void APIENTRY glWindowPos4sMESA (GLshort, GLshort, GLshort, GLshort); +extern void APIENTRY glWindowPos4svMESA (const GLshort *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); +typedef void (APIENTRY * PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); +typedef void (APIENTRY * PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); +typedef void (APIENTRY * PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); +typedef void (APIENTRY * PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRY * PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRY * PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); +typedef void (APIENTRY * PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); +typedef void (APIENTRY * PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); +typedef void (APIENTRY * PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRY * PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); +typedef void (APIENTRY * PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRY * PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); +typedef void (APIENTRY * PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRY * PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); +typedef void (APIENTRY * PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRY * PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); +#endif + +#ifndef GL_IBM_cull_vertex +#define GL_IBM_cull_vertex 1 +#endif + +#ifndef GL_IBM_multimode_draw_arrays +#define GL_IBM_multimode_draw_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glMultiModeDrawArraysIBM (GLenum, const GLint *, const GLsizei *, GLsizei, GLint); +extern void APIENTRY glMultiModeDrawElementsIBM (const GLenum *, const GLsizei *, GLenum, const GLvoid* *, GLsizei, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLMULTIMODEDRAWARRAYSIBMPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); +typedef void (APIENTRY * PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, GLint modestride); +#endif + +#ifndef GL_IBM_vertex_array_lists +#define GL_IBM_vertex_array_lists 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glSecondaryColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glEdgeFlagPointerListIBM (GLint, const GLboolean* *, GLint); +extern void APIENTRY glFogCoordPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glIndexPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glNormalPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glTexCoordPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +extern void APIENTRY glVertexPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +typedef void (APIENTRY * PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); +#endif + +#ifndef GL_SGIX_subsample +#define GL_SGIX_subsample 1 +#endif + +#ifndef GL_SGIX_ycrcba +#define GL_SGIX_ycrcba 1 +#endif + +#ifndef GL_SGIX_ycrcb_subsample +#define GL_SGIX_ycrcb_subsample 1 +#endif + +#ifndef GL_SGIX_depth_pass_instrument +#define GL_SGIX_depth_pass_instrument 1 +#endif + +#ifndef GL_3DFX_texture_compression_FXT1 +#define GL_3DFX_texture_compression_FXT1 1 +#endif + +#ifndef GL_3DFX_multisample +#define GL_3DFX_multisample 1 +#endif + +#ifndef GL_3DFX_tbuffer +#define GL_3DFX_tbuffer 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTbufferMask3DFX (GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); +#endif + +#ifndef GL_EXT_multisample +#define GL_EXT_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glSampleMaskEXT (GLclampf, GLboolean); +extern void APIENTRY glSamplePatternEXT (GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); +typedef void (APIENTRY * PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); +#endif + +#ifndef GL_SGI_vertex_preclip +#define GL_SGI_vertex_preclip 1 +#endif + +#ifndef GL_SGIX_convolution_accuracy +#define GL_SGIX_convolution_accuracy 1 +#endif + +#ifndef GL_SGIX_resample +#define GL_SGIX_resample 1 +#endif + +#ifndef GL_SGIS_point_line_texgen +#define GL_SGIS_point_line_texgen 1 +#endif + +#ifndef GL_SGIS_texture_color_mask +#define GL_SGIS_texture_color_mask 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glTextureColorMaskSGIS (GLboolean, GLboolean, GLboolean, GLboolean); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +#endif + +#ifndef GL_SGIX_igloo_interface +#define GL_SGIX_igloo_interface 1 +#ifdef GL_GLEXT_PROTOTYPES +extern void APIENTRY glIglooInterfaceSGIX (GLenum, const GLvoid *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRY * PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/native/ogl/panoramiXext.h b/src/native/ogl/panoramiXext.h new file mode 100644 index 0000000..b5162a7 --- /dev/null +++ b/src/native/ogl/panoramiXext.h @@ -0,0 +1,102 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Use is subject to license terms. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* $TOG: panoramiXext.h /main/3 1998/02/13 13:08:51 kaleb $ */ +/***************************************************************** + +Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, +BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Digital Equipment Corporation +shall not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from Digital +Equipment Corporation. + +******************************************************************/ +/* + * PanoramiX definitions + */ + +/* THIS IS NOT AN X PROJECT TEAM SPECIFICATION */ + +#define PANORAMIX_MAJOR_VERSION 1 /* current version number */ +#define PANORAMIX_MINOR_VERSION 0 + +typedef struct { + Window window; /* PanoramiX window - may not exist */ + int screen; + int State; /* PanroamiXOff, PanoramiXOn */ + int width; /* width of this screen */ + int height; /* height of this screen */ + int ScreenCount; /* real physical number of screens */ + XID eventMask; /* selected events for this client */ +} XPanoramiXInfo; + +extern XPanoramiXInfo *XPanoramiXAllocInfo ( +#if NeedFunctionPrototypes + void +#endif +); + +#define XINERAMA_PLACE_TOP 1 +#define XINERAMA_PLACE_BOTTOM 2 +#define XINERAMA_PLACE_RIGHT 4 +#define XINERAMA_PLACE_LEFT 8 + +#ifndef _XINERAMAINFO_ +#define _XINERAMAINFO_ + +#define XinID int +#define MAXSCREEN 16 +#define DELTA int +#define POINT int + +typedef struct subwid +{ + XinID wid; /* sub window id */ + DELTA dx,dy; /* delta in screen co-ord from virtual zero */ + POINT x,y; /* location of window in screen co-ord */ + DELTA wdx,wdy;/* size of window in screen co-ord */ +}SubWID, *pSubWID; + +typedef struct xineramainfo +{ + XinID wid; /* Window ID of requested virtual window */ + SubWID subs[MAXSCREEN]; /* there will be 16 slots */ +}XineramaInfo, *pXineramaInfo; +#endif + +#ifndef NO_PROTO_HERE +Bool XDgaGetXineramaInfo( +#if NeedFunctionPrototypes +/* this brakes the server +Display *, int, XID, XineramaInfo * +*/ +#endif +); +#endif diff --git a/src/native/share/build-linux-i586.xml b/src/native/share/build-linux-i586.xml new file mode 100644 index 0000000..8968f9a --- /dev/null +++ b/src/native/share/build-linux-i586.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/native/share/build-solaris-sparc-forte.xml b/src/native/share/build-solaris-sparc-forte.xml new file mode 100644 index 0000000..873cf4b --- /dev/null +++ b/src/native/share/build-solaris-sparc-forte.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/native/share/build-solaris-sparc-gcc.xml b/src/native/share/build-solaris-sparc-gcc.xml new file mode 100644 index 0000000..b3c78e2 --- /dev/null +++ b/src/native/share/build-solaris-sparc-gcc.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/native/share/build-windows-i586-gcc.xml b/src/native/share/build-windows-i586-gcc.xml new file mode 100644 index 0000000..b34144d --- /dev/null +++ b/src/native/share/build-windows-i586-gcc.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/native/share/build-windows-i586-vc.xml b/src/native/share/build-windows-i586-vc.xml new file mode 100644 index 0000000..8b4cde7 --- /dev/null +++ b/src/native/share/build-windows-i586-vc.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3