Brace yourselfs, new 3D API incoming

Xoppa, Bach and I have been working on a new 3D API, with short breaks (cause iOS…). We are now in full swing of finishing that puppy. You can follow the progress in this thread. Lots of design discussions have been had, we are trying to make the API as simple to use as SpriteBatch, while giving you as much flexibility as possible. Here’s a taste of what it looks like working with this thing at the moment:

You can find the full thingy on the new3dapi branch. I spare you the details for now, once we merged with master i’ll give you a full wiki article on all things 3D. Here’s a quick rundown of the features we are aiming for:

  • flexibility and small API über-alles
  • OpenGL ES 2.0 only for now, the API is flexible enough for you to write a GLES 1.x shader should you need that
  • Format support: FBX converter, based on Gameplay SDK. Spits out custom format more suitable for runtime consumption. Provides us with the best coverage of modelling apps. Bach’s been slaving away on this in January and its pretty much complete, save for some modelling app specific issues.
  • Modelling app support: the FBX converter is a standalone app, that’s really simple to wrap as a plugin for modelling apps. We’ll initially provide an addon for Blender, but will also try to get Maya, Softimage and 3DSMax going. Writting a plugin yourself by wrapping the converter should be extremely simple as well, much more so than writting a full-blown plugin.
  • Models, Instances and ModelBatch: models are the templates holding meshes, node hierarchy and materials. The Model is the one responsible for disposing meshes/textures, in a single place, which makes asset managment really easy. A model is analogues to a TextureAtlas/Texture/TextureRegion when working with SpriteBatch. You don’t directly render/animate a model, but create instances from the model, which share the meshes and textures. This allows you to modify materials and the node hierarchy of an instance without destroying the originals in the model. Think of instances as Sprites in the 2D analogy, you can modify it without touching the texture it may share with other sprites. Finally the ModelBatch (name change pending) allows you to render instances (it’s more flexible than that, but more on that another time).
  • Animation: skeletal animation (GPU only) and keyframed animation (ala MD2, GPU only)
  • Materials: flexible, and customizable. We try to support as many material attributes out of the box as possible.
  • Shaders: we’ll provide an über-shader that includes lighting, skinning and keyframe interpolation. You can plug in your own shading easily.

The goal of the API is to be as flexible as possible. We will likely not provide everything but the kitchen sink out of the box, but continuously add new features over time. Our biggest concern has been to make this as flexible as possible, while retaining a minimal API that’s easy to use and extend. I think we achieved that goal. What’s left to be done:

  • AssetManager support (really simple due to our data model)
  • Update current tests and demos, especially gdx-invaders. The bullet tests already use the new API on the branch
  • More comprehensive default shader
  • Node based animation
  • Skinning
  • Keyframed animation
  • Optimizations
  • Documentation

That may look like a lot, but the API design is actually what takes the most time. That’s pretty much done now, safe for some minor modifications here and there. The rest should be comparatively “easy” (yeah, i said it…).

The old API will disappear completely when we merge the new3dapi branch with the master branch in a few days

