A simple lightweight 3d framework for LWJGL3

The power of LWJGL is basically down to its low level nature, while this makes it incredibly flexible (for example you can call it directly from Javascript or even have OpenGL2.0 stand in for GLES2.0 to provide a uniform platform) however there is a price to pay – for a novice programmer not familiar with the intricacies of OpenGL the learning curve is nothing short of an exponential climb, the programming equivalent of the north face of the Eiger !

With this in mind, I decided to put together a number of pieces of code I often threw together when experimenting or trying out new ideas, while this makes an easier entry for novice programmers, it also makes a convenient starting point for more adept coders to build upon (contributions welcome!).  Its designed to work with OpenGL Core profile 3.2, hopefully this will be up to date enough but yet have the widest compatibility.

What you won’t get is an “engine” with the kitchen sink included, indeed many of the features are decidedly basic and this is entirely intentional.  Its almost certain that things will change in future so I’m most interested to hear peoples ideas and general feedback.  There are even some things missing entirely that should probably be included.

In order to show the framework in action and indeed to aid in testing and developing there is a simple demo included which I’ll run through to give you an idea of what is available in the framework.

When using OpenGL one of the most important tools is the matrix, such mathematics is outside the scope of a library like LWJGL so Mat4 is one of the classes included in the framework.  This Mat4 class sees use in a number of ways, when calculating where a triangle is to be drawn on the screen a number of things need to be taken into account.  Any time the window changes size this effects the projection matrix which is used calculate how distance alters each vertex because of perspective (distance) effects.  Hand in hand with the perspective matrix is the view matrix which can be though of as the “camera” through which you’re viewing the scene.  Finally there is the models position and orientation to consider – this is often referred to as the model matrix. The Mat4 class has sufficient methods to help with all these tasks.

If this is confusing or you’re unfamiliar in how matrices are used in 3d maths codinglabs has a great article that should be a good starting point for your research.

As LWJGL wraps the excellent GLFW, setting things up for drawing is really quite straight forward, between the JavaDoc for LWJGL and the excellent documentation for GLFW its fairly easy to work out what is going on.

```        glfwSetWindowSizeCallback(window, new GLFWWindowSizeCallback() {
@Override
public void invoke(long window, int width, int height) {
updateProjection(width,height);
}
});
```

GLFW uses “Callbacks” (see the text above) so it can call the user program when events of interest take place.

In our example when the window is resized our updateProjection method is called which is worth taking a look at.

```    private void updateProjection( float w, float h)
{
width = w; height = h;
aspect = w / h;
perspective.perspectiveProjection(45f, aspect, .1f, 10f);

vp.set(perspective);
vp.multiply(view);
}```

Given the windows new size we can use Mat4 method perspectiveProjection to recalculate the perspective matrix, it can be useful to have an intermediate matrix (here the VP matrix) which is the view and perspective matrix combined.

For rendering different instances of a 3d model, I’ve provided a handy Placement class, this keeps the models orientation and position together and allows a number of operations to effect the models position and orientation.

```        Placement boxPlacement = new Placement();
boxPlacement.setPosition(0,0,-6);```

After creating a Placement we can easily set its position

```        boxPlacement.addAxisAngle(1,0,0,40f*(float)Math.sin(thisTime)*delta);

tmpMat.set(boxPlacement.toMatrix());

mvp.set(vp);
mvp.multiply(tmpMat);```

Here we’re rotating round the three axes, and after multiplying it with the View Projection matrix we have a MVP (model view projection) matrix

```        box.prepare(texture);
box.render(mvp);
box.done();```

Once we have calculated the matrix it can be used to render an object.  As can later be seen with the pyramid model, multiple renders can be done between prepare and done method calls, all you need to do is successive apply different operations to the matrix you’re using (or use a different Placements for each render).

A quite recent addition is the Font class which uses a “pre baked” texture to render text, if you need a string of text that doesn’t change you can pre render it into a Model, this model can be translated around the screen if needed.  More useful is the print method which makes a temporary model for text that is constantly changing (such a numeric value).

While in theory you probably have enough tools to make a simple game, this isn’t really the best use, if you think of this as a learning resource then it should be possible to start experimenting and learning in almost no time, probably the easiest way to get started is to back up Test.java and modify it, for example you might want to alter the code so that the cube moves in a circle while its rotating, a more advanced modification might be to extend the SimpleShader to encapsulate a more complex shader providing simple lighting.

I hope someone finds this code useful and don’t forget there are a whole bunch of comments in Test.java, additionally if you run

`ant doc`

you’ll generate some (limited!) JavaDocs, you’ll need to either symlink or place the LWJGL3 jars into the libs directory see readme.md in libs.

please do post me feedback using the contact form…

Especially welcome would be people interested in helping with articles, coding, documentation, art, 3d modelling, any skill you think might help improve this as a learning resource.

Enjoy!

lwjgl3-framework.tar.gz