Wordclock build

Light is tricky to film! the bleed through isn’t as noticeable to the human eye and the words look more bright pastel than laser bright glowing! (I think I need a strong light source to film this!!)

First off, this is not a cheap way to make a clock, however what it will give you is a rather nice looking discussion point.  The project initially began when I stumbled on the Teensy 3.1 this is a great little Arduino clone, but built around an Arm chip instead of an Atmega chip.

Although the Teensy 3.1 is a very similar price point to an Arduino it has a number of advantages, aside from the raw speed 72Mhz (can run at 96Mhz!) compared with a typical Atmega clock speed of 16Mhz.  This is probably less important that you’d think for many projects but it is an indication of the step up.  A very nice feature is a built in real time clock – which is what inspired the idea for some kind of clock project, other features are less obvious like its internal DMA infrastructure (more on that later)

wordclock-00My initial prototype was rough and ready but it very much proved the point – working flawlessly for several months keeping great time.  The design was very simple, basically a simple print onto a transparency sheet (I actually doubled up because they were not as opaque as you’d have thought!) Using almost every pin and a whole mess of wires, only meant I had one LED per word, which didn’t quite do the job…

Looking round for an alternative lighting method, I wordclock-01decided on a strip of addressable RGB LED’s – These WS2812 usually come in lengths of one metre which contain 60 LED’s in total.  I’d already designed a grid of words, the grid ended up with 5 lines and rounding up, I could give each word one LED per two characters – this made for rows of a maximum of eleven LED’s meaning I ended up with a handful of spare LED’s (more booty for the component pile!) on the right you can also see the laser cut front stencil of words (told you its not a cheap project!!)

 

wordclock-03Printing out a template for the back of the enclosure helped with positioning the led’s.  The great thing about WS2812’s is that you can take a pair of scissors to them and have short runs separated but in the same string.  On the left you can see the five strings of LED’s for each line of text in the template. Once the LED strings were glued down I could then breadboard the circuit.

 

wordclock-05The circuit is very simple, basically consisting of an octal buffer transceiver as the Teensy 3V3 won’t drive the data inputs for the LED strings.  One important note is to be careful of the brightness of the LED’s even through paper they are quite bright – I even ended up using bits of printer paper as diffusers behind each word

 

wordclock-06 Of course I couldn’t wait to get the front on the thing so I could see individual words illuminated!  I had to add some black electrical take inside as there was a little too much leakage of light from word to word – as the front will never fit 100% flush to all the dividers in the back there will always be some bleed through but that actually adds to the effect without distracting from which word is obviously illuminated.wordclock-07

With five strings of LED’s needing signal and power and various other bits of wiring I’ll be the first to admit the back could be a bit tidier ! Ideally I should have made some kind of enclosure for the circuit…

I added a string and some stand offs later so I could hang it on the wall without the wiring getting in the way.clock-circuit

 

A tiny bit of strip board is all that’s neededclock-circuit to hold the buffer that we’re using as a voltage level shifter, it also handily works to tie everything together. As we move on to look at the firmware for the clock it might be handy to refer to this circuit.

 

As previously mentioned the Teensy has an advanced DMA infrastructure, this is used to great advantage with the WS2812 library which means we can dump a new pattern to the LED chips with minimal overhead to the CPU.  While I only need 5 out of 8 possible strings of LED’s and one string only needs 9 LEDs not 11 – this isn’t a problem just leave them out!

I found it particularly useful to write and test specific C subroutines on my machine as it can be quicker and more convenient to debug a simple C function rather than repeatedly uploading to the teensy and debugging via serial messages…

The LED’s are indexed from left to right and then on to the next string so the first LED on the second string is index 11 (starting from 0 on the first string)  This means you can treat the 5 channels as one long string, which is what I did to scroll the colour gradients.  The colour gradient is produced by successively LERPing from one random colour to the next.  Each step of the colour scroll is done once every tenth of a second, so each colour takes a little under a second to scroll from top left to bottom right.

There is also some logic to sort out the correct grammar for the time as randomly words like minutes or O’Clock are omitted, for example the same time will sometimes be shown differently

FIVE MINUTES PAST NINE O’CLOCK

FIVE MINUTES PAST NINE

FIVE PAST NINE

