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