private void CreatePrefabPlane() { Mesh mesh = (Mesh)Create("Prefab_Plane"); SubMesh subMesh = mesh.CreateSubMesh("Prefab_Plane_Submesh"); float[] vertices = { -100, -100, 0, // pos 0, 0, 1, // normal 0, 1, // texcoord 100, -100, 0, 0, 0, 1, 1, 1, 100, 100, 0, 0, 0, 1, 1, 0, -100, 100, 0, 0, 0, 1, 0, 0 }; mesh.SharedVertexData = new VertexData(); mesh.SharedVertexData.vertexCount = 4; VertexDeclaration vertexDeclaration = mesh.SharedVertexData.vertexDeclaration; VertexBufferBinding binding = mesh.SharedVertexData.vertexBufferBinding; int offset = 0; vertexDeclaration.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Position); offset += VertexElement.GetTypeSize(VertexElementType.Float3); vertexDeclaration.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Normal); offset += VertexElement.GetTypeSize(VertexElementType.Float3); vertexDeclaration.AddElement(0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0); offset += VertexElement.GetTypeSize(VertexElementType.Float2); // allocate vertex buffer HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer(offset, 4, BufferUsage.StaticWriteOnly); // set up the binding, one source only binding.SetBinding(0, vertexBuffer); vertexBuffer.WriteData(0, vertexBuffer.Size, vertices, true); subMesh.useSharedVertices = true; HardwareIndexBuffer indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer(IndexType.Size16, 6, BufferUsage.StaticWriteOnly); short[] faces = { 0, 1, 2, 0, 2, 3 }; subMesh.indexData.indexBuffer = indexBuffer; subMesh.indexData.indexCount = 6; subMesh.indexData.indexStart = 0; indexBuffer.WriteData(0, indexBuffer.Size, faces, true); mesh.BoundingBox = new AxisAlignedBox(new Vector3(-100, -100, 0), new Vector3(100, 100, 0)); mesh.BoundingSphereRadius = MathUtil.Sqrt(100 * 100 + 100 * 100); resourceList.Add(mesh.Name, mesh); }
/// <summary> /// /// </summary> public override void Initialize() { // Set up the render operation // Combine positions and texture coords since they tend to change together // since character sizes are different renderOp.vertexData = new VertexData(); VertexDeclaration decl = renderOp.vertexData.vertexDeclaration; int offset = 0; // positions decl.AddElement(POSITION_TEXCOORD, offset, VertexElementType.Float3, VertexElementSemantic.Position); offset += VertexElement.GetTypeSize(VertexElementType.Float3); // texcoords decl.AddElement(POSITION_TEXCOORD, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0); // colors, stored in seperate buffer since they change less often decl.AddElement(COLORS, 0, VertexElementType.Color, VertexElementSemantic.Diffuse); renderOp.operationType = OperationType.TriangleList; renderOp.useIndices = false; renderOp.vertexData.vertexStart = 0; // buffers are created in CheckMemoryAllocation CheckMemoryAllocation(DEFAULT_INITIAL_CHARS); }
/* * Define the size and data types that form a *Vertex*, to be used in the VertexBuffer. * NOTE: For ease of use, we define a structure QuickGUI::Vertex, with the same exact data types. */ private void _declareVertexStructure() { VertexDeclaration vd = mRenderOperation.vertexData.vertexDeclaration; // Add position - Ogre::Vector3 : 4 bytes per float * 3 floats = 12 bytes vd.AddElement(0, 0, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION); // Add color - Ogre::RGBA : 8 bits per channel (1 byte) * 4 channels = 4 bytes vd.AddElement(0, VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3), VertexElementType.VET_FLOAT4, VertexElementSemantic.VES_DIFFUSE); // Add texture coordinates - Ogre::Vector2 : 4 bytes per float * 2 floats = 8 bytes vd.AddElement(0, VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3) + VertexElement.GetTypeSize(VertexElementType.VET_FLOAT4), VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES); /* Our structure representing the Vertices used in the buffer (24 bytes): * struct Vertex * { * Ogre::Vector3 pos; * Ogre::RGBA color; * Ogre::Vector2 uv; * }; */ }
protected void SetupVertexDeclaration() { if (vertexDeclDirty) { VertexDeclaration decl = vertexData.vertexDeclaration; int offset = 0; // Add a description for the buffer of the positions of the vertices decl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Position); offset += VertexElement.GetTypeSize(VertexElementType.Float3); if (useVertexColors) { decl.AddElement(0, offset, VertexElementType.Color, VertexElementSemantic.Diffuse); offset += VertexElement.GetTypeSize(VertexElementType.Color); } if (useTextureCoords) { decl.AddElement(0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords); offset += VertexElement.GetTypeSize(VertexElementType.Float2); } if (!useTextureCoords && !useVertexColors) { log.Error( "Error - BillboardChain '" + name + "' is using neither " + "texture coordinates or vertex colors; it will not be " + "visible on some rendering APIs so you should change this " + "so you use one or the other."); } vertexDeclDirty = false; } }
/// <summary> /// /// </summary> public override void Initialize() { // setup the vertex data renderOp.vertexData = new VertexData(); // Vertex declaration: 1 position, add texcoords later depending on #layers // Create as separate buffers so we can lock & discard separately VertexDeclaration decl = renderOp.vertexData.vertexDeclaration; decl.AddElement(POSITION, 0, VertexElementType.Float3, VertexElementSemantic.Position); renderOp.vertexData.vertexStart = 0; renderOp.vertexData.vertexCount = 4; // create the first vertex buffer, mostly static except during resizing HardwareVertexBuffer buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.GetVertexSize(POSITION), renderOp.vertexData.vertexCount, BufferUsage.StaticWriteOnly); // bind the vertex buffer renderOp.vertexData.vertexBufferBinding.SetBinding(POSITION, buffer); // no indices, and issue as a tri strip renderOp.useIndices = false; renderOp.operationType = OperationType.TriangleStrip; }
private void CreateBuffers(ushort[] indices, short[] vertices) { var numIndices = indices.Length; var numVertices = vertices.Length; _vertexDeclaration = HardwareBufferManager.Instance.CreateVertexDeclaration(); _vertexDeclaration.AddElement(0, 0, VertexElementType.Short2, VertexElementSemantic.Position); _ib = HardwareBufferManager.Instance.CreateIndexBuffer(IndexType.Size16, numIndices, BufferUsage.WriteOnly); _vb = HardwareBufferManager.Instance.CreateVertexBuffer(_vertexDeclaration, numVertices, BufferUsage.WriteOnly, false); _ib.WriteData(0, numIndices * sizeof(ushort), indices, true); _vb.WriteData(0, numVertices * sizeof(ushort), vertices, true); var binding = new VertexBufferBinding(); binding.SetBinding(0, _vb); VertexData = new VertexData(); VertexData.vertexDeclaration = _vertexDeclaration; VertexData.vertexBufferBinding = binding; VertexData.vertexCount = numVertices; VertexData.vertexStart = 0; IndexData = new IndexData(); IndexData.indexBuffer = _ib; IndexData.indexCount = numIndices; IndexData.indexStart = 0; }
VertexData CreateVertexData(Vec3[] vertices) { VertexData vertexData = new VertexData(); VertexDeclaration declaration = vertexData.VertexDeclaration; declaration.AddElement(0, 0, VertexElementType.Float3, VertexElementSemantic.Position); VertexBufferBinding bufferBinding = vertexData.VertexBufferBinding; HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( 12, vertices.Length, HardwareBuffer.Usage.StaticWriteOnly); bufferBinding.SetBinding(0, vertexBuffer, true); vertexData.VertexCount = vertices.Length; unsafe { Vec3 *buffer = (Vec3 *)vertexBuffer.Lock(HardwareBuffer.LockOptions.Normal).ToPointer(); foreach (Vec3 position in vertices) { *buffer = position; buffer++; } vertexBuffer.Unlock(); } return(vertexData); }
private void CreateBuffers(ushort[] indices, short[] vertices) { var numIndices = (uint)indices.Length; var numVertices = (uint)vertices.Length; _vertexDeclaration = HardwareBufferManager.Singleton.CreateVertexDeclaration(); _vertexDeclaration.AddElement(0, 0, VertexElementType.VET_SHORT2, VertexElementSemantic.VES_POSITION); _ib = HardwareBufferManager.Singleton.CreateIndexBuffer(HardwareIndexBuffer.IndexType.IT_16BIT, numIndices, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); _vb = HardwareBufferManager.Singleton.CreateVertexBuffer(_vertexDeclaration.GetVertexSize(0), numVertices, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY, false); unsafe { fixed(ushort *x = indices) _ib.WriteData(0, numIndices * sizeof(ushort), x, true); fixed(short *x = vertices) _vb.WriteData(0, numVertices * sizeof(ushort), x, true); } var binding = new VertexBufferBinding(); binding.SetBinding(0, _vb); VertexData = new VertexData(_vertexDeclaration, binding); VertexData.vertexCount = numVertices; VertexData.vertexStart = 0; IndexData = new IndexData(); IndexData.indexBuffer = _ib; IndexData.indexCount = numIndices; IndexData.indexStart = 0; }
static TerrainPage() { terrainVertexDeclaration = HardwareBufferManager.Instance.CreateVertexDeclaration(); // set up the vertex declaration int vDecOffset = 0; terrainVertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Position); vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3); terrainVertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Normal); vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3); terrainVertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords); vertexSize = terrainVertexDeclaration.GetVertexSize(0) / 4; }
private void CreateMesh() { DetachMeshFromEntity(); DestroyMesh(); int maxVertexCount = tesselation * tesselation; int maxIndexCount = (tesselation - 1) * (tesselation - 1) * 6; string meshName = MeshManager.Instance.GetUniqueName("DynamicSinusoidSurface"); mesh = MeshManager.Instance.CreateManual(meshName); SubMesh subMesh = mesh.CreateSubMesh(); subMesh.UseSharedVertices = false; //init vertexData VertexDeclaration declaration = subMesh.VertexData.VertexDeclaration; declaration.AddElement(0, 0, VertexElementType.Float3, VertexElementSemantic.Position); declaration.AddElement(0, 12, VertexElementType.Float3, VertexElementSemantic.Normal); declaration.AddElement(0, 24, VertexElementType.Float2, VertexElementSemantic.TextureCoordinates, 0); //declaration.AddElement( 0, 32, VertexElementType.Float4, VertexElementSemantic.Tangent, 0 ); HardwareBuffer.Usage usage = HardwareBuffer.Usage.DynamicWriteOnly;//HardwareBuffer.Usage.StaticWriteOnly; HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( Marshal.SizeOf(typeof(Vertex)), maxVertexCount, usage); subMesh.VertexData.VertexBufferBinding.SetBinding(0, vertexBuffer, true); subMesh.VertexData.VertexCount = maxVertexCount; HardwareIndexBuffer indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer( HardwareIndexBuffer.IndexType._16Bit, maxIndexCount, usage); subMesh.IndexData.SetIndexBuffer(indexBuffer, true); subMesh.IndexData.IndexCount = maxIndexCount; //set material subMesh.MaterialName = "DynamicSinusoidSurface"; //set mesh gabarites Bounds bounds = new Bounds(-Scale / 2, Scale / 2); mesh.SetBoundsAndRadius(bounds, bounds.GetRadius()); }
/// <summary> /// Default constructor. /// </summary> public WireBoundingBox() { vertexData = new VertexData(); vertexData.vertexCount = 24; vertexData.vertexStart = 0; // get a reference to the vertex declaration and buffer binding VertexDeclaration decl = vertexData.vertexDeclaration; VertexBufferBinding binding = vertexData.vertexBufferBinding; // add elements for position and color only decl.AddElement(POSITION, 0, VertexElementType.Float3, VertexElementSemantic.Position); decl.AddElement(COLOR, 0, VertexElementType.Color, VertexElementSemantic.Diffuse); // create a new hardware vertex buffer for the position data HardwareVertexBuffer buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.GetVertexSize(POSITION), vertexData.vertexCount, BufferUsage.StaticWriteOnly); // bind the position buffer binding.SetBinding(POSITION, buffer); // create a new hardware vertex buffer for the color data buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.GetVertexSize(COLOR), vertexData.vertexCount, BufferUsage.StaticWriteOnly); // bind the color buffer binding.SetBinding(COLOR, buffer); Material mat = MaterialManager.Instance.GetByName("Core/WireBB"); if (mat == null) { mat = MaterialManager.Instance.GetByName("BaseWhite"); mat = mat.Clone("Core/WireBB"); mat.Lighting = false; } this.Material = mat; }
void CreateMesh() { string meshName = MeshManager.Instance.GetUniqueName("DynamicMesh"); mesh = MeshManager.Instance.CreateManual(meshName); //set mesh gabarites Bounds bounds = new Bounds(new Vec3(-.1f, -.5f, -.5f), new Vec3(.1f, .5f, .5f)); mesh.SetBoundsAndRadius(bounds, bounds.GetRadius()); SubMesh subMesh = mesh.CreateSubMesh(); subMesh.UseSharedVertices = false; int maxVertices = (Type.GridSize.X + 1) * (Type.GridSize.Y + 1); int maxIndices = Type.GridSize.X * Type.GridSize.Y * 6; //init vertexData VertexDeclaration declaration = subMesh.VertexData.VertexDeclaration; declaration.AddElement(0, 0, VertexElementType.Float3, VertexElementSemantic.Position); declaration.AddElement(0, 12, VertexElementType.Float3, VertexElementSemantic.Normal); declaration.AddElement(0, 24, VertexElementType.Float2, VertexElementSemantic.TextureCoordinates, 0); VertexBufferBinding bufferBinding = subMesh.VertexData.VertexBufferBinding; HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( 32, maxVertices, HardwareBuffer.Usage.DynamicWriteOnly); bufferBinding.SetBinding(0, vertexBuffer, true); //init indexData HardwareIndexBuffer indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer( HardwareIndexBuffer.IndexType._16Bit, maxIndices, HardwareBuffer.Usage.DynamicWriteOnly); subMesh.IndexData.SetIndexBuffer(indexBuffer, true); //set material subMesh.MaterialName = Type.MaterialName; needUpdateVertices = true; needUpdateIndices = true; }
private void CreateHardwareBuffer(uint size) { this.renderOp = new RenderOperation { vertexData = new VertexData { vertexStart = 0 } }; VertexDeclaration vd = this.renderOp.vertexData.vertexDeclaration; vd.AddElement( 0, 0, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION); vd.AddElement( 0, VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3), VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES); vd.AddElement( 0, VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3) + VertexElement.GetTypeSize(VertexElementType.VET_FLOAT2), VertexElementType.VET_COLOUR, VertexElementSemantic.VES_DIFFUSE); this.hardwareBuffer = HardwareBufferManager.Singleton.CreateVertexBuffer( vd.GetVertexSize(0), size, HardwareBuffer.Usage.HBU_DYNAMIC_WRITE_ONLY, false); this.renderOp.vertexData.vertexBufferBinding.SetBinding(0, this.hardwareBuffer); this.renderOp.operationType = RenderOperation.OperationTypes.OT_TRIANGLE_LIST; this.renderOp.useIndexes = false; }
/// <summary> /// /// </summary> public void Build() { if (mRenderMethod == BillboardMethod.Accelerated) { Clear(); //If there are no billboards to create, exit if (mBillboardBuffer.Count == 0) { return; } //Create manual mesh to store billboard quads mMesh = MeshManager.Instance.CreateManual(GetUniqueID("SBSMesh"), ResourceGroupManager.DefaultResourceGroupName, null); mSubMesh = mMesh.CreateSubMesh(); mSubMesh.useSharedVertices = false; //Setup vertex format information mSubMesh.vertexData = new VertexData(); mSubMesh.vertexData.vertexStart = 0; mSubMesh.vertexData.vertexCount = 4 * mBillboardBuffer.Count; VertexDeclaration dcl = mSubMesh.vertexData.vertexDeclaration; int offset = 0; dcl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Position); offset += VertexElement.GetTypeSize(VertexElementType.Float3); dcl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Normal); offset += VertexElement.GetTypeSize(VertexElementType.Float3); dcl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Diffuse); offset += VertexElement.GetTypeSize(VertexElementType.Color); dcl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.TexCoords); offset += VertexElement.GetTypeSize(VertexElementType.Float2); //Populate a new vertex buffer HardwareVertexBuffer vbuf = HardwareBufferManager.Instance.CreateVertexBuffer( /*offset*/ dcl, mSubMesh.vertexData.vertexCount, BufferUsage.StaticWriteOnly, false); unsafe { float *pReal = (float *)vbuf.Lock(BufferLocking.Discard); float minX = float.PositiveInfinity; float maxX = float.NegativeInfinity; float minY = float.PositiveInfinity; float maxY = float.NegativeInfinity; float minZ = float.PositiveInfinity; float maxZ = float.NegativeInfinity; foreach (StaticBillboard it in mBillboardBuffer) { StaticBillboard bb = it; float halfXScale = bb.XScale * 0.5f; float halfYScale = bb.YScale * 0.5f; // position *pReal++ = bb.Position.x; *pReal++ = bb.Position.y; *pReal++ = bb.Position.z; // normals (actually used as scale / translate info for vertex shader) *pReal++ = halfXScale; *pReal++ = halfYScale; *pReal++ = 0.0f; // color *((uint *)pReal++) = bb.Color; // uv *pReal++ = (float)(bb.TextCoordIndexU * mUFactor); *pReal++ = (float)(bb.TextCoordIndexV * mVFactor); // position *pReal++ = bb.Position.x; *pReal++ = bb.Position.y; *pReal++ = bb.Position.z; // normals (actually used as scale / translate info for vertex shader) *pReal++ = halfXScale; *pReal++ = halfYScale; *pReal++ = 1.0f; // color *((uint *)pReal++) = bb.Color; // uv *pReal++ = (float)((bb.TextCoordIndexU + 1) * mUFactor); *pReal++ = (float)(bb.TextCoordIndexV * mVFactor); // position *pReal++ = bb.Position.x; *pReal++ = bb.Position.y; *pReal++ = bb.Position.z; // normals (actually used as scale / translate info for vertex shader) *pReal++ = halfXScale; *pReal++ = halfYScale; *pReal++ = 2.0f; // color *((uint *)pReal++) = bb.Color; // uv *pReal++ = (float)(bb.TextCoordIndexU * mUFactor); *pReal++ = (float)((bb.TextCoordIndexV + 1) * mVFactor); // position *pReal++ = bb.Position.x; *pReal++ = bb.Position.y; *pReal++ = bb.Position.z; // normals (actually used as scale / translate info for vertex shader) *pReal++ = halfXScale; *pReal++ = halfYScale; *pReal++ = 3.0f; // color *((uint *)pReal++) = bb.Color; // uv *pReal++ = (float)((bb.TextCoordIndexU + 1) * mUFactor); *pReal++ = (float)((bb.TextCoordIndexV + 1) * mVFactor); //Update bounding box if (bb.Position.x - halfXScale < minX) { minX = bb.Position.x - halfXScale; } if (bb.Position.x + halfXScale > maxX) { maxX = bb.Position.x + halfXScale; } if (bb.Position.y - halfYScale < minY) { minY = bb.Position.y - halfYScale; } if (bb.Position.y + halfYScale > maxY) { maxY = bb.Position.y + halfYScale; } if (bb.Position.z - halfXScale < minZ) { minZ = bb.Position.z - halfXScale; } if (bb.Position.z + halfXScale > maxZ) { maxZ = bb.Position.z + halfXScale; } } AxisAlignedBox bounds = new AxisAlignedBox( new Vector3(minX, minY, minZ), new Vector3(maxX, maxY, maxZ)); vbuf.Unlock(); mSubMesh.vertexData.vertexBufferBinding.SetBinding(0, vbuf); //Populate index buffer mSubMesh.indexData.indexStart = 0; mSubMesh.indexData.indexCount = 6 * mBillboardBuffer.Count; mSubMesh.indexData.indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer( IndexType.Size16, mSubMesh.indexData.indexCount, BufferUsage.StaticWriteOnly); ushort *pI = (ushort *)mSubMesh.indexData.indexBuffer.Lock(BufferLocking.Discard); for (ushort i = 0; i < mBillboardBuffer.Count; i++) { ushort ofset = (ushort)(i * 4); *pI++ = (ushort)(0 + ofset); *pI++ = (ushort)(2 + ofset); *pI++ = (ushort)(1 + ofset); *pI++ = (ushort)(1 + ofset); *pI++ = (ushort)(2 + ofset); *pI++ = (ushort)(3 + ofset); } mSubMesh.indexData.indexBuffer.Unlock(); //Finish up mesh mMesh.BoundingBox = bounds; Vector3 tmp = bounds.Maximum - bounds.Minimum; mMesh.BoundingSphereRadius = tmp.Length * 0.5f; LoggingLevel lvl = LogManager.Instance.LogDetail; LogManager.Instance.LogDetail = LoggingLevel.Low; mMesh.Load(); LogManager.Instance.LogDetail = lvl; //Empty the billboardBuffer now, because all billboards have been built mBillboardBuffer.Clear(); //Create an entity for the mesh mEntity = mSceneMgr.CreateEntity(mEntityName, mMesh.Name); mEntity.CastShadows = false; //Apply texture if (mFadeEnabled) { Debug.Assert(mFadeMaterial != null); mEntity.MaterialName = mFadeMaterial.Name; } else { Debug.Assert(mMaterial != null); mEntity.MaterialName = mMaterial.Name; } //Add to scene mNode.AttachObject(mEntity); mEntity.IsVisible = mVisible; } } }
/// <summary> /// Convert Obj Model File to Ogre Mesh format /// </summary> /// <param name="fileStream">Obj File Stream</param> /// <returns>Ogre Mesh</returns> public MeshPtr ConvertObjToMesh(Stream fileStream) { List <Vector3> vertexObj = new List <Vector3>(); List <Vector3> faceObj = new List <Vector3>(); float[] vertices; float[] faces; StreamReader reader = new StreamReader(fileStream); string line; Regex floatNumber = new Regex(@"[\d\-][\d\.]*"); Regex ushortNumber = new Regex(@"\d+"); MatchCollection matchList; while ((line = reader.ReadLine()) != null) { //Read vertices if (line.Substring(0, 2) == "v ") { matchList = floatNumber.Matches(line); float x = Convert.ToSingle(matchList[0].ToString()); float y = Convert.ToSingle(matchList[1].ToString()); float z = Convert.ToSingle(matchList[2].ToString()); vertexObj.Add(new Vector3(x, y, z)); } //Read faces else if (line.Substring(0, 2) == "f ") { //Error here where invalid indices were given. This is because the OBJ file started indexing the verts from 1 instead of 0. matchList = ushortNumber.Matches(line); int v1 = -1 + Convert.ToUInt16(matchList[0].ToString()); int v2 = -1 + Convert.ToUInt16(matchList[1].ToString()); int v3 = -1 + Convert.ToUInt16(matchList[2].ToString()); faceObj.Add(new Vector3((ushort)v1, (ushort)v2, (ushort)v3)); } } int vertexNum = vertexObj.Count; vertices = new float[vertexNum * 3]; for (int i = 0; i < vertexNum; i++) { vertices[i * 3 + 0] = vertexObj[i].x; vertices[i * 3 + 1] = vertexObj[i].y; vertices[i * 3 + 2] = vertexObj[i].z; } int faceNum = faceObj.Count; faces = new float[faceNum * 3]; for (int i = 0; i < faceNum; i++) { faces[i * 3 + 0] = faceObj[i].x; faces[i * 3 + 1] = faceObj[i].y; faces[i * 3 + 2] = faceObj[i].z; } MeshPtr mesh = MeshManager.Singleton.CreateManual("mesh1", ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME); SubMesh subMesh = mesh.CreateSubMesh(); mesh.sharedVertexData = new VertexData(); mesh.sharedVertexData.vertexCount = (uint)vertexObj.Count; VertexDeclaration vdecl = mesh.sharedVertexData.vertexDeclaration; VertexBufferBinding vbind = mesh.sharedVertexData.vertexBufferBinding; vdecl.AddElement(0, 0, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION); HardwareVertexBufferSharedPtr vertexBuff = HardwareBufferManager.Singleton.CreateVertexBuffer((uint)(3 * System.Runtime.InteropServices.Marshal.SizeOf(typeof(float))), (uint)vertexObj.Count, HardwareBuffer.Usage.HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); unsafe { GCHandle handle = GCHandle.Alloc(vertices, GCHandleType.Pinned); void * pVertex = (void *)handle.AddrOfPinnedObject(); vertexBuff.WriteData(0, vertexBuff.SizeInBytes, pVertex, true); handle.Free(); vbind.SetBinding(0, vertexBuff); } HardwareIndexBufferSharedPtr indexBuff = HardwareBufferManager.Singleton.CreateIndexBuffer(HardwareIndexBuffer.IndexType.IT_32BIT, (uint)(3 * faceObj.Count), HardwareBuffer.Usage.HBU_STATIC, true); unsafe { GCHandle handle = GCHandle.Alloc(faces, GCHandleType.Pinned); void * pFaces = (void *)handle.AddrOfPinnedObject(); indexBuff.WriteData(0, indexBuff.SizeInBytes, pFaces, true); handle.Free(); } subMesh.useSharedVertices = true; subMesh.indexData.indexBuffer = indexBuff; subMesh.indexData.indexStart = 0; subMesh.indexData.indexCount = (uint)(3 * faceObj.Count); mesh._setBounds(new AxisAlignedBox(-100, -100, -100, 100, 100, 100)); mesh.Touch(); reader.Close(); return(mesh); }
private void CreateBuffers(ushort[] indices, short[] vertices) { var numIndices = (uint)indices.Length; var numVertices = (uint)vertices.Length; _vertexDeclaration = HardwareBufferManager.Singleton.CreateVertexDeclaration(); _vertexDeclaration.AddElement(0, 0, VertexElementType.VET_SHORT2, VertexElementSemantic.VES_POSITION); _ib = HardwareBufferManager.Singleton.CreateIndexBuffer(HardwareIndexBuffer.IndexType.IT_16BIT, numIndices, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); _vb = HardwareBufferManager.Singleton.CreateVertexBuffer(_vertexDeclaration.GetVertexSize(0), numVertices, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY, false); unsafe { fixed (ushort* x = indices) _ib.WriteData(0, numIndices * sizeof(ushort), x, true); fixed (short* x = vertices) _vb.WriteData(0, numVertices * sizeof(ushort), x, true); } var binding = new VertexBufferBinding(); binding.SetBinding(0, _vb); VertexData = new VertexData(_vertexDeclaration, binding); VertexData.vertexCount = numVertices; VertexData.vertexStart = 0; IndexData = new IndexData(); IndexData.indexBuffer = _ib; IndexData.indexCount = numIndices; IndexData.indexStart = 0; }
/// <summary> /// /// </summary> /// <param name="vertexData"></param> /// <returns></returns> private VertexData PrepareVertexData(VertexData orgData) { if (orgData == null) { return(null); } VertexData newData = new VertexData(); // copy things that do not change newData.vertexCount = orgData.vertexCount; newData.vertexStart = orgData.vertexStart; // copy vertex buffers VertexDeclaration newDecl = newData.vertexDeclaration; VertexBufferBinding newBinding = newData.vertexBufferBinding; // prepare buffer for each declaration for (int i = 0; i < orgData.vertexDeclaration.ElementCount; i++) { VertexElement element = orgData.vertexDeclaration.GetElement(i); VertexElementSemantic ves = element.Semantic; ushort source = element.Source; HardwareVertexBuffer orgBuffer = orgData.vertexBufferBinding.GetBuffer(source); // check usage for the new buffer bool dynamic = false; switch (ves) { case VertexElementSemantic.Normal: case VertexElementSemantic.Position: dynamic = true; break; } if (dynamic) { HardwareVertexBuffer newBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( orgBuffer.VertexSize, orgBuffer.VertexCount, BufferUsage.DynamicWriteOnly, true); // copy and bind the new dynamic buffer newBuffer.CopyData(orgBuffer, 0, 0, orgBuffer.Size, true); newBinding.SetBinding(source, newBuffer); } else { // use the existing buffer newBinding.SetBinding(source, orgBuffer); } // add the new element to the declaration newDecl.AddElement(source, element.Offset, element.Type, ves, element.Index); } // foreach return(newData); }
private void CreateMesh() { Vec3 size = new Vec3(.97f, .97f, .1f); Vec3[] positions; Vec3[] normals; int[] indices; GeometryGenerator.GenerateBox(size, out positions, out normals, out indices); string meshName = MeshManager.Instance.GetUniqueName( string.Format("JigsawPuzzlePiece[{0},{1}]", index.X, index.Y)); mesh = MeshManager.Instance.CreateManual(meshName); //create submesh SubMesh subMesh = mesh.CreateSubMesh(); subMesh.UseSharedVertices = false; //init VertexData VertexDeclaration declaration = subMesh.VertexData.VertexDeclaration; declaration.AddElement(0, 0, VertexElementType.Float3, VertexElementSemantic.Position); declaration.AddElement(0, 12, VertexElementType.Float3, VertexElementSemantic.Normal); declaration.AddElement(0, 24, VertexElementType.Float2, VertexElementSemantic.TextureCoordinates, 0); VertexBufferBinding bufferBinding = subMesh.VertexData.VertexBufferBinding; HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( 32, positions.Length, HardwareBuffer.Usage.StaticWriteOnly); bufferBinding.SetBinding(0, vertexBuffer, true); subMesh.VertexData.VertexCount = positions.Length; unsafe { Vertex *buffer = (Vertex *)vertexBuffer.Lock(HardwareBuffer.LockOptions.Normal); for (int n = 0; n < positions.Length; n++) { Vertex vertex = new Vertex(); vertex.position = positions[n]; vertex.normal = normals[n]; if (JigsawPuzzleManager.Instance != null) { Vec2I pieceCount = JigsawPuzzleManager.Instance.PieceCount; Vec2I i = index; if (vertex.position.X > 0) { i.X++; } if (vertex.position.Y > 0) { i.Y++; } vertex.texCoord = new Vec2( (float)i.X / (float)pieceCount.X, 1.0f - (float)i.Y / (float)pieceCount.Y); } *buffer = vertex; buffer++; } vertexBuffer.Unlock(); } //calculate mesh bounds Bounds bounds = Bounds.Cleared; float radius = 0; foreach (Vec3 position in positions) { bounds.Add(position); float r = position.Length(); if (r > radius) { radius = r; } } mesh.SetBoundsAndRadius(bounds, radius); //init IndexData subMesh.IndexData = IndexData.CreateFromArray(indices, 0, indices.Length, false); //init material subMesh.MaterialName = "JigsawPuzzleImage"; }
/// <summary> /// Override from Panel. /// </summary> public override void Initialize() { base.Initialize(); // base class already has added the center panel at this point, so lets create the borders renderOp2.vertexData = new VertexData(); // 8 * 4, cant resuse vertices because they might not share same tex coords renderOp2.vertexData.vertexCount = 32; renderOp2.vertexData.vertexStart = 0; // get a reference to the vertex declaration VertexDeclaration decl = renderOp2.vertexData.vertexDeclaration; // Position and texture coords each have their own buffers to allow // each to be edited separately with the discard flag decl.AddElement(POSITION, 0, VertexElementType.Float3, VertexElementSemantic.Position); decl.AddElement(TEXCOORDS, 0, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0); // position buffer HardwareVertexBuffer buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.GetVertexSize(POSITION), renderOp2.vertexData.vertexCount, BufferUsage.StaticWriteOnly); // bind position VertexBufferBinding binding = renderOp2.vertexData.vertexBufferBinding; binding.SetBinding(POSITION, buffer); // texcoord buffer buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.GetVertexSize(TEXCOORDS), renderOp2.vertexData.vertexCount, BufferUsage.StaticWriteOnly); // bind texcoords binding = renderOp2.vertexData.vertexBufferBinding; binding.SetBinding(TEXCOORDS, buffer); renderOp2.operationType = OperationType.TriangleList; renderOp2.useIndices = true; // index data renderOp2.indexData = new IndexData(); // 8 * 3 * 2 = 8 vertices, 3 indices per tri, 2 tris renderOp2.indexData.indexCount = 48; renderOp2.indexData.indexStart = 0; /* Each cell is * 0-----2 | /| | / | |/ | | 1-----3 */ // create a new index buffer renderOp2.indexData.indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer( IndexType.Size16, renderOp2.indexData.indexCount, BufferUsage.StaticWriteOnly); // lock this bad boy IntPtr data = renderOp2.indexData.indexBuffer.Lock(BufferLocking.Discard); int index = 0; unsafe { short *idxPtr = (short *)data.ToPointer(); for (short cell = 0; cell < 8; cell++) { short val = (short)(cell * 4); idxPtr[index++] = val; idxPtr[index++] = (short)(val + 1); idxPtr[index++] = (short)(val + 2); idxPtr[index++] = (short)(val + 2); idxPtr[index++] = (short)(val + 1); idxPtr[index++] = (short)(val + 3); } } // unlock the buffer renderOp2.indexData.indexBuffer.Unlock(); // create new seperate object for the panels since they have a different material borderRenderable = new BorderRenderable(this); }
// Just override the mandatory create scene method public override void CreateScene() { // Set ambient light sceneMgr.AmbientLight = new ColourValue(0.2f, 0.2f, 0.2f); // Create a point light Light l = sceneMgr.CreateLight("MainLight"); // Accept default settings: point light, white diffuse, just set position // NB I could attach the light to a SceneNode if I wanted it to move automatically with // other objects, but I don't l.Type = Light.LightTypes.LT_DIRECTIONAL; l.SetDirection(-0.5f, -0.5f, 0); // Create patch patchDecl = HardwareBufferManager.Singleton.CreateVertexDeclaration(); patchDecl.AddElement(0, 0, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION); patchDecl.AddElement(0, sizeof(float)*3, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_NORMAL); patchDecl.AddElement(0, sizeof(float)*6, VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES, 0); // Make a 3x3 patch for test patchCtlPoints = new PatchVertex[9]; // Patch data patchCtlPoints[0] = new PatchVertex(); patchCtlPoints[0].x = -500.0f; patchCtlPoints[0].y = 200.0f; patchCtlPoints[0].z = -500.0f; patchCtlPoints[0].nx = -0.5f; patchCtlPoints[0].ny = 0.5f; patchCtlPoints[0].nz = 0.0f; patchCtlPoints[0].u = 0.0f; patchCtlPoints[0].v = 0.0f; patchCtlPoints[1] = new PatchVertex(); patchCtlPoints[1].x = 0.0f; patchCtlPoints[1].y = 500.0f; patchCtlPoints[1].z = -750.0f; patchCtlPoints[1].nx = 0.0f; patchCtlPoints[1].ny = 0.5f; patchCtlPoints[1].nz = 0.0f; patchCtlPoints[1].u = 0.5f; patchCtlPoints[1].v = 0.0f; patchCtlPoints[2] = new PatchVertex(); patchCtlPoints[2].x = 500.0f; patchCtlPoints[2].y = 1000.0f; patchCtlPoints[2].z = -500.0f; patchCtlPoints[2].nx = 0.5f; patchCtlPoints[2].ny = 0.5f; patchCtlPoints[2].nz = 0.0f; patchCtlPoints[2].u = 1.0f; patchCtlPoints[2].v = 0.0f; patchCtlPoints[3] = new PatchVertex(); patchCtlPoints[3].x = -500.0f; patchCtlPoints[3].y = 0.0f; patchCtlPoints[3].z = 0.0f; patchCtlPoints[3].nx = -0.5f; patchCtlPoints[3].ny = 0.5f; patchCtlPoints[3].nz = 0.0f; patchCtlPoints[3].u = 0.0f; patchCtlPoints[3].v = 0.5f; patchCtlPoints[4] = new PatchVertex(); patchCtlPoints[4].x = 0.0f; patchCtlPoints[4].y = 500.0f; patchCtlPoints[4].z = 0.0f; patchCtlPoints[4].nx = 0.0f; patchCtlPoints[4].ny = 0.5f; patchCtlPoints[4].nz = 0.0f; patchCtlPoints[4].u = 0.5f; patchCtlPoints[4].v = 0.5f; patchCtlPoints[5] = new PatchVertex(); patchCtlPoints[5].x = 500.0f; patchCtlPoints[5].y = -50.0f; patchCtlPoints[5].z = 0.0f; patchCtlPoints[5].nx = 0.5f; patchCtlPoints[5].ny = 0.5f; patchCtlPoints[5].nz = 0.0f; patchCtlPoints[5].u = 1.0f; patchCtlPoints[5].v = 0.5f; patchCtlPoints[6] = new PatchVertex(); patchCtlPoints[6].x = -500.0f; patchCtlPoints[6].y = 0.0f; patchCtlPoints[6].z = 500.0f; patchCtlPoints[6].nx = -0.5f; patchCtlPoints[6].ny = 0.5f; patchCtlPoints[6].nz = 0.0f; patchCtlPoints[6].u = 0.0f; patchCtlPoints[6].v = 1.0f; patchCtlPoints[7] = new PatchVertex(); patchCtlPoints[7].x = 0.0f; patchCtlPoints[7].y = 500.0f; patchCtlPoints[7].z = 500.0f; patchCtlPoints[7].nx = 0.0f; patchCtlPoints[7].ny = 0.5f; patchCtlPoints[7].nz = 0.0f; patchCtlPoints[7].u = 0.5f; patchCtlPoints[7].v = 1.0f; patchCtlPoints[8] = new PatchVertex(); patchCtlPoints[8].x = 500.0f; patchCtlPoints[8].y = 200.0f; patchCtlPoints[8].z = 800.0f; patchCtlPoints[8].nx = 0.5f; patchCtlPoints[8].ny = 0.5f; patchCtlPoints[8].nz = 0.0f; patchCtlPoints[8].u = 1.0f; patchCtlPoints[8].v = 1.0f; patch = MeshManager.Singleton.CreateBezierPatch( "Bezier1", ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME, patchCtlPoints, patchDecl, 3, 3, 5, 5, PatchSurface.VisibleSide.VS_BOTH, HardwareVertexBuffer.Usage.HBU_STATIC_WRITE_ONLY, HardwareIndexBuffer.Usage.HBU_DYNAMIC_WRITE_ONLY, true, true); // Start patch at 0 detail patch.SetSubdivision(0.0f); // Create entity based on patch Entity patchEntity = sceneMgr.CreateEntity("Entity1", "Bezier1"); MaterialPtr pMat = MaterialManager.Singleton.Create("TextMat", ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME); pMat.GetTechnique(0).GetPass(0).CreateTextureUnitState( "BumpyMetal.jpg" ); patchEntity.SetMaterialName("TextMat"); patchPass = pMat.GetTechnique(0).GetPass(0); // Attach the entity to the root of the scene sceneMgr.RootSceneNode.AttachObject(patchEntity); camera.SetPosition(500,500, 1500); camera.LookAt(0,200,-300); }
// --- Protected Override Methods --- #region CreateScene() // Just override the mandatory create scene method protected override void CreateScene() { // Set ambient light scene.AmbientLight = new ColorEx(0.2f, 0.2f, 0.2f); // Create point light Light light = scene.CreateLight("MainLight"); // Accept default settings: point light, white diffuse, just set position. // I could attach the light to a SceneNode if I wanted it to move automatically with // other objects, but I don't. light.Type = LightType.Directional; light.Direction = new Vector3(-0.5f, -0.5f, 0); // Create patch with positions, normals, and 1 set of texcoords patchDeclaration = HardwareBufferManager.Instance.CreateVertexDeclaration(); patchDeclaration.AddElement(0, 0, VertexElementType.Float3, VertexElementSemantic.Position); patchDeclaration.AddElement(0, 12, VertexElementType.Float3, VertexElementSemantic.Normal); patchDeclaration.AddElement(0, 24, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0); // Patch data PatchVertex[] patchVertices = new PatchVertex[9]; patchVertices[0].X = -500; patchVertices[0].Y = 200; patchVertices[0].Z = -500; patchVertices[0].Nx = -0.5f; patchVertices[0].Ny = 0.5f; patchVertices[0].Nz = 0; patchVertices[0].U = 0; patchVertices[0].V = 0; patchVertices[1].X = 0; patchVertices[1].Y = 500; patchVertices[1].Z = -750; patchVertices[1].Nx = 0; patchVertices[1].Ny = 0.5f; patchVertices[1].Nz = 0; patchVertices[1].U = 0.5f; patchVertices[1].V = 0; patchVertices[2].X = 500; patchVertices[2].Y = 1000; patchVertices[2].Z = -500; patchVertices[2].Nx = 0.5f; patchVertices[2].Ny = 0.5f; patchVertices[2].Nz = 0; patchVertices[2].U = 1; patchVertices[2].V = 0; patchVertices[3].X = -500; patchVertices[3].Y = 0; patchVertices[3].Z = 0; patchVertices[3].Nx = -0.5f; patchVertices[3].Ny = 0.5f; patchVertices[3].Nz = 0; patchVertices[3].U = 0; patchVertices[3].V = 0.5f; patchVertices[4].X = 0; patchVertices[4].Y = 500; patchVertices[4].Z = 0; patchVertices[4].Nx = 0; patchVertices[4].Ny = 0.5f; patchVertices[4].Nz = 0; patchVertices[4].U = 0.5f; patchVertices[4].V = 0.5f; patchVertices[5].X = 500; patchVertices[5].Y = -50; patchVertices[5].Z = 0; patchVertices[5].Nx = 0.5f; patchVertices[5].Ny = 0.5f; patchVertices[5].Nz = 0; patchVertices[5].U = 1; patchVertices[5].V = 0.5f; patchVertices[6].X = -500; patchVertices[6].Y = 0; patchVertices[6].Z = 500; patchVertices[6].Nx = -0.5f; patchVertices[6].Ny = 0.5f; patchVertices[6].Nz = 0; patchVertices[6].U = 0; patchVertices[6].V = 1; patchVertices[7].X = 0; patchVertices[7].Y = 500; patchVertices[7].Z = 500; patchVertices[7].Nx = 0; patchVertices[7].Ny = 0.5f; patchVertices[7].Nz = 0; patchVertices[7].U = 0.5f; patchVertices[7].V = 1; patchVertices[8].X = 500; patchVertices[8].Y = 200; patchVertices[8].Z = 800; patchVertices[8].Nx = 0.5f; patchVertices[8].Ny = 0.5f; patchVertices[8].Nz = 0; patchVertices[8].U = 1; patchVertices[8].V = 1; patch = MeshManager.Instance.CreateBezierPatch("Bezier1", patchVertices, patchDeclaration, 3, 3, 5, 5, VisibleSide.Both, BufferUsage.StaticWriteOnly, BufferUsage.DynamicWriteOnly, true, true); // Start patch a 0 detail patch.SetSubdivision(0); // Create entity based on patch patchEntity = scene.CreateEntity("Entity1", "Bezier1"); Material material = (Material)MaterialManager.Instance.Create("TextMat"); material.GetTechnique(0).GetPass(0).CreateTextureUnitState("BumpyMetal.jpg"); patchEntity.MaterialName = "TextMat"; // Attach the entity to the root of the scene scene.RootSceneNode.AttachObject(patchEntity); camera.Position = new Vector3(500, 500, 1500); camera.LookAt(new Vector3(0, 200, -300)); }
/// <summary> /// /// </summary> /// <param name="v1"></param> /// <param name="v2"></param> /// <param name="v3"></param> public Triangle(Vector3 v1, Vector3 v2, Vector3 v3, ColorEx c1, ColorEx c2, ColorEx c3) { vertexData = new VertexData(); vertexData.vertexCount = 3; vertexData.vertexStart = 0; VertexDeclaration decl = vertexData.vertexDeclaration; VertexBufferBinding binding = vertexData.vertexBufferBinding; // add a position and color element to the declaration decl.AddElement(POSITION, 0, VertexElementType.Float3, VertexElementSemantic.Position); decl.AddElement(COLOR, 0, VertexElementType.Color, VertexElementSemantic.Diffuse); // POSITIONS // create a vertex buffer for the position HardwareVertexBuffer buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.GetVertexSize(POSITION), vertexData.vertexCount, BufferUsage.StaticWriteOnly); Vector3[] positions = new Vector3[] { v1, v2, v3 }; // write the positions to the buffer buffer.WriteData(0, buffer.Size, positions, true); // bind the position buffer binding.SetBinding(POSITION, buffer); // COLORS // create a color buffer buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.GetVertexSize(COLOR), vertexData.vertexCount, BufferUsage.StaticWriteOnly); // create an int array of the colors to use. // note: these must be converted to the current API's // preferred packed int format uint[] colors = new uint[] { Root.Instance.RenderSystem.ConvertColor(c1), Root.Instance.RenderSystem.ConvertColor(c2), Root.Instance.RenderSystem.ConvertColor(c3) }; // write the colors to the color buffer buffer.WriteData(0, buffer.Size, colors, true); // bind the color buffer binding.SetBinding(COLOR, buffer); // MATERIAL // grab a copy of the BaseWhite material for our use Material material = MaterialManager.Instance.GetByName("BaseWhite"); material = material.Clone("TriMat"); // disable lighting to vertex colors are used material.Lighting = false; // set culling to none so the triangle is drawn 2 sided material.CullingMode = CullingMode.None; materialName = "TriMat"; this.Material = material; // set the bounding box of the tri // TODO: not right, but good enough for now this.box = new AxisAlignedBox(new Vector3(25, 50, 0), new Vector3(-25, 0, 0)); }
void CreateDecal() { Bounds bounds = Bounds.Cleared; foreach (Vertex vertex in vertices) { bounds.Add(vertex.position); } VertexData vertexData = new VertexData(); IndexData indexData = new IndexData(); //init vertexData VertexDeclaration declaration = vertexData.VertexDeclaration; declaration.AddElement(0, 0, VertexElementType.Float3, VertexElementSemantic.Position); declaration.AddElement(0, 12, VertexElementType.Float3, VertexElementSemantic.Normal); declaration.AddElement(0, 24, VertexElementType.Float2, VertexElementSemantic.TextureCoordinates, 0); declaration.AddElement(0, 32, VertexElementType.Float3, VertexElementSemantic.Tangent); VertexBufferBinding bufferBinding = vertexData.VertexBufferBinding; HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( 44, vertices.Length, HardwareBuffer.Usage.StaticWriteOnly); bufferBinding.SetBinding(0, vertexBuffer, true); vertexData.VertexCount = vertices.Length; //init indexData Trace.Assert(vertices.Length < 65536, "Decal: vertices.Length < 65536"); HardwareIndexBuffer indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer( HardwareIndexBuffer.IndexType._16Bit, indices.Length, HardwareBuffer.Usage.StaticWriteOnly); indexData.SetIndexBuffer(indexBuffer, true); indexData.IndexCount = indices.Length; //init material Material material = null; shaderBaseMaterial = HighLevelMaterialManager.Instance. GetMaterialByName(sourceMaterialName) as ShaderBaseMaterial; //only default shader technique for ShaderBase material if (shaderBaseMaterial != null && !shaderBaseMaterial.IsDefaultTechniqueCreated()) { shaderBaseMaterial = null; } if (shaderBaseMaterial != null) { //ShaderBase material material = shaderBaseMaterial.BaseMaterial; } else { //standard material or fallback ShaderBase technique Material sourceMaterial = MaterialManager.Instance.GetByName(sourceMaterialName); if (sourceMaterial != null) { //clone standard material clonedStandardMaterial = MaterialManager.Instance.Clone(sourceMaterial, MaterialManager.Instance.GetUniqueName(sourceMaterialName + "_Cloned")); material = clonedStandardMaterial; } } staticMeshObject = SceneManager.Instance.CreateStaticMeshObject(bounds + Position, Position, Quat.Identity, new Vec3(1, 1, 1), true, material, vertexData, indexData, true); staticMeshObject.AddToRenderQueue += StaticMeshObject_AddToRenderQueue; UpdateBuffers(); }
public unsafe void createMesh() { /// Create the mesh via the MeshManager MeshPtr msh = MeshManager.Singleton.CreateManual("ColourCube", "General"); /// Create one submesh SubMesh sub = msh.CreateSubMesh(); /// Define the vertices (8 vertices, each consisting of 2 groups of 3 floats //const int nVertices = 8; //int row = recordno; // int col = demcol; int row = recordno; int col = 1100; int step = 10; int vbufCount; uint nVertices = (uint)(col * row); float[] vertices = CreateVertices(row, col, step, out vbufCount); /// Define 12 triangles (two triangles per cube face) /// The values in this table refer to vertices in the above table uint ibufCount; ushort[] faces = CreateFaces(row, col, out ibufCount); /// Create vertex data structure for 8 vertices shared between submeshes msh.sharedVertexData = new VertexData(); msh.sharedVertexData.vertexCount = nVertices; /// Create declaration (memory format) of vertex data VertexDeclaration decl = msh.sharedVertexData.vertexDeclaration; uint offset = 0; // 1st buffer decl.AddElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION); offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3); decl.AddElement(0, offset, VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES); offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT2); /// Allocate vertex buffer of the requested number of vertices (vertexCount) /// and bytes per vertex (offset) HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager.Singleton.CreateVertexBuffer(offset, msh.sharedVertexData.vertexCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); /// Upload the vertex data to the card fixed(void *p = vertices) { vbuf.WriteData(0, vbuf.SizeInBytes, p, true);// writeData(0, vbuf->getSizeInBytes(), vertices, true); } /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer VertexBufferBinding bind = msh.sharedVertexData.vertexBufferBinding;// msh->sharedVertexData->vertexBufferBinding; bind.SetBinding(0, vbuf); /// Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager.Singleton.CreateIndexBuffer(HardwareIndexBuffer.IndexType.IT_16BIT, ibufCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card fixed(void *p = faces) { ibuf.WriteData(0, ibuf.SizeInBytes, p, true); } /// Set parameters of the submesh sub.useSharedVertices = true; sub.indexData.indexBuffer = ibuf; sub.indexData.indexCount = ibufCount; sub.indexData.indexStart = 0; /// Set bounding information (for culling) msh._setBounds(new AxisAlignedBox(min, max)); // msh._setBoundingSphereRadius(Mogre.Math.Sqrt(3 * 100 * 100)); /// Notify Mesh object that it has been loaded msh.Load(); }
} // CreateTetrahedron unsafe static public void CreateTetrahedron2(string strName) { float r = 1f; int nRings = 8; int nSegments = 8; Single scale = 1; Mogre.Vector3 position = new Mogre.Vector3(); MeshPtr pTetra = MeshManager.Singleton.CreateManual(strName, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME); SubMesh pTetraVertex = pTetra.CreateSubMesh(); pTetra.sharedVertexData = new VertexData(); VertexData vertexData = pTetra.sharedVertexData; // define the vertex format VertexDeclaration vertexDecl = vertexData.vertexDeclaration; uint currOffset = 0; // positions vertexDecl.AddElement(0, currOffset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION); currOffset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3); // normals vertexDecl.AddElement(0, currOffset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_NORMAL); currOffset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3); // two dimensional texture coordinates vertexDecl.AddElement(0, currOffset, VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES, 0); currOffset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT2); // allocate the vertex buffer vertexData.vertexCount = 4; //(uint)((nRings + 1) * (nSegments + 1)); HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager.Singleton.CreateVertexBuffer(vertexDecl.GetVertexSize(0), vertexData.vertexCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY, false); VertexBufferBinding binding = vertexData.vertexBufferBinding; binding.SetBinding(0, vBuf); float *pVertex = (float *)vBuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD); uint numIndexes = (uint)(6 * 4); // allocate index buffer pTetraVertex.indexData.indexCount = numIndexes; pTetraVertex.indexData.indexBuffer = HardwareBufferManager.Singleton.CreateIndexBuffer(HardwareIndexBuffer.IndexType.IT_16BIT, pTetraVertex.indexData.indexCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY, false); HardwareIndexBufferSharedPtr iBuf = pTetraVertex.indexData.indexBuffer; ushort *pIndices = (ushort *)iBuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD); //float fDeltaRingAngle = (float)(Mogre.Math.PI / nRings); //float fDeltaSegAngle = (float)(2 * Mogre.Math.PI / nSegments); ushort wVerticeIndex = 0; // calculate corners of tetrahedron (with point of origin in middle of volume) Single mbot = scale * 0.2f; // distance middle to bottom Single mtop = scale * 0.62f; // distance middle to top Single mf = scale * 0.289f; // distance middle to front Single mb = scale * 0.577f; // distance middle to back Single mlr = scale * 0.5f; // distance middle to left right // width / height / depth Mogre.Vector3[] c = new Mogre.Vector3[4]; // corners c[0] = new Mogre.Vector3(-mlr, -mbot, mf); // left bottom front c[1] = new Mogre.Vector3(mlr, -mbot, mf); // right bottom front c[2] = new Mogre.Vector3(0, -mbot, -mb); // (middle) bottom back c[3] = new Mogre.Vector3(0, mtop, 0); // (middle) top (middle) // add position offset for all corners (move tetrahedron) for (Int16 i = 0; i <= 3; i++) { c[i] += position; } Mogre.Vector3 vNormal = new Mogre.Vector3(); *pVertex++ = c[0].x; *pVertex++ = c[0].y; *pVertex++ = c[0].z; vNormal = (new Mogre.Vector3(c[0].x, c[0].y, c[0].z)).NormalisedCopy; *pVertex++ = vNormal.x; *pVertex++ = vNormal.y; *pVertex++ = vNormal.z; *pVertex++ = (float).25; *pVertex++ = (float).25; *pIndices++ = (ushort)(wVerticeIndex + numIndexes + 1); *pIndices++ = wVerticeIndex; *pIndices++ = (ushort)(wVerticeIndex + numIndexes); *pIndices++ = (ushort)(wVerticeIndex + numIndexes + 1); *pIndices++ = (ushort)(wVerticeIndex + 1); *pIndices++ = wVerticeIndex; wVerticeIndex++; *pVertex++ = c[1].x; *pVertex++ = c[1].y; *pVertex++ = c[1].z; vNormal = (new Mogre.Vector3(c[1].x, c[1].y, c[1].z)).NormalisedCopy; *pVertex++ = vNormal.x; *pVertex++ = vNormal.y; *pVertex++ = vNormal.z; *pVertex++ = (float).50; *pVertex++ = (float).50; *pIndices++ = (ushort)(wVerticeIndex + numIndexes + 1); *pIndices++ = wVerticeIndex; *pIndices++ = (ushort)(wVerticeIndex + numIndexes); *pIndices++ = (ushort)(wVerticeIndex + numIndexes + 1); *pIndices++ = (ushort)(wVerticeIndex + 1); *pIndices++ = wVerticeIndex; wVerticeIndex++; *pVertex++ = c[2].x; *pVertex++ = c[2].y; *pVertex++ = c[2].z; vNormal = (new Mogre.Vector3(c[2].x, c[2].y, c[2].z)).NormalisedCopy; *pVertex++ = vNormal.x; *pVertex++ = vNormal.y; *pVertex++ = vNormal.z; *pVertex++ = (float).75; *pVertex++ = (float).75; *pIndices++ = (ushort)(wVerticeIndex + numIndexes + 1); *pIndices++ = wVerticeIndex; *pIndices++ = (ushort)(wVerticeIndex + numIndexes); *pIndices++ = (ushort)(wVerticeIndex + numIndexes + 1); *pIndices++ = (ushort)(wVerticeIndex + 1); *pIndices++ = wVerticeIndex; wVerticeIndex++; *pVertex++ = c[3].x; *pVertex++ = c[3].y; *pVertex++ = c[3].z; vNormal = (new Mogre.Vector3(c[3].x, c[3].y, c[3].z)).NormalisedCopy; *pVertex++ = vNormal.x; *pVertex++ = vNormal.y; *pVertex++ = vNormal.z; *pVertex++ = (float)1; *pVertex++ = (float)1; *pIndices++ = (ushort)(wVerticeIndex + numIndexes + 1); *pIndices++ = wVerticeIndex; *pIndices++ = (ushort)(wVerticeIndex + numIndexes); *pIndices++ = (ushort)(wVerticeIndex + numIndexes + 1); *pIndices++ = (ushort)(wVerticeIndex + 1); *pIndices++ = wVerticeIndex; wVerticeIndex++; //manObTetra.Begin(materialName, RenderOperation.OperationTypes.OT_TRIANGLE_LIST); //manObTetra.Position(c[2]); //manObTetra.Position(c[1]); //manObTetra.Position(c[0]); //manObTetra.Triangle(0, 1, 2); //manObTetra.End(); //// create right back side //manObTetra.Begin(materialName, RenderOperation.OperationTypes.OT_TRIANGLE_LIST); //manObTetra.Position(c[1]); //manObTetra.Position(c[2]); //manObTetra.Position(c[3]); //manObTetra.Triangle(0, 1, 2); //manObTetra.End(); //// create left back side //manObTetra.Begin(materialName, RenderOperation.OperationTypes.OT_TRIANGLE_LIST); //manObTetra.Position(c[3]); //manObTetra.Position(c[2]); //manObTetra.Position(c[0]); //manObTetra.Triangle(0, 1, 2); //manObTetra.End(); //// create front side //manObTetra.Begin(materialName, RenderOperation.OperationTypes.OT_TRIANGLE_LIST); //manObTetra.Position(c[0]); //manObTetra.Position(c[1]); //manObTetra.Position(c[3]); //manObTetra.Triangle(0, 1, 2); //manObTetra.End(); //return manObTetra; //// Generate the group of rings for the sphere //for (int ring = 0; ring <= nRings; ring++) //{ // float r0 = r * Mogre.Math.Sin(ring * fDeltaRingAngle); // float y0 = r * Mogre.Math.Cos(ring * fDeltaRingAngle); // // Generate the group of segments for the current ring // for (int seg = 0; seg <= nSegments; seg++) // { // float x0 = r0 * Mogre.Math.Sin(seg * fDeltaSegAngle); // float z0 = r0 * Mogre.Math.Cos(seg * fDeltaSegAngle); // // Add one vertex to the strip which makes up the sphere // *pVertex++ = x0; // *pVertex++ = y0; // *pVertex++ = z0; // Mogre.Vector3 vNormal = (new Mogre.Vector3(x0, y0, z0)).NormalisedCopy; // *pVertex++ = vNormal.x; // *pVertex++ = vNormal.y; // *pVertex++ = vNormal.z; // *pVertex++ = (float)seg / (float)nSegments; // *pVertex++ = (float)ring / (float)nRings; // if (ring != nRings) // { // // each vertex (except the last) has six indices pointing to it // *pIndices++ = (ushort)(wVerticeIndex + nSegments + 1); // *pIndices++ = wVerticeIndex; // *pIndices++ = (ushort)(wVerticeIndex + nSegments); // *pIndices++ = (ushort)(wVerticeIndex + nSegments + 1); // *pIndices++ = (ushort)(wVerticeIndex + 1); // *pIndices++ = wVerticeIndex; // wVerticeIndex++; // } // }; // end for seg //} // end for ring // Unlock vBuf.Unlock(); iBuf.Unlock(); // Generate face list pTetraVertex.useSharedVertices = true; // the original code was missing this line: pTetra._setBounds(new AxisAlignedBox(new Mogre.Vector3(-r, -r, -r), new Mogre.Vector3(r, r, r)), false); pTetra._setBoundingSphereRadius(r); // this line makes clear the mesh is loaded (avoids memory leaks) pTetra.Load(); }
/// <summary> /// Called to update the texture coords when layers change. /// </summary> protected virtual void UpdateTextureGeometry() { if (material != null) { int numLayers = material.GetTechnique(0).GetPass(0).NumTextureUnitStages; VertexDeclaration decl = renderOp.vertexData.vertexDeclaration; // if the required layers is less than the current amount of tex coord buffers, remove // the extraneous buffers if (numTexCoords > numLayers) { for (int i = numTexCoords; i > numLayers; --i) { // TODO: Implement RemoveElement //decl.RemoveElement(TEXTURE_COORDS, i); } } else if (numTexCoords < numLayers) { // we need to add more buffers int offset = VertexElement.GetTypeSize(VertexElementType.Float2) * numTexCoords; for (int i = numTexCoords; i < numLayers; i++) { decl.AddElement(TEXTURE_COORDS, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, i); offset += VertexElement.GetTypeSize(VertexElementType.Float2); } // for } // if // if the number of layers changed at all, we'll need to reallocate buffer if (numTexCoords != numLayers) { HardwareVertexBuffer newBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.GetVertexSize(TEXTURE_COORDS), renderOp.vertexData.vertexCount, BufferUsage.StaticWriteOnly); // Bind buffer, note this will unbind the old one and destroy the buffer it had renderOp.vertexData.vertexBufferBinding.SetBinding(TEXTURE_COORDS, newBuffer); // record the current number of tex layers now numTexCoords = numLayers; } // if // get the tex coord buffer HardwareVertexBuffer buffer = renderOp.vertexData.vertexBufferBinding.GetBuffer(TEXTURE_COORDS); IntPtr data = buffer.Lock(BufferLocking.Discard); unsafe { float *texPtr = (float *)data.ToPointer(); int texIndex = 0; int uvSize = VertexElement.GetTypeSize(VertexElementType.Float2) / sizeof(float); int vertexSize = decl.GetVertexSize(TEXTURE_COORDS) / sizeof(float); for (int i = 0; i < numLayers; i++) { // Calc upper tex coords float upperX = 1.0f * tileX[i]; float upperY = 1.0f * tileY[i]; /* * 0-----2 | /| | / | |/ | | 1-----3 */ // Find start offset for this set texIndex = (i * uvSize); texPtr[texIndex] = 0.0f; texPtr[texIndex + 1] = 0.0f; texIndex += vertexSize; // jump by 1 vertex stride texPtr[texIndex] = 0.0f; texPtr[texIndex + 1] = upperY; texIndex += vertexSize; texPtr[texIndex] = upperX; texPtr[texIndex + 1] = 0.0f; texIndex += vertexSize; texPtr[texIndex] = upperX; texPtr[texIndex + 1] = upperY; } // for } // unsafev // unlock the buffer buffer.Unlock(); } // if material != null }
/// <summary> /// /// </summary> protected void Initialize() { Vector3 ax = Vector3.Zero, ay = Vector3.Zero, az = Vector3.Zero; int x = 0; Quaternion q = Quaternion.Identity; this.things.Clear(); this.orbits.Clear(); for (x = 0; x < this.count; x++) { ax = new Vector3(GenerateRandomFloat(), GenerateRandomFloat(), GenerateRandomFloat()); ay = new Vector3(GenerateRandomFloat(), GenerateRandomFloat(), GenerateRandomFloat()); az = ax.Cross(ay); ay = az.Cross(ax); ax.Normalize(); ay.Normalize(); az.Normalize(); q = Quaternion.FromAxes(ax, ay, az); this.things.Add(q); ax = new Vector3(GenerateRandomFloat(), GenerateRandomFloat(), GenerateRandomFloat()); ay = new Vector3(GenerateRandomFloat(), GenerateRandomFloat(), GenerateRandomFloat()); az = ax.Cross(ay); ay = az.Cross(ax); ax.Normalize(); ay.Normalize(); az.Normalize(); q = Quaternion.FromAxes(ax, ay, az); this.orbits.Add(q); } int nVertices = this.count * 4; var indexData = new IndexData(); var vertexData = new VertexData(); //Quads var faces = new short[this.count * 6]; for (x = 0; x < this.count; x++) { faces[x * 6 + 0] = (short)(x * 4 + 0); faces[x * 6 + 1] = (short)(x * 4 + 1); faces[x * 6 + 2] = (short)(x * 4 + 2); faces[x * 6 + 3] = (short)(x * 4 + 0); faces[x * 6 + 4] = (short)(x * 4 + 2); faces[x * 6 + 5] = (short)(x * 4 + 3); } vertexData.vertexStart = 0; vertexData.vertexCount = nVertices; VertexDeclaration decl = vertexData.vertexDeclaration; VertexBufferBinding bind = vertexData.vertexBufferBinding; int offset = 0; offset += decl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Position).Size; this.vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer(decl.Clone(0), nVertices, BufferUsage.DynamicWriteOnly); bind.SetBinding(0, this.vertexBuffer); HardwareIndexBuffer indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer(IndexType.Size16, this.count * 6, BufferUsage.StaticWriteOnly); indexData.indexBuffer = indexBuffer; indexData.indexStart = 0; indexData.indexCount = this.count * 6; indexBuffer.WriteData(0, indexBuffer.Size, faces, true); faces = null; renderOperation.operationType = OperationType.TriangleList; renderOperation.indexData = indexData; renderOperation.vertexData = vertexData; renderOperation.useIndices = true; }
//MeshPtr CreateMesh(string Name, string Group, IndexData IndexDataArg, VertexData VertexDataArg, AxisAlignedBox BoundingBox) { // Mogre.Mesh Mesh = Mogre.MeshManager.Singleton.CreateManual(Name, Group,null); // SubMesh SubMesh = Mesh.CreateSubMesh(); // //Shallow copy the IndexBuffer argument into the SubMesh's indexData property // SubMesh.indexData.indexBuffer = IndexDataArg.indexBuffer; // SubMesh.indexData.indexCount = IndexDataArg.indexCount; // //Deep copy the VertexData argument into the Mesh's sharedVertexData // SubMesh.useSharedVertices = true; // Mesh.sharedVertexData = new VertexData(); // Mesh.sharedVertexData.vertexBufferBinding.SetBinding(0, VertexDataArg.vertexBufferBinding.GetBuffer(0)); // Mesh.sharedVertexData.vertexDeclaration = VertexDataArg.vertexDeclaration.Clone(); // Mesh.sharedVertexData.vertexCount = VertexDataArg.vertexCount; // Mesh._setBounds(BoundingBox); // Mesh.Load(); // return Mesh; //} unsafe static public void CreateSphere(string strName, float r, int nRings, int nSegments) { MeshPtr pSphere = Mogre.MeshManager.Singleton.CreateManual(strName, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME); SubMesh pSphereVertex = pSphere.CreateSubMesh(); pSphere.sharedVertexData = new VertexData(); VertexData vertexData = pSphere.sharedVertexData; // define the vertex format VertexDeclaration vertexDecl = vertexData.vertexDeclaration; uint currOffset = 0; // positions vertexDecl.AddElement(0, currOffset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION); currOffset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3); // normals vertexDecl.AddElement(0, currOffset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_NORMAL); currOffset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3); // two dimensional texture coordinates vertexDecl.AddElement(0, currOffset, VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES, 0); currOffset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT2); // allocate the vertex buffer vertexData.vertexCount = (uint)((nRings + 1) * (nSegments + 1)); HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager.Singleton.CreateVertexBuffer(vertexDecl.GetVertexSize(0), vertexData.vertexCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY, false); VertexBufferBinding binding = vertexData.vertexBufferBinding; binding.SetBinding(0, vBuf); float *pVertex = (float *)vBuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD); // allocate index buffer pSphereVertex.indexData.indexCount = (uint)(6 * nRings * (nSegments + 1)); pSphereVertex.indexData.indexBuffer = HardwareBufferManager.Singleton.CreateIndexBuffer(Mogre.HardwareIndexBuffer.IndexType.IT_16BIT, pSphereVertex.indexData.indexCount, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY, false); HardwareIndexBufferSharedPtr iBuf = pSphereVertex.indexData.indexBuffer; ushort *pIndices = (ushort *)iBuf.Lock(HardwareBuffer.LockOptions.HBL_DISCARD); float fDeltaRingAngle = (float)(Mogre.Math.PI / nRings); float fDeltaSegAngle = (float)(2 * Mogre.Math.PI / nSegments); ushort wVerticeIndex = 0; // Generate the group of rings for the sphere for (int ring = 0; ring <= nRings; ring++) { float r0 = r * Mogre.Math.Sin(ring * fDeltaRingAngle); float y0 = r * Mogre.Math.Cos(ring * fDeltaRingAngle); // Generate the group of segments for the current ring for (int seg = 0; seg <= nSegments; seg++) { float x0 = r0 * Mogre.Math.Sin(seg * fDeltaSegAngle); float z0 = r0 * Mogre.Math.Cos(seg * fDeltaSegAngle); // Add one vertex to the strip which makes up the sphere *pVertex++ = x0; *pVertex++ = y0; *pVertex++ = z0; Mogre.Vector3 vNormal = (new Mogre.Vector3(x0, y0, z0)).NormalisedCopy; *pVertex++ = vNormal.x; *pVertex++ = vNormal.y; *pVertex++ = vNormal.z; *pVertex++ = (float)seg / (float)nSegments; *pVertex++ = (float)ring / (float)nRings; if (ring != nRings) { // each vertex (except the last) has six indices pointing to it *pIndices++ = (ushort)(wVerticeIndex + nSegments + 1); *pIndices++ = wVerticeIndex; *pIndices++ = (ushort)(wVerticeIndex + nSegments); *pIndices++ = (ushort)(wVerticeIndex + nSegments + 1); *pIndices++ = (ushort)(wVerticeIndex + 1); *pIndices++ = wVerticeIndex; wVerticeIndex++; } } ; // end for seg } // end for ring // Unlock vBuf.Unlock(); iBuf.Unlock(); // Generate face list pSphereVertex.useSharedVertices = true; // the original code was missing this line: pSphere._setBounds(new AxisAlignedBox(new Mogre.Vector3(-r, -r, -r), new Mogre.Vector3(r, r, r)), false); pSphere._setBoundingSphereRadius(r); // this line makes clear the mesh is loaded (avoids memory leaks) pSphere.Load(); }
private void BuildVertexBuffer() { if (vertexData != null) { // if we already have a buffer, free the hardware buffer vertexData.vertexBufferBinding.GetBuffer(0).Dispose(); } // // create vertexData object // vertexData = new VertexData(); // // Set up the vertex declaration // VertexDeclaration vertexDecl = vertexData.vertexDeclaration; int currOffset = 0; // add position data vertexDecl.AddElement(0, currOffset, VertexElementType.Float3, VertexElementSemantic.Position); currOffset += VertexElement.GetTypeSize(VertexElementType.Float3); // add texture coords vertexDecl.AddElement(0, currOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0); currOffset += VertexElement.GetTypeSize(VertexElementType.Float2); // // create hardware vertex buffer // int innerVertexCount = numVerticesForPlane(-outerWaveDistance, outerWaveDistance, -outerWaveDistance, outerWaveDistance, innerMetersPerSample); int outerVertexCount = numVerticesForPlane(-outerViewDistance, outerViewDistance, -outerViewDistance, -outerWaveDistance, outerMetersPerSample) + numVerticesForPlane(-outerViewDistance, -outerWaveDistance, -outerWaveDistance, outerWaveDistance, outerMetersPerSample) + numVerticesForPlane(outerWaveDistance, outerViewDistance, -outerWaveDistance, outerWaveDistance, outerMetersPerSample) + numVerticesForPlane(-outerViewDistance, outerViewDistance, outerWaveDistance, outerViewDistance, outerMetersPerSample); vertexData.vertexCount = innerVertexCount + outerVertexCount; // create a new vertex buffer (based on current API) HardwareVertexBuffer vbuf = HardwareBufferManager.Instance.CreateVertexBuffer(vertexDecl.GetVertexSize(0), vertexData.vertexCount, BufferUsage.StaticWriteOnly, false); // get a reference to the vertex buffer binding VertexBufferBinding binding = vertexData.vertexBufferBinding; // bind the first vertex buffer binding.SetBinding(0, vbuf); // generate vertex data unsafe { // lock the vertex buffer IntPtr data = vbuf.Lock(BufferLocking.Discard); float *pData = (float *)data.ToPointer(); pData = fillVertexPlane(pData, -outerWaveDistance, outerWaveDistance, -outerWaveDistance, outerWaveDistance, innerMetersPerSample); pData = fillVertexPlane(pData, -outerViewDistance, outerViewDistance, -outerViewDistance, -outerWaveDistance, outerMetersPerSample); pData = fillVertexPlane(pData, -outerViewDistance, -outerWaveDistance, -outerWaveDistance, outerWaveDistance, outerMetersPerSample); pData = fillVertexPlane(pData, outerWaveDistance, outerViewDistance, -outerWaveDistance, outerWaveDistance, outerMetersPerSample); pData = fillVertexPlane(pData, -outerViewDistance, outerViewDistance, outerWaveDistance, outerViewDistance, outerMetersPerSample); // unlock the buffer vbuf.Unlock(); } // unsafe }
/// <summary> /// /// </summary> private unsafe void CreateGeometry() { int numVertices = this.Steps * this.Circles + 1; int numEule = 6 * this.Steps * (this.Circles - 1) + 3 * this.Steps; // Vertex buffers this.SubMesh.vertexData = new VertexData(); this.SubMesh.vertexData.vertexStart = 0; this.SubMesh.vertexData.vertexCount = (uint)numVertices; VertexDeclaration vdecl = this.SubMesh.vertexData.vertexDeclaration; VertexBufferBinding vbind = this.SubMesh.vertexData.vertexBufferBinding; uint offset = 0; vdecl.AddElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION); offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3); vdecl.AddElement(0, offset, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_TEXTURE_COORDINATES, 0); offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3); vdecl.AddElement(0, offset, VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES, 1); offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT2); vdecl.AddElement(0, offset, VertexElementType.VET_FLOAT1, VertexElementSemantic.VES_TEXTURE_COORDINATES, 2); offset += VertexElement.GetTypeSize(VertexElementType.VET_FLOAT1); _vertexBuffer = HardwareBufferManager.Singleton.CreateVertexBuffer(offset, (uint)numVertices, HardwareBuffer.Usage.HBU_DYNAMIC_WRITE_ONLY); vbind.SetBinding(0, _vertexBuffer); int[] indexBuffer = new int[numEule]; for (int k = 0; k < this.Steps; k++) { indexBuffer[k * 3] = 0; indexBuffer[k * 3 + 1] = k + 1; if (k != this.Steps - 1) { indexBuffer[k * 3 + 2] = k + 2; } else { indexBuffer[k * 3 + 2] = 1; } } for (int y = 0; y < this.Circles - 1; y++) { for (int x = 0; x < this.Steps; x++) { int twoface = (y * this.Steps + x) * 6 + 3 * this.Steps; int p0 = 1 + y * this.Steps + x; int p1 = 1 + y * this.Steps + x + 1; int p2 = 1 + (y + 1) * this.Steps + x; int p3 = 1 + (y + 1) * this.Steps + x + 1; if (x == this.Steps - 1) { p1 -= x + 1; p3 -= x + 1; } // First triangle indexBuffer[twoface + 2] = p0; indexBuffer[twoface + 1] = p1; indexBuffer[twoface + 0] = p2; // Second triangle indexBuffer[twoface + 5] = p1; indexBuffer[twoface + 4] = p3; indexBuffer[twoface + 3] = p2; } } // Prepare buffer for indices _indexBuffer = HardwareBufferManager.Singleton.CreateIndexBuffer(Mogre.HardwareIndexBuffer.IndexType.IT_32BIT, (uint)numEule, HardwareBuffer.Usage.HBU_STATIC, true); //for(int z = 0; z < indexBuffer.Length;z++) // LogManager.Singleton.Write("Index " + indexBuffer[z]); fixed(int *addr = &indexBuffer[0]) { _indexBuffer.WriteData(0, _indexBuffer.SizeInBytes, addr, true); } // Set index buffer for this submesh this.SubMesh.indexData.indexBuffer = _indexBuffer; this.SubMesh.indexData.indexStart = 0; this.SubMesh.indexData.indexCount = (uint)numEule; // Create our internal buffer for manipulations _vertices = new PosUVVertex[1 + this.Steps * this.Circles]; }
/// <summary> /// /// </summary> /// <param name="startPoint">Point where the line will start.</param> /// <param name="direction">The direction the vector is heading in.</param> /// <param name="length">The length (magnitude) of the line vector.</param> /// <param name="color">The color which this line should be.</param> public Line3d(Vector3 startPoint, Vector3 direction, float length, ColorEx color) { // normalize the direction vector to ensure all elements fall in [0,1] range. direction.Normalize(); // calculate the actual endpoint Vector3 endPoint = startPoint + (direction * length); vertexData = new VertexData(); vertexData.vertexCount = 2; vertexData.vertexStart = 0; VertexDeclaration decl = vertexData.vertexDeclaration; VertexBufferBinding binding = vertexData.vertexBufferBinding; // add a position and color element to the declaration decl.AddElement(POSITION, 0, VertexElementType.Float3, VertexElementSemantic.Position); decl.AddElement(COLOR, 0, VertexElementType.Color, VertexElementSemantic.Diffuse); // create a vertex buffer for the position HardwareVertexBuffer buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.GetVertexSize(POSITION), vertexData.vertexCount, BufferUsage.StaticWriteOnly); Vector3[] pos = new Vector3[] { startPoint, endPoint }; // write the data to the position buffer buffer.WriteData(0, buffer.Size, pos, true); // bind the position buffer binding.SetBinding(POSITION, buffer); // create a color buffer buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.GetVertexSize(COLOR), vertexData.vertexCount, BufferUsage.StaticWriteOnly); uint colorValue = Root.Instance.RenderSystem.ConvertColor(color); uint[] colors = new uint[] { colorValue, colorValue }; // write the data to the position buffer buffer.WriteData(0, buffer.Size, colors, true); // bind the color buffer binding.SetBinding(COLOR, buffer); // MATERIAL // grab a copy of the BaseWhite material for our use Material material = MaterialManager.Instance.GetByName("BaseWhite"); material = material.Clone("LineMat"); // disable lighting to vertex colors are used material.Lighting = false; // set culling to none so the triangle is drawn 2 sided material.CullingMode = CullingMode.None; this.Material = material; // set the bounding box of the line this.box = new AxisAlignedBox(startPoint, endPoint); }
public void Init(TerrainOptions options) { this.options = options; numMipMaps = options.maxMipmap; size = options.size; terrain = new VertexData(); terrain.vertexStart = 0; // Turbo: appended factor 3 // Not sure about that, but without that the terrain manager seems // to mess up memory because of buffer overruns //terrain.vertexCount = options.size * options.size; terrain.vertexCount = options.size * options.size * 3; VertexDeclaration decl = terrain.vertexDeclaration; VertexBufferBinding binding = terrain.vertexBufferBinding; int offset = 0; // Position/Normal decl.AddElement(POSITION, 0, VertexElementType.Float3, VertexElementSemantic.Position); decl.AddElement(NORMAL, 0, VertexElementType.Float3, VertexElementSemantic.Normal); // TexCoords decl.AddElement(TEXCOORD, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0); offset += VertexElement.GetTypeSize(VertexElementType.Float2); decl.AddElement(TEXCOORD, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 1); offset += VertexElement.GetTypeSize(VertexElementType.Float2); // TODO: Color HardwareVertexBuffer buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.GetVertexSize(POSITION), terrain.vertexCount, BufferUsage.StaticWriteOnly, true); binding.SetBinding(POSITION, buffer); buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl.GetVertexSize(NORMAL), terrain.vertexCount, BufferUsage.StaticWriteOnly, true); binding.SetBinding(NORMAL, buffer); buffer = HardwareBufferManager.Instance.CreateVertexBuffer( offset, terrain.vertexCount, BufferUsage.StaticWriteOnly, true); binding.SetBinding(TEXCOORD, buffer); minLevelDistSqr = new float[numMipMaps]; int endx = options.startx + options.size; int endz = options.startz + options.size; // TODO: name buffers different so we can unlock HardwareVertexBuffer posBuffer = binding.GetBuffer(POSITION); IntPtr pos = posBuffer.Lock(BufferLocking.Discard); HardwareVertexBuffer texBuffer = binding.GetBuffer(TEXCOORD); IntPtr tex = texBuffer.Lock(BufferLocking.Discard); float min = 99999999, max = 0; unsafe { float *posPtr = (float *)pos.ToPointer(); float *texPtr = (float *)tex.ToPointer(); int posCount = 0; int texCount = 0; for (int j = options.startz; j < endz; j++) { for (int i = options.startx; i < endx; i++) { float height = options.GetWorldHeight(i, j) * options.scaley; posPtr[posCount++] = (float)i * options.scalex; posPtr[posCount++] = height; posPtr[posCount++] = (float)j * options.scalez; texPtr[texCount++] = (float)i / (float)options.worldSize; texPtr[texCount++] = (float)j / (float)options.worldSize; texPtr[texCount++] = ((float)i / (float)options.size) * (float)options.detailTile; texPtr[texCount++] = ((float)j / (float)options.size) * (float)options.detailTile; if (height < min) { min = height; } if (height > max) { max = height; } } // for i } // for j } // unsafe // unlock the buffers posBuffer.Unlock(); texBuffer.Unlock(); box.SetExtents( new Vector3((float)options.startx * options.scalex, min, (float)options.startz * options.scalez), new Vector3((float)(endx - 1) * options.scalex, max, (float)(endz - 1) * options.scalez)); center = new Vector3((options.startx * options.scalex + endx - 1) / 2, (min + max) / 2, (options.startz * options.scalez + endz - 1) / 2); float C = CalculateCFactor(); CalculateMinLevelDist2(C); }