Local Info

Topics

j3d.org

Render to Texturing Example

Rendering to an offscreen buffer, and then using that as a texture is a relatively common excercise for most games to employ. This gives the ability to have effects like rear-view mirrors, dynamic environment mapping, shadows and so-forth. Aviatrix3D takes a very different approach to this design to other scene graph API by placing the capability directly in the scene graph as a node, rather than letting you set up a separate scene graph and render cycle, followed by bit copying to update the real texture. Thus, the complexities of working with pBuffers, and the JOGL abstractions of them are largely hidden. In this example, we'll walk you through a simple demo of how to set these up within Aviatrix3D.

If you would like to see the complete version of this code, it can be found in the examples/texture directory and is named SimpleRenderToTextureDemo.java.

 

How Aviatrix3D Models Dynamically Generated Textures

One of the design goals of Aviatrix3D is to keep a scene graph structure while still enabling all of the features that a traditional linear-style of programming would use. This is most clearly scene in how we deal with extended texturing capabilities like this capability (pBuffer-based textures) and multipass rendering. These are classic linear programming styles that have a rendering loop that pushes all of these to the front by rendering the texture, then using something like glCopyTexSubImage2D() to an appropriate texture target and then finally handles the main scene drawing. What our design philosophy does is to represent that capability through the normal scene graph. For these, you are always rendering some sort of scene structure to what eventually gets used as a texture. Whether that scene structure is your main scene, but with a different set of viewpoints or from another view and completely separate setup, such as creating stencil masks for shadows, all of that setup is abstracted into the scene graph structure.

OffscreenTexture2D.

Setting up the application

In this example, we are going create a very simple scene graph structure to illustrate how the pieces fit together. In this, we will have a single camera-aligned quad which the texture will be rendered into. The texture itself will have just a simple triangle drawn on it and animated.

The basic scene graph structure follows that of our previous examples - a single viewpoint and the geometry declaration like so:

    Viewpoint vp = new Viewpoint();

    Vector3f trans = new Vector3f(0, 0, 1);

    Matrix4f mat = new Matrix4f();
    mat.setIdentity();
    mat.setTranslation(trans);

    TransformGroup tx = new TransformGroup();
    tx.addChild(vp);
    tx.setTransform(mat);

    Group scene_root = new Group();
    scene_root.addChild(tx);

    ...
    TriangleArray geom = new TriangleArray();
    geom.setVertices(TriangleArray.COORDINATE_3, coord, 6);
    geom.setTextureCoordinates(tex_type, tex_coord, 1);

    Appearance app = new Appearance();

    // Create basic texture here:


    TextureUnit[] tu = new TextureUnit[1];
    tu[0] = new TextureUnit();
    tu[0].setTexture(texture);

    app.setTextureUnits(tu, 1);

    Shape3D shape = new Shape3D();
    shape.setGeometry(geom);
    shape.setAppearance(app);

    scene_root.addChild(shape);

    SimpleScene scene = new SimpleScene();
    scene.setRenderedGeometry(scene_root);
    scene.setActiveView(vp);

    sceneManager.setScene(scene);

Limitations of the Aviatrix3D model

JOGL-imposed limitations

Can only be used as a 2D texture. No ability to set it up as an input to a cubic environment map or other texture type. This is a limitation imposed by JOGL and not something we can work around. However, still works well as an input to a shader.

Scene Graph looping

We impose the restriction that you cannot loop the scene graph so that the rendered texture contains the main scene. It may contain parts of the parent scene, which is useful if you want to have a mirror, but we don't allow you to create complete loops. Checks are in place and will throw an exception if we notice this.