[glu3-devel] [RFC] GLUshape and GLUshapeConsumer

Ian Romanick idr at freedesktop.org
Thu Mar 4 00:09:18 PST 2010


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

One of the last things that I want to add for a 1.0 release is some way
to generate simple shapes.  Most of the GLU-like libraries out there
have some way to generate data for cubes, spheres, tori, etc.  I've come
up with a C++ interface, and I'm working on a similar C interface.
These follow in spirit of the GLUquardric from class GLU.

In the C++ interface there are two classes.  One represents the
producer, and the other represents the consumer.  The producer is called
GLUshape, and looks roughly like:

class GLUshape {
public:
        virtual ~GLUshape();

        /** Select the orientation of generated normals */
        void orientation(bool outside);

        /** Select per-vertex or per-polygon normals */
        void normals(bool per_vertex);

        /** Get the number of vertices in the shape */
        virtual unsigned vertex_count(void) const = 0;

        /** Get the number of elements used to draw primitives for the
shape */
        virtual unsigned element_count(void) const = 0;

        /** Get the number of primitves used to draw the shape */
        virtual unsigned primitive_count(void) const = 0;

        /** Generate the primitive */
        virtual void generate(GLUshapeConsumer *consumer) const = 0;

protected:
        GLUshape(void);
};

I have created GLUshapeCube and GLUshapeSphere subclasses so far.
GLUshapeTorus, GLUshapeCylinder, GLUshapeCone, and GLUshapeDisc are not
far behind.  The sphere is implemented as a surface of revolution, so
most of the hard work for the other shapes is already done.

I also intend to provide a GLUshapeMesh that generates the indices for
drawing a rectangular mesh.  I've had to write code to do that enough
times over the years (including for the GLUshapeSphere!) that I don't
want to do it again.  The backing code is written.  I just need to
expose it.

One thing that hasn't been implemented yet is support for per-surface
vs. per-vertex normals.  Right now that state is ignored.  GLUshapeCube
always generates per-surface normals, and GLUshapeSphere always
generates per-vertex normals.

The GLUshape::generate method takes a GLUshapeConsumer object as a
parameter.  The GLUshapeConsumer encapsulates the small handful of
callbacks that are used to get the data out.  The GLUshapeConsumer looks
like:

class GLUshapeConsumer {
public:
        /** Emit an individual vertex */
        virtual void vertex(const GLUvec4 &position,
                            const GLUvec4 &normal,
                            const GLUvec4 &tangent,
                            const GLUvec4 &uv) = 0;

        /** Start a new indexed primitive. */
        virtual void begin_primitive(GLenum mode) = 0;

        /** Emit an element index for drawing */
        virtual void index(unsigned idx) = 0;

        /** End an index primitive previously started with
begin_primitive */
        virtual void end_primitive(void) = 0;
};

GLUshape::generate calls GLUshapeConsumer::vertex for each unique vertex
in the shape being generated.  After the vertex data is generated,
GLUshape::generate calls the remaining GLUshapeConsumer callbacks in
much the same way an application could call glBegin / glArrayElement /
glEnd.

I am considering removing the GLUshape::orientation interface.  I don't
think it will be used very often, and consumers can get the same effect
by modifying the normal in the GLUshapeConsumer::vertex implementation.

I've written a bit of code that uses these interfaces, and they seem to
work pretty well.  There still seems to be a lot of typing to do to
implement the first concrete GLUshapeConsumer.  It should be possible to
create a simple concrete class that is good enough for the typical
"hello, world" OpenGL program.  I want to make easy uses be easy, and
let more complex uses be possible.  In some of my experiments the
GLUshapeConsumer is smart enough to batch up element indices to be used
for glMultiDrawArrays, primitive restart, or glMultiModeDrawArraysIBM
dynamically.

All of the implementation and some tests are in my personal tree in the
GLUshape branch:

	git://anongit.freedesktop.org/~idr/glu3

Do these seem like sensible interfaces?  Are there other shapes the
really should be implemented for a 1.0 release?  Other comments?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkuPaq0ACgkQX1gOwKyEAw8eUgCghI7hM/SaY64FQHm8K/V/TEtH
dbMAniLLUL6tecUZt38Tn9gJyB7kcZQu
=Owwe
-----END PGP SIGNATURE-----


More information about the GLU3-devel mailing list