Public Types | Public Member Functions

Wizt::VertexRenderObject Class Reference
[The Fish Eye Retina - Fiber Bundle to OpenGL Gateway via Vish API]

Base class for object that render data given on vertices. More...

#include <VertexRenderObject.hpp>

List of all members.

Public Types

Public Member Functions


Detailed Description

Base class for object that render data given on vertices.

This class takes care of shuffling data from a set a Fiber::Fields to the graphics card as a vertex array. In the constructor there only needs to be defined a mapping from Fiber::Fields to vertex arrays, which then can be used directly in a Shader, for instance via the Programmable class. The FragmentPainter base class takes care of setting up a Vertex Buffer Object (VBO) with the set of Fiber::Fields loaded as vertex arrays, possibly creating and calling multiple VBOs in case the field comes with fragmented data instead of contiguous arrays.

An example shuffing a scalar field of type double to the GPU is given by the following code snippet. An input port expecting a Fiber::Field of name "scalarfield" is setup, it expect data to be of type double. This will be load the scalar field's data as a one-dimensional texture coordinate for texture unit 0. It is stored internally via a "scalarvalues" identifier, which is not visible to GLGS code. In cases where not a pre-defined OpenGL type is used, such as an named array, this name will be expected to be an existing vertex array attribture in the GLGS code and the FragmentPainter will assign this array with the field data.

        insertVertexField("scalarvalue",
                          new VBOField<TypedTexCoordArray<double> >(this, "scalarfield", 0) );

Rendering is performed by overloading FragmentPainter::createRenderer(), which by default performs an DrawArray() call. This might just be right for most cases, it will be sufficient for all cases where just points are drawn. Overloading it and replacing it by another kind of VBO::Renderer will be required if topological information among vertices is to be taken into account, such as when drawing lines or triangles.

To execute a specific GLGS shader program on each vertex overload the render() function, create a Program there, use it (Program::use()), and call the renderFragments() function. This code will use the same shader program with different vertex arrays, according to the Fragments of the Fiber::Field. Code will look like this:

class   MyRenderer : public VertexRenderObject
{
        ...

        void    render(VRenderContext&Context) const
        {
        RefPtr<VertexRenderState> myState = getState(Context);

                // Create GSGL program
        RefPtr<Program> myProgram = ...
                ...
                myProgram->use();
                renderFragments(*myState, Context, myProgram );
        }
};

Note that class Programmable provides convenience functions to create GLGS Shader Programs. It is adviseable to derive from this class, which reduces code size even further:

class   MyRenderer : public VertexRenderObject, public Programmable
{
        ...

        void    render(VRenderContext&Context) const
        {
        RefPtr<VertexRenderState> myState = getState(Context);
        RefPtr<Program> myProgram = CompileShader(Context, Name() );
                myProgram->use();
                renderFragments(*myState, Context, myProgram );
        }
};

The above function still needs to implement the virtual functions of class Programmable. If the render object would make use of a geometry shader, then derive from class ProgrammableGeometry instead.

Author:
Werner Benger

Member Function Documentation

RefPtr< ValueSet > Wizt::VertexRenderObject::CacheableVariables ( const RefPtr< ValuePool > &  Context  )  const [virtual]

Return a set of variables for which the results shall be cached, i.e.

there resides an OpenGL object for each state of each of those variables. They are all kept in memory until the cache is full. A typical example are fields. So when the user switches from one field to another field, and back to the first one, the OpenGL object does not need to be recomputed again, but is retrieved from the Cache. A typical counter example is a floating point value, since that one has an infinite number of possibilities. And it is unlikely that a user will accidentally switch back to an old value of a float slider, thus caching relative to float values is not reasonable. It is still possible, however, and could make sense if float values are rounded.

A typical implementation of this function, assuming two slots "MyGrid" and "MyField") looks like this:

           RefPtr<ValueSet> CacheableVariables(const RefPtr<ValuePool>&Context) const
           {
           RefPtr<ValueSet> retval = new ValueSet( MyGrid(Context) );
                        *retval << (*MyField)(Context);
                        return retval;
           }
Deprecated:

Reimplemented from Wizt::FragmentPainter.