diff options
Diffstat (limited to 'src/native/ogl/GeometryArrayRetained.c')
-rw-r--r-- | src/native/ogl/GeometryArrayRetained.c | 3599 |
1 files changed, 3599 insertions, 0 deletions
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 <stdio.h> +#include <jni.h> + +#include "gldefs.h" + +#ifdef WIN32 +#include <wingdi.h> + +#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); + } +} + + |