Model represents a 3D model - its constructor takes a filename and VARAreaRef as arguments, and loads an IFS model from the specfied file using G3D's BinaryInput object. First a couple of general parameters are loaded using readString32() and readFloat32() on the BinaryInput instance.
The vertices are then read using readVector3() into the vertex Vector3 array (a private member of Model). Next, the triangles which make up the shape are read, as sets of 3 integers using readUInt32(). These integers are indices of the vertex array representing the corners of a triangle. For each triangle, the 'face normal' is computed, and added to whatever is held in the normal Vector3 array (another private member of Model). The 3 corner indicies are stored in the index uint32 array by calling append() on it.
Once this is done, the vectors in the normal array are set to unit length, and the varVertex and varNormal private VAR members are initialised using the vertex and normal arrays respectively.
The public numPolys() method simply returns the number of triangles in the model, as the size of the index array divided by 3. Not sure when this would be useful.
The other public method is render(), which draws the model. If the traditional per-primitive rendering has been chosen, we call beginPrimitive(RenderDevice::TRIANGLES) and then loop through each element of the index array, sending the element from the normal array indexed by the value from the index array to setNormal(), and the element from the vertex array indexed by the same value to sendVertex(). Once we've looped through all indices in the index array, we call endPrimitive() on the render device, and we're done.
If we have chosen the streaming vertex array, we begin with a call to beginIndexedPrimitives(), and now initialise two new VAR objects, n and v, using the normal and vertex private member arrays and varStream rather than varStatic. These are passed to the render device's setNormalArray() and setVertexArray() methods respectively. We then call renderDevice->sendIndices(), passing in the index array. We finish off with a call to renderDevice->endIndexedPrimitives().
So the final rendering approach, using static vertex arrays, is just the same as for streaming ones, except that setNormalArray() and setVertexArray() take VAR objects that were initialised with varStatic rather than varStream. You may remember that we've stored these as private member variables, so we can just pass these into the two render device methods. The only other difference is that with streaming arrays, we need to check for 'headspace' on the varStream, and reset it if we don't have enough.
There are seemingly eight, described on the G3D web site; it's not clear if there's any natural progression through them.
- ArticulatedModel loads models from files in 3DS, IFS, and PLY2 formats. Creates a scene graph, uses 'Pixel Shader 2.0' and 'fixed function' pipelines, apparently.
- GLSL_Shader_Demo uses pixel and vertex shaders to make a 2D texture appear to have shape.
- VAR Demo demonstrates rendering using dynamic vertex arrays, static vertex arrays, and the 'traditional per primitive rendering'.
- MD2Model_Demo uses animated models from Quake 2.
- Collision_Demo as name indicates, this uses the collision detection features of G3D.
- Win32_Demo uses non-OpenGL Win32 routines to display a JPG.
- Cg_Shader_Demo appears to show different approaches to texture mapping with Cg. Bump mapping, per-pixel shading, and normal mapping.
- ASM_Shader_Demo using programmable hardware of ATi/nVidia's chips to manipulate a 3D model.
compton
7:00 am, Thursday, 22 December 05
I got it to run by adding its main.cpp to the G3Dtest project as an existing item. It then ran fine, and works very well. There are 50 p-51 Mustangs flying around the origin, all bobbing and swaying quite pleasingly, some going slow, others faster. Pressing Space switched the rendering method, the best being static vertex array. The dynamic array (or streaming) was nearly as good, and the traditional per-primitive rendering (which is what I was doing in G3Dtest) was very jerky.
The code is all contained within a single main.cpp file. In this file, there are 3 classes defined, Model, Demo and App.