aboutsummaryrefslogtreecommitdiffstats
path: root/src/native/ogl/CgShaderProgram.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/native/ogl/CgShaderProgram.c')
-rw-r--r--src/native/ogl/CgShaderProgram.c1815
1 files changed, 1815 insertions, 0 deletions
diff --git a/src/native/ogl/CgShaderProgram.c b/src/native/ogl/CgShaderProgram.c
new file mode 100644
index 0000000..5e7654b
--- /dev/null
+++ b/src/native/ogl/CgShaderProgram.c
@@ -0,0 +1,1815 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Use is subject to license terms.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+#if defined(LINUX)
+#define _GNU_SOURCE 1
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <jni.h>
+
+#include "gldefs.h"
+#include "CgWrapper.h"
+
+#if defined(UNIX)
+#include <dlfcn.h>
+#endif
+
+
+extern char *strJavaToC(JNIEnv *env, jstring str);
+extern void throwAssert(JNIEnv *env, char *str);
+extern jobject createShaderError(JNIEnv *env,
+ int errorCode,
+ const char *errorMsg,
+ const char *detailMsg);
+
+static void cgVertexAttrPointer(GraphicsContextPropertiesInfo *ctxProperties,
+ int index, int size, int type, int stride,
+ const void *pointer);
+static void cgEnableVertexAttrArray(GraphicsContextPropertiesInfo *ctxProperties,
+ int index);
+static void cgDisableVertexAttrArray(GraphicsContextPropertiesInfo *ctxProperties,
+ int index);
+static void cgVertexAttr(GraphicsContextPropertiesInfo *ctxProperties,
+ int index, const float *v);
+
+
+/* Global CG wrapper info struct, created by MasterControl during initialization */
+static CgWrapperInfo *globalCgWrapperInfo = NULL;
+
+
+/*
+ * Class: javax_media_j3d_MasterControl
+ * Method: loadNativeCgLibrary
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_javax_media_j3d_MasterControl_loadNativeCgLibrary(
+ JNIEnv *env,
+ jclass clazz,
+ jobjectArray libpath)
+{
+ CgWrapperInfo *cgWrapperInfo;
+ int i, pathLen;
+ char *errName = NULL;
+
+#ifdef WIN32
+ DWORD err;
+ LPTSTR errString;
+ UINT origErrorMode;
+#endif /* WIN32 */
+
+ /*
+ * This method is called exactly once to load and initialize the
+ * CG wrapper library.
+ */
+
+ /* Assertion check that we don't get called more than once */
+ if (globalCgWrapperInfo != NULL) {
+ throwAssert(env, "MasterControl.loadNativeCgLibrary called more than once");
+ return JNI_FALSE;
+ }
+
+ /* Allocate global Cg wrapper struct */
+ cgWrapperInfo = (CgWrapperInfo*)malloc(sizeof(CgWrapperInfo));
+ cgWrapperInfo->loaded = JNI_FALSE;
+ cgWrapperInfo->cgLibraryHandle = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+
+ /* Remove the following print statement when the native Cg code is done */
+ fprintf(stderr, "*** JAVA 3D : loading experimental native Cg library\n");
+
+ /* Get number of entries in libpath array */
+ pathLen = (*env)->GetArrayLength(env, libpath);
+ /*fprintf(stderr, "pathLen = %d\n", pathLen);*/
+
+#ifdef UNIX
+
+ for (i = 0; i < pathLen; i++) {
+ jstring libname;
+ char *libnameStr;
+
+ libname = (*env)->GetObjectArrayElement(env, libpath, i);
+ libnameStr = strJavaToC(env, libname);
+ /*fprintf(stderr, "dlopen(%s)\n", libnameStr);*/
+ cgWrapperInfo->cgLibraryHandle = dlopen(libnameStr, RTLD_LAZY);
+ if ((cgWrapperInfo->cgLibraryHandle == NULL) && (i == pathLen-1)) {
+ errName = strdup(libnameStr);
+ }
+ free(libnameStr);
+ if (cgWrapperInfo->cgLibraryHandle != NULL) {
+ break;
+ }
+ }
+
+ if (cgWrapperInfo->cgLibraryHandle == NULL) {
+ fprintf(stderr, "JAVA 3D ERROR : Unable to load library ");
+ perror(errName);
+ free(errName);
+ free(cgWrapperInfo);
+ return JNI_FALSE;
+ }
+
+ /* Get pointer to library function to setup function pointers */
+ cgWrapperInfo->j3dLoadCgFunctionPointers =
+ (PFNJ3DLOADCGFUNCTIONPOINTERS)dlsym(cgWrapperInfo->cgLibraryHandle,
+ "j3dLoadCgFunctionPointers");
+
+#endif /* UNIX */
+
+#ifdef WIN32
+
+ /* Load the library, suppressing any dialog boxes that may occur */
+ origErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX |
+ SEM_FAILCRITICALERRORS);
+
+ for (i = 0; i < pathLen; i++) {
+ jstring libname;
+ char *libnameStr;
+
+ libname = (*env)->GetObjectArrayElement(env, libpath, i);
+ libnameStr = strJavaToC(env, libname);
+ /*fprintf(stderr, "LoadLibrary(%s)\n", libnameStr);*/
+ cgWrapperInfo->cgLibraryHandle = LoadLibrary(libnameStr);
+ if ((cgWrapperInfo->cgLibraryHandle == NULL) && (i == pathLen-1)) {
+ errName = strdup(libnameStr);
+ }
+ free(libnameStr);
+ if (cgWrapperInfo->cgLibraryHandle != NULL) {
+ break;
+ }
+ }
+
+ SetErrorMode(origErrorMode);
+
+ if (cgWrapperInfo->cgLibraryHandle == NULL) {
+ err = GetLastError();
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, err, 0, (LPTSTR)&errString, 0, NULL);
+
+ fprintf(stderr,
+ "JAVA 3D ERROR : Unable to load library %s: %s\n",
+ errName, errString);
+ free(errName);
+ return JNI_FALSE;
+ }
+
+ cgWrapperInfo->j3dLoadCgFunctionPointers =
+ (PFNJ3DLOADCGFUNCTIONPOINTERS)GetProcAddress(
+ (HMODULE)cgWrapperInfo->cgLibraryHandle,
+ "j3dLoadCgFunctionPointers");
+
+ if (cgWrapperInfo->j3dLoadCgFunctionPointers == NULL) {
+ err = GetLastError();
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, err, 0, (LPTSTR)&errString, 0, NULL);
+
+ fprintf(stderr,
+ "JAVA 3D ERROR : Unable to find: j3dLoadCgFunctionPointers: %s\n",
+ errString);
+ return JNI_FALSE;
+ }
+
+#endif /* WIN32 */
+
+ if (cgWrapperInfo->j3dLoadCgFunctionPointers) {
+ cgWrapperInfo->j3dLoadCgFunctionPointers(cgWrapperInfo);
+ cgWrapperInfo->loaded = JNI_TRUE;
+ }
+
+#else /* COMPILE_CG_SHADERS */
+
+ fprintf(stderr, "Java 3D: CgShaderProgram code not compiled\n");
+
+#endif /* COMPILE_CG_SHADERS */
+
+ /* Save pointer in global variable */
+ globalCgWrapperInfo = cgWrapperInfo;
+
+ return cgWrapperInfo->loaded;
+}
+
+
+#ifdef COMPILE_CG_SHADERS
+
+static char *
+getErrorLog(
+ GraphicsContextPropertiesInfo* ctxProperties,
+ CGerror lastError)
+{
+ CgCtxInfo *cgCtxInfo = ctxProperties->cgCtxInfo;
+ CgWrapperInfo *cgWrapperInfo = cgCtxInfo->cgWrapperInfo;
+
+ if (lastError != 0) {
+ const char *errString = cgWrapperInfo->cgGetErrorString(lastError);
+ const char *delimeter1 = "\n";
+ const char *listing = cgWrapperInfo->cgGetLastListing(cgCtxInfo->cgCtx);
+
+ char *errMsg = (char *)
+ malloc(strlen(errString) + strlen(delimeter1) + strlen(listing) + 1);
+
+ if (errMsg == NULL) {
+ perror("malloc");
+ return NULL;
+ }
+
+ strcpy(errMsg, errString);
+ strcat(errMsg, delimeter1);
+ strcat(errMsg, listing);
+
+ return errMsg;
+ }
+
+ fprintf(stderr, "Assertion error: assert(lastError != 0) failed\n");
+ return NULL;
+}
+
+
+static CgCtxInfo *
+createCgShaderContext(
+ JNIEnv *env,
+ GraphicsContextPropertiesInfo *ctxInfo)
+{
+ jclass oom;
+ CGerror lastError;
+ CgCtxInfo *cgCtxInfo = NULL;
+ CgWrapperInfo *cgWrapperInfo;
+
+ /* Assertion check that we don't get here unless the library is loaded */
+ if (globalCgWrapperInfo == NULL) {
+ throwAssert(env, "createCgShaderContext: cgWrapperInfo is NULL");
+ return NULL;
+ }
+
+ if (!globalCgWrapperInfo->loaded) {
+ throwAssert(env, "createCgShaderContext: cgWrapper library not loaded");
+ return NULL;
+ }
+
+ cgCtxInfo = (CgCtxInfo*)malloc(sizeof(CgCtxInfo));
+ if (cgCtxInfo == NULL) {
+ if ((oom = (*env)->FindClass(env, "java/lang/OutOfMemoryError")) != NULL) {
+ (*env)->ThrowNew(env, oom, "malloc");
+ }
+ return NULL;
+ }
+
+ /* Point to the global CG wrapper info */
+ cgWrapperInfo = cgCtxInfo->cgWrapperInfo = globalCgWrapperInfo;
+
+ /* Create CG context */
+ cgCtxInfo->cgCtx = cgWrapperInfo->cgCreateContext();
+
+ if ((lastError = cgWrapperInfo->cgGetError()) != 0) {
+ fprintf(stderr, "Fatal error in creating Cg context:\n");
+ fprintf(stderr, "\t%s\n", cgWrapperInfo->cgGetErrorString(lastError));
+ free(cgCtxInfo);
+ return NULL;
+ }
+
+ if (cgCtxInfo->cgCtx == 0) {
+ fprintf(stderr, "Invalid NULL Cg context\n");
+ free(cgCtxInfo);
+ return NULL;
+ }
+
+ /* Use GL_ARB_vertex_program extension if supported by video card */
+ if (cgWrapperInfo->cgGLIsProfileSupported(CG_PROFILE_ARBVP1)) {
+ fprintf(stderr, "Using CG_PROFILE_ARBVP1\n");
+ cgCtxInfo->vProfile = CG_PROFILE_ARBVP1;
+ }
+ else if (cgWrapperInfo->cgGLIsProfileSupported(CG_PROFILE_VP20)) {
+ fprintf(stderr, "Using CG_PROFILE_VP20\n");
+ cgCtxInfo->vProfile = CG_PROFILE_VP20;
+ }
+ else {
+ fprintf(stderr,
+ "ERROR: Vertex programming extensions (GL_ARB_vertex_program or\n"
+ "GL_NV_vertex_program) not supported, exiting...\n");
+ free(cgCtxInfo);
+ return NULL;
+ }
+
+ if ((lastError = cgWrapperInfo->cgGetError()) != 0) {
+ fprintf(stderr, "FATAL ERROR IN CREATING VERTEX SHADER PROFILE:\n");
+ fprintf(stderr, "\t%s\n", cgWrapperInfo->cgGetErrorString(lastError));
+ free(cgCtxInfo);
+ return NULL;
+ }
+
+ /* Use GL_ARB_fragment_program extension if supported by video card */
+ if (cgWrapperInfo->cgGLIsProfileSupported(CG_PROFILE_ARBFP1)) {
+ fprintf(stderr, "Using CG_PROFILE_ARBFP1\n");
+ cgCtxInfo->fProfile = CG_PROFILE_ARBFP1;
+ }
+ else if (cgWrapperInfo->cgGLIsProfileSupported(CG_PROFILE_FP20)) {
+ fprintf(stderr, "Using CG_PROFILE_FP20\n");
+ cgCtxInfo->fProfile = CG_PROFILE_FP20;
+ }
+ else {
+ fprintf(stderr,
+ "Fragment programming extensions (GL_ARB_fragment_program or\n"
+ "GL_NV_fragment_program) not supported, exiting...\n");
+ free(cgCtxInfo);
+ return NULL;
+ }
+
+ if ((lastError = cgWrapperInfo->cgGetError()) != 0) {
+ fprintf(stderr, "FATAL ERROR IN CREATING FRAGMENT SHADER PROFILE:\n");
+ fprintf(stderr, "\t%s\n", cgWrapperInfo->cgGetErrorString(lastError));
+ free(cgCtxInfo);
+ return NULL;
+ }
+
+ /*
+ fprintf(stderr, "createCgShaderContext: SUCCESS\n");
+ fprintf(stderr, " cgCtx = 0x%x\n", cgCtxInfo->cgCtx);
+ fprintf(stderr, " vProfile = 0x%x\n", cgCtxInfo->vProfile);
+ fprintf(stderr, " fProfile = 0x%x\n", cgCtxInfo->fProfile);
+ */
+
+ return cgCtxInfo;
+}
+
+#endif /* COMPILE_CG_SHADERS */
+
+
+/*
+ * Called by getPropertiesFromCurrentContext to initialize the Cg
+ * shader function pointers and set the flag indicating whether Cg
+ * shaders are available.
+ */
+void
+checkCgShaderExtensions(
+ JNIEnv *env,
+ jobject obj,
+ char *tmpExtensionStr,
+ GraphicsContextPropertiesInfo *ctxInfo,
+ jboolean cgLibraryAvailable)
+{
+ ctxInfo->shadingLanguageCg = JNI_FALSE;
+ ctxInfo->cgCtxInfo = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+ if (cgLibraryAvailable) {
+ /* TODO: need to free ctxInfo->cgCtxInfo when ctxInfo is freed */
+ ctxInfo->cgCtxInfo = createCgShaderContext(env, ctxInfo);
+ if (ctxInfo->cgCtxInfo != NULL) {
+ CgWrapperInfo *cgWrapperInfo = ctxInfo->cgCtxInfo->cgWrapperInfo;
+
+ /*
+ fprintf(stderr, "Cg ctx is available\n");
+ */
+ ctxInfo->shadingLanguageCg = JNI_TRUE;
+
+ /* TODO: Query Cg texture sampler limits */
+ ctxInfo->maxTextureImageUnits = ctxInfo->maxTextureUnits;
+ ctxInfo->maxVertexTextureImageUnits = 0;
+ ctxInfo->maxCombinedTextureImageUnits = ctxInfo->maxTextureUnits;
+
+ /* TODO: Query max vertex attrs */
+ ctxInfo->maxVertexAttrs = 2;
+
+ /* Initialize shader vertex attribute function pointers */
+ ctxInfo->vertexAttrPointer = cgVertexAttrPointer;
+ ctxInfo->enableVertexAttrArray = cgEnableVertexAttrArray;
+ ctxInfo->disableVertexAttrArray = cgDisableVertexAttrArray;
+ ctxInfo->vertexAttr1fv = cgVertexAttr;
+ ctxInfo->vertexAttr2fv = cgVertexAttr;
+ ctxInfo->vertexAttr3fv = cgVertexAttr;
+ ctxInfo->vertexAttr4fv = cgVertexAttr;
+ }
+ /*
+ else {
+ fprintf(stderr, "ERROR: Cg ctx *not* available\n");
+ }
+ */
+ }
+#endif /* COMPILE_CG_SHADERS */
+
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: createNativeShader
+ * Signature: (JI[J)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_createNativeShader(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jint shaderType,
+ jlongArray shaderIdArray)
+{
+ jobject shaderError = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+ GraphicsContextPropertiesInfo* ctxProperties = (GraphicsContextPropertiesInfo* )ctxInfo;
+ CgCtxInfo *cgCtxInfo = ctxProperties->cgCtxInfo;
+
+ jlong *shaderIdPtr;
+ CGprogram shaderId = 0;
+ jclass oom;
+ CgShaderInfo *cgShaderInfo;
+
+ fprintf(stderr, "CgShaderProgramRetained.createNativeShader\n");
+
+ cgShaderInfo = (CgShaderInfo*)malloc(sizeof(CgShaderInfo));
+ if (cgShaderInfo == NULL) {
+ if ((oom = (*env)->FindClass(env, "java/lang/OutOfMemoryError")) != NULL) {
+ (*env)->ThrowNew(env, oom, "malloc");
+ }
+ return NULL;
+ }
+ cgShaderInfo->cgShader = 0;
+ cgShaderInfo->shaderType = shaderType;
+ if (shaderType == javax_media_j3d_Shader_SHADER_TYPE_VERTEX) {
+ cgShaderInfo->shaderProfile = cgCtxInfo->vProfile;
+ }
+ else if (shaderType == javax_media_j3d_Shader_SHADER_TYPE_FRAGMENT) {
+ cgShaderInfo->shaderProfile = cgCtxInfo->fProfile;
+ }
+ else {
+ cgShaderInfo->shaderProfile = 0;
+ fprintf(stderr, "shaderType = %d\n", shaderType);
+ throwAssert(env, "unrecognized shaderType");
+ return NULL;
+ }
+
+ shaderIdPtr = (*env)->GetLongArrayElements(env, shaderIdArray, NULL);
+ shaderIdPtr[0] = (jlong) cgShaderInfo;
+ (*env)->ReleaseLongArrayElements(env, shaderIdArray, shaderIdPtr, 0);
+
+#else /* COMPILE_CG_SHADERS */
+
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_UNSUPPORTED_LANGUAGE_ERROR,
+ "CgShaderProgram support not compiled",
+ NULL);
+
+#endif /* !COMPILE_CG_SHADERS */
+
+ return shaderError;
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: destroyNativeShader
+ * Signature: (JJ)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_destroyNativeShader(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderId)
+{
+ jobject shaderError = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+
+ GraphicsContextPropertiesInfo* ctxProperties = (GraphicsContextPropertiesInfo* )ctxInfo;
+ CgCtxInfo *cgCtxInfo = ctxProperties->cgCtxInfo;
+ CgWrapperInfo *cgWrapperInfo = cgCtxInfo->cgWrapperInfo;
+
+ CgShaderInfo *cgShaderInfo = (CgShaderInfo *)shaderId;
+
+ fprintf(stderr, "CgShaderProgramRetained.destroyNativeShader\n");
+
+ if (cgShaderInfo != NULL) {
+ if (cgShaderInfo->cgShader != 0) {
+ cgWrapperInfo->cgDestroyProgram(cgShaderInfo->cgShader);
+ }
+
+ free(cgShaderInfo);
+ }
+
+#else /* COMPILE_CG_SHADERS */
+
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_UNSUPPORTED_LANGUAGE_ERROR,
+ "CgShaderProgram support not compiled",
+ NULL);
+
+#endif /* !COMPILE_CG_SHADERS */
+
+ return shaderError;
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: compileNativeShader
+ * Signature: (JJLjava/lang/String;)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_compileNativeShader(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderId,
+ jstring program)
+{
+ jobject shaderError = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+
+ /* TODO: implement this */
+
+ GraphicsContextPropertiesInfo* ctxProperties = (GraphicsContextPropertiesInfo* )ctxInfo;
+ CgCtxInfo *cgCtxInfo = ctxProperties->cgCtxInfo;
+ CgWrapperInfo *cgWrapperInfo = cgCtxInfo->cgWrapperInfo;
+
+ CgShaderInfo *cgShaderInfo = (CgShaderInfo *)shaderId;
+ CGerror lastError;
+ GLcharARB *shaderString = NULL;
+
+ fprintf(stderr, "CgShaderProgramRetained.compileNativeShader\n");
+
+ /* Assertion check the cgShaderInfo pointer */
+ if (cgShaderInfo == NULL) {
+ throwAssert(env, "cgShaderInfo is NULL");
+ return NULL;
+ }
+
+ /* Assertion check the program string */
+ if (program == NULL) {
+ throwAssert(env, "shader program string is NULL");
+ return NULL;
+ }
+
+ shaderString = strJavaToC(env, program);
+ if (shaderString == NULL) {
+ /* Just return, since strJavaToC will throw OOM if it returns NULL */
+ return NULL;
+ }
+
+ /* create the shader */
+ if (cgShaderInfo->shaderType == javax_media_j3d_Shader_SHADER_TYPE_VERTEX) {
+ fprintf(stderr, "Create vertex shader\n");
+ }
+ else if (cgShaderInfo->shaderType == javax_media_j3d_Shader_SHADER_TYPE_FRAGMENT) {
+ fprintf(stderr, "Create fragment shader\n");
+ }
+ fprintf(stderr, "cgCtx = 0x%x\n", cgCtxInfo->cgCtx);
+ fprintf(stderr, "shaderProfile = 0x%x\n", cgShaderInfo->shaderProfile);
+ cgShaderInfo->cgShader = cgWrapperInfo->cgCreateProgram(cgCtxInfo->cgCtx,
+ CG_SOURCE, shaderString,
+ cgShaderInfo->shaderProfile, NULL, NULL);
+ fprintf(stderr, " cgShader = 0x%x\n", cgShaderInfo->cgShader);
+
+ free(shaderString);
+
+#ifdef OUT__XXX__OUT
+ cgShaderInfo->cgShader = 0;
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_COMPILE_ERROR,
+ "Cg shader compile error",
+ "NOT YET IMPLEMENTED...");
+#endif /* OUT__XXX__OUT */
+
+ if ((lastError = cgWrapperInfo->cgGetError()) != 0) {
+ char *detailMsg = getErrorLog(ctxProperties, lastError);
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_COMPILE_ERROR,
+ "Cg shader compile error",
+ detailMsg);
+ if (detailMsg != NULL) {
+ free(detailMsg);
+ }
+ }
+
+#else /* COMPILE_CG_SHADERS */
+
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_UNSUPPORTED_LANGUAGE_ERROR,
+ "CgShaderProgram support not compiled",
+ NULL);
+
+#endif /* !COMPILE_CG_SHADERS */
+
+ return shaderError;
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: createNativeShaderProgram
+ * Signature: (J[J)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_createNativeShaderProgram(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlongArray shaderProgramIdArray)
+{
+ jobject shaderError = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+
+ jlong *shaderProgramIdPtr;
+
+ CgShaderProgramInfo *shaderProgramInfo =
+ (CgShaderProgramInfo*)malloc(sizeof(CgShaderProgramInfo));
+
+ fprintf(stderr, "CgShaderProgramRetained.createNativeShaderProgram\n");
+
+ shaderProgramInfo->vShader = NULL;
+ shaderProgramInfo->fShader = NULL;
+ shaderProgramInfo->numVtxAttrs = 0;
+ shaderProgramInfo->vtxAttrs = NULL;
+
+ shaderProgramIdPtr = (*env)->GetLongArrayElements(env, shaderProgramIdArray, NULL);
+ shaderProgramIdPtr[0] = (jlong)shaderProgramInfo;
+ (*env)->ReleaseLongArrayElements(env, shaderProgramIdArray, shaderProgramIdPtr, 0);
+
+#else /* COMPILE_CG_SHADERS */
+
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_UNSUPPORTED_LANGUAGE_ERROR,
+ "CgShaderProgram support not compiled",
+ NULL);
+
+#endif /* !COMPILE_CG_SHADERS */
+
+ return shaderError;
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: destroyNativeShaderProgram
+ * Signature: (JJ)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_destroyNativeShaderProgram(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderProgramId)
+{
+ jobject shaderError = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+
+ CgShaderProgramInfo *shaderProgramInfo = (CgShaderProgramInfo*)shaderProgramId;
+
+ fprintf(stderr, "CgShaderProgramRetained.destroyNativeShaderProgram\n");
+
+ if (shaderProgramInfo != NULL) {
+ if (shaderProgramInfo->vtxAttrs != NULL) {
+ free(shaderProgramInfo->vtxAttrs);
+ shaderProgramInfo->vtxAttrs = NULL;
+ }
+ free(shaderProgramInfo);
+ }
+
+#else /* COMPILE_CG_SHADERS */
+
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_UNSUPPORTED_LANGUAGE_ERROR,
+ "CgShaderProgram support not compiled",
+ NULL);
+
+#endif /* !COMPILE_CG_SHADERS */
+
+ return shaderError;
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: linkNativeShaderProgram
+ * Signature: (JJ[J)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_linkNativeShaderProgram(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderProgramId,
+ jlongArray shaderIdArray)
+{
+ jobject shaderError = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+
+ GraphicsContextPropertiesInfo* ctxProperties = (GraphicsContextPropertiesInfo* )ctxInfo;
+ CgCtxInfo *cgCtxInfo = ctxProperties->cgCtxInfo;
+ CgWrapperInfo *cgWrapperInfo = cgCtxInfo->cgWrapperInfo;
+
+ jsize shaderIdArrayLength = (*env)->GetArrayLength(env, shaderIdArray);
+ jlong *shaderIdPtr = (*env)->GetLongArrayElements(env, shaderIdArray, NULL);
+ CGerror lastError;
+
+ int i;
+
+ CgShaderProgramInfo *shaderProgramInfo = (CgShaderProgramInfo*)shaderProgramId;
+
+ fprintf(stderr, "CgShaderProgramRetained.linkNativeShaderProgram\n");
+
+ /*
+ * NOTE: we assume that the caller has already verified that there
+ * is at most one vertex program and one fragment program
+ */
+ shaderProgramInfo->vShader = NULL;
+ shaderProgramInfo->fShader = NULL;
+ for (i = 0; i < shaderIdArrayLength; i++) {
+ CgShaderInfo *shader = (CgShaderInfo*)shaderIdPtr[i];
+ if (shader->shaderType == javax_media_j3d_Shader_SHADER_TYPE_VERTEX) {
+ shaderProgramInfo->vShader = shader;
+ } else {
+ shaderProgramInfo->fShader = shader;
+ }
+
+ cgWrapperInfo->cgGLLoadProgram(shader->cgShader);
+
+ if ((lastError = cgWrapperInfo->cgGetError()) != 0) {
+ char *detailMsg = getErrorLog(ctxProperties, lastError);
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_LINK_ERROR,
+ "Cg shader link/load error",
+ detailMsg);
+ if (detailMsg != NULL) {
+ free(detailMsg);
+ }
+ }
+
+ cgWrapperInfo->cgGLBindProgram(shader->cgShader);
+
+ if ((lastError = cgWrapperInfo->cgGetError()) != 0) {
+ char *detailMsg = getErrorLog(ctxProperties, lastError);
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_LINK_ERROR,
+ "Cg shader link/bind error",
+ detailMsg);
+ if (detailMsg != NULL) {
+ free(detailMsg);
+ }
+ }
+ }
+
+ (*env)->ReleaseLongArrayElements(env, shaderIdArray, shaderIdPtr, JNI_ABORT);
+
+#else /* COMPILE_CG_SHADERS */
+
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_UNSUPPORTED_LANGUAGE_ERROR,
+ "CgShaderProgram support not compiled",
+ NULL);
+
+#endif /* !COMPILE_CG_SHADERS */
+
+ return shaderError;
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: lookupNativeVertexAttrNames
+ * Signature: (JJI[Ljava/lang/String;[Z)V
+ */
+JNIEXPORT void JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_lookupNativeVertexAttrNames(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderProgramId,
+ jint numAttrNames,
+ jobjectArray attrNames,
+ jbooleanArray errArr)
+{
+#ifdef COMPILE_CG_SHADERS
+
+ GraphicsContextPropertiesInfo* ctxProperties = (GraphicsContextPropertiesInfo* )ctxInfo;
+ CgCtxInfo *cgCtxInfo = ctxProperties->cgCtxInfo;
+ CgWrapperInfo *cgWrapperInfo = cgCtxInfo->cgWrapperInfo;
+
+ CgShaderProgramInfo *shaderProgramInfo = (CgShaderProgramInfo*)shaderProgramId;
+
+ int i;
+ jstring attrName;
+ char *attrNameString;
+ jboolean *errPtr;
+
+ errPtr = (*env)->GetBooleanArrayElements(env, errArr, NULL);
+
+ if (shaderProgramInfo->vShader == NULL) {
+ /* If there if no vertex shader, no attributes can be looked up, so all fail */
+ for (i = 0; i < numAttrNames; i++) {
+ errPtr[i] = JNI_TRUE;
+ }
+ (*env)->ReleaseBooleanArrayElements(env, errArr, errPtr, 0);
+ return;
+ }
+
+ shaderProgramInfo->numVtxAttrs = numAttrNames;
+ shaderProgramInfo->vtxAttrs = (CGparameter *)malloc(numAttrNames * sizeof(CGparameter));
+
+ fprintf(stderr, "CgShaderProgramRetained.lookupNativeVertexAttrNames()\n");
+ for (i = 0; i < numAttrNames; i++) {
+ attrName = (*env)->GetObjectArrayElement(env, attrNames, i);
+ attrNameString = strJavaToC(env, attrName);
+
+ shaderProgramInfo->vtxAttrs[i] =
+ cgWrapperInfo->cgGetNamedParameter(shaderProgramInfo->vShader->cgShader,
+ attrNameString);
+ fprintf(stderr, " %s : 0x%x\n", attrNameString, shaderProgramInfo->vtxAttrs[i]);
+ if (shaderProgramInfo->vtxAttrs[i] == NULL) {
+ errPtr[i] = JNI_TRUE;
+ }
+
+ free(attrNameString);
+ }
+
+ (*env)->ReleaseBooleanArrayElements(env, errArr, errPtr, 0);
+
+#endif /* COMPILE_CG_SHADERS */
+}
+
+
+#ifdef COMPILE_CG_SHADERS
+
+static jint
+cgToJ3dType(CGtype type)
+{
+ switch (type) {
+ case CG_BOOL:
+ case CG_BOOL1:
+ case CG_FIXED:
+ case CG_FIXED1:
+ case CG_HALF:
+ case CG_HALF1:
+ case CG_INT:
+ case CG_INT1:
+ return TYPE_INTEGER;
+
+ /*
+ * TODO: add ShaderAttribute support for setting samplers. In the
+ * mean time, the binding between sampler and texture unit will
+ * need to be specified in the shader itself (which it already is
+ * in most example shaders).
+ *
+ * case CG_SAMPLER2D:
+ * case CG_SAMPLER3D:
+ * case CG_SAMPLERCUBE:
+ *
+ */
+
+ case CG_BOOL2:
+ case CG_FIXED2:
+ case CG_HALF2:
+ case CG_INT2:
+ /* TODO: return TYPE_TUPLE2I; */
+ return -1;
+
+ case CG_BOOL3:
+ case CG_FIXED3:
+ case CG_HALF3:
+ case CG_INT3:
+ /*TODO: return TYPE_TUPLE3I; */
+ return -1;
+
+ case CG_BOOL4:
+ case CG_FIXED4:
+ case CG_HALF4:
+ case CG_INT4:
+ /*TODO: return TYPE_TUPLE4I; */
+ return -1;
+
+ case CG_FLOAT:
+ case CG_FLOAT1:
+ return TYPE_FLOAT;
+
+ case CG_FLOAT2:
+ /*TODO: return TYPE_TUPLE2F; */
+ return -1;
+
+ case CG_FLOAT3:
+ /*TODO: return TYPE_TUPLE3F; */
+ return -1;
+
+ case CG_FLOAT4:
+ /*TODO: return TYPE_TUPLE4F; */
+ return -1;
+
+ case CG_FLOAT3x3:
+ /*TODO: return TYPE_MATRIX3F; */
+ return -1;
+
+ case CG_FLOAT4x4:
+ /*TODO: return TYPE_MATRIX4F; */
+ return -1;
+
+ /*
+ * Java 3D does not support the following sampler types:
+ *
+ * case CG_SAMPLER1D:
+ * case CG_SAMPLERRECT:
+ */
+ }
+
+ return -1;
+}
+
+static CGparameter
+lookupParams(
+ CgWrapperInfo *cgWrapperInfo,
+ CgShaderInfo *shader,
+ char *attrNameString,
+ CGtype *type,
+ int *size,
+ jboolean *isArray)
+{
+ CGparameter loc;
+ CGparameter firstElem;
+
+ loc = cgWrapperInfo->cgGetNamedParameter(shader->cgShader,
+ attrNameString);
+ if (loc != NULL) {
+ *type = cgWrapperInfo->cgGetParameterType(loc);
+ if (*type == CG_ARRAY) {
+ *isArray = JNI_TRUE;
+ *size = cgWrapperInfo->cgGetArraySize(loc, 0);
+ /**type = cgWrapperInfo->cgGetArrayType(loc);*/
+ firstElem = cgWrapperInfo->cgGetArrayParameter(loc, 0);
+ *type = cgWrapperInfo->cgGetParameterType(firstElem);
+ /*
+ fprintf(stderr,
+ "firstElem = %d, *type = %d\n",
+ firstElem, *type);
+ */
+ }
+ else {
+ *isArray = JNI_FALSE;
+ *size = 1;
+ }
+ }
+
+ return loc;
+}
+
+#endif /* COMPILE_CG_SHADERS */
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: lookupNativeShaderAttrNames
+ * Signature: (JJI[Ljava/lang/String;[J[I[I[Z)V
+ */
+JNIEXPORT void JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_lookupNativeShaderAttrNames(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderProgramId,
+ jint numAttrNames,
+ jobjectArray attrNames,
+ jlongArray locArr,
+ jintArray typeArr,
+ jintArray sizeArr,
+ jbooleanArray isArrayArr)
+{
+
+#ifdef COMPILE_CG_SHADERS
+
+ GraphicsContextPropertiesInfo* ctxProperties = (GraphicsContextPropertiesInfo* )ctxInfo;
+ CgCtxInfo *cgCtxInfo = ctxProperties->cgCtxInfo;
+ CgWrapperInfo *cgWrapperInfo = cgCtxInfo->cgWrapperInfo;
+ CgShaderProgramInfo *shaderProgramInfo = (CgShaderProgramInfo*)shaderProgramId;
+
+ jstring attrName;
+ char *attrNameString;
+ jlong *locPtr;
+ jint *typePtr;
+ jint *sizePtr;
+ jboolean *isArrayPtr;
+ CGparameter vLoc, fLoc;
+ CGtype vType, fType;
+ int vSize, fSize;
+ jboolean vIsArray, fIsArray;
+ int i;
+
+ locPtr = (*env)->GetLongArrayElements(env, locArr, NULL);
+ typePtr = (*env)->GetIntArrayElements(env, typeArr, NULL);
+ sizePtr = (*env)->GetIntArrayElements(env, sizeArr, NULL);
+ isArrayPtr = (*env)->GetBooleanArrayElements(env, isArrayArr, NULL);
+
+ /*
+ * Set the loc, type, and size arrays to out-of-band values
+ */
+ for (i = 0; i < numAttrNames; i++) {
+ locPtr[i] = -1;
+ typePtr[i] = -1;
+ sizePtr[i] = -1;
+ }
+
+ /* Now lookup the location of each name in the attrNames array */
+ for (i = 0; i < numAttrNames; i++) {
+ jboolean err;
+ CgParameterInfo *cgParamInfo;
+
+ attrName = (*env)->GetObjectArrayElement(env, attrNames, i);
+ attrNameString = (GLcharARB *)strJavaToC(env, attrName);
+
+ fprintf(stderr, "lookup %s\n", attrNameString);
+
+ /*
+ * Get uniform attribute location -- note that we need to
+ * lookup the name in both the vertex and fragment shader
+ * (although we will generalize it to look at the list of "N"
+ * shaders). If all parameter locations are NULL, then no
+ * struct will be allocated and -1 will be stored for this
+ * attribute. If there is more than one non-NULL parameter,
+ * then all must be of the same type and dimensionality,
+ * otherwise an error will be generated and -1 will be stored
+ * for this attribute. If all non-NULL parameters are of the
+ * same type and dimensionality, then a struct is allocated
+ * containing the list of parameters.
+ *
+ * When any of the setUniform methods are called, the attribute
+ * will be set for each parameter in the list.
+ */
+ cgParamInfo = (CgParameterInfo *)malloc(sizeof(CgParameterInfo));
+ cgParamInfo->vParam = NULL;
+ cgParamInfo->fParam = NULL;
+ err = JNI_FALSE;
+
+ vLoc = NULL;
+ if (shaderProgramInfo->vShader != NULL) {
+ vLoc = lookupParams(cgWrapperInfo, shaderProgramInfo->vShader,
+ attrNameString, &vType, &vSize, &vIsArray);
+ cgParamInfo->vParam = vLoc;
+ if (vLoc != NULL) {
+ sizePtr[i] = (jint)vSize;
+ isArrayPtr[i] = vIsArray;
+ typePtr[i] = cgToJ3dType(vType);
+
+ fprintf(stderr, " vLoc = %d, vType = %d, vSize = %d, vIsArray = %d\n",
+ vLoc, vType, vSize, vIsArray);
+ }
+ }
+
+ fLoc = NULL;
+ if (shaderProgramInfo->fShader != NULL) {
+ fLoc = lookupParams(cgWrapperInfo, shaderProgramInfo->fShader,
+ attrNameString, &fType, &fSize, &fIsArray);
+ cgParamInfo->fParam = fLoc;
+ if (fLoc != NULL) {
+ sizePtr[i] = (jint)fSize;
+ isArrayPtr[i] = fIsArray;
+ typePtr[i] = cgToJ3dType(fType);
+
+ fprintf(stderr, " fLoc = %d, fType = %d, fSize = %d, fIsArray = %d\n",
+ fLoc, fType, fSize, fIsArray);
+ }
+ }
+
+ /*
+ * If the name lookup found an entry in both vertex and
+ * fragment program, verify that the type and size are the
+ * same.
+ */
+ if (cgParamInfo->vParam != NULL && cgParamInfo->fParam != NULL) {
+ if (vType != fType || vSize != fSize || vIsArray != fIsArray) {
+ /* TODO: the following needs to be propagated to ShaderError */
+ fprintf(stderr,
+ "JAVA 3D : error shader attribute type mismatch: %s\n",
+ attrNameString);
+ fprintf(stderr,
+ " 1 : type = %d, size = %d, isArray = %d\n",
+ vType, vSize, vIsArray);
+ fprintf(stderr,
+ " 0 : type = %d, size = %d, isArray = %d\n",
+ fType, fSize, fIsArray);
+ err = JNI_TRUE;
+ }
+ }
+
+ /*
+ * Report an error if we got a mismatch or if the attribute
+ * was not found in either the vertex or the fragment program
+ */
+ if (err || (cgParamInfo->vParam == NULL && cgParamInfo->fParam == NULL)) {
+ /* TODO: distinguish between (err) and (vParam and fParam both NULL) */
+ free(cgParamInfo);
+ locPtr[i] = (jlong)-1;
+ }
+ else {
+ /*
+ * TODO: need to store the cgParamInfo pointers in the
+ * shader program so we can free them later.
+ *
+ * NOTE: WE CURRENTLY HAVE A MEMORY LEAK.
+ */
+ locPtr[i] = (jlong)cgParamInfo;
+ }
+
+ free(attrNameString);
+ }
+
+ /* Release JNI arrays */
+ (*env)->ReleaseLongArrayElements(env, locArr, locPtr, 0);
+ (*env)->ReleaseIntArrayElements(env, typeArr, typePtr, 0);
+ (*env)->ReleaseIntArrayElements(env, sizeArr, sizePtr, 0);
+ (*env)->ReleaseBooleanArrayElements(env, isArrayArr, isArrayPtr, 0);
+
+#endif /* COMPILE_CG_SHADERS */
+
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: useShaderProgram
+ * Signature: (JJ)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_useShaderProgram(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderProgramId)
+{
+#ifdef COMPILE_CG_SHADERS
+
+ GraphicsContextPropertiesInfo* ctxProperties = (GraphicsContextPropertiesInfo* )ctxInfo;
+ CgCtxInfo *cgCtxInfo = ctxProperties->cgCtxInfo;
+ CgWrapperInfo *cgWrapperInfo = cgCtxInfo->cgWrapperInfo;
+
+ CgShaderProgramInfo *shaderProgramInfo = (CgShaderProgramInfo*)shaderProgramId;
+
+ cgWrapperInfo->cgGLDisableProfile(cgCtxInfo->vProfile);
+ cgWrapperInfo->cgGLDisableProfile(cgCtxInfo->fProfile);
+
+ if (shaderProgramId != 0) {
+ if (shaderProgramInfo->vShader != NULL) {
+ cgWrapperInfo->cgGLBindProgram(shaderProgramInfo->vShader->cgShader);
+ cgWrapperInfo->cgGLEnableProfile(shaderProgramInfo->vShader->shaderProfile);
+ }
+
+ if (shaderProgramInfo->fShader != NULL) {
+ cgWrapperInfo->cgGLBindProgram(shaderProgramInfo->fShader->cgShader);
+ cgWrapperInfo->cgGLEnableProfile(shaderProgramInfo->fShader->shaderProfile);
+ }
+ }
+ else {
+ /* TODO: Unbind old shader program */
+ }
+
+ ctxProperties->shaderProgramId = shaderProgramId;
+
+#endif /* COMPILE_CG_SHADERS */
+
+ return NULL;
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniform1i
+ * Signature: (JJJI)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_setUniform1i(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderProgramId,
+ jlong location,
+ jint value)
+{
+ jobject shaderError = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+
+ /* TODO: implement this */
+
+#else /* COMPILE_CG_SHADERS */
+
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_UNSUPPORTED_LANGUAGE_ERROR,
+ "CgShaderProgram support not compiled",
+ NULL);
+
+#endif /* !COMPILE_CG_SHADERS */
+
+ return shaderError;
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniform1f
+ * Signature: (JJJF)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_setUniform1f(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderProgramId,
+ jlong location,
+ jfloat value)
+{
+ jobject shaderError = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+
+ GraphicsContextPropertiesInfo* ctxProperties = (GraphicsContextPropertiesInfo* )ctxInfo;
+ CgCtxInfo *cgCtxInfo = ctxProperties->cgCtxInfo;
+ CgWrapperInfo *cgWrapperInfo = cgCtxInfo->cgWrapperInfo;
+ CgShaderProgramInfo *shaderProgramInfo = (CgShaderProgramInfo*)shaderProgramId;
+ CgParameterInfo *cgParamInfo = (CgParameterInfo *)location;
+
+ if (cgParamInfo->vParam != NULL) {
+ cgWrapperInfo->cgSetParameter1f(cgParamInfo->vParam, value);
+ }
+
+ if (cgParamInfo->fParam != NULL) {
+ cgWrapperInfo->cgSetParameter1f(cgParamInfo->fParam, value);
+ }
+
+#else /* COMPILE_CG_SHADERS */
+
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_UNSUPPORTED_LANGUAGE_ERROR,
+ "CgShaderProgram support not compiled",
+ NULL);
+
+#endif /* !COMPILE_CG_SHADERS */
+
+ return shaderError;
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniform2i
+ * Signature: (JJJ[I)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_setUniform2i(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderProgramId,
+ jlong location,
+ jintArray varray)
+{
+ jobject shaderError = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+
+ /* TODO: implement this */
+
+#else /* COMPILE_CG_SHADERS */
+
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_UNSUPPORTED_LANGUAGE_ERROR,
+ "CgShaderProgram support not compiled",
+ NULL);
+
+#endif /* !COMPILE_CG_SHADERS */
+
+ return shaderError;
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniform2f
+ * Signature: (JJJ[F)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_setUniform2f(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderProgramId,
+ jlong location,
+ jfloatArray varray)
+{
+ jobject shaderError = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+
+ /* TODO: implement this */
+
+#else /* COMPILE_CG_SHADERS */
+
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_UNSUPPORTED_LANGUAGE_ERROR,
+ "CgShaderProgram support not compiled",
+ NULL);
+
+#endif /* !COMPILE_CG_SHADERS */
+
+ return shaderError;
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniform3i
+ * Signature: (JJJ[I)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_setUniform3i(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderProgramId,
+ jlong location,
+ jintArray varray)
+{
+ jobject shaderError = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+
+ /* TODO: implement this */
+
+#else /* COMPILE_CG_SHADERS */
+
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_UNSUPPORTED_LANGUAGE_ERROR,
+ "CgShaderProgram support not compiled",
+ NULL);
+
+#endif /* !COMPILE_CG_SHADERS */
+
+ return shaderError;
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniform3f
+ * Signature: (JJJ[F)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_setUniform3f(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderProgramId,
+ jlong location,
+ jfloatArray varray)
+{
+ jobject shaderError = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+
+ /* TODO: implement this */
+
+#else /* COMPILE_CG_SHADERS */
+
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_UNSUPPORTED_LANGUAGE_ERROR,
+ "CgShaderProgram support not compiled",
+ NULL);
+
+#endif /* !COMPILE_CG_SHADERS */
+
+ return shaderError;
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniform4i
+ * Signature: (JJJ[I)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_setUniform4i(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderProgramId,
+ jlong location,
+ jintArray varray)
+{
+ jobject shaderError = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+
+ /* TODO: implement this */
+
+#else /* COMPILE_CG_SHADERS */
+
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_UNSUPPORTED_LANGUAGE_ERROR,
+ "CgShaderProgram support not compiled",
+ NULL);
+
+#endif /* !COMPILE_CG_SHADERS */
+
+ return shaderError;
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniform4f
+ * Signature: (JJJ[F)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_setUniform4f(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderProgramId,
+ jlong location,
+ jfloatArray varray)
+{
+ jobject shaderError = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+
+ /* TODO: implement this */
+
+#else /* COMPILE_CG_SHADERS */
+
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_UNSUPPORTED_LANGUAGE_ERROR,
+ "CgShaderProgram support not compiled",
+ NULL);
+
+#endif /* !COMPILE_CG_SHADERS */
+
+ return shaderError;
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniformMatrix3f
+ * Signature: (JJJ[F)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_setUniformMatrix3f(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderProgramId,
+ jlong location,
+ jfloatArray varray)
+{
+ jobject shaderError = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+
+ /* TODO: implement this */
+
+#else /* COMPILE_CG_SHADERS */
+
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_UNSUPPORTED_LANGUAGE_ERROR,
+ "CgShaderProgram support not compiled",
+ NULL);
+
+#endif /* !COMPILE_CG_SHADERS */
+
+ return shaderError;
+}
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniformMatrix4f
+ * Signature: (JJJ[F)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL
+Java_javax_media_j3d_CgShaderProgramRetained_setUniformMatrix4f(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jlong shaderProgramId,
+ jlong location,
+ jfloatArray varray)
+{
+ jobject shaderError = NULL;
+
+#ifdef COMPILE_CG_SHADERS
+
+ /* TODO: implement this */
+
+#else /* COMPILE_CG_SHADERS */
+
+ shaderError = createShaderError(env,
+ javax_media_j3d_ShaderError_UNSUPPORTED_LANGUAGE_ERROR,
+ "CgShaderProgram support not compiled",
+ NULL);
+
+#endif /* !COMPILE_CG_SHADERS */
+
+ return shaderError;
+}
+
+
+/*
+ * Cg vertex attribute functions
+ */
+
+static void
+cgVertexAttrPointer(
+ GraphicsContextPropertiesInfo *ctxProperties,
+ int index, int size, int type, int stride,
+ const void *pointer)
+{
+ /* TODO: implement this */
+ fprintf(stderr, "cgVertexAttrPointer: not implemented\n");
+}
+
+static void
+cgEnableVertexAttrArray(
+ GraphicsContextPropertiesInfo *ctxProperties,
+ int index)
+{
+ /* TODO: implement this */
+ fprintf(stderr, "cgEnableVertexAttrArray: not implemented\n");
+}
+
+static void
+cgDisableVertexAttrArray(
+ GraphicsContextPropertiesInfo *ctxProperties,
+ int index)
+{
+ /* TODO: implement this */
+ fprintf(stderr, "cgDisableVertexAttrArray: not implemented\n");
+}
+
+static void
+cgVertexAttr(
+ GraphicsContextPropertiesInfo *ctxProperties,
+ int index, const float *v)
+{
+ /*
+ * NOTE: we should never get here. This function is only called
+ * when building display lists for geometry arrays with vertex
+ * attributes, and such display lists are disabled in Cg mode.
+ */
+ fprintf(stderr,
+ "Java 3D ERROR : Assertion failed: invalid call to cgVertexAttr*f\n");
+}
+
+
+#if 0
+
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniform1iArray
+ * Signature: (JJJI[I)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL Java_javax_media_j3d_CgShaderProgramRetained_setUniform1iArray
+ (JNIEnv *, jobject, jlong, jlong, jlong, jint, jintArray);
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniform1fArray
+ * Signature: (JJJI[F)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL Java_javax_media_j3d_CgShaderProgramRetained_setUniform1fArray
+ (JNIEnv *, jobject, jlong, jlong, jlong, jint, jfloatArray);
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniform2iArray
+ * Signature: (JJJI[I)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL Java_javax_media_j3d_CgShaderProgramRetained_setUniform2iArray
+ (JNIEnv *, jobject, jlong, jlong, jlong, jint, jintArray);
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniform2fArray
+ * Signature: (JJJI[F)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL Java_javax_media_j3d_CgShaderProgramRetained_setUniform2fArray
+ (JNIEnv *, jobject, jlong, jlong, jlong, jint, jfloatArray);
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniform3iArray
+ * Signature: (JJJI[I)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL Java_javax_media_j3d_CgShaderProgramRetained_setUniform3iArray
+ (JNIEnv *, jobject, jlong, jlong, jlong, jint, jintArray);
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniform3fArray
+ * Signature: (JJJI[F)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL Java_javax_media_j3d_CgShaderProgramRetained_setUniform3fArray
+ (JNIEnv *, jobject, jlong, jlong, jlong, jint, jfloatArray);
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniform4iArray
+ * Signature: (JJJI[I)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL Java_javax_media_j3d_CgShaderProgramRetained_setUniform4iArray
+ (JNIEnv *, jobject, jlong, jlong, jlong, jint, jintArray);
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniform4fArray
+ * Signature: (JJJI[F)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL Java_javax_media_j3d_CgShaderProgramRetained_setUniform4fArray
+ (JNIEnv *, jobject, jlong, jlong, jlong, jint, jfloatArray);
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniformMatrix3fArray
+ * Signature: (JJJI[F)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL Java_javax_media_j3d_CgShaderProgramRetained_setUniformMatrix3fArray
+ (JNIEnv *, jobject, jlong, jlong, jlong, jint, jfloatArray);
+
+/*
+ * Class: javax_media_j3d_CgShaderProgramRetained
+ * Method: setUniformMatrix4fArray
+ * Signature: (JJJI[F)Ljavax/media/j3d/ShaderError;
+ */
+JNIEXPORT jobject JNICALL Java_javax_media_j3d_CgShaderProgramRetained_setUniformMatrix4fArray
+ (JNIEnv *, jobject, jlong, jlong, jlong, jint, jfloatArray);
+
+
+
+#endif
+
+
+
+
+
+#if 0
+/*
+ * Class: javax_media_j3d_CgShaderProgram
+ * Method: updateNative
+ * Signature: (JLjava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_javax_media_j3d_CgShaderProgram_updateNative(
+ JNIEnv *env,
+ jobject obj,
+ jlong ctxInfo,
+ jstring vertexShader,
+ jstring fragmentShader)
+{
+#ifndef COMPILE_CG_SHADERS
+ static GLboolean firstTime = GL_TRUE;
+
+ if (firstTime) {
+ fprintf(stderr, "Java 3D ERROR : CgShader code not compiled\n");
+ firstTime = GL_FALSE;
+ }
+ return;
+#endif /* !COMPILE_CG_SHADERS */
+
+#ifdef COMPILE_CG_SHADERS
+ /* Null-terminated "C" strings */
+ char *vertexShaderString = NULL;
+ char *fragmentShaderString = NULL;
+
+ /* Process vertex shader */
+ /*
+ fprintf(stderr, " vertexShader == 0x%x\n", vertexShader);
+ */
+ if (vertexShader != 0) {
+ vertexShaderString = strJavaToC(env, vertexShader);
+ if (vertexShaderString == NULL) {
+ return;
+ }
+
+ /*
+ * TODO: need to check whether the shader has changed and free up the
+ * old shader before allocating a new one (like we do for texture)
+ */
+ if (vContext == 0) {
+ /* Use GL_ARB_vertex_program extension if supported by video card */
+ if (cgGLIsProfileSupported(CG_PROFILE_ARBVP1)) {
+ fprintf(stderr, "Using CG_PROFILE_ARBVP1\n");
+ vProfile = CG_PROFILE_ARBVP1;
+ }
+ else if (cgGLIsProfileSupported(CG_PROFILE_VP20)) {
+ fprintf(stderr, "Using CG_PROFILE_VP20\n");
+ vProfile = CG_PROFILE_VP20;
+ }
+ else {
+ fprintf(stderr,
+ "ERROR: Vertex programming extensions (GL_ARB_vertex_program or\n"
+ "GL_NV_vertex_program) not supported, exiting...\n");
+ return;
+ }
+
+ cgSetErrorCallback(cgErrorCallback);
+
+ vContext = cgCreateContext();
+
+ /* create the vertex shader */
+ fprintf(stderr,
+ "CgShaderProgram_updateNative: create vertex shader program\n");
+ vShader = cgCreateProgram(vContext,
+ CG_SOURCE, vertexShaderString,
+ vProfile, NULL, NULL);
+ }
+ free(vertexShaderString);
+
+ /*
+ fprintf(stderr,
+ "CgShaderProgram_updateNative: load/bind/enable vertex shader program\n");
+ */
+ cgGLLoadProgram(vShader);
+ cgGLBindProgram(vShader);
+ cgGLEnableProfile(vProfile);
+ }
+ else {
+ if (vProfile != 0) {
+ cgGLDisableProfile(vProfile);
+ }
+ }
+
+ /* Process fragment shader */
+ /*
+ fprintf(stderr, " fragmentShader == 0x%x\n", fragmentShader);
+ */
+ if (fragmentShader != 0) {
+ fragmentShaderString = strJavaToC(env, fragmentShader);
+ if (fragmentShaderString == NULL) {
+ return;
+ }
+
+ /*
+ * TODO: need to check whether the shader has changed and free up the
+ * old shader before allocating a new one (like we do for texture)
+ */
+ if (fContext == 0) {
+ /* Use GL_ARB_fragment_program extension if supported by video card */
+ if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1)) {
+ fprintf(stderr, "Using CG_PROFILE_ARBFP1\n");
+ fProfile = CG_PROFILE_ARBFP1;
+ }
+ else if (cgGLIsProfileSupported(CG_PROFILE_FP20)) {
+ fprintf(stderr, "Using CG_PROFILE_FP20\n");
+ fProfile = CG_PROFILE_FP20;
+ }
+ else {
+ fprintf(stderr,
+ "Fragment programming extensions (GL_ARB_fragment_program or\n"
+ "GL_NV_fragment_program) not supported, exiting...\n");
+ return;
+ }
+
+ cgSetErrorCallback(cgErrorCallback);
+
+ fContext = cgCreateContext();
+
+ /* create the fragment shader */
+ fprintf(stderr,
+ "CgShaderProgram_updateNative: create fragment shader program\n");
+ fShader = cgCreateProgram(fContext,
+ CG_SOURCE, fragmentShaderString,
+ fProfile, NULL, NULL);
+ }
+ free(fragmentShaderString);
+
+ cgGLLoadProgram(fShader);
+ cgGLBindProgram(fShader);
+ /*
+ fprintf(stderr,
+ "CgShaderProgram_updateNative: load/bind/enable fragment shader program\n");
+ */
+ cgGLEnableProfile(fProfile);
+ }
+ else {
+ if (fProfile != 0) {
+ cgGLDisableProfile(fProfile);
+ }
+ }
+#endif /* COMPILE_CG_SHADERS */
+
+}
+/* KCR: END CG SHADER HACK */
+
+#endif /* 0 */