Equally when quarter or half (past/to) are used you can’t show “minutes”

The logic is a little convoluted and rather than over complicate things I just made a bunch of IF statements to handle parsing the time.  I wouldn’t claim it to be anything like a master piece of coding but for what its worth I’ve made the code available and the template design for the front panel here… wordclock-files

There are two simple switches available for changing the time, one increases the hour and the other the minute, rather than increase in five minute steps it increases in just minute increments – this means a whole bunch of presses to set the time, but it does allow you to set the time a few minutes fast… This means as the time approaches for example half past it will show half past as you’d read the time to someone…

The switches trip interrupt routines and there is some timing to de-bounce a potentially noisy switch, so setting the time is independent of the code that handles colour scrolling and displaying the time.

UPDATE….

You know how a project is never finished !  While I’ll leave the clock as is for the time being looking back at the build there are some things I’d have done differently and some things I’ll be changing…

On the back side I’ll add a fence around the edge instead of two small hold offs, just so it will sit a lot more square to the wall!

The dividers for each word should really by attached to the template, while the position of the lights can be a little off – the dividers are not quite in exactly the correct position – an in fact if I were to re-design the front word template I’d make a little more room between characters…

The diffuser material (printer paper!) could be glued to the back of the front word template, also I’d put diffusers on the few dummy letters as they look darker than even unilluminated letters with diffusers.

So some more “tweaking” to do at a later date!

Posted in Uncategorized | Leave a comment

OpenGL core profile – an introduction

OpenGL core profile is centred around OpenGL 3.2 and allows you to use OpenGL without the old deprecated stuff and as such is likely before long to be a common minimum standard for support.

There are some slight differences with GLSL if you’re maybe been concentrating on mobile shaders, but nothing thats too far beyond the pale.

Lets have a quick wander down the code and see whats what…

#include "gl_core_3_2.h"
#include <GLFW/glfw3.h>

The first thing to mention is I’ve used a code generator to make me a procedure loader to load up all the functions that appeared after OpenGL1.1 – why this isn’t done automatically when a core profile context is created, well maybe I shouldn’t expect “common” sense !

I used the generator here which both seems robust and should work OK on other platforms too (Although I could guess developing windows OpenGL applications is not a joyous experience!)

Next we have a very simple set of shaders to make up a simple shader program

const char* vertex_shader =
/*01*/ "#version 150 core \n"
/*02*/ " \n"
/*03*/ "in vec3 vp; \n"
/*04*/ "uniform float u_time; \n"
/*05*/ "out float blank; \n"
/*06*/ " \n"
/*07*/ "void main () { \n"
/*08*/ " vec4 p = vec4(vp, 1.0); \n"
/*09*/ " p.x = p.x + (sin(u_time+p.y)/4.0); \n"
/*10*/ " p.y = p.y + (cos(u_time+p.x)/4.0); \n"
/*11*/ " gl_Position = p; \n"
/*12*/ " blank = sin((u_time+p.x+p.y)*4.0); \n"
/*13*/ "}";
const char* fragment_shader =
/*01*/ "#version 150 core \n"
/*02*/ " \n"
/*03*/ "out vec4 frag_colour; \n"
/*04*/ "uniform float u_time; \n"
/*05*/ "in float blank; \n"
/*06*/ " \n"
/*07*/ "void main () { \n"
/*08*/ " frag_colour = vec4 (0.5, abs(sin(u_time)), abs(cos(u_time)), 1.0); \n"
/*09*/ " if (blank<0) frag_colour = vec4 (0.5, abs(cos(u_time)), abs(sin(u_time)), 1.0); \n"
/*10*/ "}

There’s not a great deal to say here, except do note that I label line numbers, although you might have to do a little maintenance – doing this is very helpful when shader compiling fails…

    if (!glfwInit ()) {
        fprintf (stderr, "10 ERROR: could not start GLFW3\n");
        return 1;
    }

    // tell glfw we want the core profile
    glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* window = glfwCreateWindow (640, 480, "Hello Triangle", NULL, NULL);
    if (!window) {
        fprintf (stderr, "20 ERROR: could not open window with GLFW3\n");
        glfwTerminate();
        return 1;
    }

