OGRE Wiki
Support and community documentation for Ogre3D
Ogre Forums
ogre3d.org
Log in
Username:
Password:
CapsLock is on.
Remember me (for 1 year)
Log in
Home
Tutorials
Tutorials Home
Basic Tutorials
Intermediate Tutorials
Mad Marx Tutorials
In Depth Tutorials
Older Tutorials
External Tutorials
Cookbook
Cookbook Home
CodeBank
Snippets
Experiences
Ogre Articles
Libraries
Libraries Home
Alternative Languages
Assembling A Toolset
Development Tools
OGRE Libraries
List of Libraries
Tools
Tools Home
DCC Tools
DCC Tutorials
DCC Articles
DCC Resources
Assembling a production pipeline
Development
Development Home
Roadmap
Building Ogre
Installing the Ogre SDK
Setting Up An Application
Ogre Wiki Tutorial Framework
Frequently Asked Questions
Google Summer Of Code
Help Requested
Ogre Core Articles
Community
Community Home
Projects Using Ogre
Recommended Reading
Contractors
Wiki
Immediate Wiki Tasklist
Wiki Ideas
Wiki Guidelines
Article Writing Guidelines
Wiki Styles
Wiki Page Tracker
Ogre Wiki Help
Ogre Wiki Help Overview
Help - Basic Syntax
Help - Images
Help - Pages and Structures
Help - Wiki Plugins
Toolbox
Freetags
Categories
List Pages
Structures
Trackers
Statistics
Rankings
List Galleries
Ogre Lexicon
Comments
History: MOGRE GeneratingAMesh
View page
Source of version: 2
(current)
If you look at the original code snippet for generating a Mesh, you will see that some pointers arithmetic is needed. That could be fine with C++, but by default C# does not support pointer arithmetic. However, by using the unsafe keyword, it is possible to define an unsafe context in which pointers can be used. In order to hide the complexity of unsafe code we use the following class: {CODE(wrap="1", colors="c#")}using System; using Mogre; namespace Mogre.Helpers { /// <summary> /// A helper class for manual mesh // This class hide unsafe code /// This code is based on MeshBuilderHelper.h /// originally developed by rastaman 11/16/2005 /// </summary> public class MeshBuilderHelper { public MeshBuilderHelper(String name, String resourcegroup, bool usesharedvertices, uint vertexstart, uint vertexcount) { mName = name; mResourceGroup = resourcegroup; mVertextStart = vertexstart; mVertexCount = vertexcount; // Return now if already exists if (MeshManager.Singleton.ResourceExists(name)) return; mMeshPtr = MeshManager.Singleton.CreateManual(mName, mResourceGroup); mSubMesh = mMeshPtr.CreateSubMesh(); mSubMesh.useSharedVertices = usesharedvertices; mSubMesh.vertexData = new VertexData(); mSubMesh.vertexData.vertexStart = mVertextStart; mSubMesh.vertexData.vertexCount = mVertexCount; offset = 0; mIndexType = HardwareIndexBuffer.IndexType.IT_16BIT; } public virtual VertexElement AddElement(VertexElementType theType, VertexElementSemantic semantic) { VertexElement ve = mSubMesh.vertexData.vertexDeclaration.AddElement(0, offset, theType, semantic); offset += VertexElement.GetTypeSize(theType); return ve; } public virtual void CreateVertexBuffer(uint numVerts, HardwareBuffer.Usage usage) { CreateVertexBuffer(numVerts, usage, false); } public virtual void CreateVertexBuffer(uint numVerts, HardwareBuffer.Usage usage, bool useShadowBuffer) { mVertexSize = offset; mNumVerts = numVerts; mvbuf = HardwareBufferManager.Singleton.CreateVertexBuffer( mVertexSize, mNumVerts, usage, useShadowBuffer); unsafe { pVBuffStart = mvbuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD); } } public virtual void SetVertFloat(uint vertexindex, uint byteoffset, float val1) { if (vertexindex >= mNumVerts) throw new IndexOutOfRangeException( "'vertexIndex' cannot be greater than the number of vertices."); unsafe { byte* pp = (byte*)pVBuffStart; pp += (mVertexSize * vertexindex) + byteoffset; float* p = (float*)pp; *p = val1; } } public virtual void SetVertFloat(uint vertexindex, uint byteoffset, float val1, float val2) { if (vertexindex >= mNumVerts) throw new IndexOutOfRangeException( "'vertexIndex' cannot be greater than the number of vertices."); unsafe { byte* pp = (byte*)pVBuffStart; pp += (mVertexSize * vertexindex) + byteoffset; float* p = (float*)pp; *p++ = val1; *p = val2; } } public virtual void SetVertFloat(uint vertexindex, uint byteoffset, float val1, float val2, float val3) { if (vertexindex >= mNumVerts) throw new IndexOutOfRangeException( "'vertexIndex' cannot be greater than the number of vertices."); unsafe { byte* pp = (byte*)pVBuffStart; pp += (mVertexSize * vertexindex) + byteoffset; float* p = (float*)pp; *p++ = val1; *p++ = val2; *p = val3; } } public virtual void SetVertFloat(uint vertexindex, uint byteoffset, float val1, float val2, float val3, float val4) { if (vertexindex >= mNumVerts) throw new IndexOutOfRangeException( "'vertexIndex' cannot be greater than the number of vertices."); unsafe { byte* pp = (byte*)pVBuffStart; pp += (mVertexSize * vertexindex) + byteoffset; float* p = (float*)pp; *p++ = val1; *p++ = val2; *p++ = val3; *p = val4; } } public virtual void CreateIndexBuffer(uint triaglecount, HardwareIndexBuffer.IndexType itype, HardwareBuffer.Usage usage) { CreateIndexBuffer(triaglecount, itype, usage, false); } public virtual void CreateIndexBuffer(uint triaglecount, HardwareIndexBuffer.IndexType itype, HardwareBuffer.Usage usage, bool useShadowBuffer) { mvbuf.Unlock(); mTriagleCount = triaglecount; mIndexType = itype; mSubMesh.vertexData.vertexBufferBinding.SetBinding(0, mvbuf); mSubMesh.indexData.indexCount = mTriagleCount * 3; HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager.Singleton .CreateIndexBuffer(mIndexType, mTriagleCount * 3, usage, useShadowBuffer); mSubMesh.indexData.indexBuffer = ibuf; unsafe { pIBuffStart = ibuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD); } } public virtual void SetIndex16bit(uint triagleIdx, ushort vidx1, ushort vidx2, ushort vidx3) { if (triagleIdx >= mTriagleCount) throw new IndexOutOfRangeException( "'triagleIdx' cannot be greater than the number of triangles."); if (mIndexType != HardwareIndexBuffer.IndexType.IT_16BIT) throw new NotSupportedException( "HardwareIndexBuffer.IndexType other than 'IT_16BIT' is not supported."); unsafe { ushort* p = (ushort*)pIBuffStart; p += (triagleIdx * 3); *p++ = vidx1; *p++ = vidx2; *p = vidx3; } } public virtual void SetIndex32bit(uint triagleIdx, uint vidx1, uint vidx2, uint vidx3) { if (triagleIdx >= mTriagleCount) throw new IndexOutOfRangeException( "'triagleIdx' cannot be greater than the number of triangles."); if (mIndexType != HardwareIndexBuffer.IndexType.IT_16BIT) throw new NotSupportedException( "HardwareIndexBuffer.IndexType other than 'IT_16BIT' is not supported."); unsafe { uint* p = (uint*)pIBuffStart; p += (triagleIdx * 3); *p++ = vidx1; *p++ = vidx2; *p = vidx3; } } public virtual MeshPtr Load(String materialname) { mSubMesh.indexData.indexBuffer.Unlock(); mSubMesh.MaterialName = materialname; mMeshPtr.Load(); return mMeshPtr; } #region Protected and Private fields protected MeshPtr mMeshPtr; protected SubMesh mSubMesh; protected String mName, mResourceGroup; protected uint mVertextStart, mVertexCount; protected HardwareVertexBufferSharedPtr mvbuf; protected uint offset; protected uint mVertexSize; protected uint mNumVerts; protected unsafe void* pVBuffStart = (void*)0; protected uint mTriagleCount; protected HardwareIndexBuffer.IndexType mIndexType; protected unsafe void* pIBuffStart = (void*)0; #endregion } }{CODE} Remember that you must compile your MeshBuilderHelper class with the unsafe option. Now, you can create your own mesh. In our example, we create a classical triangle with the following code. {CODE(wrap="1", colors="c#")} void CreateTriangle(string name) { MeshBuilderHelper mbh = new MeshBuilderHelper(name, "General", false, 0, 3); UInt32 offPos = mbh.AddElement(VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION).Offset; UInt32 offDiff = mbh.AddElement(VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_DIFFUSE).Offset; mbh.CreateVertexBuffer(3, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); mbh.SetVertFloat(0, offPos, 0, 0, 0); //position mbh.SetVertFloat(0, offDiff, 1, 0, 0); //color mbh.SetVertFloat(1, offPos, 0, 10, 0); //position mbh.SetVertFloat(1, offDiff, 0, 0, 1); //color mbh.SetVertFloat(2, offPos, 10, 0, 0); //position mbh.SetVertFloat(2, offDiff, 0, 1, 0); //color mbh.CreateIndexBuffer(1, HardwareIndexBuffer.IndexType.IT_16BIT, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); mbh.SetIndex16bit(0, (UInt16)0, (UInt16)2, (UInt16)1); // we create a material for our triangle. This could/must be defined outside MaterialPtr material = MaterialManager.Singleton.Create("Test/ColourTest", ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME); material.GetTechnique(0).GetPass(0).VertexColourTracking = (int)TrackVertexColourEnum.TVC_AMBIENT; MeshPtr m = mbh.Load("Test/ColourTest"); m._setBounds(new AxisAlignedBox(0.0f, 0.0f, 0.0f, 10.0f, 10.0f, 10.0f), false); m._setBoundingSphereRadius((float)System.Math.Sqrt(10.0f * 10.0f + 10.0f * 10.0f)); }{CODE} To display this triangle within your Mogre application, you'll need to set up a material definition that looks like: {CODE(wrap="1", colors="c#")}material Test/ColourTest { technique { pass { ambient vertexcolour } } }{CODE} Alternatively, the material can be created directly in C#: {CODE(wrap="1", colors="c#")}MaterialPtr material = MaterialManager.Singleton.Create("Test/ColourTest", ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME); material.GetTechnique(0).GetPass(0).VertexColourTracking = (int)TrackVertexColourEnum.TVC_AMBIENT;{CODE} In our example we have defined the material inside our CreateTriangle function, but you are free to define it before calling CreateTriangle. Now, if I want to insert the mesh into a scene: {CODE(wrap="1", colors="c#")} public override void CreateScene() { CreateTriangle("myTriangle"); Entity ent1 = base.sceneMgr.CreateEntity("Triangle1", "myTriangle"); SceneNode node1 = base.sceneMgr.RootSceneNode.CreateChildSceneNode("TriangleNode"); node1.AttachObject(ent1); }{CODE} A final note. If you are using the sample Application, our camera is too far from our triangle. I recomend to use this code in your main program: {CODE(wrap="1", colors="c#")}public override void CreateCamera() { // Create the camera camera = sceneMgr.CreateCamera("PlayerCam"); // Position it at 30 in Z direction camera.Position = new Vector3(0, 0, 30); // Look at our triangle camera.LookAt(new Vector3(5, 5, 5)); camera.NearClipDistance = 1; }{CODE} Finally, if everything is OK, you will see: {img src="img/wiki_up/TriangleScreenshotWithMogre.jpg" alt="TriangleScreenshotWithMogre.jpg"}
Search by Tags
Search Wiki by Freetags
Latest Changes
Minimal Ogre Collision
Artifex Terra
OpenMB
Advanced Mogre Framework
MogreSocks
Critter AI
Mogre Add-ons
MOGRE
Mogre MyGUI wrapper
MOGRE Editable Terrain Manager
...more
Search
Find
Advanced
Search Help
Online Users
31 online users