SilenceEngine - A 2D/3D Game Engine

I don’t know if that is engine specific code, or GLFW code, but the name implies that the OP is copying the current context, and creating a new context. Basically just a copy of the original context. Don’t take my word for it, though, because I don’t entirely know. It’s just my best inference.

The call to [icode]GLContext.createFromCurrent()[/icode] changes the context used by LWJGL’s GL** class functions to the context from the active glfwContext.

I tried it myself and I was having troubles until I realised that although all images and that are still kept I still have to re-enable stuff like GL_TEXTURE_2D, GL_BLEND, etc. and set everything up.

EDIT: thx for the help, your engine is amazing btw.

Just did a large amount of changes into the engine. The changes include a lot of improvements to the Batcher, and a whole package full of classes that let you use OpenGL just like another object of a Java class, most of them are encapsulated (Not sure if I can use this term in the meaning of wrapping)

The Batcher brings the good old Immediate Mode rendering to VBOs and VAOs, you just add the geometry to be streamed using [icode]vertex()[/icode], [icode]color()[/icode] and [icode]texCoord()[/icode] methods of the batcher. Only one thing is that the begin mode is FIXED as triangles, as changing that will also increase the size of Mesh class. Here’s a small example.


batcher.begin();
{
    batcher.vertex(0, 0.5f);
    batcher.color(Color.CORN_FLOWER_BLUE);

    batcher.vertex(-0.5f, -0.5f);
    batcher.color(Color.INDIAN_RED);

    batcher.vertex(0.5f, -0.5f);
    batcher.color(Color.OLIVE_DRAB);

    batcher.vertex(1, 1, 0);
    batcher.vertex(1, -1, 0);
    batcher.vertex(0.5f, 0, 1);
}
batcher.end();

Produces two triangles, one colored and one pure white on the screen. The next major change is done to the shader classes. I’ve separated the [icode]ShaderProgram[/icode] class into two separate [icode]Shader[/icode] and [icode]Program[/icode] classes, which would give a lot of comfortability to the user when implementing custom shaders.

Another change is that every frame, Game class will call the [icode]setupUniforms()[/icode] public method in the Program class, which can be used to set the uniforms, allowing the user to change the names of the uniforms in his shaders. Here is the code in the [icode]DefaultProgram[/icode] class that sets the uniforms.


public void setupUniforms()
{
    setUniform("tex", Texture.getActiveUnit());
    setUniform("mTransform", Game.getBatcher().getTransform().getMatrix());
    setUniform("camProj", BaseCamera.projection);
    setUniform("camView", BaseCamera.view);
}

I think you got it. Also you do not need to worry about state changes, the OpenGL state functions are only called when the state really changes. These classes keeps track of current object that is bound, for example, you have [icode]Texture.CURRENT[/icode] and [icode]Program.CURRENT[/icode]. This allows for less state changing.

Another major change is the introduction of Development mode, which is true by default. You are expected to turn it off when you are distributing, because it turns off basic OpenGL error checking, usually done after every OpenGL function is called, thus saving you a few extra frames. To turn it off, place this code in the class that extends from [icode]Game[/icode] class.


static
{
    development = false;
}

This is all for now guys, see ya’ soon with much more updates :wink:

Hey friends, say hello to SilenceEngine’s Scene Graph!!

http://puu.sh/dsHug/498246d87c.gif

The Scene Graph is a way of managing the relationship between objects in the form of a tree, i.e., a Parent-Child relation ship. In SilenceEngine, this SceneGraph is implemented in two classes [icode]Scene[/icode] and [icode]SceneNode[/icode] and are part of the [icode]com.shc.silenceengine.scene[/icode] package. The Scene class is the root node, you just make an instance of it. The [icode]SceneNode[/icode] is just a normal class, and every object you wish to place in the scene should extend from it.

The Scene’s life style starts with calling [icode]Scene.init()[/icode] function. This clears any existing children and resets the world transform. Then you add children. This is the code from the above test.