I like to let GLFW do the heavy lifting and as you can see making a compatible context is no where near as painful as EGL can be!

    glfwMakeContextCurrent (window);

    if(ogl_LoadFunctions() == ogl_LOAD_FAILED) {
        fprintf (stderr, "30 ERROR: failed to load gl functions\n");
        glfwTerminate();
        return 1;
    }

Once we actually have a context created we can go ahead and load up all those missing function pointers.

The rest of the code such that it is – is very simple “ordinary” GL code, coming from GLES2.0 (mobile) arena, the shader is where a far bit has been changed and that you need a vertex array.

 

Enjoy!

 

Posted in Uncategorized | Leave a comment

Raspberry PI 2 – first impressions

It was some time since I used my original Rasperry PI, as it had been gathering dust for a number of reasons.  The main reason was one of performance, as much as anyone might love the PI they cannot claim that at 700mhz browsing the internet on a PI is anything more that a turgid experience.

So you can understand when reading of a claimed six fold improvement in performance my interest was defiantly piqued…

I’ll start off with a round up of the good! basically the performance is defiantly there – to the extent that browsing the internet is actually practical.  The improved architecture (ARMv6 v’s ARMv7) and the increase clock speed to 1Ghz definitely make a difference, what makes less of a difference is the fact it’s a quad core.  While for heavy weight applications (multi core compiling, rendering etc) it will have quite an impact, for general desktop use, you are unlikely to be troubling multiple cores (at the same time)

Obviously this extra power comes at a price, namely power (the other sort!) you will defiantly require a decent power supply – (a good quality 2amp wall wart is indicated) – this meant for me that even with the power plugged into my lapdock, it just didn’t quite cut it.  This leads on to a useful feature – if the PI doesn’t have sufficient power you will see a small 4 colour icon in the top right of the screen.  This extra power requirement may well catch a number of people out but then there is always the option to underclock…

The thing that disappointed me most is the seeming lack of low level (open source) progress, for example the implementation of EGL / GLES only really allows for fullscreen rendering in X11, however from my experimentation it should be quite possible to have a small (hardware) overlay window on top and moving around with a blank X11 window, all this with no copying during buffer swaps.  While I was tempted to have a go at an X11 version of EGL / GLES the thing really putting me off is the lack of documentation for broardcoms API.  Sure you have *some* of the source code, and even a datasheet, but without proper docs its hard to guess how you’re supposed to do something new with the API (as opposed to following boiler plate examples)

The upshot of all this is that although I should be able to take a program I’ve written on my laptop targeting GLES2.0,  recompile it on the PI and it just work, alas this is not possible – you have to port from Linux to Linux and add platform specific code… (not a great thing to be encouraging people in education to be doing…)

So its a mixed bag, I’d really like to see the PI become an end to end open source solution (with work on reverse engineering the firmware) but Broadcoms marketing stunt about opening up the PI was somewhat disingenuous – being basically a bunch of RPC glue and stubs to call GPU binary blobs even the shader compiler is a binary blob!

So hardware performance – could do better but a great improvement

Open and cross platform compliant…. errrr NOT (still!)

 

Posted in Uncategorized | Leave a comment

Inkscape to Adobe Illustrator

When sending some SVG work to a laser cutter I stumbled on an interesting problem (where really there shouldn’t be one!)

Now you’d be forgiven for thinking that a vector graphics format using document units of mm (millimetres) couldn’t possible have any issue with scale from one package to another… Surely 1mm in Inkscape = 1mm in Adobe Illustrator = 1mm on Pluto!…. You’d think….

It turns out that Inkscape uses a DPI (whats DPI got to do with vector graphics anyway!) of 90DPI which is a size used a couple of times in the w3c SVG standard – of course since its mentioned a few times no doubt Chinese whispers on some forums will quote it as a law…

As far as I can tell there seem to be no way to change this 90DPI value – which seems odd but still….

On the other hand Adobe Illustrator has a hang back from the Mac days where all the screens used to be 72DPI (no doubt internally to MacOS there is some backward compatibility kludge regarding this size too (just a guess!))

The upshot is that if you open an SVG in Inkscape created with Adobe Illustrator you’ll need to scale it by 125% (90/72=1.25)

Of more interest to Inkscape users is creating a document that a Laser cutter firm can handle without problems…

