Code Search for Developers
 
 
  

GzzGL-jni.cxx from gzz at Krugle


Show GzzGL-jni.cxx syntax highlighted

/*
GzzGL-jni.cxx
 *    
 *    Copyright (c) 2003, Tuomas J. Lukka
 *    
 *    This file is part of Gzz.
 *    
 *    Gzz is free software; you can redistribute it and/or modify it under
 *    the terms of the GNU Lesser General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *    
 *    Gzz is distributed in the hope that it will be useful, but WITHOUT
 *    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 *    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
 *    Public License for more details.
 *    
 *    You should have received a copy of the GNU Lesser General
 *    Public License along with Gzz; if not, write to the Free
 *    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *    
 *    
 */
/*
 * Written by Tuomas J. Lukka
 */

#include <vector>
#include "gzz_gfx_gl_GL.h"

#include "librenderables/Renderables.hxx"
#include "librenderables/RealRenderables.hxx"

#include "libcallgl/callgl.hxx"
#include "libtext/Text.hxx"
#include "libutil/Vec23.hxx"
#include "libutil/Debug.hxx"
#include "libutil/buildmipmaps.hxx"

#include "libos/Os.hxx"

//obsolete #include "libimagecache/ImageCache.hxx"

using namespace Vec23;

using Text::DenseGlyphs;

using std::cout;
using std::cerr;

Os::WindowSystem *ws;
using Util::ObjectStorer;
using Os::Image;

using Renderables::Renderable0;
using Renderables::Renderable1;
using Renderables::Renderable2;
using Renderables::Renderable3;
using Renderables::TextRenderer;


// XXX MEMLEAK
struct RealFont {
    Text::Font *f;
    Renderables::TextRenderer *rend;
   RealFont(Text::Font *f) : f(f) {
       rend = new Renderables::TextRenderer(f);
   }
   float getGlyphWidth(int c) { return rend->g.getGlyphWidth(c); }
};

typedef std::vector<GLubyte> ByteVector;

ObjectStorer<Os::RenderingSurface> windows("windows");
ObjectStorer<Image> images("images");
ObjectStorer<Mosaic::MosaicTile> imagetiles("imagetiles");
ObjectStorer<RealFont> fonts("fonts");
ObjectStorer<Renderable0> renderable0s("renderable0s");
ObjectStorer<Renderable1> renderable1s("renderable1s");
ObjectStorer<Renderable2> renderable2s("renderable2s");
ObjectStorer<Renderable3> renderable3s("renderable3s");
ObjectStorer<ByteVector> bytevectors("bytevectors");

extern ObjectStorer<Paper::Paper> papers;

Renderables::Renderer renderer;

Mosaic::MosaicBuilder *mosaicbuilder;

Os::Window *defaultWindow; // A kludge

DBGVAR(dbg, "JNI.general");
DBGVAR(dbg_event, "JNI.event");

// FPS
DBGVAR(dbg_fps, "JNI.fps");
DBGVAR(dbg_fps_cout, "JNI.fps_console");

struct JavaException { };

JNIEnv *jnienv_eventloop;

vector<int> contextStack;

/** Converts jstring to unistring
 *
 * Unistring type currently defined at 
 * gzz/gfx/librenderables/Renderables.hxx
 * 
 * @param env the JNI interface pointer
 */
Renderables::unicodecharvector jstr2unistr(JNIEnv *env, jstring jstr) {
  const jchar *strptr = env->GetStringChars(jstr, 0);
  Renderables::unicodecharvector unistr(strptr, strptr + env->GetStringLength(jstr));
  env->ReleaseStringChars(jstr, strptr);
  return unistr;
}
/** Converts jstring to std::string through UTF-8 transformation */
std::string jstr2stdstr(JNIEnv *env, jstring jstr) {
  const char *strptr = env->GetStringUTFChars(jstr, 0);
  std::string stdstr(strptr, env->GetStringUTFLength(jstr));
  env->ReleaseStringUTFChars(jstr, strptr);
  return stdstr;
}
/** Converts unistring to jstring */
jstring unistr2jstr(JNIEnv *env, Renderables::unicodecharvector unistr) {
  return env->NewString(&(unistr[0]), unistr.size());
}
/** Converts std::string to jstring through UTF-8 transformation */
jstring stdstr2jstr(JNIEnv *env, std::string stdstr) {
  return env->NewStringUTF(stdstr.c_str());
}

Os::RenderingSurface *getWindowByWID(int wid) {
    return  (wid<0 ? defaultWindow : windows.get(wid));
}

void setWindow(int wid = -1) {
    Os::RenderingSurface *win = getWindowByWID(wid);
    if(!win->setCurrent()) {
	  cerr << "Couldn't set window to current -> returning\n";
	  return;
    }
    contextStack.push_back(wid);
    DBG(dbg) << "Set current "<<wid<<"\n";

}
void releaseWindow() {
    if(contextStack.size() == 0) {
	  cerr << "TRYING TO RELEASE CONTEXT WHEN STACK EMPTY!!! PLEASE REPORT BUG!";
	  return;
    }
    int wid = contextStack[contextStack.size()-1];
    contextStack.pop_back();
    Os::RenderingSurface *win = getWindowByWID(wid);
    if(!win->releaseCurrent()) {
	  cerr << "Couldn't release window current!!!";
	  exit(17);
    }
    if(contextStack.size() != 0) {
	getWindowByWID(contextStack[contextStack.size()-1])->setCurrent();
    }
    DBG(dbg) << "Release current "<<wid<<"\n";
}

/** If an exception occurred, print a debug message for it and clear it.
*/
void javaExc(JNIEnv *env, const char *where) {
    if(env->ExceptionOccurred()) {
	cerr << "Exception in "<<where<<"\n";
         env->ExceptionDescribe();
         env->ExceptionClear();
    }
}

struct GZZJNIEventHandler : public Os::Eventhandler {

    jobject globalRef;
    jclass globalclass; // must keep for mid to remain valid
    jmethodID mid_repaint;
    jmethodID mid_keystroke;
    jmethodID mid_mousepress;
    jmethodID mid_timeout;
    jmethodID mid_windowClosed;

