Highlighted Changes in Ardor3D 1.5 - Renanse/Ardor3D GitHub Wiki

Goal

The goal of version "1.5" of Ardor3D is to provide an OpenGL 3.3+ forward-compatible rendering engine, porting as many features of the “1.0” engine as possible.

Important Areas of Change

MeshData and DataMode

The MeshData class in Ardor3D provides a way to package together per-vertex data for a Mesh. In the past, this data was stored as individual, hardcoded buffer fields that mapped to vertex properties handled in fixed-function OpenGL (position, normal, texture coordinates, etc.) This hard-coded approach meant that user-defined vertex properties (for example, per-vertex bone weights for skeletal animation) had to be handled separately.

In addition, previously a DataMode scene hint instructed Ardor3D on how this data was sent to the card - either as Arrays or as Vertex Buffer Objects (VBO). Arrays send data through on each render whereas VBO data would be sent once to the card and referenced by id on subsequent renders, updating only if flagged that the data was dirty.

Modern OpenGL does away with Arrays, so all data in Ardor3D is now handled via VBO. Per-vertex data is still kept in MeshData but is now stored in a map that is keyed by a String. Old methods for referencing vertex information (getVertexCoords, getNormalCoords, etc.) are maintained for convenience but internally access the map using keys predefined as constants in MeshData.

In addition, MeshData sent to the card is now wrapped up in a Vertex Array Object during rendering. This approach allows referencing all contained data with a single id and can reduce the amount of data sent to the card each frame, improving performance. The side effect, however, is that code modifying vertex data must flag the buffer (and MeshData itself) as being dirty.

You can mark individual AbstractBufferData objects dirty via their markDirty() method. Keep in mind that you will need to also mark the MeshData as dirty via markBuffersDirty().

meshData.getVertexCoords().markDirty();
meshData.markBuffersDirty(); // tells Ardor3D that one or more buffers need updates.

Alternatively, you can do both at once by calling markBufferDirty(key) on MeshData, providing the key used for the buffer you are changing. This is the recommended approach.

meshData.markBufferDirty(MeshData.KEY_VertexCoords);

Spatial Properties

Previous versions of Ardor3D allowed storing a single Object on a Spatial via getUserData(Object). Similar to MeshData’s new per-vertex properties, this user data field has been replaced with a Map<String, Object>. The old methods currently remain for convenience, making use of the constant Spatial.KEY_UserData, but are marked as deprecated.

Properties are set on a Spatial using the setProperty(String, Object) method. Properties can be retrieved from a Spatial using either getLocalProperty(String) or getProperty(String). The former will return only properties locally set on the given Spatial whereas the latter will use a new scene hint called PropertyMode to determine if and how it should look at parent properties in the Scene when determining how to retrieve a property value.

Moving to a Map of properties allows us to store useful data locally to the scenegraph and provides one possible source of values for shader uniforms during rendering. See the Material System section below for more on that.

Currently, properties are not stored during Savable export, but the intention is to do so in the future.

RenderState

Ardor3D’s RenderState classes were originally designed to mirror the state of OpenGL itself and assist in reducing the number of calls made by the engine to change that state. Modern OpenGL removes a large amount of this state information, expecting relevant information to be passed directly to the shaders in use. Therefore, we are removing several RenderState classes to mirror this change.

Removed States

State Replacement Strategy
Material Supply material face color and shininess to an appropriate shader as a ColorSurface uniform.
Shading Turn on Flat shading via the use of the flat keyword on in/out shader variables.
Fog Supply fog properties to the shader via a FogParams uniform supplier.
Clip Supply clip planes to the shader as uniform and test fragments + discard.
FragmentProgram / VertexProgram The old ARB assembly language style shader programs are obsolete and have no direct replacement in Ardor3D 1.5. They will need to be rewritten in GLSL and accessed via the Material System.
GLSLShader Use the Material System.
Light Lights are now Spatial objects and can be added directly to the scene. Other Spatials in the scene can be marked as capable of receiving light via the SpatialProperty "_receiveLight". (See convenience method LightProperties.setLightReceiver(boolean).) By default, this is true unless specifically set to false. The flag indicates to the engine that it should spend time determining which lights would have the most effect on a given Spatial. Note that the material for a mesh must also integrate light data for the lighting to have any effect during rendering.