Now because a stencil font can’t have isolated islands of material, for the project I was working on I ended up making the text myself manually with individual strokes grouped together.  The first problem with this is that my strokes were 3mm wide to show the discard area, thankfully laser beams are a tad finer than 3mm so I had to turn my strokes into outlines (these outline have to be rather thin too – more on that later)

i2ai-1i2ai-2If you have a group of stokes for a font, first combine then using combine in the path menu, this actually makes them one “object” rather than a group of individual strokes.  That done now with the combined letter selected, in the path menu use the stroke to path menu item.

Ni2ai-4i2ai-3ow you have a path for each letter you can disable fill and enable stoke paint (in the fill and paint side dialog) for the selected path. You will probably have to ramp down the stroke width but leave it something visible for now like 1mm so you can actually see it while fully zoomed out…

Once everything is done as an outline you are probably as well to put a box around the whole design that is the expected dimension for the whole material like for example 297mm X 210mm for landscape A4.

The last job is to scale the whole thing by 80%, but as this will also effect the stroke width we need to pre-scale the stroke width before scaling it (You could prevent scale from touching stroke widths in preferences – but this is probably not a good idea to keep this setting all the time).

A common width for Laser cutting paths is 0.01mm yes thats 100th of a mm !  However we need to pre-scale that first so 0.01mm x 125% = 0.0125, now don’t worry when you plug this value into the width as it will have seemed to round it up to 0.013 (but it seems to actually keep the correct value) Now when you select everything in the project and apply a scale transform of 80%  (Transform is in the object menu – it will open a dialog in the side bar) if you look at the stroke width it should be 0.01mm as intended.  There may be (probably is) a way to turn off or alter the value display rounding but I couldn’t find it!

Oh now we have our 80% scaled work with 0.01mm paths make sure its all pure red (RGBA ff0000ff) this is another common value in use to indicate a cut as opposed to a burn (or shade) when lasering!

Now hopefully your printer/cutter will find it easier to use your designs, but don’t forget to ask them to verify that the outside box has the exact physical dimensions you expect !

Many thanks to Amy of artisan model makers (UK) for her patience in allowing me to bat multiple files at her so we could work out what was going on!

 

 

Posted in Uncategorized | Leave a comment

Kobo mini – doing without the official reader software.

The mini is a great ereader, I love the fact that its size makes it even more convenient than a pulp paperback, best of all I love that the internal boot media is a removable SD card, while its not a terrible inconvenience to use something like a bus pirate to modify a flash chip it is a fair bit easier to write to a removable device! additionally its a snap to upgrade, which if you’re going to mess with your Kobo I’d really recommend you do.

You need to be sure you can recreate and backup an original Kobo boot SD, then you can store the old SD card as a backup, as well as keep backup of the first 10MB of the disk, also an image of the first partition (at least!) and keep this separate backup on your HD.

Once you’ve made and tested your newly cloned SD card you can start modifying it.

First of all you want to install the launcher software you may be interested in some of the other software he bundles with the launcher and if you are using it regularly you might consider a donation…

Of course the bit we’re interested in is his port of coolreader (I can’t seem to find any source for his modifications which is a pity, but I’ll admit I’ve not looked too hard)

Coolreader is much better than it used to me and unlike the “official” reader its able to cope with large collections without slowing to a crawl, you may have to wait 10 secs or so if you open a file selection dialog in a folder with a few thousand or more files – but frankly I really should curate my collection better than just bunging most stuff in one general folder!…

Customization is a snap, for example I have the launcher “autoboot” straight into coolreader, changing screensaver images is very simple (images live in the sleep folder) and unlike the “official” reader the text actually fills the screen.  Just one small gottcha if you want complete control over how the document is displayed you’ll have to disable auto text formatting…

kobo-coolreaderAssuming you’re happy with coolreader, and why wouldn’t you be! notice you get a whole screen full of text rather than large variable gaps at the top and bottom of the screen… (don’t worry about it being inverse – I’m trying it out for a while to see if I like it, you don’t have to!), the next step is to stop the “official” software from ever running (this is not obligatory but good riddance an’ all that!)

The boot sequence they are using is slightly none standard but thankfully simple to modify…

