public void Define(Array controlPointArray, VertexDeclaration declaration, int width, int height, int uMaxSubdivisionLevel, int vMaxSubdivisionLevel, VisibleSide visibleSide, BufferUsage vbUsage, BufferUsage ibUsage, bool vbUseShadow, bool ibUseShadow) { VertexBufferUsage = vbUsage; UseVertexShadowBuffer = vbUseShadow; IndexBufferUsage = ibUsage; UseIndexShadowBuffer = ibUseShadow; // Init patch builder // define the surface // NB clone the declaration to make it independent this.vertexDeclaration = (VertexDeclaration)declaration.Clone(); this.patchSurface.DefineSurface(controlPointArray, this.vertexDeclaration, width, height, PatchSurfaceType.Bezier, uMaxSubdivisionLevel, vMaxSubdivisionLevel, visibleSide); }
// ------------------------------------ // ------------------------------------ /// <summary> /// Creates a new PatchMesh. /// </summary> /// <remarks> /// As defined in <see cref="MeshManager.CreateBezierPatch" />. /// </remarks> public PatchMesh(string name, System.Array controlPointBuffer, VertexDeclaration declaration, int width, int height, int uMaxSubdivisionLevel, int vMaxSubdivisionLevel, VisibleSide visibleSide, BufferUsage vbUsage, BufferUsage ibUsage, bool vbUseShadow, bool ibUseShadow) : base(name) { vertexBufferUsage = vbUsage; useVertexShadowBuffer = vbUseShadow; indexBufferUsage = ibUsage; useIndexShadowBuffer = ibUseShadow; // Init patch builder // define the surface // NB clone the declaration to make it independent vertexDeclaration = (VertexDeclaration)declaration.Clone(); patchSurface.DefineSurface(controlPointBuffer, vertexDeclaration, width, height, PatchSurfaceType.Bezier, uMaxSubdivisionLevel, vMaxSubdivisionLevel, visibleSide); }
/// <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; }
private void LoadLevelVertices(Quake3Level q3lvl) { //----------------------------------------------------------------------- // Vertices //----------------------------------------------------------------------- // Allocate memory for vertices & copy vertexData = new VertexData(); // Create vertex declaration VertexDeclaration decl = vertexData.vertexDeclaration; int offset = 0; int lightTexOffset = 0; decl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Position); offset += VertexElement.GetTypeSize(VertexElementType.Float3); decl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Normal); offset += VertexElement.GetTypeSize(VertexElementType.Float3); decl.AddElement(0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0); offset += VertexElement.GetTypeSize(VertexElementType.Float2); decl.AddElement(0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 1); // Build initial patches - we need to know how big the vertex buffer needs to be // to accommodate the subdivision // we don't want to include the elements for texture lighting, so we clone it InitQuake3Patches(q3lvl, (VertexDeclaration)decl.Clone()); // this is for texture lighting color and alpha decl.AddElement(1, lightTexOffset, VertexElementType.Color, VertexElementSemantic.Diffuse); lightTexOffset += VertexElement.GetTypeSize(VertexElementType.Color); // this is for texture lighting coords decl.AddElement(1, lightTexOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 2); // Create the vertex buffer, allow space for patches HardwareVertexBuffer vbuf = HardwareBufferManager.Instance.CreateVertexBuffer( Marshal.SizeOf(typeof(BspVertex)), q3lvl.NumVertices + patchVertexCount, BufferUsage.StaticWriteOnly, // the vertices will be read often for texture lighting, use shadow buffer true ); // Create the vertex buffer for texture lighting, allow space for patches HardwareVertexBuffer texLightBuf = HardwareBufferManager.Instance.CreateVertexBuffer( Marshal.SizeOf(typeof(TextureLightMap)), q3lvl.NumVertices + patchVertexCount, BufferUsage.DynamicWriteOnly, false ); // COPY static vertex data - Note that we can't just block-copy the vertex data because we have to reorder // our vertex elements; this is to ensure compatibility with older cards when using // hardware vertex buffers - Direct3D requires that the buffer format maps onto a // FVF in those older drivers. // Lock just the non-patch area for now. unsafe { BspVertex vert = new BspVertex(); TextureLightMap texLightMap = new TextureLightMap(); // Keep another base pointer for use later in patch building for (int v = 0; v < q3lvl.NumVertices; v++) { QuakeVertexToBspVertex(q3lvl.Vertices[v], out vert, out texLightMap); BspVertex * bvptr = | TextureLightMap *tlptr = &texLightMap; vbuf.WriteData( v * sizeof(BspVertex), sizeof(BspVertex), (IntPtr)bvptr ); texLightBuf.WriteData( v * sizeof(TextureLightMap), sizeof(TextureLightMap), (IntPtr)tlptr ); } } // Setup binding vertexData.vertexBufferBinding.SetBinding(0, vbuf); // Setup texture lighting binding vertexData.vertexBufferBinding.SetBinding(1, texLightBuf); // Set other data vertexData.vertexStart = 0; vertexData.vertexCount = q3lvl.NumVertices + patchVertexCount; }
public void Init(TerrainOptions options) { this.options = options; this.numMipMaps = options.maxMipmap; this.size = options.size; this.terrain = new VertexData(); this.terrain.vertexStart = 0; this.terrain.vertexCount = options.size * options.size; VertexDeclaration decl = this.terrain.vertexDeclaration; VertexBufferBinding binding = this.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.Clone(POSITION), this.terrain.vertexCount, BufferUsage.StaticWriteOnly, true); binding.SetBinding(POSITION, buffer); buffer = HardwareBufferManager.Instance.CreateVertexBuffer(decl.Clone(NORMAL), this.terrain.vertexCount, BufferUsage.StaticWriteOnly, true); binding.SetBinding(NORMAL, buffer); buffer = HardwareBufferManager.Instance.CreateVertexBuffer(decl.Clone(TEXCOORD), this.terrain.vertexCount, BufferUsage.StaticWriteOnly, true); binding.SetBinding(TEXCOORD, buffer); this.minLevelDistSqr = new float[this.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); var pos = posBuffer.Lock(BufferLocking.Discard); HardwareVertexBuffer texBuffer = binding.GetBuffer(TEXCOORD); var tex = texBuffer.Lock(BufferLocking.Discard); float min = 99999999, max = 0; #if !AXIOM_SAFE_ONLY unsafe #endif { var posPtr = pos.ToFloatPointer(); var texPtr = tex.ToFloatPointer(); 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++] = i * options.scalex; posPtr[posCount++] = height; posPtr[posCount++] = j * options.scalez; texPtr[texCount++] = (float)i / options.worldSize; texPtr[texCount++] = (float)j / options.worldSize; texPtr[texCount++] = ((float)i / options.size) * options.detailTile; texPtr[texCount++] = ((float)j / options.size) * options.detailTile; if (height < min) { min = height; } if (height > max) { max = height; } } // for i } // for j } // unsafe // unlock the buffers posBuffer.Unlock(); texBuffer.Unlock(); this.box.SetExtents(new Vector3(options.startx * options.scalex, min, options.startz * options.scalez), new Vector3((endx - 1) * options.scalex, max, (endz - 1) * options.scalez)); this.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); }