    GZZJNIEventHandler(JNIEnv *env, jobject globalRef) : globalRef(globalRef) {
	if(globalRef) {
	    jclass cls = env->GetObjectClass(globalRef);
	    globalclass = (jclass)env->NewGlobalRef(cls);
	    mid_repaint = env->GetMethodID(globalclass,
			 "repaint", "()V");
	    mid_keystroke =
		 env->GetMethodID(cls,
			 "keystroke", "(Ljava/lang/String;)V");
	    mid_mousepress =
	      env->GetMethodID(cls, "mouse", "(IIII)V");
	    mid_timeout =
	      env->GetMethodID(cls, "timeout", "(I)V");
	    mid_windowClosed =
	      env->GetMethodID(cls, "windowClosed", "()V");
	}
    }
    ~GZZJNIEventHandler() {
    }
    void repaint() {
	DBG(dbg_event) << "CALLING REPAINT!!!\n";
	jnienv_eventloop->CallVoidMethod(globalRef, mid_repaint);
	javaExc(jnienv_eventloop, "repaint");

	// jnienv_eventloop->DeleteLocalRef(cls);

	DBG(dbg_event) << "CALLED REPAINT\n";
    }
    virtual void keystroke(const char *str) {
	DBG(dbg_event) << "Keystroke being sent to java: '"<<str<<"' \n";
	jstring jstr = jnienv_eventloop->NewStringUTF(str);
	DBG(dbg_event) << "Keystroke has been sent\n";

	jnienv_eventloop->CallVoidMethod(globalRef, mid_keystroke, jstr);
	javaExc(jnienv_eventloop, "keystroke");

	DBG(dbg_event) << "Call finished\n";
    }

    virtual void mouse(int x, int y, int button, int type) {

        jnienv_eventloop->CallVoidMethod(globalRef, mid_mousepress, x, y, button, type);
	javaExc(jnienv_eventloop, "mouse");
    }
    virtual void timeout(int id) {
        jnienv_eventloop->CallVoidMethod(globalRef, mid_timeout, id);
	javaExc(jnienv_eventloop, "timeout");
    }
    virtual void windowClosed() {
        jnienv_eventloop->CallVoidMethod(globalRef, mid_windowClosed);
	javaExc(jnienv_eventloop, "windowClosed");
    }
};

extern "C" {

int inited = 0;

JNIEXPORT jstring JNICALL Java_gzz_gfx_gl_GL_1Testing_loopUnistrConv
(JNIEnv *env, jobject obj, jstring jstr) {
  return unistr2jstr(env, jstr2unistr(env, jstr));
}

JNIEXPORT jstring JNICALL Java_gzz_gfx_gl_GL_1Testing_loopStdstrConv
(JNIEnv *env, jobject obj, jstring jstr) {
  return stdstr2jstr(env, jstr2stdstr(env, jstr));
}

JNIEXPORT jdouble JNICALL Java_gzz_gfx_gl_GL_1Testing_useAtof
(JNIEnv *env, jobject obj, jstring jstr) {
  return (jdouble) atof(jstr2stdstr(env, jstr).c_str());
}

JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_init
  (JNIEnv *env, jclass, jint) {
      if(inited++) {
	  cerr << "Already inited: "<<(inited-1)<<"\n";
	  return 0;
      }
      DBG(dbg) << "Initializing GZZGL\n";
      ws = Os::WindowSystem::getInstance();
      DBG(dbg) << "Creating one new window for initialization purposes\n";
      defaultWindow = ws->openWindow(0, 0, 2, 2);
      DBG(dbg) << "Setting it current to get a gl context\n";

      setWindow();

      GZZJNIEventHandler *eh = new GZZJNIEventHandler(env, 0);
      eh = eh; // eat warning
      DBG(dbg) << "Creating texturefactory\n";
      Mosaic::Texture2DFactory *fact =
	new Mosaic::Texture2DFactory(
	    new Mosaic::Raster<Mosaic::Format::RGBA>(2048, 2048)
	    );
      DBG(dbg) << "Initializing Mosaicbuilder\n";
      mosaicbuilder = new Mosaic::MosaicBuilder(fact);
      DBG(dbg) << "Returning\n";


      // We don't release the window here, to leave the context
      // current.
      // releaseWindow();
    return 0;
  }

// RenderingSurface

JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_createStableRenderingSurfaceImpl
  (JNIEnv *env, jclass, jint w, jint h) {
	Os::RenderingSurface *win = ws->openStableOffScreen(w, h);
	return windows.add(win);
}

// Window

JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_createWindowImpl
  (JNIEnv *env, jclass, jint x, jint y, jint w, jint h, jobject eh) {
      DBG(dbg) << "Creating new window for Java "<<x<<" "<<y<<" "<<w<<" "<<h<<"\n";
      jobject ehglobal = env->NewGlobalRef(eh);
      GZZJNIEventHandler *evh = new GZZJNIEventHandler(env, ehglobal);
      Os::Window *win = ws->openWindow(x, y, w, h);
      DBG(dbg) << "Setting its eventhandler to "<<((int)evh)<<"\n";
      win->setEventHandler(evh);
      DBG(dbg) << "Return to J\n";
      return windows.add(win);
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_deleteWindow
  (JNIEnv *env, jclass, jint id) {

      // Window *w = windows.get(id);
      // GZZJNIEventHandler *h = (GZZJNIEventHandler *)w->getEventHandler();
      // env->DeleteGlobalRef(h->globalRef);
      windows.remove(id);
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_getWindowSize
  (JNIEnv *env, jclass, jint id, jobject rect) {
      Os::RenderingSurface *win = windows.get(id);
      int xywh[4];
      win->getSize(xywh);

      jclass clazz = env->GetObjectClass(rect);

      jfieldID f;
      f = env->GetFieldID(clazz, "x", "I");
      if(f!=0) env->SetIntField(rect, f, xywh[0]);
      f = env->GetFieldID(clazz, "y", "I");
      if(f!=0) env->SetIntField(rect, f, xywh[1]);
      f = env->GetFieldID(clazz, "width", "I");
      if(f!=0) env->SetIntField(rect, f, xywh[2]);
      f = env->GetFieldID(clazz, "height", "I");
      if(f!=0) env->SetIntField(rect, f, xywh[3]);

  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_addTimeoutWindow
  (JNIEnv *env, jclass, jint id, jint ms, jint tid) {
      Os::Window *w = (Os::Window *)windows.get(id);
      w->addTimeout(ms, tid);
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1Window_1setCurrent
  (JNIEnv *env, jclass, jint id) {
      setWindow(id);
}

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1Window_1release
  (JNIEnv *env, jclass, jint id) {
      releaseWindow();
}

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1Window_1move
  (JNIEnv *env, jclass, jint id, jint x, jint y) {
      Os::Window *w = (Os::Window *)windows.get(id);
      DBG(dbg) << "Move window "<<id<<" "<<x<<" "<<y<<" at "<<(int)w<<"\n";
      w->move(x,y);
}

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1Window_1resize
  (JNIEnv *env, jclass, jint id, jint wid, jint h) {
      Os::Window *w = (Os::Window *)windows.get(id);
      w->resize(wid,h);
}


// ImageCache
/* THIS DOES NOT COMPILE ON JDK 1.4 !!!!!!

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GZZGL_writeToImageCache
  (JNIEnv *env, jclass cls, jstring juri, jcharArray jbuf, jint len) {

    char uri[] = (char *)((*env)->GetStringUTFChars(env, juri, 0));
    char buf[] = (char *)((*env)->GetCharArrayElements(env, jbuf, 0));
//    imageCache->write(new string(uri), buf, len);
    (*env)->ReleaseStringUTFChars(env, juri, uri);
    (*env)->ReleaseCharArrayElements(env, jbuf, buf, 0);
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GZZGL_getFromImageCache
  (JNIEnv *env, jclass cls, jstring juri, jint lod) {

    char uri[] = (char *)((env *)->GetStringUTFChars(env, juri, 0));
    string suri = new string(uri);
//    GdkPixbuf *pb = imageCache->getPixbuf(suri, lod);
    if (pb == START_PIXBUF_BACKGROUND_LOADER) {
	methodID mid = (*env)->GetStaticMethodID(env, cls,
	    "startBackgroundImageLoader", "(Ljava/lang/String;)V");
        if (mid != 0) {
	    (*env)->CallStaticVoidMethod(env, cls, mid, juri);
	}
//	pb = imageCache->getPixbuf(suri, lod);
    }
    (*env)->ReleaseStringUTFChars(env, juri, uri);
*/

// Image

JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_createImageImpl
  (JNIEnv *env, jclass, jstring filename) {
      std::string utf = jstr2stdstr(env, filename);
      Image *img = ws->loadImageFile(utf.c_str());
      return images.add(img);
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_deleteImage
  (JNIEnv *, jclass, jint img) {
      images.remove(img);
  }

JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_getImageSize
  (JNIEnv *, jclass, jint img, jint dimNo) {
      Image *i = images[img];
      if(dimNo == 0)
	  return i->w;
      else
	  return i->h;
}

// TexRect

JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_createTexRectImpl
  (JNIEnv *, jclass, jint id)
{
    DBG(dbg) << "CreateTexRectImpl\n";
    setWindow();
    Image *img = images.get(id);
    DBG(dbg) << "got image\n";
    Mosaic::MosaicTile *t = new Mosaic::MosaicTile();
    int w = img->w;
    int h = img->h;
    *t = mosaicbuilder->alloc(w, h);
    DBG(dbg) << "got mosaic tile\n";
    img->loadInto(*t, 0, 0, w, h);
    DBG(dbg) << "loaded image into tile\n";
    mosaicbuilder->prepare();
    DBG(dbg) << "prepared builder\n";
    releaseWindow();
    DBG(dbg) << "Created tex rect, in "<<t->getRect().tex<<"\n";
    return imagetiles.add(t);
}

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_deleteTexRect
  (JNIEnv *, jclass, jint id)
{
    // MEMLEAK! MUST FREE MOSAICTILE FIRST!
    imagetiles.remove(id);
}

JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_getTexRectTexID
  (JNIEnv *, jclass, jint id)
{
    return imagetiles[id]->getRect().tex.getTexId();
}

JNIEXPORT jdouble JNICALL Java_gzz_gfx_gl_GL_getTexRectTexCoord
  (JNIEnv *, jclass, jint id, jint coord, double v)
{
    Mosaic::Rect &rect = imagetiles[id]->getRect();
    if(coord == 0) {
	return Renderables::lerp(rect.tx1, rect.tx2, v);
    } else {
	return Renderables::lerp(rect.ty1, rect.ty2, v);
    }
}

// Texture
JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_impl_1createTexture
  (JNIEnv *, jclass) {
      setWindow();
      GLuint ret;
      glGenTextures(1, &ret);
      DBG(dbg) << "Created texture id "<<ret<<"\n";
      GLERR
      releaseWindow();
      return ret;
}

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1deleteTexture
  (JNIEnv *, jclass, jint id) {
      setWindow();
      GLuint rel = id;
      glDeleteTextures(1, &rel);
      releaseWindow();
}

GLenum tokenFromJstring(JNIEnv *env, jstring token) {
    std::string str = jstr2stdstr(env, token);
    GLenum ret = CallGL::getTokenValue(str.c_str());
    return ret;
}

bool hasGenMipmaps() {
    static int initialized;
    static bool hasExtension;
    // XXX: the test should probably be done elsewhere
    if (!initialized) {
	hasExtension = strstr((const char *)glGetString(GL_EXTENSIONS), 
			      "GL_SGIS_generate_mipmap") != 0;
	initialized = true;
    }
    return hasExtension;
}

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1Texture_1loadNull2D
  (JNIEnv *env, jclass, jint id, jint level, jstring internalFormat_s,
    jint w, jint h, jint border, jstring format_s, jstring type_s) {
    int internalFormat = tokenFromJstring(env, internalFormat_s);
    int format = tokenFromJstring(env, format_s);
    int type = tokenFromJstring(env, type_s);

    glBindTexture(GL_TEXTURE_2D, id);
    // Null = just set size and texture format. 
    glTexImage2D(GL_TEXTURE_2D,
		level, internalFormat, w, h, border, format, type, NULL);
    glBindTexture(GL_TEXTURE_2D, 0);
    GLERR
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1Texture_1texImage2D
  (JNIEnv *env, jclass, jint id, jint level, jstring internalFormat_s,
    jint w, jint h, jint border, jstring format_s, jstring type_s,
    jbyteArray jdata) {
    int internalFormat = tokenFromJstring(env, internalFormat_s);
    int format = tokenFromJstring(env, format_s);
    int type = tokenFromJstring(env, type_s);
    jbyte *data = env->GetByteArrayElements(jdata, 0);

    glBindTexture(GL_TEXTURE_2D, id);
    glTexImage2D(GL_TEXTURE_2D,
		level, internalFormat, w, h, border, format, type, data);
    env->ReleaseByteArrayElements(jdata, data, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
    GLERR
  }


JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1Texture_1loadSubImage
  (JNIEnv *env, jclass, jint id, jint level, jint imageId, jint x, jint y,
    jint xoffs, jint yoffs, jint w, jint h) {

    glBindTexture(GL_TEXTURE_2D, id);
    GLERR
    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
    GLERR

    Image *img = images.get(imageId);
    img->loadIntoTexture(level, x, y, xoffs, yoffs, w, h);
    GLERR
    glBindTexture(GL_TEXTURE_2D, 0);
    GLERR
}


JNIEXPORT jbyteArray JNICALL Java_gzz_gfx_gl_GL_impl_1Texture_1getCompressedTexImage
  (JNIEnv *env, jclass, jint id, jint lod) {
      int size;
      glBindTexture(GL_TEXTURE_2D, id);
      glGetTexLevelParameteriv(GL_TEXTURE_2D, lod, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &size);
      GLERR;
      jbyteArray arr = env->NewByteArray(size);
      jbyte *b = env->GetByteArrayElements(arr, 0);
      glGetCompressedTexImageARB(GL_TEXTURE_2D, lod, b);
      env->ReleaseByteArrayElements(arr, b, 0);
      glBindTexture(GL_TEXTURE_2D, 0);
      GLERR;
     return arr;
}

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1Texture_1getTexImage
 (JNIEnv *env, jclass, jint id, jint level, jstring jformat, jstring jtype,
    jbyteArray jdata) {
    glBindTexture(GL_TEXTURE_2D, id);
    GLenum format = tokenFromJstring(env, jformat);
    GLenum type = tokenFromJstring(env, jtype);
    jbyte *b = env->GetByteArrayElements(jdata, 0);

    glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
    glPixelStorei(GL_PACK_ROW_LENGTH, 0);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);

    glGetTexImage(GL_TEXTURE_2D, level, format, type, b);

    glPopClientAttrib();

    env->ReleaseByteArrayElements(jdata, b, 0);
    GLERR
 }



JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1Texture_1compressedTexImage
 (JNIEnv *env, jclass, jint id, jint level, jstring jinternalFormat, jint width, jint height,
	jint border, jbyteArray jdata) {
     int size = env->GetArrayLength(jdata);
     jbyte *data = env->GetByteArrayElements(jdata, 0);
     glBindTexture(GL_TEXTURE_2D, id);
     GLenum internalFormat = tokenFromJstring(env, jinternalFormat);

     glCompressedTexImage2DARB(GL_TEXTURE_2D, level, internalFormat,
		    width, height, border, size, data);
     glFinish(); // Appears that NV 4191 drivers need this.
     glBindTexture(GL_TEXTURE_2D, 0);
     env->ReleaseByteArrayElements(jdata, data, 0);
     GLERR;

}

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1Texture_1downsampleInto
  (JNIEnv *env, jclass, jint id, jint intoid, jstring targetstr, jint level, jstring internalFormat, jstring transferType) 
{
    GLenum target = tokenFromJstring(env, targetstr);
    GLenum intern = tokenFromJstring(env, internalFormat);
    GLenum trans = tokenFromJstring(env, transferType);
    glBindTexture(target, id);
    GLint w=0,h=0;
    // XXX Only does 2D
    glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &w);
    glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &h);

    GLubyte *data = new GLubyte[w*h*4]; // assuming 4 components

    glPixelStorei(GL_PACK_ROW_LENGTH, 0);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    glGetTexImage(target, level, trans, GL_UNSIGNED_BYTE, data);


    glBindTexture(target, intoid);
    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
    glTexImage2D(target, 0, intern, w, h, 0, trans, GL_UNSIGNED_BYTE,
	    data);

    delete[] data;
    glBindTexture(target, 0);


}

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1Texture_1copyTexImage2D(
    JNIEnv *env, jclass, jint id, jint wid, jstring bufferstr,
    jstring targetstr, jint level,
    jstring iforstring, jint x, jint y, jint w, jint h,
    jint border) {
    setWindow(wid);
    GLenum buffer = tokenFromJstring(env, bufferstr);
    GLenum target = tokenFromJstring(env, targetstr);
    GLenum ifor = tokenFromJstring(env, iforstring);
    glBindTexture(target, id);
    glReadBuffer(buffer);
    DBG(dbg) << "Copyteximage "<<target<<" "<<level<<" "<<ifor<<" "
	    <<x<<" "<<y<<" "<<w<<" "<<h<<" "<<border<<"\n";
    glCopyTexImage2D(target, level, ifor, x, y, w, h, border);
    glBindTexture(target, 0);
    GLERR
    releaseWindow();
}

Texture::TextureParam textureParams(JNIEnv *env, jobjectArray params) {

      Texture::TextureParam p;

      for(int i=0; i<env->GetArrayLength(params)-1; i+=2) {
	  std::string k = jstr2stdstr(env, (jstring)(env->GetObjectArrayElement(params, i)));
	  std::string v = jstr2stdstr(env, (jstring)(env->GetObjectArrayElement(params, i+1)));
	  p.setParam(k.c_str(), v.c_str());
      }

      return p;
}

JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_impl_1Texture_1shade
  (JNIEnv *env, jclass, jint id, jint w, jint h, jint d, jint comp, 
	jstring internalFormat,
	jstring format,
	    jstring name, jobjectArray params, jboolean shade_all_levels) {
      setWindow();
      DBG(dbg)<<"Shade into "<<id<<"\n";

      std::string name_utf = jstr2stdstr(env, name);

      Texture::Texture *s = Texture::Texture::getTexture(name_utf.c_str());

      if(!s) {
	  return 0;
      }

      Texture::TextureParam p = textureParams(env, params);

      float *value = new float[w * h * (d==0?1:d) * comp];

      GLenum target = (d == 0) ? GL_TEXTURE_2D : GL_TEXTURE_3D;

      glBindTexture(target, id);

      int buildmipmaps = 0;

      if (!shade_all_levels) {
	  if (hasGenMipmaps()) {
	      glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
	      GLERR;
	  } else {
	      buildmipmaps = 1;
	  }
      } 
	
      int level;
      for (level = 0; ; level++) {
	  s->render(&p, w, h, (d==0?1:d), comp, value);

	  if (buildmipmaps) {
	      assert(d==0); // 3D buildmipmaps not implemented in libutil
	      Util::buildmipmaps(GL_TEXTURE_2D, 
				 tokenFromJstring(env, internalFormat),
				 w, h, 
				 tokenFromJstring(env, format),
				 GL_FLOAT,
				 value);
	  } else 
	  if (d == 0)
	      glTexImage2D(GL_TEXTURE_2D, level,
			   tokenFromJstring(env, internalFormat),
			   w, h, 0, 
			   tokenFromJstring(env, format),
			   GL_FLOAT,
			   value);
	  else
	      glTexImage3D(GL_TEXTURE_3D, level,
			   tokenFromJstring(env, internalFormat),
			   w, h, d, 0, 
			   tokenFromJstring(env, format),
			   GL_FLOAT,
			   value);

	  GLERR;
	      
	  if (! (shade_all_levels && (w > 1 || h > 1 || d > 1))) break;
	  
	  w = (w + 1) >> 1;
	  h = (h + 1) >> 1;
	  d = (d + 1) >> 1;
      } 
      
      if (shade_all_levels) {
	  glTexParameterf(target, GL_TEXTURE_BASE_LEVEL, 0);
	  glTexParameterf(target, GL_TEXTURE_MAX_LEVEL, level);
      }

      glBindTexture(target, 0);
      GLERR;

      delete[] value;
      delete s;

      releaseWindow();

      return 1;
}


// OpenGL Program
JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_impl_1createProgram
  (JNIEnv *, jclass) {
      setWindow();
      GLuint ret;
#ifdef GL_VERTEX_PROGRAM_ARB
      glGenProgramsARB(1, &ret);
      GLERR;
#endif
      releaseWindow();
      return ret;
}

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1deleteProgram
  (JNIEnv *, jclass, jint id) {
#ifdef GL_VERTEX_PROGRAM_ARB
      setWindow();
      GLuint rel = id;
      glDeleteProgramsARB(1, &rel);
      releaseWindow();
#endif
}

JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_impl_1Program_1load
  (JNIEnv *env, jclass, jint id, jstring prog) {
#ifdef GL_VERTEX_PROGRAM_ARB
      setWindow();
      std::string prog_utf = jstr2stdstr(env, prog);
      CallGL::loadProgram(id, prog_utf);
      releaseWindow();
#endif
      return 1;
  }


// Font

JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_createFontImpl
  (JNIEnv *env, jclass, jstring file, jint pt) {
      DBG(dbg) << "creatFontImpl\n";
      setWindow();
      std::string utf = jstr2stdstr(env, file);
      Text::Font *gf0 = ws->loadFont(utf.c_str(), pt);
      Text::Font *gf = new Text::Font_Bordered(
		    gf0, 10);
      RealFont *f = new RealFont(gf);
      releaseWindow();
      return fonts.add(f);
  }

JNIEXPORT jfloat JNICALL Java_gzz_gfx_gl_GL_getFontHeight
  (JNIEnv *, jclass, jint i) {
      return fonts.get(i)->f->getLineHeight();
  }

JNIEXPORT jfloat JNICALL Java_gzz_gfx_gl_GL_getFontYOffs
  (JNIEnv *, jclass, jint i) {
      return fonts.get(i)->f->getLineOffset();
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_deleteFont
  (JNIEnv *, jclass, jint i) {
      fonts.remove(i);
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_putFontWidths
 (JNIEnv *env, jclass, jint fontId, jfloatArray widths) {

     int arrayLength = env->GetArrayLength(widths);
     jfloat *w = env->GetFloatArrayElements(widths, 0);
     RealFont *font = fonts.get(fontId);

     for(int i=0; i<arrayLength; i++) {
	 w[i] = font->getGlyphWidth(i);
     }

     env->ReleaseFloatArrayElements(widths, w, 0);
 }


// DisplayList

JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_createDisplayListImpl
  (JNIEnv *, jclass) {
      setWindow();
      int l = glGenLists(1);
      releaseWindow();
      if(!l) {
	  cerr << "Couldn't allocate display list\n";
	  exit(25);
      }
      return l;
  }
JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_startCompile
  (JNIEnv *, jclass, jint l, jint wid) {
      DBG(dbg) << "Start list compilation "<<l<<"\n";

      setWindow(wid);

      GLERR
      glNewList(l, GL_COMPILE);
      GLERR
  }
JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_endCompile
  (JNIEnv *, jclass, jint, jint wid) {
      DBG(dbg) << "End list compilation\n";
      GLERR
      glEndList();
      GLERR

      releaseWindow();
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_compileCallGL
  (JNIEnv *env, jclass, jint l, jstring s) {
      DBG(dbg) << "Start callgl\n";
      setWindow();
      DBG(dbg) << "set win\n";
      std::string utf = jstr2stdstr(env, s);
      DBG(dbg) << "got str\n";
      CallGL::callGL(utf.c_str(), l);
      DBG(dbg) << "called\n";
      releaseWindow();
      DBG(dbg) << "released window\n";
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_deleteDisplayList
  (JNIEnv *, jclass, jint l) {
      DBG(dbg) << "Delete display list (XXX Might crash if contexts wrong)\n";
      glDeleteLists(l, 1);
      DBG(dbg) << "Deleted display list\n";
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1DisplayList_1call
  (JNIEnv *, jclass, jint l, jint w) {
      setWindow(w);
      glCallList(l);
      releaseWindow();
}

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1DisplayList_1call0
  (JNIEnv *, jclass, jint l) {
      glCallList(l);
}


// ByteVector
//
JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_createByteVectorImpl
  (JNIEnv *, jclass, jint size) {
      ByteVector *vec = new ByteVector(size);
      DBG(dbg) << "Alloc byte vector "<<(int)vec<<"\n";
      return bytevectors.add(vec);
}

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_deleteByteVector
  (JNIEnv *, jclass, jint id) {
      DBG(dbg) << "Delete byte vector "<<(int)bytevectors[id]<<"\n";
      bytevectors.remove(id);
}

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1ByteVector_1readFromBuffer
  (JNIEnv *env, jclass, jint id, jint winid, jstring buffer, 
	jint x, jint y, jint w, jint h, 
	jstring format, jstring type) 
{
    setWindow(winid);
    ByteVector *v = bytevectors[id];
    GLenum buf = tokenFromJstring(env, buffer);
    GLenum form = tokenFromJstring(env, format);
    GLenum typ = tokenFromJstring(env, type);

    glPushAttrib(GL_PIXEL_MODE_BIT);
    glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
    glReadBuffer(buf);
    glPixelStorei(GL_PACK_ROW_LENGTH, 0);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    glReadPixels(x, y, w, h, form, typ, &((*v)[0]));
    GLERR
    glPopClientAttrib();
    glPopAttrib();
    releaseWindow();
}

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_impl_1ByteVector_1drawPixels
  (JNIEnv *env, jclass, jint id, jint winid, 
	jint x, jint y, jfloat z, jint w, jint h, 
	jstring format, jstring type) 
{
    setWindow(winid);
    ByteVector *v = bytevectors[id];
    GLenum form = tokenFromJstring(env, format);
    GLenum typ = tokenFromJstring(env, type);

    glPushAttrib(GL_PIXEL_MODE_BIT);
    glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glRasterPos3f(x, y, z);
    glDrawPixels(w, h, form, typ, &((*v)[0]));
    GLERR
    glPopClientAttrib();
    glPopAttrib();
    releaseWindow();
}


JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_impl_1ByteVector_1get__II
 (JNIEnv *env, jclass, jint id, jint ind) {
    return (*bytevectors[id])[ind];
}

JNIEXPORT jbyteArray JNICALL Java_gzz_gfx_gl_GL_impl_1ByteVector_1get__I
  (JNIEnv *env, jclass, jint id) {
    int len = bytevectors[id]->size();
    jbyteArray arr = env->NewByteArray(len);
    env->SetByteArrayRegion(arr, 0, len, (jbyte*) &(*(bytevectors[id]))[0]);
    return arr;
}

JNIEXPORT jintArray JNICALL Java_gzz_gfx_gl_GL_impl_1ByteVector_1getInts
  (JNIEnv *env, jclass, jint id) {
    int len = bytevectors[id]->size() / 4;
    jintArray arr = env->NewIntArray(len);
    env->SetIntArrayRegion(arr, 0, len, (jint*) (&(*(bytevectors[id]))[0]));
    return arr;
}


JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_impl_1ByteVector_1shade
  (JNIEnv *env, jclass, jint id, jint w, jint h, jint d, jint comp, 
	    jstring name, jobjectArray params) {
      setWindow();
      DBG(dbg)<<"Shade into "<<id<<"\n";

      std::string name_utf = jstr2stdstr(env, name);

      Texture::Texture *s = Texture::Texture::getTexture(name_utf.c_str());

      if(!s) {
	  return 0;
      }

      Texture::TextureParam p = textureParams(env, params);

      bytevectors[id]->resize(w * h * (d==0 ? 1 : d) * comp * 4);
      s->render( &p, w, h, (d==0?1:d), comp, (float*)&((*bytevectors[id])[0]));
      return 1;
}


// Renderable

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_deleteRenderable0
  (JNIEnv *, jclass, jint id) {
      DBG(dbg) << "Delete renderable0 "<<id<<"\n";
      renderable0s.remove(id);
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_deleteRenderable1
  (JNIEnv *, jclass, jint id) {
      DBG(dbg) << "Delete renderable1 "<<id<<"\n";
      renderable1s.remove(id);
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_deleteRenderable2
  (JNIEnv *, jclass, jint id) {
      DBG(dbg) << "Delete renderable2 "<<id<<"\n";
      renderable2s.remove(id);
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_deleteRenderable3
  (JNIEnv *, jclass, jint id) {
      DBG(dbg) << "Delete renderable3 "<<id<<"\n";
      renderable3s.remove(id);
  }
// functions

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_startContext
  (JNIEnv *env, jclass) {
    setWindow();
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_endContext
  (JNIEnv *env, jclass) {
    releaseWindow();
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_eventLoop
  (JNIEnv *env, jclass, jboolean wait) {
      DBG(dbg) << "Going into eventloop in C++\n";
      try {
	jnienv_eventloop = env;
	  ws->eventLoop(wait);
      } catch(JavaException e) {
	  cerr << "CAUGHT JAVA EXCEPTION\n";
      }
  }

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_interruptEventloop
  (JNIEnv *env, jclass) {
      DBG(dbg) << "Interrupting C++ eventloop\n";
      ws->interrupt();
      DBG(dbg) << "Done interrupting - should wake soon\n";
  }



#include <sys/time.h>
double getTime() {
  struct timeval t;
  gettimeofday(&t, 0);
  return t.tv_usec*1E-6 + t.tv_sec;
}

JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_renderImpl
  (JNIEnv *env, jclass, jint window,
	jint numinds,
	jintArray j_inds1, jfloatArray j_pts1, 
	jintArray j_interpinds,
	jintArray j_inds2, jfloatArray j_pts2, 
	jintArray j_codes,
	jfloat fract, jboolean standardcoords, jboolean showFinal) {
       DBG(dbg) << "RENDER "<<window<<" "<<numinds<<" "
		<<j_inds1<<" "<<j_pts1<<" "<<
		j_interpinds<<" "<<j_inds2<<" "<<j_pts2<<" "<<j_codes<<"\n";
       GLERR
       DBG(dbg) << "1\n";
       if(standardcoords) 
	   setWindow(window);
       DBG(dbg) << "2\n";

       if(sizeof(jint) != sizeof(jint) ||
	 sizeof(jfloat) != sizeof(float))
	  env->FatalError("Invalid data type sizes!");
       DBG(dbg) << "3\n";

      jint *inds1 = env->GetIntArrayElements(j_inds1, 0);
       DBG(dbg) << "4\n";
      jfloat *pts1 = env->GetFloatArrayElements(j_pts1, 0);
       DBG(dbg) << "5\n";

      jint *inds2 = 0;
      jfloat *pts2 = 0;
      jint *interpinds = 0;
      if(j_inds2 != 0) {
	   DBG(dbg) << "6\n";
	  inds2 = env->GetIntArrayElements(j_inds2, 0);
	  pts2 = env->GetFloatArrayElements(j_pts2, 0);
	  interpinds = env->GetIntArrayElements(j_interpinds, 0);
      }
       DBG(dbg) << "7\n";

      jint *codes = env->GetIntArrayElements(j_codes, 0);

      DBG(dbg) << "Got data\n";

      renderer.setPoints((int)numinds, 
			(int *)inds1, (float *)pts1,
			(int *)interpinds,
			(int *)inds2, (float *)pts2,
			(float)fract, (bool)showFinal);

      DBG(dbg) << "Set datapoints\n";

      if(standardcoords) {
	  int xywh[4];
	  windows.get(window)->getSize(xywh);
	  DBG(dbg) << "Did getSize "<<xywh[0]<<" "<<xywh[1]<<" "<<xywh[2]<<" "
		    <<xywh[3]<<"\n";

	  Renderables::setStandardCoordinates(Vec(xywh[2], xywh[3]));
      }
       GLERR

      DBG(dbg) << "Did stdcoords\n";
      renderer.renderScene((int *)codes, renderable0s, renderable1s, renderable2s, renderable3s);
      DBG(dbg) << "Did renderscene\n";
      windows.get(window)->swapBuffers();
      DBG(dbg) << "Did swapbuffers\n";

      env->ReleaseIntArrayElements(j_codes, codes, JNI_ABORT);

      env->ReleaseIntArrayElements(j_inds1, inds1, JNI_ABORT);
      env->ReleaseFloatArrayElements(j_pts1, pts1, JNI_ABORT);

      if(inds2 != 0) {
	env->ReleaseIntArrayElements(j_inds2, inds2, JNI_ABORT);
	env->ReleaseFloatArrayElements(j_pts2, pts2, JNI_ABORT);
        env->ReleaseIntArrayElements(j_interpinds, interpinds, JNI_ABORT);
      }
      DBG(dbg) << "Did releasearrays\n";
       GLERR

      if(standardcoords) {
	  releaseWindow();
      }


      if(dbg_fps) {
	double new_time = getTime();
	CurrentFPS::current_fps = 1.0/(new_time - CurrentFPS::last_time[CurrentFPS::count]);
	DBG(dbg_fps_cout) << "CurrentFPS: " << CurrentFPS::current_fps << "\n";
	CurrentFPS::count ++;
	CurrentFPS::count %= CurrentFPS::NCounts;
	CurrentFPS::current_fps5 = CurrentFPS::NCounts *
				    1.0/(new_time - CurrentFPS::last_time[CurrentFPS::count]);
        CurrentFPS::last_time[CurrentFPS::count] = new_time;

      }
  }


JNIEXPORT jfloat JNICALL Java_gzz_gfx_gl_GL_timeRenderImpl
  (JNIEnv *env, jclass, jint window, jint iters,
	jint numinds,
	jintArray j_inds1, jfloatArray j_pts1, 
	jintArray j_codes,
	jboolean standardcoords) {
       DBG(dbg) << "RENDER\n";
       GLERR
       if(standardcoords) 
	   setWindow(window);

       if(sizeof(jint) != sizeof(jint) ||
	 sizeof(jfloat) != sizeof(float))
	  env->FatalError("Invalid data type sizes!");

      jint *inds1 = env->GetIntArrayElements(j_inds1, 0);
      jfloat *pts1 = env->GetFloatArrayElements(j_pts1, 0);

      jint *codes = env->GetIntArrayElements(j_codes, 0);

      DBG(dbg) << "Got data\n";

      renderer.setPoints((int)numinds, 
			(int *)inds1, (float *)pts1);

      DBG(dbg) << "Set datapoints\n";

      if(standardcoords) {
	  int xywh[4];
	  windows.get(window)->getSize(xywh);
	  DBG(dbg) << "Did getSize "<<xywh[0]<<" "<<xywh[1]<<" "<<xywh[2]<<" "
		    <<xywh[3]<<"\n";

	  Renderables::setStandardCoordinates(Vec(xywh[2], xywh[3]));
      }
       GLERR


      double t0 = getTime();
      for (int i = 0; i < iters; i++) {
	renderer.renderScene((int *)codes, renderable0s, renderable1s, renderable2s, renderable3s);
	DBG(dbg) << "Did renderscene\n";
	windows.get(window)->swapBuffers();
	DBG(dbg) << "Did swapbuffers\n";
      }
      double t1 = getTime();
      float t = t1 - t0;
      DBG(dbg) << "The time was " << t << " [" << t0 << " - " << t1 << "]\n";

      env->ReleaseIntArrayElements(j_codes, codes, JNI_ABORT);

      env->ReleaseIntArrayElements(j_inds1, inds1, JNI_ABORT);
      env->ReleaseFloatArrayElements(j_pts1, pts1, JNI_ABORT);

      DBG(dbg) << "Did releasearrays\n";
       GLERR

      if(standardcoords) {
	  releaseWindow();
      }

     return t;
  }





JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_setDebugVar
  (JNIEnv *env, jclass, jstring name, jint value) {
      std::string utf = jstr2stdstr(env, name);
      Debug::var(utf.c_str()) = value;
}

JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_getDebugVar
  (JNIEnv *env, jclass, jstring name) {
      std::string utf = jstr2stdstr(env, name);
      int value = Debug::var(utf.c_str()) ;
      return value;
}

JNIEXPORT jobjectArray Java_gzz_gfx_gl_GL_getDebugVarNames
  (JNIEnv *env, jclass) {
      vector<const char *> vec;
      vec = Debug::getVarNames();
      jclass strclass = env->FindClass("java/lang/String");
      jobjectArray result = env->NewObjectArray(vec.size(), 
				  strclass, 0);
      for(unsigned i=0; i<vec.size(); i++)
	  env->SetObjectArrayElement(result, i, 
			  env->NewStringUTF(vec[i]));
      return result;
}

JNIEXPORT jstring JNICALL Java_gzz_gfx_gl_GL_getGLString
  (JNIEnv *env, jclass, jstring name) {
      std::string utf = jstr2stdstr(env, name);
      const char *value = CallGL::getString(utf.c_str()) ;
      return env->NewStringUTF(value);
}

JNIEXPORT jfloatArray JNICALL Java_gzz_gfx_gl_GL_getGLFloat
  (JNIEnv *env, jclass, jstring name) {
      std::string utf = jstr2stdstr(env, name);
      vector<float> vec = CallGL::getFloat(utf.c_str()) ;
      jfloatArray result = env->NewFloatArray(vec.size());
      env->SetFloatArrayRegion(result, 0, vec.size(), &vec[0]);
      return result;
}

JNIEXPORT jfloatArray JNICALL Java_gzz_gfx_gl_GL_getGLProgram
  (JNIEnv *env, jclass, jstring j_target, jstring j_name) {
      std::string target = jstr2stdstr(env, j_target);
      std::string name = jstr2stdstr(env, j_name);
      vector<float> vec = CallGL::getProgram(target.c_str(), name.c_str()) ;
      jfloatArray result = env->NewFloatArray(vec.size());
      env->SetFloatArrayRegion(result, 0, vec.size(), &vec[0]);
      return result;
}

JNIEXPORT jint JNICALL Java_gzz_gfx_gl_GL_getGLProgrami
  (JNIEnv *env, jclass, jstring j_target, jint id, jstring j_name) {
      GLenum target = tokenFromJstring(env, j_target);
      GLenum name = tokenFromJstring(env, j_name);
      glBindProgramARB(target, id);
      GLint res;
      glGetProgramivARB(target, name, &res);
      glBindProgramARB(target, 0);
      return res;
}

JNIEXPORT jfloatArray JNICALL Java_gzz_gfx_gl_GL_getGLTexParameterFloat
  (JNIEnv *env, jclass, jstring target, jint tex, jstring name) {
      std::string utf_target = jstr2stdstr(env, target);
      std::string utf = jstr2stdstr(env, name);
      vector<float> vec = CallGL::getTexParameterFloat(utf_target.c_str(), tex, utf.c_str());
      jfloatArray result = env->NewFloatArray(vec.size());
      env->SetFloatArrayRegion(result, 0, vec.size(), &vec[0]);
      return result;
}

JNIEXPORT jfloatArray JNICALL Java_gzz_gfx_gl_GL_getGLTexLevelParameterFloat
  (JNIEnv *env, jclass, jstring target, jint tex, jint level, jstring name) {
      std::string utf_target = jstr2stdstr(env, target);
      std::string utf = jstr2stdstr(env, name);
      vector<float> vec = CallGL::getTexLevelParameterFloat(utf_target.c_str(), tex, level, utf.c_str()) ;
      jfloatArray result = env->NewFloatArray(vec.size());
      env->SetFloatArrayRegion(result, 0, vec.size(), &vec[0]);
      return result;
}

JNIEXPORT jstring JNICALL Java_gzz_gfx_gl_GL_getGLTokenString
  (JNIEnv *env, jclass, jint value) {
      const char *str = CallGL::getTokenString(value) ;
      return env->NewStringUTF(str);
}

JNIEXPORT jboolean JNICALL Java_gzz_gfx_gl_GL_transform
 (JNIEnv *env, jclass, jint ninds, jintArray j_inds, jfloatArray j_pts,
    jint coordsys, jboolean inverse, jfloatArray j_points, jfloatArray j_into) {
      jint *inds = env->GetIntArrayElements(j_inds, 0);
      jfloat *pts = env->GetFloatArrayElements(j_pts, 0);

      Coords::CoordSet coordset;
      coordset.clean();
      coordset.setPoints((int)ninds, (int*)inds, 
			 (float*)pts, (int*)0,
			 (int*)0, (float*)0, 
			 (float)0, (bool)true);

     int arrayLength = env->GetArrayLength(j_points);
     jfloat *points = env->GetFloatArrayElements(j_points, 0);
     jfloat *into = env->GetFloatArrayElements(j_into, 0);

     Coords::CoordSys *cs = coordset.get(coordsys);
     if(cs != 0) {
	 if(inverse) cs = cs->getInverse();
	 if(cs != 0)
	  for(int i=0; i<arrayLength; i+=3) {
	     ZPt pt(points[i], points[i+1], points[i+2]);
	     ZPt pt2 = cs->transform(pt);
	     into[i] = pt2.x;
	     into[i+1] = pt2.y;
	     into[i+2] = pt2.z;
	  }
      }

      env->ReleaseFloatArrayElements(j_points, points, JNI_ABORT);
      env->ReleaseFloatArrayElements(j_into, into, 0); // These were changed, commit.

      env->ReleaseIntArrayElements(j_inds, inds, JNI_ABORT);
      env->ReleaseFloatArrayElements(j_pts, pts, JNI_ABORT);

      return (cs != 0);
 }

JNIEXPORT jboolean JNICALL Java_gzz_gfx_gl_GL_transform2
 (JNIEnv *env, jclass, jint ninds, jintArray j_inds, jfloatArray j_pts,
	jintArray j_interpinds, jintArray j_inds2, jfloatArray j_pts2,
	jfloat fract, jboolean show1,
    jint coordsys, jboolean inverse, jfloatArray j_points, jfloatArray j_into) {

      jint *inds = env->GetIntArrayElements(j_inds, 0);
      jfloat *pts = env->GetFloatArrayElements(j_pts, 0);

      jint *interpinds = env->GetIntArrayElements(j_interpinds, 0);

      jint *inds2 = env->GetIntArrayElements(j_inds2, 0);
      jfloat *pts2 = env->GetFloatArrayElements(j_pts2, 0);

      Coords::CoordSet coordset;
      coordset.clean();
      coordset.setPoints((int)ninds, (int*)inds, 
			 (float*)pts, (int*)interpinds,
			 (int*)inds2, (float*)pts2, 
			 (float)fract, (bool)show1);

     int arrayLength = env->GetArrayLength(j_points);
     jfloat *points = env->GetFloatArrayElements(j_points, 0);
     jfloat *into = env->GetFloatArrayElements(j_into, 0);

     Coords::CoordSys *cs = coordset.get(coordsys);
     if(cs != 0) {
	 if(inverse) cs = cs->getInverse();
	  for(int i=0; i<arrayLength; i+=3) {
	     ZPt pt(points[i], points[i+1], points[i+2]);
	     ZPt pt2 = cs->transform(pt);
	     into[i] = pt2.x;
	     into[i+1] = pt2.y;
	     into[i+2] = pt2.z;
	  }
      }

      env->ReleaseFloatArrayElements(j_points, points, JNI_ABORT);
      env->ReleaseFloatArrayElements(j_into, into, 0); // These were changed, commit.

      env->ReleaseIntArrayElements(j_inds, inds, JNI_ABORT);
      env->ReleaseFloatArrayElements(j_pts, pts, JNI_ABORT);

      env->ReleaseIntArrayElements(j_interpinds, interpinds, JNI_ABORT);

      env->ReleaseIntArrayElements(j_inds2, inds2, JNI_ABORT);
      env->ReleaseFloatArrayElements(j_pts2, pts2, JNI_ABORT);

      return (cs != 0);
 }

struct Match {
    int ind;
    float depth;
    bool operator<(const Match &m) const {
	return depth < m.depth;
    }
};

JNIEXPORT jintArray JNICALL Java_gzz_gfx_gl_GL_getAllCSAt
 (JNIEnv *env, jclass, jint ninds, jintArray j_inds, jfloatArray j_pts,
    jint parent, jfloat x, jfloat y) {
      jint *inds = env->GetIntArrayElements(j_inds, 0);
      jfloat *pts = env->GetFloatArrayElements(j_pts, 0);

      vector<Match> matches;

      Coords::CoordSet coordset;
      coordset.clean();
      coordset.setPoints((int)ninds, (int*)inds, 
			 (float*)pts, (int*)0,
			 (int*)0, (float*)0, 
			 (float)0, (bool)true);

     ZPt screenpt(x, y, 0);
     for(Coords::CoordSet::iterator iter = coordset.begin(); 
	     iter != coordset.end(); iter++) {
	// XXX Break encapsulation badly
	if(!(inds[*iter] & Coords::CSFLAG_ACTIVE))
	    continue;
	Coords::CoordSys *cs = coordset.get(*iter);
	if(!cs) continue;

	// Transform screen point to inside coordsys
	ZPt pt = cs->getInverse()->transform(screenpt);
	Pt sq = cs->getSqSize();
	// See whether inside unit square
	if(pt.x < 0 || pt.x > sq.x ||
	   pt.y < 0 || pt.y > sq.y) continue;
	// Project to zero plane
	pt.z = 0;
	// Transform back to screen coordinates
	pt = cs->transform(pt);
	// Add match object
	Match m = { *iter, pt.z };
	matches.push_back(m);
     }

     // Sort the matches according to depth
     std::sort(matches.begin(), matches.end());

     // Put the matching indices into the output array.
     jintArray arr = env->NewIntArray(matches.size());
     jint *els = env->GetIntArrayElements(arr, 0);

     for(unsigned i = 0; i<matches.size(); i++)
	els[i] = matches[i].ind;

     env->ReleaseIntArrayElements(arr, els, 0); // Commit


      env->ReleaseIntArrayElements(j_inds, inds, JNI_ABORT);
      env->ReleaseFloatArrayElements(j_pts, pts, JNI_ABORT);

      return arr;
 }



using namespace Renderables;

#include "librenderables/RealRenderables-jni.hxx"

}












See more files for this project here

gzz

An implementation of Ted Nelson's ZZstructure. ZZstructure is a new type of programming platform for structured data.

Project homepage: http://savannah.nongnu.org/projects/gzz
Programming language(s): C++,Java,Python
License: lgpl21

  GzzGL-jni.cxx
  Makefile
  paper-jni.cxx