Trying 3D with jMonkeyEngine

    Almost everyone who was involved in game development understands that the best performance in this area, for obvious reasons, can only be achieved in C / C ++ / asm. I won’t argue with this statement in this article, and even before I hadn’t even thought about creating realtime games in other languages. However, the games are different, and you need to be aware of how justified the labor costs for the implementation of the next product. If the project is monstrous, with a “heavy” graphic component, even after very aggressive optimization, it still requires top-end hardware on board from end users (gamers), then there are no special competitors among the development languages ​​in C / C ++ in this case . But if the toy is nothing more than an ordinary casual, for the launch of which a netbook will be enough, then you can allow yourself much more room for imagination in the matter of choosing tools for development. Based on this principle, in this article we will try to figure out what it boasts of in the field of game dev, such a seemingly not quite suitable for this, but generally convenient Java language, using the jME engine as an example.

    Intro


    jMonkeyEngine . There is nothing to be done, the engine is really called that, and even the slogan on the site reads “Serious monkeys. Serious engine ”(“ Serious monkeys. Serious engine ”). Some developers obviously have something tied to these animals (I recall the same RenderMonkey for developing and debugging shaders).

    Nevertheless, the only comic title in the engine. jME supports everything you need for a comfortable and fairly quick creation of games, and it is not exclusively a graphical visualizer, i.e. an input processing system and a library of physics simulation and audio playback are also available. In addition to the standard set of tools inherent in many other engines, you can note such features as:
    • Multithreading. OpenGL calls and game logic run in different threads. The logic of work can be implemented using the built-in game state management system. There are several predefined state classes, for example, the TransitionState class for implementing the loading screen
    • Integration in Java Applet, AWT, Swing and SWT
    • The engine only works with a special binary format of JME models. Nevertheless, there are many converters such as X -> jme (where X == obj, 3ds, etc.) that allow you to import models from other formats directly at runtime (there is no need to translate the created models into JME format in advance)
    • “Forced” control over the organization of limiting volumes. When loading / creating the next grid model in the code, you must explicitly indicate what bounding volume will be used for it
    • Rendering Swing Components Inside a Scene
    • Fast math core actively using pre-calculated value tables
    • Built-in effects such as Bloom, Depth Of Field, dot3 bump mapping, Lens Flare, etc. Of course, support for GLSL and ARB :)
    • Tissue simulation
    • www.jmonkeyengine.com/wiki/doku.php/complete_features_list

    Installation and simplest use case


    Loading finished engine or merge with repository sources and collect themselves. In both cases, we get the necessary libraries for the output, which we put in any convenient place on the disk.
    Now create an empty project in Eclipse and go to Properties -> Java build path:

    image

    Poke Add External JARs and add libraries from the folders / path / to / the / engine / lib (packages of the engine itself) and / path / to / the / engine / lib / lib / lwjgl (the visualizer packages that will be used by the engine, in this case LWJGL). Of course, adding all packages is not necessary, only those that will be really used are enough. It should look something like this:

    image

    In the properties of the LWJGL packages we specify the native libraries necessary for their operation, located at the address / path / to / the / engine / lib / lib / lwjgl / native / <your_os>. For example:

    image

    Initial preparations are completed, now create a new class (Program, for example). We will make this class an inheritor of the SimpleGame class, which is well suited for test programs, as automatically configures all the necessary parameters and creates a first-person camera. The program will do two simple things - create a cube and load the model from a .obj file.
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.net.URL;

    import com.jme.app.SimpleGame;
    import com.jme.bounding.BoundingBox;
    import com.jme.math.Vector3f;
    import com.jme.scene.TriMesh;
    import com.jme.scene.shape.Box;
    import com.jme.util.export.binary.BinaryImporter;
    import com.jmex.model.converters.ObjToJme;

    public class Program extends SimpleGame
    {
      public static void main(String[] args)
      {
        Program game = new Program();
        // При запуске всегда показывать диалог выбора настроек
        game.setConfigShowMode(ConfigShowMode.AlwaysShow);
        game.start();
      }
      
      @Override
      protected void simpleInitGame()
      {
        // Создаём куб
        Box b = new Box("Testbox", new Vector3f(0, 0, 0), new Vector3f(1, 1, 1));
        // Устанавливаем ограничивающий объём
        b.setModelBound(new BoundingBox());
        // Подгоняем его параметры автоматически
        b.updateModelBound();
        // Присоединяем к корневому узлу графа сцены (rootNode присутствует в SimpleGame)
        rootNode.attachChild(b);
        
        // Загружаем модель из .obj файла
        ObjToJme converter = new ObjToJme();
        URL full_mesh_path = Program.class.getResource("mesh.obj");
        TriMesh mesh = null;
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        try
        {
          converter.convert(full_mesh_path.openStream(), output);
          mesh = (TriMesh)BinaryImporter.getInstance().load(output.toByteArray());
        }
        catch (IOException e)
        {
          System.exit(1);
        }
        mesh.setModelBound(new BoundingBox());
        mesh.updateModelBound();
        mesh.setLocalTranslation(Vector3f.UNIT_Y.mult(5));
        rootNode.attachChild(mesh);
      }
    }

    * This source code was highlighted with Source Code Highlighter.

    Nothing complicated. It is worth paying attention to the line

    URL full_mesh_path = Program.class.getResource ("mesh.obj");

    So we tell the program to look for the mesh.obj file in the same place where the Program.class file is. This can be convenient, for example, if game resources will lie inside a .jar archive containing .class program files.

    Now the program should start, display a dialog box with a choice of graphic settings, create a window and display in it a manually created cube and a loaded grid model. The SimpleGame class implements the ability to display runtime statistics, which is enabled by pressing F4. Of course, in real projects, such default things are unlikely to be needed by anyone, therefore for games it is more serious than Hello, world , it is better to use the StandardGame class, or, if you go even higher in the hierarchy, BaseGame, where you have to write all the initialization yourself.

    Now prepare the program for distribution. To do this, execute File -> Export -> Runnable JAR file. In the window that appears, select the exported program, destination folder, select Package required libraries into generated JAR. After clicking finish, we have a .jar file containing the program executable code and all the necessary engine libraries. To start, you also need to copy the native libraries from the folder that was indicated at the beginning into the folder with the program (for example, in ./lib). To run, we execute
    java -Djava.library.path =. / lib -jar program.jar

    The program will be able to load the mesh.obj file if it is located either in the folder with program.jar or directly in the program.jar file. You can add a file inside the archive with any archiver.

    There is a completely logical question here - how fast does it work? .. Look at it for a completely natural answer - see for yourself . The site has a certain number of demos downloaded via jnlp, including not so primitive ones as this example. On them you can evaluate the speed of work.

    The finish


    This fact-finding article can be considered completed. A simple example shows well the ease of creating games using jME. On the other hand, he does not reveal the real capabilities of the engine, but they are revealed by the wiki on the off site, as well as javadoc , so that those who are interested have room for creativity and all available platforms for conquering.

    Work safe. Work smart. Your future depends on it © Half Life railway

    Also popular now: