/// <summary> /// createGrassMesh2 /// This demonstrates how to use MeshBuilderHelper class. /// /// </summary> void createGrassMesh2() { mLog.LogMessage("createGrassMesh start"); OgreDotNet.MeshBuilderHelper mbh = new MeshBuilderHelper( GRASS_MESH_NAME, "General", false, 0, 12); UInt32 offPos = mbh.addElement(VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION).getOffset(); mLog.LogMessage(string.Format("createGrassMesh offPos={0}", offPos)); UInt32 offNorm = mbh.addElement(VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_NORMAL).getOffset(); mLog.LogMessage(string.Format("createGrassMesh offNorm={0}", offNorm)); UInt32 offUV = mbh.addElement(VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES).getOffset(); mLog.LogMessage(string.Format("createGrassMesh offUV={0}", offUV)); mbh.createVertexBuffer(12, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); Vector3 baseVec = new Vector3(GRASS_WIDTH / 2.0f, 0.0f, 0.0f); Vector3 vec = new Vector3(baseVec.x, baseVec.y, baseVec.z); Quaternion rot = Quaternion.FromAngleAxis(60, Vector3.UnitY); uint i; for (i = 0; i < 3; ++i) { mbh.setVertFloat((i * 4) + 0, offPos, -vec.x, GRASS_HEIGHT, -vec.z); //position mbh.setVertFloat((i * 4) + 0, offNorm, 0.0f, 1.0f, 0.0f); //normal mbh.setVertFloat((i * 4) + 0, offUV, 0.0f, 0.0f); //uv mbh.setVertFloat((i * 4) + 1, offPos, vec.x, GRASS_HEIGHT, vec.z); //position mbh.setVertFloat((i * 4) + 1, offNorm, 0.0f, 1.0f, 0.0f); //normal mbh.setVertFloat((i * 4) + 1, offUV, 1.0f, 0.0f); //uv mbh.setVertFloat((i * 4) + 2, offPos, -vec.x, 0.0f, -vec.z); //position mbh.setVertFloat((i * 4) + 2, offNorm, 0.0f, 1.0f, 0.0f); //normal mbh.setVertFloat((i * 4) + 2, offUV, 0.0f, 1.0f); //uv mbh.setVertFloat((i * 4) + 3, offPos, vec.x, 0.0f, vec.z); //position mbh.setVertFloat((i * 4) + 3, offNorm, 0.0f, 1.0f, 0.0f); //normal mbh.setVertFloat((i * 4) + 3, offUV, 1.0f, 1.0f); //uv vec = rot * vec; } mbh.createIndexBuffer(6, HardwareIndexBuffer.IndexType.IT_16BIT, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); for (i = 0; i < 3; ++i) { UInt16 off = (UInt16)(i * 4); mbh.setIndex16bit((i * 2) + 0, (UInt16)(0 + off), (UInt16)(3 + off), (UInt16)(1 + off)); mbh.setIndex16bit((i * 2) + 1, (UInt16)(0 + off), (UInt16)(2 + off), (UInt16)(3 + off)); } mbh.Load(GRASS_MATERIAL); mLog.LogMessage("createGrassMesh end"); }
protected void updateHardwareBuffers() { if (mChainElementList.Count < 2) { return; } // Here. we need to compute the position of the camera in the coordinate system of the billboard chain. Vector3 eyePos = this.ParentNode._getDerivedOrientation().Inverse() * (mCamera.GetDerivedPosition() - this.ParentNode._getDerivedPosition()); IntPtr ptrBuff; uint buffIdx = 0; int chainSize = mChainElementList.Count; mVD.vertexCount = (uint)chainSize * 2; // Setup the vertex coordinates HardwareVertexBufferSharedPtr pPosBuffer = mVD.vertexBufferBinding.getBuffer(POSITION_BINDING); ptrBuff = pPosBuffer.Get().Lock(HardwareBuffer.LockOptions.HBL_DISCARD); // Compute the position of the vertices in the chain for (int i = 0; i < chainSize; i++) { myBillBoardChainElement bbe = (myBillBoardChainElement)mChainElementList[i]; Vector3 chainTangent; if (i == 0) { chainTangent = bbe.position - ((myBillBoardChainElement)mChainElementList[0]).position; } else if (i == chainSize - 1) { chainTangent = ((myBillBoardChainElement)mChainElementList[chainSize - 1]).position - ((myBillBoardChainElement)mChainElementList[chainSize - 2]).position; } else { chainTangent = ((myBillBoardChainElement)mChainElementList[i + 1]).position - ((myBillBoardChainElement)mChainElementList[i - 1]).position; } Vector3 p1 = bbe.position; Vector3 vP1ToEye = eyePos - p1; Vector3 vPerpendicular = chainTangent.Cross(vP1ToEye); vPerpendicular.Normalize(); vPerpendicular *= bbe.width; Vector3 pos0 = p1 - vPerpendicular; Vector3 pos1 = p1 + vPerpendicular; // Update the buffer with the 2 vertex positions MeshBuilderHelper.SetVertexFloat(ptrBuff, mVBVertexSize, buffIdx++, mVBPostOff, pos0.x, pos0.y, pos0.z); MeshBuilderHelper.SetVertexFloat(ptrBuff, mVBVertexSize, buffIdx++, mVBPostOff, pos1.x, pos1.y, pos1.z); } pPosBuffer.Get().Unlock(); // Setup the diffuse color of the vertex HardwareVertexBufferSharedPtr pVertexColorBuffer = mVD.vertexBufferBinding.getBuffer(DIFFUSE_COLOR_BINDING); ptrBuff = pVertexColorBuffer.Get().Lock(HardwareBuffer.LockOptions.HBL_DISCARD); buffIdx = 0; for (int i = 0; i < chainSize; i++) { Color col = ((myBillBoardChainElement)mChainElementList[i]).colour; MeshBuilderHelper.SetVertexFloat(ptrBuff, mVCBVertexSize, buffIdx++, mVCBrgbaOff, ((float)col.R / 255.0f), ((float)col.G / 255.0f), ((float)col.B / 255.0f), ((float)col.A / 255.0f)); MeshBuilderHelper.SetVertexFloat(ptrBuff, mVCBVertexSize, buffIdx++, mVCBrgbaOff, ((float)col.R / 255.0f), ((float)col.G / 255.0f), ((float)col.B / 255.0f), ((float)col.A / 255.0f)); } pVertexColorBuffer.Get().Unlock(); // Setup the texture coordinates HardwareVertexBufferSharedPtr pTexCoordBuffer = mVD.vertexBufferBinding.getBuffer(TEXCOORD_BINDING); ptrBuff = pTexCoordBuffer.Get().Lock(HardwareBuffer.LockOptions.HBL_DISCARD); buffIdx = 0; for (int i = 0; i < chainSize; i++) { myBillBoardChainElement bbe = (myBillBoardChainElement)mChainElementList[i]; MeshBuilderHelper.SetVertexFloat(ptrBuff, mTCVertexSize, buffIdx++, mTCBuvOff, bbe.uTexCoord, 0.0f); MeshBuilderHelper.SetVertexFloat(ptrBuff, mTCVertexSize, buffIdx++, mTCBuvOff, bbe.uTexCoord, 1.0f); } pTexCoordBuffer.Get().Unlock(); }
public void drawLines() { //resizeing code adapted from //http://www.ogre3d.org/wiki/index.php/DynamicGrowingBuffers HardwareVertexBufferSharedPtr vbuf; uint newVertCapacity = mVertexBufferCapacity; if (!mDrawn) { mDrawn = true; mVertexBufferCapacity = 0; newVertCapacity = 1; // Make capacity the next power of two while (newVertCapacity < mPoints.Count) { newVertCapacity <<= 1; } mVertexBufferCapacity = newVertCapacity; // Initialization stuff this.RO_IndexData = null; this.RO_UseIndexes = false; mVD.vertexCount = (uint)mPoints.Count; mVD.vertexStart = 0; this.RO_OperationType = OperationType.OT_LINE_STRIP; // OT_LINE_LIST, OT_LINE_STRIP offPos = mVD.vertexDeclaration.addElement( POSITION_BINDING, 0, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION).getOffset(); mVertexSize = VertexElement.getTypeSize(VertexElementType.VET_FLOAT3); vbuf = HardwareBufferManager.getSingleton().createVertexBuffer( mVD.vertexDeclaration.getVertexSize(POSITION_BINDING), mVertexBufferCapacity, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); mVD.vertexBufferBinding.setBinding(POSITION_BINDING, vbuf); } if ((mPoints.Count > mVertexBufferCapacity) || (mVertexBufferCapacity == 0)) { // vertexCount exceeds current capacity! // It is necessary to reallocate the buffer. // Check if this is the first call... should never happen(we have mDrawn flag check) if (newVertCapacity == 0) { newVertCapacity = 1; } // Make capacity the next power of two while (newVertCapacity < mPoints.Count) { newVertCapacity <<= 1; } } else if (mPoints.Count < (mVertexBufferCapacity >> 1)) { // Make capacity the previous power of two while (mPoints.Count < (newVertCapacity >> 1)) { newVertCapacity >>= 1; } } if (newVertCapacity != mVertexBufferCapacity) { mVertexBufferCapacity = newVertCapacity; mVD.vertexCount = mVertexBufferCapacity; // Create new vertex buffer vbuf = HardwareBufferManager.getSingleton().createVertexBuffer( mVD.vertexDeclaration.getVertexSize(POSITION_BINDING), mVertexBufferCapacity, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); //the old buffer will automatically be deleted once no more references to it exist //http://www.ogre3d.org/phpBB2/viewtopic.php?t=13058&highlight=vertexbuffer+update // Bind buffer mVD.vertexBufferBinding.setBinding(POSITION_BINDING, vbuf); } else { //we need to set vbuf vbuf = mVD.vertexBufferBinding.getBuffer(POSITION_BINDING); } // Update vertex count in the render operation mVD.vertexCount = (uint)mPoints.Count; // Drawing stuff int size = mPoints.Count; Vector3 vaabMin = (Math3D.Vector3)mPoints[0]; Vector3 vaabMax = (Math3D.Vector3)mPoints[0]; IntPtr ptrBuff = vbuf.Get().Lock(HardwareBuffer.LockOptions.HBL_DISCARD); for (int i = 0; i < size; i++) { MeshBuilderHelper.SetVertexFloat(ptrBuff, mVertexSize, (uint)i, offPos, ((Math3D.Vector3)mPoints[i]).x, ((Math3D.Vector3)mPoints[i]).y, ((Math3D.Vector3)mPoints[i]).z); if (((Math3D.Vector3)mPoints[i]).x < vaabMin.x) { vaabMin.x = ((Math3D.Vector3)mPoints[i]).x; } if (((Math3D.Vector3)mPoints[i]).y < vaabMin.y) { vaabMin.y = ((Math3D.Vector3)mPoints[i]).y; } if (((Math3D.Vector3)mPoints[i]).z < vaabMin.z) { vaabMin.z = ((Math3D.Vector3)mPoints[i]).z; } if (((Math3D.Vector3)mPoints[i]).x > vaabMax.x) { vaabMax.x = ((Math3D.Vector3)mPoints[i]).x; } if (((Math3D.Vector3)mPoints[i]).y > vaabMax.y) { vaabMax.y = ((Math3D.Vector3)mPoints[i]).y; } if (((Math3D.Vector3)mPoints[i]).z > vaabMax.z) { vaabMax.z = ((Math3D.Vector3)mPoints[i]).z; } } vbuf.Get().Unlock(); AxisAlignedBox box = this.CallBase_getBoundingBox(); box.SetExtents(vaabMin, vaabMax); }
static void BuildPlaneMesh(string name, ushort pointsX, ushort pointsY) { MeshBuilderHelper mbh = new MeshBuilderHelper(name, "Terrrain", false, 0, (uint)(pointsY * pointsX)); UInt32 offPos = mbh.AddElement(VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION).Offset; mbh.CreateVertexBuffer(HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); /// // This function uses one big zigzag triangle strip for the whole grid. // And insert degenerated (invisible) triangles to join 2 rows. For instance: // 0 1 2 3 // 4 5 6 7 // 8 9 10 11 // 12 13 14 15 // // The index buffer would look like : // 0, 4, 1, 5, 2, 6, 3, 7, 7, 7, 11, 6, 10, 5, 9, 4, 8, 8, 8, 12, 9, 13, 10, 14, 11, 15 /// uint vertexindex = 0; for (int y = pointsY - 1; y >= 0; y--) { for (int x = 0; x <= pointsX - 1; x++) { mbh.SetVertFloat(vertexindex, offPos, x, y, 0.0f); //position //mbh.SetVertFloat(vertexindex, offColor, 0, 0, 1); vertexindex++; } } mbh.CreateIndexBufferForTriStrip((uint)(pointsX * 2 * (pointsY - 1) + pointsY - 2), HardwareIndexBuffer.IndexType.IT_16BIT, HardwareBuffer.Usage.HBU_STATIC_WRITE_ONLY); for (ushort y = 0; y < pointsY - 1; y++) { if (y % 2 == 0) { for (int x = 0; x < pointsX; x++) { mbh.Index16bit(((ushort)(y * pointsX + x))); //(x, y + 1, 0.0f); mbh.Index16bit((ushort)(y * pointsX + x + pointsX)); //(x, y, 0.0f); } if (y != pointsY - 2) { mbh.Index16bit(((ushort)(y * pointsX + pointsX - 1))); //(0, y+1, 0.0f); } } else { for (int x = pointsX - 1; x >= 0; x--) { mbh.Index16bit((ushort)(y * pointsX + x)); //(x, y + 1, 0.0f); mbh.Index16bit((ushort)(y * pointsX + x + pointsX)); //(x, y, 0.0f); } if (y != pointsY - 2) { mbh.Index16bit((ushort)(y * pointsX + pointsX)); } } } MeshPtr m = mbh.Load("Terrain/Terrain_Material"); m._setBounds(new AxisAlignedBox(0.0f, 0.0f, 0.0f, pointsX - 1, pointsY - 1, 10.0f), false); }