Most modification is in within /etc/init.d/rcS

First I commented out just the section that executes the updates (any hacks that use KoboRoot.tgz I install – and check – manually)

Next to go is the boot animation, frankly in the 3-4 seconds it takes to boot linux and the 3-4 seconds the launcher/coolreader takes to run its superfluous anyhow, so I couldn’t be bothered to kill it rather I simply commented it out

# ( usleep 400000; /etc/init.d/on-animator.sh ) &

My next modifications are all at the bottom of the file

# disable the flashing led
echo "ch 3" > /sys/devices/platform/pmic_light.1/lit
echo "cur 0" > /sys/devices/platform/pmic_light.1/lit
echo "dc 0" > /sys/devices/platform/pmic_light.1/lit

I found this from the boot sequence of xcsoar and stopping it here means while Linux is booting we’ll have some visual conformation via the power LED

# run dropbear in background
( /mnt/onboard/.kobo/vlasovsoft/usbnet-silent.sh ) &

Because I’m I want dropbear running all the time, I run a modified version of the usbnet script that comes with the launcher (more on this later)

finally we can run the launcher itself…

/mnt/onboard/.kobo/vlasovsoft/launcher.sh

Because the usbnet script isn’t being run by the launcher but by the bootscript it won’t have the environment variables set that it expects.  First copy and rename the usbnet.sh (so the original can still be used by the Launcher menu as normal) first we need to supply the ROOT variable, our first modification (of the COPY!) is at the top of the script

# used during boot, only show msgbox if there is an error
ROOT=/mnt/onboard/.kobo/vlasovsoft
root=$ROOT/usbnet

last near the end of the script we just need to comment out the success message box

    # msgbox "usbnet" "usb network started!"

and thats about it!

The caveats

Obviously nothing is perfect, first off usb mass storage, now its eminently possible to get this working but frankly I couldn’t be bothered, with dropbear you can log in with filezilla for GUI file management.

Also not utilised is WIFI but for an ereader I increasingly find this less than relevant, while the Kobo’s web browser is a nice try, its not really up to the job, and if I’m browsing I’d rather be using a device better suited.

All in all I’m happy with the recent advances made with Coolreader (I hadn’t looked in quite some time!) and certainly glad to be rid of the “official” software…

 

Posted in Uncategorized | Leave a comment

Java Jni wrapping a simple callback machanism

Here we’re going to look at a very simple callback in C an how you might wrap it for Java. Let’s dive straight in with some example code

JNIEXPORT void JNICALL Java_Bogus_setCallback
  (JNIEnv *e, jclass c, jobject inst, jstring method) 
{
    const char *cbn = (*e)->GetStringUTFChars(e, method, 0);
    bcbclass = (*e)->GetObjectClass(e, inst);
    bcbmethod = (*e)->GetMethodID(e, bcbclass, cbn, "(III)V");
    (*e)->ReleaseStringUTFChars(e, method, cbn);  
    bcbe=e;
    if (bcbmethod == 0) return;
    BogusSetCallback(bogusCallBack);
      
}

We’re using a class instance and a method name to identify where the callback method is, additionally we’re caching the object class and method id, even if you’re not caching this info its still a good idea to do a dry run on the method id here, as if something is wrong with the method name JNI will issue an exception (which is why we return without need of error message) – WAIT…. JNI causing an exception – what no throwing the dummy out the pram seg fault behaviour…. I know shocking!

Don’t forget you can always use javap to help determine what the method signature should be.

Internally to our wrapper we will need a C function to actually receive the callback and dispatch it off to our Java version

void bogusCallBack(int a, int b, int c)
{
 (*bcbe)->CallVoidMethod(bcbe, bcbclass, bcbmethod, a, b, c);
}

So we have a number of cached values here that if you need a callback per C “object” you’ll need to lookup on the fly. bcbclass being the instance class and bcbmethod being the method ID.  If the library you’re wrapping is multi-threaded you’ll need to read up on attach thread take a look at the documentation here

Enjoy!

Posted in Uncategorized | Leave a comment

Wrapping a returned C struct from inside JNI (and other JNI stuff)

First off I don’t claim to be any kind of JNI guru and frankly I like to touch C as little as possible – C’s memory management model is only marginally better than C++’s (shudder) – that should get me a few flames >:)