Scene scene = new Scene();
SceneObject root = new SceneObject(new Vector2(0, 0), Color.RED);
{
    root.addChild(new SceneObject(new Vector2(-0.5f, 0.5f), Color.GREEN));
    root.addChild(new SceneObject(new Vector2(0.5f, 0.5f), Color.BLUE));
    root.addChild(new SceneObject(new Vector2(0, -0.5f), Color.SILVER));
}
scene.addChild(root);
scene.init();

Though I called the first object as root, the Scene is actually the root. I also added some more nodes to the node I just created, and added that to the Scene. The [icode]SceneObject[/icode] class is just a small class that extends the [icode]SceneNode[/icode] which takes some parameters such as position and a color.

Then you just update the whole scene and render it using the static functions of the Scene class. The advantage of this is that if you transform the parent, then the children will also get transformed. Regarding transformations, every [icode]SceneNode[/icode] contains two transformations, [icode]transform[/icode] and [icode]localTransform[/icode]. The difference is that the transform also contains the transformations of the parent, it is the one you apply to the batcher when drawing. The localTransform will only contain the transformation of that node, and is what you use to transform the node.


// In update code
getLocalTransform().reset().rotate(Vector3.AXIS_Z, rotation)
                           .translate(new Vector3(position.getX(), position.getY(), z));

// In render code
batcher.applyTransform(getTransform());

This is what makes the Scene Graph. If you want to remove a child node, call the [icode]destroy()[/icode] function on it, as calling the remove directly causes the next object to lost a frame. This, combined with some fun with trigonometry, generated the above SceneTest.

That’s all for now, stay tuned for more!!

Why is the Scene static?

I don’t see any point in having two scenes at a moment. You can simply clear the previous scene and re-initialize it with new nodes. Basically, I use the scene as a level, containing a lot of objects. In this case, I don’t think making it non-static can be of any other benefit, so I made it static.

A debug window would need its own scene, for instance.
And if you do not need multiple scenes, static lifecycle methods prevent your users from easy modifications and takes away flexibility for no benefit.

In my humble opinion, you should do the opposite, you should have a strong reason to make it static to do it, otherwise just don’t do that. You can’t imagine how the developers are going to use your engine, keep it as flexible as possible except when a constraint is useful.

You’re right, I didn’t get that thought. I’ve made it non-static now. Thanks for saying that to me.

This is just another update, I’ve implemented 2D geometry classes [icode]Polygon[/icode], [icode]Rectangle[/icode] and [icode]Circle[/icode] in SilenceEngine. They can be rotated at any time, and can be tested for intersections. The collision detection is based on the SAT (Separating Axis Theorem). Anyway, here’s a crappy gif that I recorded.

http://puu.sh/dvg3V/1a66f8a624.gif

Unlike the similar classes, I’ve kept the position and vertices seperately in them, so the vertices will only regenerate when they are rotated. Next up, I’m planning to implement Scene colliders to automatically test collisions between objects in the scene.

Keep up the good work! Make sure as you progress to keep things just as simple as it is now. If this starts getting overly complicated and over engineered it will have no use.

Great work nonetheless!

Hello everyone, this is time to introduce [icode]SceneCollider2D[/icode] interface and the two colliders that implement this interface. Basically in SilenceEngine, a SceneCollider is an object that takes care of collisions between entities in a scene automatically for you.

[icode]SceneCollider2D[/icode] interface specifies how a collider should be implemented for 2D entities, that is, they only check between collisions for classes that extend [icode]Entity2D[/icode] class. As specified in the name, these colliders need the scene to check collisions in. What you basically do is this.


// Create the scene
scene = new Scene();

... // Add entities to the scene

// Create the collider
collider = new GridSceneCollider(width, height, cellWidth, cellHeight); // OR
collider = new QuadTreeSceneCollider(width, height);

// Set the scene to the collider
collider.setScene(scene);

This is how you create the colliders. The next thing you have to do is to specify for which entities the collisions should be detected. This is done with the [icode]register[/icode] method of the colliders like this.