23 thoughts on “Brace yourselfs, new 3D API incoming

  1. Ohhh, a lot of work is coming to change projects from old api to new )
    Thanks for this huge work, guys!

  2. Wow, this looks incredible! You guys are really doing a lot to make professional quality game development feasible for indies.

    Thanks so much for the excellent work.

  3. This is fantastic.

    One observation though – JsonModelLoader doesn’t sound right. A loader is a loader. Does it matter in class naming how it loads it?

  4. Very exciting news! You truly are making cross platform game-making available to the masses.

  5. Have been eagerly waiting for the upgrade and final API layout, this is very exciting and I can’t wait to implement the changes into my Application. Big thanks.

  6. I’ve postpone all the 3D aspect of my project pending the new API.

    To be honest, even if it is not always a lot of fun to write, I’m looking forward to documentation and / or explanations.
    Also, how to manage the various animation sequences of a same skeleton? Can we still get anchor points to assemble animated models? etc …

    Finally, maintaining visibility on future developments, with the order of priority and, insofar as possible, what schedule?

    Here are all my wishes!

    Until now, the use of libgdx is a pleasure and an accelerator development. I appreciate especially the dynamism of its development, and its phylosophy: provides relevant and effective tools.
    For that, thank you to the all team!

  7. I checked twice to see if this post was posted on April 1st or not…
    But I still have to ask; is this a joke?!
    What’s wrong with the current 3D API? Why would this new API in any way be a better solution if it;
    1. Breaks compatibility with all applications currently employing the old API including those in development
    2. Breaks OpenGL ES 1.X support
    3. Breaks .MD2 file format/Keyframe Animation support
    4. Forces more LibGDX-style coding constructs (batches, etc.) upon the coder instead of relying on the current OpenGL-compatible API, impacting portability
    5. Requires a model’s conversion to FBX before being converted to some internal text-based format, forcing use of a particular workflow while right now we can import 3 different file formats directly.
    6. Couples textures and models together, taking away the liberty of the programmer to manage textures according to the needs of the application. If I want to throw a cube-map on a previously non-reflective model at run-time I imagine it’s not going to be a walk in the park using this new API. How about if I want to cover the entire scene in a specific texture or lightmap based on user actions interactively? Right now all I need to do is call texture.bind() before rendering the scene and not binding any textures for the scene components instead of assigning each and every model the same texture in a loop and then afterwards reverting to the original.

    Not a lot of people will remember it, but this reminds me of Microsoft’s “Direct 3D Retained Mode API”. Sure with it you could show an animated model on the screen in 100 lines of code instead of 1000, but no serious developer would give up the flexibility of low-level OpenGL-like 3D programming. In fact, after scrapping that API they made Direct3D even more OpenGL-like and lower-level. If tomorrow I want to port my 3D Engine to native C++ with OpenGL all I have to do is make some minor syntax changes and add my own model/texture loaders and sound routines since most 3D stuff currently is basically OpenGL with classes wrapping texture and vertex data (Mesh). When you start introducing things like “model batches” there is absolutely no analog in any 3D API (OpenGL, Direct3D, …) you can translate your code to, giving you the options to either re-write all your 3D code completely or implementing a “Model Batch” compatible with LibGDX’s.

    What people probably want as improvements to LibGDX’s 3D API is simply;
    – Collision Detection
    – Physics
    – Shadowing
    – .3DS/.X/.FBX import

    Not a re-write of the current stuff that makes it an alien to 3D API Land and takes away features instead of adding them.

    Mike

  8. Hey Mike,

    First up: Thanks for the feedback. Really sorry if these changes are causing you problems 🙁

    We never take API changes lightly and are aware of the sometimes painful consequences of such. It is why we communicate them well in advance and try and make transitions as easy as possible with extensive blog posts (such as this one). Actually, the new API has been discussed for months now in the forums.

    If you have done some more advanced work with the current/old 3d API in libgdx, you’d know that it was unfortunately broken in many ways. It simply couldn’t stay the way it was (especially the loaders).

    Does it still suck? Yes. Are the changes worth it in the long run? Absolutely. Fact is – the API had to change for us to be able to move forward. We make these kind of changes only because we actually think they are worth it.

    On the topic of API: If you want barebones OpenGL API, you can and will always be able to do that with libgdx. You don’t have to use any of the fancy batching & material management that the new API offers. All the new 3d stuff is an additional layer on top, you can still just use Mesh, Shader & Texture. No problems there.

    If these changes break your current project, I’d definitely recommend sticking with stable until the next release. In the meantime we will of course try and help the transition wherever possible.

    Cheers,
    Bach

  9. Adding to what Bach said, and addressing your points directly:

    1) Breaks compatibility with all applications currently employing the old API including those in development

    That’s why we have release builds. If you rely on a feature that we change/break, you can always go back to the latest stable release, and/or use a previous commit (or get one of the current nightlies). If you want to benefit from any bug fixes that are made on master, you can fork libgdx, put in the code we removed, and just pull the latest changes from upstream. The old API is broken on a fundamental level, the only way to fix it was reworking it.

    Breaks OpenGL ES 1.X support

    It actually does not, see https://github.com/libgdx/libgdx/blob/new3dapi/gdx/src/com/badlogic/gdx/graphics/g3d/test/GLES10Shader.java That’s actually used in the reworked version of gdx-invaders, which is still supportin both GLES 1.x and 2.0. As evident from the code above, it’s extremely simple to write your own shader should the need arise.

    3. Breaks .MD2 file format/Keyframe Animation support

    The new data model actually allows writing importers in a much cleaner and more straight forward way. We currently only support G3DJ (converted from FBX) and OBJ. We have plans to reintroduce the model-loaders extension with cleaned up loaders for other formats.

    4. Forces more LibGDX-style coding constructs (batches, etc.) upon the coder instead of relying on the current OpenGL-compatible API, impacting portability

    I really tried to make sense of this one, but failed. The old API uses the exact same coding constructs, see https://github.com/libgdx/libgdx/blob/master/extensions/model-loaders/model-loaders/src/com/badlogic/gdx/graphics/g3d/test/PrototypeRendererGL20.java In my opinion its actually beneficial to unify the terminology and concepts, to make the entrance into 3D as easy as possible for people that are accustomed to the 2D APIs. Also, if you dislike the “libgdx-style” coding constructs, why are you using libgdx in the first place? I also have no idea how the changes would affect portability and would be happy if you could elaborate.

    5. Requires a model’s conversion to FBX before being converted to some internal text-based format, forcing use of a particular workflow while right now we can import 3 different file formats directly.

    I can see that this seems like a step backwards. However, all the formats we supported with the old API have no, or extremely buggy exporters for common modelling apps like Blender, Maya, 3DS, Softimage. FBX is the industry standard (even more so than COLLADA), and is supported across all of this formats. We are trying to improve the workflow by providing exporters for popular modelling apps, starting with Blender. These exporters are one click solutions, directly saving your model into the runtime format. It also allows us to simplify creation of exporters for modelling apps as all we need to do is wrap the fbx-conv binary. If you ever tried to write an exporter for any of the 3D modelling apps out there you will know that handcrafting exporters for each app individually does not scale at all.

    6. Couples textures and models together, taking away the liberty of the programmer to manage textures according to the needs of the application. …

    I have no idea why you think that’s the case? First of all, the actual model data is stored without any OpenGL resources in an instance of ModelData. From that we derrive Model instances that are responsible for managing OpenGL resources. If anything, that actually decouples the resources more cleanly. The model is the single point of entry for all resource managment, making it a lot easier to keep track of things than the old way of doing it within material attributes. Never the less, you can opt out of the automatic managment by providing your own TextureProvider. That can feed off of an AssetManager, or a custom asset managment facility. You are absolutely encouraged to exploit this simple mechanism and optimize texture managment for your application.

    If I want to throw a cube-map on a previously non-reflective model at run-time I imagine it’s not going to be a walk in the park using this new API

    It’s the same, with cleaner ownership semantics. You create a Model instance, which you can modify however you want, without destroying the original model. You can then switch out materials and their attributes however you want, exactly like you do in the old API.

    How about if I want to cover the entire scene in a specific texture or lightmap based on user actions interactively? Right now all I need to do is call texture.bind() before rendering the scene and not binding any textures for the scene components instead of assigning each and every model the same texture in a loop and then afterwards reverting to the original.

    You do exactly the same with the new API. You seem to have chosen not to use the renderers in the old API, but just use the meshes and textures loaded by the importers with your custom rendering code. Nothing keeps you to do that with the new API. There’s are no dependencies what so ever between the Model and the ModelBatch, you can use the former without the later (and vice versa btw…).

    Not a lot of people will remember it, but this reminds me of Microsoft’s “Direct 3D Retained Mode API”. Sure with it you could show an animated model on the screen in 100 lines of code instead of 1000, but no serious developer would give up the flexibility of low-level OpenGL-like 3D programming.

    I do indeed remember that transition. I don’t quite see how this is analogous to what we did with the new 3D API. It actually allows you a lot more fine-grained control over materials/meshes and their ownership, application of materials (which was hardcoded in material attributes in the old API!), rendering order, shader application and so on. As i said above, you can still use plain OpenGL ES together with the raw data loaded from the file, just as you seem to have done with the old API.

    The rest of your points are pretty much a rehash of what was already said and addressed above. So one more time: you can still use all the low-level OpenGL ES you want, there is nothing forcing you to use the rendering pipeline we provide. Just as you ignored the old pipeline.

    Furthermore, I’d like to emphasize that we don’t take API breakage lightly. I blogged a few times about the 3D API and asked for feedback. Nobody ever chimed in, apart from the folks actively helping out to make things better. As stated in the reply to point 1, you can always roll back to an older version, take the old code and merge it with the latest code, or switch to the new API, not using the parts that offend you. I’d also suggest to actually read and try to understand the code and its implications. As stated in the blog post, this is just a glimpse at how things will look like for folks that do not have the need to customize all the things. I even emphasized multiple times that this new API is all about being more flexible. How you derive your conclusion is frankly a mystery to me. Please take some time to check out the new code, and base feedback on that.

  10. I really enjoyed the wall of text Mario (No I am being series it was a good read)

    As a person just getting into programming and game developmental I never believed the old saying start with something difficult than the easier is better. “start with c++ not C#” my thought has always been, why don’t I start at binary than, cause before c++ the saying probably still stood. (yes c++ is currently more desirable in the workforce)
    Point:
    1000 lines of code to render a model or 100… Ill take the 100 and feel good in the fact that I can in time read and understand the source, than make the 1000 lines of code a my leisure.

    I would talk about the well designed api allowing me to directly(as far as my weak understanding goes) interface with opengl but Mario blew that out of the water.

    I love libgdx and the work you guys do. I am looking forward to the new 3dapi!

  11. I’m here to say that new 3d api looks fantastic to me and I totally can’t wait to apply required refactoring to my projects 🙂

  12. 3D API looks great. can’t wait for it anymore 🙂 checking git every day for a merge into master..

Leave a Reply

Your email address will not be published.