That said I did struggle to find any easy to digest info that did just what I wanted, so I thought I’d document my solution, just to muddy the waters further!

When using JNI its important to remember that you’ve been spoilt rotten by Java’s garbage collection, things in C are all together more hairy and its all too easy to forget that passing a local variable back through the  “JNI barrier” is gonna cause you nothing but pain…

Its common to have a C or C++ objects wrapped in a Java object with its own close or delete method,leaving you responsible for calling it before the Java Object is GC’d.  This isn’t particularly a very “Java way” to do things and in some cases it can be avoided.

It’s not uncommon to see C stucts returned from functions and if they are simple structures for example just containing ints and floats (basically you’re sure they don’t contain references to allocated memory you are responsible for freeing) then they are a very good candidate for encapsulating within a Java class, that can be automagically GC’d

The first thing you need is a buffer in your wrapping class, this needs to be created in a particular way to ensure stuff doesn’t get mangled, if the struct for example only holds floats, you can write pure Java accessors which directly get or put to a FloatBuffer.  Lets look at how the buffer needs to be created.

buff = ByteBuffer.allocateDirect(16).order(ByteOrder.nativeOrder());

In the constructor I’m creating a buffer big enough for 4 Floats, you could argue that you should have a native function that returns the size in bytes of the structure, but in our case we’re going to assume that the structure is only going to be four floats….forever….

notice two things its allocated as a “direct” buffer and the byte order is set to the machines current native order, its returned as a float buffer in this case as we’ll be directly manipulating it from Java as well as creating it in C.

Don’t worry if your struct has mixed (native) types consider this code

        bb=ByteBuffer.allocateDirect(8).order(ByteOrder.nativeOrder());
        
        ib = bb.asIntBuffer();
        fb = bb.asFloatBuffer();
        
        System.out.println("ib 0 ="+ib.get(0));
        System.out.println("bb 0 ="+bb.get(0)+","+bb.get(1)+","+bb.get(2)+","+bb.get(3));
        fb.put(0,1.1f);
        System.out.println("ib 0 ="+ib.get(0));
        System.out.println("bb 0 ="+bb.get(0)+","+bb.get(1)+","+bb.get(2)+","+bb.get(3));

Crucially here ByteBuffers asIntBuffer and asFloatBuffer doesn’t make a copy of the byte buffer but rather its a different “view” of the same ByteBuffer, so as you can see you have a fair bit of scope for accessing values directly from Java even if there are mixed types in the structure…

First lets look at the worst case where there isn’t an existing Java object and we need to create one from C

jobject createBogusJobject(JNIEnv *e) {
    jclass cls = (*e)->FindClass(e, "wrapper$Bogus");
    jmethodID constructor = (*e)->GetMethodID(e, cls, "<init>", "()V");    
    jobject bogus = (*e)->NewObject(e, cls, constructor);
    return bogus;
}

There is no error checking here, however assuming that you have the right class and field name, then all should be well… (but it probably is a good idea to check the new object was actually created.)

On the Java side of our imaginary wrapper, our Bogus class is a static sub class of a singleton wrapper class (I’ll leave it to you to work out why).  When actually creating the object the NewObject function needs to know which constructor to call,  method signatures are probably not terribly intuitive, but you can use javap to tell you, for example :-

javap -s jni/wrapper\$Bogus.class

will tell you all you need to know, notice that the $ is escaped (and the path separator is a *nix one, yours could be different…!).

Now we have our object either new or it could be passed from Java, we need to get a pointer to our object’s buffer and copy our C struct into it.

Lets see how we do this with an existing Java class

JNIEXPORT void JNICALL Java_wrapper__1_1bogusOp
  (JNIEnv *e, jclass c, jobject jbogus, jfloat x, jfloat y, jfloat z)
{
    Bogus b = aBogusOp(x, y, z);
    Bogus* dp = getBuffPtr(e,jbogus);
    *dp = b;
}

Given a Java Bogus object and some parameters, we can call a native routine that passes back a struct as a return value.  Next we need to copy it into our Java object for which we need a pointer to the ByteBuffer (more on that in a moment) By dereferencing the ByteBuffer pointer we can then copy the local bogus variable into the buffer.