collider.register(Player.class, Floor.class);
collider.register(Player.class, Coin.class );
collider.register(Player.class, Enemy.class);
collider.register(Enemy.class,  Floor.class);

The class you pass to the register must be a Entity2D or extend from it. Only for these registered classes, the collisions will be checked, that too, in the same order that you register. In the above example, the collisions will be checked for every Player with every Floor, but they will only be notified to the [icode]collision[/icode] method in the Player.

To check for the collisions and to update the scene, do the following.


scene.update(delta);
collider.checkCollisions();

It’s that simple! And to be notified of collisions, the entity class should override the collision method provided by the Entity2D class. This is all for now guys, stay tuned for more!

Nice engine and updates coming just rapidly :smiley: keep it going :wink:

Hello friends, here’s the update for today, the [icode]ResourceLoader[/icode], the way of loading resources in SilenceEngine.

http://puu.sh/dyxgT/210e906f1d.png

One of the main features of this [icode]ResourceLoader[/icode] is that it does not multithread loading, it loads the resources in the same thread that the game is running. And it is really simple to use too. Here’s the sample code from the [icode]ResourceLoaderTest[/icode] to get you started.


ResourceLoader loader = ResourceLoader.getInstance();

int fontID1 = loader.defineFont("Times New Roman", TrueTypeFont.STYLE_NORMAL, 24);
int fontID2 = loader.defineFont("Comic Sans MS", TrueTypeFont.STYLE_NORMAL, 24);
int textureID = loader.defineTexture("resources/texture2.png");

loader.startLoading();

texture = loader.getTexture(textureID);
font1   = loader.getFont(fontID1);
font2   = loader.getFont(fontID2);

It basically follows a very simple three step process that you can simply integrate into any existing game skeleton. You first define the texture and/or fonts which gives you an ID for that resource and call the [icode]startLoading[/icode] method on the loader, which starts loading the files in the current thread, displaying a progress bar to show you the progress.

Once loading has been completed, you simply assign your variables to the loaded resources using the IDs that were generated when you defined them, and the game starts playing. Once you don’t need those resources, you can simply call [icode]ResourceLoader.getInstance().dispose()[/icode] to dispose all the resources that are loaded by the loader.

You can change your logo displayed there by calling the [icode]ResourceLoader.getInstance().setLogo(“resources/logo.png”)[/icode] or whatever, but it is recommended to keep the SilenceEngine logo if you want to show some love! ::slight_smile:

By the way, you can use the [icode]defineFont()[/icode] method in two ways, it can be used to load from a face name, or from a TTF file. If you passed it a resource name, it will load from the resource, or it will load from the family name.

This is just a small update, but a big one actually. SilenceEngine now supports overhanging glyphs in TrueTypeFont.

http://puu.sh/dAZq0/823d3907a3.png

This update also fixed the issue of texture blending that occured due to the usage of depth testing in OrthoCam.

Hello friends, I made a new game to test SilenceEngine, this is a 2D Top-Down Shooter, and also my entry for TAFSJ (The Actually Finish Something Jam).

Here is a huge crappy GIF (10 MB)

http://puu.sh/dLeLk/fc6e95392b.gif

Download JAR (3.5 MB) ( Requires Java8 )
Source Code (GitHub)

This is a feature introduction after a long time, now I present you the Audio API of SilenceEngine. I have wrapped up OpenAL into Java classes in [icode]com.shc.silenceengine.audio.openal[/icode] package allowing you use OpenAL directly in your code.

http://puu.sh/dMjmb/60978f7d48.png

I also created a [icode]Sound[/icode] class to simply load and play the sound files. Currently I only had [icode]WaveReader[/icode] class that can read WAV, MIDI, AI, AIFF files, but I’m looking into JOrbis to be able to load Ogg vorbis audio as well.

The [icode]Sound[/icode] class allows you to easily load and play the sounds, all you need to do is to call the constructor with a file name (there is also a constructor for InputStream) and use the methods play, pause, stop, etc., to control the audio.


music = new Sound("resources/music.wav");
music.setLooping(true);
music.play();