State Changes

State Notes
Texture 1. Adding a texture to the TextureState will no longer automatically make use of it - this depends on the Material used and how it accesses Textures.
2. Textures no longer have EnvironmentalMapMode, ApplyMode, or any fields related to ApplyMode - these types of operations should be done by the shader itself.
3. Textures no longer have a TextureMatrix. Use uniform values to supply desired matrices to the Material.
4. "Disabling" the Texture state does not automatically remove texturing - instead, it means the associated Texture(s) will not be sent to the card. This could result in bleeding of other Textures in the scene or other unexpected behavior if the current Material and Shader do not take this into account.

No Changes

The following RenderStates should work as expected during rendering: Blend, Wireframe, ZBuffer, Cull, Stencil, ColorMask and Offset.

Material System

With the move to a Shader-based modern OpenGL pipeline, there was a need to greatly improve the handling of OpenGL shaders and how data are supplied to shaders. In Ardor3D 1.5, this is now done with the new classes: RenderMaterial, MaterialTechnique, and TechniquePass.

Ardor3D Render Material Structure

RenderMaterial

RenderMaterial represents a style of drawing a renderable in Ardor3D and consists of one or more techniques.

MaterialTechnique

MaterialTechnique represents one method of rendering the given material style. The technique used is decided based on a scoring system. This scoring system is not currently implemented so the first technique is always used. The future intent is that the technique will provide scoring logic.

Techniques consist of one or more passes. These passes are executed in the order they are listed in the technique.

TechniquePass

TechniquePass contains the render information necessary to draw a renderable once. This information includes shaders, attributes, and uniforms.

Shaders

A pass must at least have shaders assigned for ShaderType.Vertex and ShaderType.Fragment. It can currently have up to five shaders - one for each shader type. Shaders can be set on passes as a String, a List of Strings (concatenated by the driver) or an InputStream.

Attributes

Attributes are per-vertex data provided via information stored in a MeshData object and referenced by a String key. This relationship is described via the VertexAttributeRef class, which maps either a specific shader variable by name or a specific attribute location, to an AbstractBufferData object stored in MeshData by a String key. This data may be traditional information familiar to fixed function rendering such as vertex positions, per-vertex normal vectors, and texture coordinates, or less traditional information such as per-vertex weights, particle influences, and much more.

Uniforms

Uniforms are data provided to the shader once per render pass. This data can come from a variety of sources, including static values, Spatial properties, Render matrices, engine state values, or even a user-provided function. Uniforms can also provide default values. This relationship is described via the UniformRef class.

Constructing Materials

Code Example

While a bit laborious and less reusable than Material Files (see below), you can build shaders directly in Java code. Below is a simple example of a material that draws a Mesh in solid white. We provide a single attribute, vertex position, and three matrix uniforms for the mesh’s world transform, camera transform and screen space transform. The vertex shader simply transforms the coordinate into the screen. The fragment shader simply returns a white pixel.

RenderMaterial material = new RenderMaterial();
MaterialTechnique technique = new MaterialTechnique();
material.addTechnique(technique);
TechniquePass pass = new TechniquePass();
technique.addPass(pass);

pass.addAttribute(new VertexAttributeRef(MeshData.KEY_VertexCoords));
pass.addUniform(new UniformRef("model", UniformType.Matrix4x4,
    UniformSource.RendererMatrix, RenderMatrixType.Model));
pass.addUniform(new UniformRef("view", UniformType.Matrix4x4,
    UniformSource.RendererMatrix, RenderMatrixType.View));
pass.addUniform(new UniformRef("projection", UniformType.Matrix4x4,
    UniformSource.RendererMatrix, RenderMatrixType.Projection));

final String vertexShader = //
        "#version 330 core\n" + //
        "in vec3 vertex;\n" + //
        "uniform mat4 model, view, projection;\n" + //
        "void main() {\n" + //
        "    gl_Position = projection * view * model * vec4(vertex, 1.0);\n" + //
        "}";
pass.setShader(ShaderType.Vertex, vertexShader);

final String fragmentShader = //
        "#version 330 core\n" + //
        "out vec4 FragColor;\n" + //
        "void main() {\n" + //
        "    FragColor = vec4(1.0, 1.0, 1.0, 1.0);\r\n" + //
        "}";
pass.setShader(ShaderType.Fragment, fragmentShader);

YAML Material File Example

Here is that same simple material as a YAML file. We go into more detail on the format below.

---
techniques: 
  passes: 
      - 
        attributes:
          - key: vertex
        uniforms: 
          - builtIn: [model, view, projection]
        shaders: 
          Vertex: 
            program: |
                #version 330 core
                in vec3 vertex;
                uniform mat4 model, view, projection;
                void main() {
                    gl_Position = projection * view * model * vec4(vertex, 1.0);
                }
          Fragment:
            program: |
                #version 330 core
                out vec4 FragColor;
                void main() {
                    FragColor = vec4(1.0, 1.0, 1.0, 1.0);
                }</td>
  </tr>
</table>

YAML File Format Detail

The YAML-based file format Ardor3D uses to describe render materials has several features designed to make things easier and more extensible. We go into these below. How YAML works, in general, is not covered here, but there are excellent resources online such as yaml.org.

Reading in a .yaml file is done via the YamlMaterialReader class in ardor3d-core. Ardor3d’s included material files currently only supply one material per file, however, each file can contain more than one if desired. You can then read the file with the reader and pull out the material by index or by looking for a particular name.

It is important to note that when supplying the name of a .yaml file to Spatial.setRenderMaterial, only the first material in the file is used.

Each material in the material file is laid out in as a list of 1 or more techniques, each with 1 or more passes. Each of these passes is laid out in 3 major sections: attributes, uniforms, and shaders.

Attributes

The attributes section of the YAML file provides information about the connection of MeshData buffers to vertex shader inputs. This section is a sequence of mapping nodes, each describing a single shader input.

The following keys are available in each mapping node:

Key Purpose
key String: Used for both meshKey and shaderKey, if either, or both, are not specified.
location Integer: The specific vertex shader stage input location to map to, regardless of the variable name used in the shader. If this is specified, shaderKey should not be. The vertex shader should have a matching layout (location=X) where X is the same integer supplied here in the yaml.
meshKey String: The key used to pull the desired AbstractDataBuffer from our MeshData. Defaults to any value supplied to key (above) if not supplied.
shaderKey String: The variable name to match to in the vertex shader. Ignored if location is supplied.
span Integer: Number of tuples that combine to form a single attribute. Default is 1.
stride Integer: Specifies the offset between consecutive generic vertex attributes. This value will be converted to bytes by the engine. If stride is 0, the generic vertex attributes are understood to be tightly packed in the array. See also glVertexAttribPointer. Default is 0.
offset Integer: Specifies the offset into the buffer, in tuples, to find the first value for this attribute. This value will be converted to bytes by the engine. Default is 0.
divisor Integer: Used when drawing multiple instances of a mesh in a single draw call. See also glVertexAttribDivisor. Default is 0.
normalized Boolean: Specifies whether fixed-point data values should be normalized (true) or converted directly as fixed-point values (false). See also glVertexAttribPointer. Default is false.
Examples
        attributes:
          - key: vertex
          - 
            meshKey: normal
            shaderKey: in_normal
          - 
            meshKey: color
            location: 2
          - 
            key: uv0
            location: 4
Matching Shader Inputs
#version 330 core

in vec3 vertex;
in vec3 in_normal;
layout (location = 2) in vec4 in_color;
layout (location = 4) in vec2 texCoord;
Uniforms

The uniforms section of the YAML file provides information on how to provide data to shader uniform variables. This section is a sequence of mapping nodes, each describing a single shader uniform. The shader uniforms can be in any of the shaders provided to the material.

The following keys are available in each mapping node:

Key Purpose
shaderKey String: The variable name to match to in the vertex shader. Ignored if location is supplied.
location Integer: The specific uniform buffer location to map to, regardless of the variable name used in the shader. If this is specified, shaderKey should not be. (note, this feature is not fully tested.)
type Enum: The data type of the uniform. Defaults to `Int1`

One of: Float1, Float2, Float3, Float4, Int1, Int2, Int3, Int4, UInt1, UInt2, UInt3, UInt4, Double1, Double2, Double3, Double4, Matrix2x2, Matrix2x3, Matrix2x4, Matrix2x2D, Matrix2x3D, Matrix2x4D, Matrix3x2, Matrix3x3, Matrix3x4, Matrix3x2D, Matrix3x3D, Matrix3x4D, Matrix4x2, Matrix4x3, Matrix4x4, Matrix4x2D, Matrix4x3D, Matrix4x4D, UniformSupplier

source Enum: The source of data for the uniform. Defaults to `Value`

One of:

Value A value specified by the value key in this yaml node.
SpatialProperty A value held in the scenegraph as a Spatial property. The value key in this yaml node specifies the String key to look up the value by. If no value is provided, shaderKey is used.
RendererMatrix A Matrix4x4 value calculated by Ardor3D. Which matrix to send is specified by the value key in this yaml node as an Enum value - one of: Model, View, Projection, Normal
Ardor3dState A value held by current state tracking in Ardor3D. Which value to send is specified by the value key in this yaml node as an Enum value - one of: MeshDefaultColorRGBA, MeshDefaultColorRGB, CurrentCameraLocation, Light
Function A user supplied function of type BiFunction<Mesh, Object, Object> - not currently available via yaml.
Supplier A user supplied supplier of type Supplier<Object> - not currently available directly via yaml. This source is often used under the covers by uniforms of type UniformSupplier.
value The value of the data. Appropriate content depends on the value of source. See source table for additional information.
extra Some combinations of source and value require an additional parameter. For example, Ardor3dState + Light needs to know the index of the light in question. Extra is used to provide this information.
defaultValue The numeric value to use if a particular data source does not exist to read from - for example, if a SpatialProperty is missing.
Examples

Source: Value Note: "source" key is optional since the default is “Value”.

        uniforms: 
          - 
            shaderKey: cubeMap
            type: Int1
            value: 0
          -  
            shaderKey: reflectMat
            type: Matrix4x4
            value: [[-1, 0, 0, 0],
                    [ 0, 1, 0, 0],
                    [ 0, 0, 1, 0],
                    [ 1, 0, 0, 1]]

Source: SpatialProperty Note: shaderKey is used for the spatial property key as well, since value is not specified.

        uniforms: 
          - 
            shaderKey: roughness
            type: Float1
            source: SpatialProperty

Source = RendererMatrix Note: See "builtin" section below for a more compact way to specify these common uniforms.

        uniforms: 
          - 
            shaderKey: model
            type: Matrix4x4
            source: RendererMatrix
            value: Model

Source = Ardor3dState Note: See Ardor3dStateProperty enum for possible values and their appropriate type.

        uniforms: 
          - 
            shaderKey: defaultColor
            type: Float4
            source: Ardor3dState
            value: MeshDefaultColor
Uniform Shortcuts

We have added some optional shortcuts for often-used uniform settings such as render matrices. These shortcuts are accessed by adding the key "builtIn" to the uniforms section, followed by a list of shortcut values. These are shorthand for fully expressed uniform nodes.

Example

        uniforms: 
          - builtIn: [model, view, projection]

List of current available built in values:

Shortcut Value Fully Expanded Form
view
- 
  shaderKey: view
  type: Matrix4x4
  source: RendererMatrix
  value: View
model
- 
  shaderKey: model
  type: Matrix4x4
  source: RendererMatrix
  value: Model
projection
- 
  shaderKey: projection
  type: Matrix4x4
  source: RendererMatrix
  value: Projection
normalMat
- 
  shaderKey: normalMat
  type: Matrix3x3
  source: RendererMatrix
  value: Normal