The last piece of this particular puzzle is to get a pointer to our ByteBuffer.

void* getBuffPtr(JNIEnv *e, jobject jo)
{
    jobject cls = (*e)->GetObjectClass(e, jo);
    jfieldID fid = (*e)->GetFieldID(e, cls,"buff","Ljava/nio/ByteBuffer;");
    jobject jbuff = (*e)->GetObjectField(e, jo, fid);
    return (*e)->GetDirectBufferAddress(e, jbuff);
}

I use this routine for a number of different Classes, for this reason their ByteBuffers must all be called “buff” again we need an arcane field signature but javap will help out.  Again there is nothing in the way of error checking here!

On the subject of error checking your biggest ally is the Java compiler, its fairly difficult to supply the wrong type of parameter and checking for NULL references will stop many of the more spectacular dummy throwing JNI can do.  Remember that its much better to check what you are supplying to JNI in the first place….

with that in mind I use a very simple macro when I need to pass an jobject to C

#define checkJO(JO, MSG) if (JO==NULL) { printf(MSG); fflush(stdout); return; }

The first thing I do is check all user supplied java objects passed to my C JNI function for example

checkJO(jbogus,"\nbogusOp was passed a NULL bogus!\n");

Two things to note, first off the 2 carriage returns, basically we’re sharing a terminal with Java’s error reporting and even flushing the buffer you can still get any message you emit munged up with a JVM error message such as an uncaught NULL pointer exception.

Lastly the macro returns from the function immediately so if you have a none void returning JNI function you’ll need a macro that returns NULL which can be tested later so you know there’s a problem… Don’t forget in this example I’m using an existing Java object to pass back return values but you could easily be returning Java object created in C.

Well theres a fair bit to digest there! so probably best we leave it here, don’t forget to check out the JNI documentation

Enjoy!

Posted in Uncategorized | Leave a comment

Jnanovg initial release!

I posted last time about my discovery of nanovg a lightweight vector graphic library, and mentioned that I was wrapping it for Java.

Well now its in a working condition I put it up on github

Enjoy!

 

 

Posted in Uncategorized | Leave a comment

nanovg a lightweight vector graphics library

I stumbled on a really nice vector graphics library, its not all featured but the big advantage its both lightweight and simple and makes some nice graphics as can be seen by a screen shot

nanovg

Its not an actual gui just a mock up, but there is some animation to the demo, and it looks very easy to render some nice content….

I was so impressed I’ve decided to wrap it for Java, while my primary usage will be for my own GLES 2.0 wrapper (Jgles2) I’m being careful to only make the example for the wrapper reliant on it, with a simple change it will be easy to recompile the wrapper for OpenGL (instead of GLES 2.0) and then use it with for example Lwjgl…

I’ve got as far as rendering some quadratic / bezier and even straight lines and animating them

Jnanovg

This in no way troubles the cpu load meter and looking at the speed of the C example I can see that you should be able to render a full GUI while rendering a 3d scene without any problems at all….

So far the Java wrapper has almost written itself as I watch some naff TV…. there’s no callbacks and the various structures seem simple and hopefully shouldn’t present a problem. What a nice find…..

 

Posted in Uncategorized | Leave a comment

Jgles2 new example

Jgles2-shotI looked at using Lwjgl’s framework for creating a GLES 2.0 wrapper, but failed miserably (several times) at even working out how you’d even tell it there was a new library… instead I decided to port my Lwjgl3 example to an existing GLES 2.0 wrapper…

For a while now I’ve had a slim wrapper of GLES 2.0 for Java which is available here.  Its far from perfect but does basically what I need of it (contributions and feedback welcome)

There are some minor differences which are basically to do with Java convenience, and is leading me towards thinking that rather than excepting different types of buffers as parameters for GLES functions, I should consider just having a utility to return a pointer (as a java long) for a buffer, this would simplify some things and also make the functions very much 1:1 with the native library.

So which is best – well to be honest neither really, obviously Lwjgl will enjoy wider support and cross platform native libraries (I used to know how to compile a windows DLL from Linux – I really must get round to reimplementing this…!) but mainly the difference is just that they are *slightly* different!

 

 

Posted in Uncategorized | Leave a comment