History: ManualObject
Preview of version: 22
Using a ManualObject you don't need to load ressources and it's nice to create dynamic objects or simple ones.
To do so, you define the needed points ({LEX(pagename="Vertex")}vertices{LEX}), rendering type (points, lines, surfaces) and assign a {LEX()}material{LEX}. To add it to the {LEX()}scene{LEX}, it has to be attached to a {LEX()}SceneNode{LEX} (e.g. the {LEX()}RootSceneNode{LEX}).
It's possible to add several code blocks begin(), ...add content..., end() to the one ManualObject. So you can use different materials and rendering types. As a result you can get lines, surfaces or a combination of it. Transparency is also possible (by use of materials with transparency property).
If several instances (copies) of a ManualObject are needed, you have to create a {LEX()}Mesh{LEX} from it by use of ManualObject::convertToMesh(). When you load such a Mesh to your scene, it becomes an Entity. An other advantage of the ToMesh conversion is, that you can apply different materials to the same shape.
In some cases the identity projection can be interesting. With this the coordinates are in 2D screen space of the current camera. Useful for {LEX()}overlay{LEX} rendering.
Example
A very minimal example that gives an outlined square (or quad):
ManualObject* manual = mSceneMgr->createManualObject("manual"); manual->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP); manual->position(-100.0, -100.0, 0.0); manual->position( 100.0, -100.0, 0.0); manual->position( 100.0, 100.0, 0.0); manual->position(-100.0, 100.0, 0.0); manual->end(); mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(manual);
If you want to update (change) the ManualObject later or create a {LEX()}Mesh{LEX} out of it, you have to add indices.
ManualObject* manual = mSceneMgr->createManualObject("manual"); manual->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP); manual->position(-100.0, -100.0, 0.0); manual->position( 100.0, -100.0, 0.0); manual->position( 100.0, 100.0, 0.0); manual->position(-100.0, 100.0, 0.0); manual->index(0); manual->index(1); manual->index(2); manual->index(3); manual->index(0); manual->end(); mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(manual);
Rendering Types
enum Ogre::RenderOperation::OperationType
| OT_POINT_LIST | A list of points | 1 vertex per point |
| OT_LINE_LIST | A list of lines | 2 vertices per line |
| OT_LINE_STRIP | A strip of connected lines | 1 start vertex and 1 vertex per line |
| OT_TRIANGLE_LIST | A list of triangles | 3 vertices per triangle |
| OT_TRIANGLE_STRIP | A strip of triangles | 3 vertices for the first triangle and 1 per triangle after that |
| OT_TRIANGLE_FAN | A fan of triangles | 3 vertices for the first triangle and 1 per triangle after that |
Triangle Strip:
A triangle strip is a series of connected triangles, sharing vertices, allowing for faster rendering and more efficient memory usage. They are optimized on most graphics cards, making them the most efficient way of describing an object.
More details you find in this Wikipedia page.
Triangle Fan:
A triangle fan describes a set of connected triangles that share one central vertex.
More details you find in this Wikipedia page.
Using a triangle strip or triangle fan you need just N+2 vertices for describing N triangles (instead of 3N as for seperately defined triangles).
Points:
The size of one point is 1 pixel, independent of its distance to the camera. The point size can be changed by the material settings. Use Material::setPointSize() for the whole material or more differentiated Technique::setPointSize() or Pass::setPointSize().
It's also possible to render the line thickness dependent to the distance. For details look to setPointAttenuation, setPointMinSize, setPointMaxSize and
setPointSpritesEnabled of the Pass class.
Details
This detailed description was copied from the Ogre 1.7.1 class reference of ManualObject.
Building one-off geometry objects manually usually requires getting down and dirty with the vertex buffer and vertex declaration API, which some people find a steep learning curve. This class gives you a simpler interface specifically for the purpose of building a 3D object simply and quickly. Note that if you intend to instance your object you will still need to become familiar with the Mesh class.
This class draws heavily on the interface for OpenGL immediate-mode (glBegin, glVertex, glNormal etc), since this is generally well-liked by people. There are a couple of differences in the results though - internally this class still builds hardware buffers which can be re-used, so you can render the resulting object multiple times without re-issuing all the same commands again. Secondly, the rendering is not immediate, it is still queued just like all OGRE objects. This makes this object more efficient than the equivalent GL immediate-mode commands, so it's feasible to use it for large objects if you really want to.
To construct some geometry with this object:
- If you know roughly how many vertices (and indices, if you use them) you're going to submit, call estimateVertexCount and estimateIndexCount. This is not essential but will make the process more efficient by saving memory reallocations.
- Call begin() to begin entering data
- For each vertex, call position(), normal(), textureCoord(), colour() to define your vertex data. Note that each time you call position() you start a new vertex. Note that the first vertex defines the components of the vertex - you can't add more after that. For example if you didn't call normal() in the first vertex, you cannot call it in any others. You ought to call the same combination of methods per vertex.
- If you want to define triangles (or lines/points) by indexing into the vertex list, you can call index() as many times as you need to define them. If you don't do this, the class will assume you want triangles drawn directly as defined by the vertex list, i.e. non-indexed geometry. Note that stencil shadows are only supported on indexed geometry, and that indexed geometry is a little faster; so you should try to use it.
- Call end() to finish entering data.
- Optionally repeat the begin-end cycle if you want more geometry using different rendering operation types, or different materials After calling end(), the class will organise the data for that section internally and make it ready to render with. Like any other MovableObject you should attach the object to a SceneNode to make it visible. Other aspects like the relative render order can be controlled using standard MovableObject methods like setRenderQueueGroup.
You can also use beginUpdate() to alter the geometry later on if you wish. If you do this, you should call setDynamic(true) before your first call to begin(), and also consider using estimateVertexCount / estimateIndexCount if your geometry is going to be growing, to avoid buffer recreation during growth.
Note that like all OGRE geometry, triangles should be specified in anti-clockwise winding order (whether you're doing it with just vertices, or using indexes too). That is to say that the front of the face is the one where the vertices are listed in anti-clockwise order.
Basics about 3D objects
A Crash Course in 3D Objects
This section was taken from the Intermediate Tutorial 4.
Before we start diving directly into making a mesh, it would probably be useful to talk about what a mesh is, and what it is made up of. Though this is a gross oversimplification, a mesh consists of roughly two parts: the vertex buffer and the index buffer.
Vertex buffers define points in 3D space. Each element in the vertex buffer is defined by several attributes you can set. The only attribute you must set is the position of the vertex. Aside from that, there are many optional properties you can set, such as the color of the vertex, the texture coordinates, and so on. Which ones you will actually need to use is dependent on what you are trying to do with the mesh.
Index buffers "connect the dots" by selecting points from the vertex buffer. Every three indexes specified in the index buffer defines a single triangle to be drawn by the GPU. The order in which you select vertices in the index buffer tells the graphics card which way the triangle faces. A triangle which is drawn counter-clockwise is facing you, one drawn clockwise is facing away from you. Normally only the front of a triangle is rendered, so it is important to be sure that your triangles are setup properly.
Though all meshes have a vertex buffer, not all meshes will have an index buffer. For example, the mesh we are about to create will not have an index buffer since we want to create an empty rectangle (as opposed to a filled rectangle). Lastly, note that vertex and index buffers are usually stored in the video card's own memory, so your software can just send the card one simple, discrete set of commands to tell it to use those predefined buffers to render an entire 3D mesh in one go.
How to create 3D objects (by code)
This section was taken from the Intermediate Tutorial 4.
There are two ways to create your own mesh within Ogre. The first way is to subclass the SimpleRenderable object and provide it with the vertex and index buffers directly. This is the most direct way to create one, but it's also the most cryptic. The Generating A Mesh code snippet shows an example of this.
To make things easier, Ogre provides a much nicer interface called ManualObject, which allows you to use some simple functions to define a mesh instead of writing raw data to the buffer objects. Instead of dropping the position, color, and so on into a buffer, you simply call the "position" and "colour" functions.
|
|
|