modelViewProj
- 
  shaderKey: modelViewProj
  type: Matrix4x4
  source: RendererMatrix
  value: ModelViewProjection
modelViewProjection
- 
  shaderKey: modelViewProjection
  type: Matrix4x4
  source: RendererMatrix
  value: ModelViewProjection
textureMatrix0
- 
  shaderKey: textureMatrix0
  type: Matrix4x4
  source: SpatialProperty
  value: textureMatrix0
  defaultValue: [[1, 0, 0, 0][0, 1, 0, 0][0, 0, 1, 0][0, 0, 0, 1]]
textureMatrix1
- 
  shaderKey: textureMatrix1
  type: Matrix4x4
  source: SpatialProperty
  value: textureMatrix1
  defaultValue: [[1, 0, 0, 0][0, 1, 0, 0][0, 0, 1, 0][0, 0, 0, 1]]
textureMatrix2
- 
  shaderKey: textureMatrix2
  type: Matrix4x4
  source: SpatialProperty
  value: textureMatrix2
  defaultValue: [[1, 0, 0, 0][0, 1, 0, 0][0, 0, 1, 0][0, 0, 0, 1]]
textureMatrix3
- 
  shaderKey: textureMatrix3
  type: Matrix4x4
  source: SpatialProperty
  value: textureMatrix3
  defaultValue: [[1, 0, 0, 0][0, 1, 0, 0][0, 0, 1, 0][0, 0, 0, 1]]
viewSize
- 
  shaderKey: viewSize
  type: Float2
  source: Ardor3dState
  value: CurrentViewportSizePixels
viewOffset
- 
  shaderKey: viewOffset
  type: Float2
  source: Ardor3dState
  value: CurrentViewportOffsetPixels
cameraLoc
- 
  shaderKey: cameraLoc
  type: Float3
  source: Ardor3dState
  value: CurrentCameraLocation
defaultColor
- 
  shaderKey: defaultColor
  type: Float4
  source: Ardor3dState
  value: MeshDefaultColorRGBA
defaultColorRGB
- 
  shaderKey: defaultColorRGB
  type: Float3
  source: Ardor3dState
  value: MeshDefaultColorRGB
colorSurface
- 
  shaderKey: surface
  type: UniformSupplier
  source: SpatialProperty
  extra: com.ardor3d.surface.ColorSurface
pbrSurface
- 
  shaderKey: surface
  type: UniformSupplier
  source: SpatialProperty
  extra: com.ardor3d.surface.PbrSurface
pbrTexturedSurface
- 
  shaderKey: surface
  type: UniformSupplier
  source: SpatialProperty
  extra: com.ardor3d.surface.PbrTexturedSurface
fogParams
- 
  shaderKey: fogParams
  type: UniformSupplier
  source: SpatialProperty
  extra: com.ardor3d.renderer.material.fog.FogParams
lights
- 
  shaderKey: lightProps
  type: UniformSupplier
  source: Ardor3dState
  value: LightProperties
alphaTest
- 
  shaderKey: alphaTestType
  type: Int1
  source: SpatialProperty
  defaultValue: 7
- 
  shaderKey: alphaReference
  type: Float1
  source: SpatialProperty
  defaultValue: 0
Uniform Suppliers

Oftentimes information we wish to send to the shader may be grouped logically into a class on the Java side. Enabling that class to directly provide uniform information to the shader can reduce the verbosity of our material files or code. In Ardor3d 1.5, this can be done via implementing the IUniformSupplier interface and sending the class as a single uniform using the UniformType, UniformSupplier.

Ardor3d takes these classes and calls the interface method, getUniforms, to expand it into multiple uniform refs. During rendering, the original name of the supplier uniform is prepended to the name of its supplied uniforms, so you will need to provide a matching struct and variable in the shader code to receive the value.

In addition, if no instance of the object is found by the material to supply values, a new instance of the class is created, cached at the uniform instance level, and used to provide default values to the shader. The instance will have the method applyDefaultUniformValues called after creation to set it up for this use.

Below is an example of a class and material using the IUniformSupplier. Imagine newing up an instance of the class ColorSurface below and adding it as a spatial property under the key "surface". The single “surface” uniform in the material below will get expanded into 4 uniforms, pulling their data directly from the class instance methods.

Class implementing IUniformSupplier

public class ColorSurface implements IUniformSupplier {

    public final ColorRGBA ambient = new ColorRGBA(0.1f, 0.1f, 0.1f, 1f);
    public final ColorRGBA diffuse = new ColorRGBA(.5f, .5f, .5f, 1f);
    public final ColorRGBA specular = new ColorRGBA(1f, 1f, 1f, 1f);
    public float shininess = 32f;
    protected final List<UniformRef> cachedUniforms = new ArrayList<>();

    public ColorSurface() {
        cachedUniforms.add(new UniformRef("ambient", UniformType.Float3, UniformSource.Supplier, (Supplier<ReadOnlyColorRGBA>) this::getAmbient));
        cachedUniforms.add(new UniformRef("diffuse", UniformType.Float3, UniformSource.Supplier, (Supplier<ReadOnlyColorRGBA>) this::getDiffuse));
        cachedUniforms.add(new UniformRef("specular", UniformType.Float3, UniformSource.Supplier, (Supplier<ReadOnlyColorRGBA>) this::getSpecular));
        cachedUniforms.add(new UniformRef("shininess", UniformType.Float1, UniformSource.Supplier, (Supplier<Float>) this::getShininess));
    }

    @Override
    public void applyDefaultUniformValues() {}

    public ColorRGBA getAmbient() {
        return ambient;
    }

    public ColorRGBA getDiffuse() {
        return diffuse;
    }

    public ColorRGBA getSpecular() {
        return specular;
    }

    public float getShininess() {
        return shininess;
    }

    @Override
    public List<UniformRef> getUniforms() {
        return cachedUniforms;
    }
}

Material using the class

---
techniques: 
  passes: 
      - 
        attributes:
          - key: vertex
          - key: normal

        uniforms: 
          - builtIn: [model, view, projection, normalMat, cameraLoc, defaultColor, lights, alphaTest]
          - 
            shaderKey: surface
            type: UniformSupplier
            source: SpatialProperty
            extra: com.ardor3d.surface.ColorSurface
            
        shaders: 
          Vertex: 
            source: phong/phong.vert
          Fragment:
            source: phong/phong_modulate.frag
Shaders

The shaders section of the YAML file provides the source of the shader code to be sent to the OpenGL driver. Shader code is provided under a node named for the type of shader and can either be directly provided as text in the YAML file, or referenced as an external file.

Shader code is provided directly in the YAML via the use of the program key. An external file can be used instead by the use of the source or sources key (the latter taking a list of source files.) External files are located by Ardor3D via the standard lookup mechanism provided by ResourceLocator, using the resource type ResourceLocatorTool.TYPE_SHADER.

Example

        shaders: 
          Vertex:
            source: pbr/pbr.vert
          Fragment:
            program: |
                #version 330 core
                out vec4 FragColor;
                void main() {
                    FragColor = vec4(1.0, 1.0, 1.0, 1.0);
                }

Additional mechanisms are available in this section as well that provide greater flexibility and allow you to create libraries of reusable shader code. These are described below.

Inject and Define

The first mechanism is the ability to provide one or more chunks of code for injection into the associated shader. This injection is done via the keywords inject(s) and define(s).

inject takes a string or list of strings (injects) and includes them as new lines after the #version line in the shader. The lines are included in the order provided.

define is the same as inject except that it automatically places #define before the text provided. This keyword is provided purely as a way to allow the YAML files to be terser.

Example

...
        shaders: 
          Vertex: 
            source: ui/ui_textured.vert
            define: VERTEX_COLORS

          Fragment:
            source: ui/ui_textured.frag
            define: VERTEX_COLORS

Shader output: note that the 2nd line is injected by Ardor3D

#version 330 core
#define VERTEX_COLORS

in vec3 vertex;
in vec2 uv0;
#ifdef VERTEX_COLORS
in vec4 color;
#endif
...
Import

The other mechanism provided is the import directive. This directive allows injecting source code from other shader files into an arbitrary position of other shader source and is done via a keyword and relative path. The keyword is defined in Ardor3D in the static field MaterialManager.ImportMarker and is "@import" by default.

MaterialManager provides the method inflateShaderImports(String) to properly inflate any imports found in a given chunk of shader code, thus allowing this mechanism to be used outside of YAML as well.

Example

#version 400 core

@import include/alpha_test.glsl
@import include/phong_lighting.glsl

#ifdef USE_FOG
@import include/fog.glsl
#endif

...

TextureRenderer

Previously, Ardor3D’s TextureRenderer supported two different implementations: FBO and Pbuffer. The actual choice between these implementations was abstracted away via Ardor3D’s TextureRendererFactory. This approach meant priming the factory with the correct TextureRenderer implementation prior to usage and also resulted in an odd situation where you could technically provide different OpenGL bindings for the creation of the TextureRenderer target versus rendering of content to that target.

With the move to OpenGL 3.3+ and forward compatibility, Pbuffer is no longer supported, simplifying TextureRenderer implementation and creation. Now, TextureRenderers are created directly from a Renderer. There is only a single method for doing this in Renderer, reducing confusion over which settings provided actually have an effect. Methods that only had a material effect when the backend was a Pbuffer have also been removed as has the TextureRendererFactory class.

Old code:

TextureRendererFactory.INSTANCE.setProvider(new LwjglTextureRendererProvider());
DisplaySettings settings = new DisplaySettings(512, 512, 24, 0, 0, 24, 0, 0, false, false);
TextureRenderer texRend = TextureRendererFactory.INSTANCE
        .createTextureRenderer(settings, false, renderer, 
         ContextManager.getCurrentContext().getCapabilities());

New code:

TextureRenderer texRend = renderer.createTextureRenderer(512, 512, 24, 0);

In addition, it is now possible to resize an existing TextureRenderer on the fly, allowing for reuse. This functionality is best used in situations where you are doing one-off renders, such as generating diffuse maps, etc. as it would be expensive to resize every frame.

There are two Texture related changes worth noting here. Textures now have a field for specifying the mip level to render into during Render to Texture operations. This can be set via the method setTexRenderMipLevel(int). Also, in the past, any time we rendered to a Texture using a TextureRenderer and the Texture used a minification filter that used mipmaps, we would automatically generate new mipmaps. When rendering to a specific mipmap, however, this functionality may not be desired. You can set the behavior you desire on the TextureRenderer using the method setEnableMipGeneration(boolean). The default is true.

LWJGL Renderer Updated

The LWJGL2 based renderer has been replaced with an LWJGL3 renderer under the subproject ardor3d-lwjgl3. Right now this includes:

  • A GLFW based implementation of Ardor3D’s NativeCanvas.
  • A headless version of the above.
  • A GLFW based implementation of Ardor3D’s KeyboardWrapper, MouseWrapper, and MouseManager.
  • An LWJGL3 based implementation of Ardor3D’s Renderer and TextureRenderer.

Additional Canvas Types:

  • A java.awt.Canvas based Lwjgl canvas is found in subproject ardor3d-lwjgl3-awt.
  • An SWT based Lwjgl canvas is found in subproject ardor3d-lwjgl3-swt.

Intended future support here includes:

  • Android support

JOGL Renderer Dropped

The JOGL renderer has been dropped in Ardor3D 1.5, though the core of the engine has been left renderer-agnostic so as to allow re-adding JOGL (or some other binding) in the future. The main reasons for dropping JOGL support include:

  • Lack of customer usage - current users of the original Ardor3D repo have decided to focus on LWJGL.
  • JOGL Ardor3D community/fork - folks using Ardor3D and JOGL decided several years ago to fork and continue the development of Ardor3D within their own community. Thus someone interested in using JOGL and Ardor3D already has a community-supported means of doing so.
⚠️ **GitHub.com Fallback** ⚠️