You can also use the [icode]ResourceLoader[/icode] to load the sounds by using the [icode]defineSound()[/icode] and [icode]getSound()[/icode] methods of the ResourceLoader. Here is a short example on using it.


ResourceLoader loader = ResourceLoader.getInstance();
int musicID = loader.defineSound("resources/music.wav");
loader.startLoading();
music = loader.getSound(musicID);

That’s all for today friends, thanks for stopping by and taking a look at my SilenceEngine.

EDIT: Just added [icode]OggReader[/icode] class to read from OGG files. JOrbis and JOgg are awesome!!

I’m happy to announce that SilenceEngine now reached version 0.0.1, the version information of SilenceEngine follows the three number versioning system, major, minor, alpha/bugfix.

UPDATE ON 14th JANUARY 2015

After a long gap, here is the news about the new collision detection system in 2D. Everything related to collision is present in the [icode]com.shc.silenceengine.collision[/icode] package. This package is again sub-divided into [icode]colliders[/icode] and [icode]broadphase[/icode].

In SilenceEngine, a collider is an object that checks for collisions among registered types of entities in a scene. The broadphase, is an algorithm that reduces the amount of collision tests that need to be performed. I provide three implementations of broadphase, namely [icode]Grid[/icode], [icode]QuadTree[/icode] and [icode]DynamicTree2D[/icode]. Each of these implementations implement the [icode]IBroadPhaseResolver2D[/icode] interface.


public interface IBroadphaseResolver2D
{
    public void clear();

    public void insert(Entity2D e);

    public void remove(Entity2D e);

    public List<Entity2D> retrieve(Rectangle rect);

    public default List<Entity2D> retrieve(Entity2D e)
    {
        return retrieve(e.getBounds());
    }
}

For every of these broadphase implementation, there is a collider implemented. All you have to do, is to create an instance of that collider and set the scene to check for collisions. Here is an example for each of these implementations.

GridSceneCollider

The GridSceneCollider uses the Grid as the broadphase implementation. This is a boundary based broadphase, meaning that you should specify an area rectangle which is then divided into grid cells or buckets. In my opinion, use this when you are having small scenes which are in fixed space.


Scene scene = // Create the scene here
scene.init();

SceneCollider2D collider = new GridSceneCollider(sceneWidth, sceneHeight, cellWidth, cellHeight);
collider.setScene(scene);

All the parameters passed here are self explanatory, and are in pixels. The Scene class doesn’t give them for you, so tweak those values to make it efficient.

QuadTreeSceneCollider

The QuadTreeSceneCollider uses the QuadTree as the broadphase algorithm to reduce the number of collision checks. Unlike the Grid, this QuadTree is more memory efficient (due to less number of ArrayLists of objects stored) and works well for large maps too. Here is some example code.


Scene scene = // Create the scene here
scene.init();

SceneCollider2D collider = new QuadTreeSceneCollider(sceneWidth, sceneHeight);
collider.setScene(scene);

This collider requires only two parameters, scene width and scene height, in pixels. It is better to use this collider instead of GridSceneCollider, because of it’s less memory usage.

DynamicSceneCollider2D

This DynamicSceneCollider2D uses the 2D Dynamic AABB Tree as it’s broadphase implementation. The advantage of this collider is that it is borderless, it has no constraints. I have implemented this by following a tutorial called Game Physics: Broadphase Dynamic AABB Tree written by Allen Chou. Here is some code as usual.


Scene scene = // Create the scene here
scene.init();

SceneCollider2D collider = new DynamicSceneCollider2D();
collider.setScene(scene);

This collider is the best of all the colliders in SilenceEngine in my opinion, and I recommend to use this if you are not sure why to use others. The best part, is this collider doesn’t require any parameters, and is also very fast. Thanks to @Phased for helping me to spot a bug that occurred when I’m translating pointers in C++ to Java references when following Allen’s tutorial.

That’s all for now folks! Stay tuned for more information!!

Great work on this! Can’t wait to see more updates. :wink: