One thing that would not hurt OpenTK.Utilities are a couple of classes that allow straightforward creation of geometry such as cube, sphere, plane, etc. When experimenting with GL Extensions you often need *something* to draw, it does not really matter so much what is drawn exactly, and it is often desireable to experiment in a contained and simple to debug situation, rather than doing that experimentation in large applications.
To give some concrete example: The API should be dead-simple so it's most convenient to write examples or prototypes - e.g. shaders - without having to worry about the geometry and it's attributes. Also for debugging a physics binding it will be helpful to have this option.
The usage should be as simple as:
Shape MyGeom = new SierpinskiTetrahedron( scale, eSubdivisions.Four, false ); // create object, immutable MyGeom.Draw(); // draw object MyGeom.Dispose(); // properly clean up object
The boolean paramater controls whether upon first call of MyGeom.Draw() a Display List should be compiled and executed, or simply GL.Begin() Immediate Mode calls are done. Making the use of Display Lists optional allows the programmer to group multiple objects into a single Display List, at the programmers discretion i.e. the API itself does only deal with DL for a single object. If the geometry instance's Draw method is ever called with using Display Lists, MyGeom.Dispose() must be called prior to context destruction.
The only way to use the object with VBO is calling MyGeom.GetVBO() and handle it from there on your own.
The objects I've been working on so far are:
-Menger Sponge (sometimes called Sierpinski Carpet)
-WIP: Capsule and Chamfercube.
-A Koch subdivision applied to a Tetrahedron, I don't think there's a name for this yet (if you know, please tell!) so I'll simply show what it looks like untextured to give an idea. (Yes, it has TexCoords, but it increases difficulty to make sense of the object ^10)
The API is easily extensible for more objects, all that new objects must be able to supply are:
Graphics.BeginMode PrimitiveMode Vertex VertexArray uint IndexArray
Let me try sum it up:
Guidelines for writing additional objects
- Shapes may have multiple contructors, but once leaving the constructor an instance is immutable, i.e. can only call .Draw() .GetVBO() and .Dispose(). Deriving classes may not add any new public methods or fields.
- No compromises must be made that would favor easy editing of the generated geometry over the simplicity to generate or draw it. I.e. if someone wishes to add the procedural objects to an 3D Editor, they must either clean up the generated arrays or implement it on their own.
- Shapes should be marked sealed, if you intend to create a compound shape like a cylinder (2x disc, 1x tube) the correct way to do this is instantiating the 2 discs and tube, GetVBO() their arrays and merge it into a single VBO.
- The amount of CPU cycles and memory used during shape creation is irrelevant, the user may call GetVBO() and dump to disk or serialize the instance to avoid repeated calculation of the geometry and memory allocations.
- The Vertex and optionally Index Array must be set in the constructor. No additional methods to alter level of detail are permitted, the user should instantiate a new shape for that.
- Explicit parameter description including default and few recommended values in the summary.
- Vertex Attributes must be no more and no less than T2N3V3 at double-precision floating-point per Vertex.
- Texture Coordinates should assume a tilable texture and keep their coordinates within [0..1]. Do not attempt to implement a dozen ways to map UV coordinates, a user must resort to modelling applications if more control is required.
- It does not matter whether the output is for GL.DrawElements() or GL.DrawArrays(), the later simply has no Index Array. It is assumed that the Vertex Array is intended for DrawArrays in that case. Shapes that are intended to be part of compound shapes must use the Index Array, since they can have arbitrary high tesselation.
- One may chose to query BeginMode from the user in the constructor, but not doing so is fine aswell.
- The object center is ideally at (0,0,0) to allow easy rotation around itself, e.g. the Sierpinski Tetrehedron is fit into a Sphere of radius 1.0. None of it's vertices are further away from 0,0,0 than 1.0, that results in a great rotation center, as opposed to using one of the 4 corners as origin.
|Koch Curve Tetrahedron.png||226.82 KB|