/* * We need this because we draw a head and a body, which requires two vertex buffers to do. */ public override void Render(Device device) { // Draw head first List <Vector2> vertices = verticesMHead; // Ensure we have at least a triangle if (vertices.Count >= 3) { // Ensure the number of vertices and textures are the same System.Diagnostics.Debug.Assert(textureCHead.Count == vertices.Count); if (verticesVHead == null) { verticesVHead = new VertexBuffer(typeof(CustomVertex.PositionColoredTextured), // Type vertices.Count, // How many device, // What device 0, // No special usage CustomVertex.PositionColoredTextured.Format, Pool.Managed); } GraphicsStream gs = verticesVHead.Lock(0, 0, 0); // Lock the background vertex list int clr = color.ToArgb(); for (int i = 0; i < vertices.Count; i++) { Vector2 v = vertices[i]; Vector2 t = textureCHead[i]; gs.Write(new CustomVertex.PositionColoredTextured(v.X, v.Y, 0, clr, t.X, t.Y)); } verticesVHead.Unlock(); if (transparent) { device.RenderState.AlphaBlendEnable = true; device.RenderState.SourceBlend = Blend.SourceAlpha; device.RenderState.DestinationBlend = Blend.InvSourceAlpha; } device.SetTexture(0, texture); device.SetStreamSource(0, verticesVHead, 0); device.VertexFormat = CustomVertex.PositionColoredTextured.Format; device.DrawPrimitives(PrimitiveType.TriangleFan, 0, vertices.Count - 2); device.SetTexture(0, null); if (transparent) { device.RenderState.AlphaBlendEnable = false; } } //Now the body vertices = verticesMBody; // Ensure we have at least a triangle if (vertices.Count >= 3) { // Ensure the number of vertices and textures are the same System.Diagnostics.Debug.Assert(textureCBody.Count == vertices.Count); if (verticesVBody == null) { verticesVBody = new VertexBuffer(typeof(CustomVertex.PositionColoredTextured), // Type vertices.Count, // How many device, // What device 0, // No special usage CustomVertex.PositionColoredTextured.Format, Pool.Managed); } GraphicsStream gs = verticesVBody.Lock(0, 0, 0); // Lock the background vertex list int clr = color.ToArgb(); for (int i = 0; i < vertices.Count; i++) { Vector2 v = vertices[i]; Vector2 t = textureCBody[i]; gs.Write(new CustomVertex.PositionColoredTextured(v.X, v.Y, 0, clr, t.X, t.Y)); } verticesVBody.Unlock(); if (transparent) { device.RenderState.AlphaBlendEnable = true; device.RenderState.SourceBlend = Blend.SourceAlpha; device.RenderState.DestinationBlend = Blend.InvSourceAlpha; } device.SetTexture(0, texture); device.SetStreamSource(0, verticesVBody, 0); device.VertexFormat = CustomVertex.PositionColoredTextured.Format; device.DrawPrimitives(PrimitiveType.TriangleFan, 0, vertices.Count - 2); device.SetTexture(0, null); if (transparent) { device.RenderState.AlphaBlendEnable = false; } } }
public override void CreateGeometryForObjects(Device device, ICollection <IAtom> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { // fillable fields int positionPos = -1; int normalPos = -1; int diffusePos = -1; // match field locations for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") { positionPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "NORMAL") { normalPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "DIFFUSE") { diffusePos = geomStream.FieldPositions[gf]; } break; } } } // actually create the metaball triangles or points IVolume[] volumes = new IVolume[objs.Count]; int sIdx = 0; AtomShadingDesc aShading = coDesc.AtomShadingDesc; IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; foreach (IAtom atom in objs) { IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); IMoleculeMaterial material = null; if (matTemp != null) { material = matTemp.BySymbol; } else { PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; if (pe != null) { material = lookup.GetBySeries(pe.ChemicalSerie); } } volumes[sIdx++] = new Metaball(new Vector3((float)atom.X3d, (float)atom.Y3d, (float)atom.Z3d), 0.17f, material.BaseColor); } // process volume into triangles GenericVolumeScene scene = new GenericVolumeScene(volumes); int[] triangles = null; Vector3[] vertices; Color[] colours; Vector3[] normals = null; if (!pointsOnly) { IsosurfaceGenerator3D.GenerateSimpleMesh(scene, new Vector3(), scene.EstimateVolumeMaxSize(), 40, false, out triangles, out vertices, out colours); MeshOptimzer.GenerateTriPointNormals(triangles, vertices, out normals); } else { IsosurfaceGenerator3D.GenerateSimplePointOutline(scene, new Vector3(), scene.EstimateVolumeMaxSize(), 40, out vertices, out colours); } // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Buffer = new VertexBuffer(device, geomStream.Stride * vertices.Length, Usage.WriteOnly, geomStream.Format, Pool.Managed); buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = vertices.Length; buffer.vBuffers[0].Format = geomStream.Format; buffer.iBuffers = new BufferedGeometryData.IndexData[1]; buffer.iBuffers[0] = new BufferedGeometryData.IndexData(); buffer.iBuffers[0].Desc = BufferedGeometryData.IndexData.Description.Geometry; if (pointsOnly) { buffer.iBuffers[0].NumPrimitives = vertices.Length; buffer.iBuffers[0].PrimType = PrimitiveType.PointList; buffer.Light = false; } else { buffer.iBuffers[0].NumPrimitives = triangles.Length / 3; buffer.iBuffers[0].PrimType = PrimitiveType.TriangleList; buffer.iBuffers[0].Buffer = new IndexBuffer(typeof(int), triangles.Length, device, Usage.WriteOnly, Pool.Managed); } // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); // fill fields int clr = Color.FromArgb(255, 255, 255).ToArgb(); long pos = 0; for (int i = 0; i < vertices.Length; i++) { if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(vertices[i].X); data.Write(vertices[i].Y); data.Write(vertices[i].Z); } if (normalPos != -1 && !pointsOnly) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(normals[i].X); data.Write(normals[i].Y); data.Write(normals[i].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(colours[i].ToArgb()); } //verts[i].Color = colours[i].ToArgb(); pos += geomStream.Stride; } buffer.vBuffers[0].Buffer.Unlock(); if (!pointsOnly) { buffer.iBuffers[0].Buffer.SetData(triangles, 0, LockFlags.None); } // dispose of temp data }
/// <summary> /// 頂点をDirect3Dバッファに書き込みます。 /// </summary> /// <param name="device">device</param> public void WriteBuffer(Device device) { int numVertices = vertices.Length; int numFaces = numVertices - 2; if (dm != null) { dm.Dispose(); dm = null; } dm = new Mesh(numFaces, numVertices, MeshFlags.Managed | MeshFlags.WriteOnly, ve, device); // // rewrite vertex buffer // { GraphicsStream gs = dm.LockVertexBuffer(LockFlags.None); { for (int i = 0; i < vertices.Length; i++) { Vertex v = vertices[i]; gs.Write(v.position); for (int j = 0; j < 4; j++) { gs.Write(v.skin_weights[j].weight); } gs.Write(v.bone_indices); gs.Write(v.normal); gs.Write(v.u); gs.Write(v.v); } } dm.UnlockVertexBuffer(); } // // rewrite index buffer // { GraphicsStream gs = dm.LockIndexBuffer(LockFlags.None); { for (int i = 2; i < vertices.Length; i++) { if (i % 2 != 0) { gs.Write((short)(i - 0)); gs.Write((short)(i - 1)); gs.Write((short)(i - 2)); } else { gs.Write((short)(i - 2)); gs.Write((short)(i - 1)); gs.Write((short)(i - 0)); } } } dm.UnlockIndexBuffer(); } // // rewrite attribute buffer // { dm.SetAttributeTable(new AttributeRange[] { ar }); } }
protected void BlitFromMemoryImpl(PixelBox src, BasicBox dstBox) { // TODO: This currently does way too many copies. We copy // from src to a converted buffer (if needed), then from // converted to a byte array, then into the temporary surface, // and finally from the temporary surface to the real surface. PixelBox converted = src; IntPtr bufPtr = IntPtr.Zero; GCHandle bufGCHandle = new GCHandle(); // convert to pixelbuffer's native format if necessary if (D3DHelper.ConvertEnum(src.Format) == D3D.Format.Unknown) { int bufSize = PixelUtil.GetMemorySize(src.Width, src.Height, src.Depth, format); byte[] newBuffer = new byte[bufSize]; bufGCHandle = GCHandle.Alloc(newBuffer, GCHandleType.Pinned); bufPtr = bufGCHandle.AddrOfPinnedObject(); converted = new PixelBox(src.Width, src.Height, src.Depth, format, bufPtr); PixelUtil.BulkPixelConversion(src, converted); } // int formatBytes = PixelUtil.GetNumElemBytes(converted.Format); Surface tmpSurface = device.CreateOffscreenPlainSurface(converted.Width, converted.Height, D3DHelper.ConvertEnum(converted.Format), Pool.Scratch); int pitch; // Ideally I would be using the Array mechanism here, but that doesn't seem to work GraphicsStream buf = tmpSurface.LockRectangle(LockFlags.NoSystemLock, out pitch); buf.Position = 0; unsafe { int bufSize = PixelUtil.GetMemorySize(converted.Width, converted.Height, converted.Depth, converted.Format); byte * srcPtr = (byte *)converted.Data.ToPointer(); byte[] ugh = new byte[bufSize]; for (int i = 0; i < bufSize; ++i) { ugh[i] = srcPtr[i]; } buf.Write(ugh); } tmpSurface.UnlockRectangle(); buf.Dispose(); //ImageInformation imageInfo = new ImageInformation(); //imageInfo.Format = D3DHelper.ConvertEnum(converted.Format); //imageInfo.Width = converted.Width; //imageInfo.Height = converted.Height; //imageInfo.Depth = converted.Depth; if (surface != null) { // I'm trying to write to surface using the data in converted Rectangle srcRect = ToD3DRectangleExtent(converted); Rectangle destRect = ToD3DRectangle(dstBox); SurfaceLoader.FromSurface(surface, destRect, tmpSurface, srcRect, Filter.None, 0); } else { D3D.Box srcBox = ToD3DBoxExtent(converted); D3D.Box destBox = ToD3DBox(dstBox); Debug.Assert(false, "Volume textures not yet supported"); // VolumeLoader.FromStream(volume, destBox, converted.Data, converted.RowPitch * converted.SlicePitch * formatBytes, srcBox, Filter.None, 0); VolumeLoader.FromStream(volume, destBox, buf, srcBox, Filter.None, 0); } tmpSurface.Dispose(); // If we allocated a buffer for the temporary conversion, free it here // If I used bufPtr to store my temporary data while I converted // it, I need to free it here. This invalidates converted. // My data has already been copied to tmpSurface and then to the // real surface. if (bufGCHandle.IsAllocated) { bufGCHandle.Free(); } if (doMipmapGen) { GenMipmaps(); } }
public override void CreateGeometryForObjects(Device device, ICollection <IAtom> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { // fillable fields int positionPos = -1; int normalPos = -1; int diffusePos = -1; int texPos = -1; // match field locations //int[] fieldsPos = new int[fields.Length]; for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") { positionPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "NORMAL") { normalPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "DIFFUSE") { diffusePos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "TEXTURE0") { texPos = geomStream.FieldPositions[gf]; } //fieldsPos[i] = geomStream.FieldPositions[gf]; break; } } } int numVerts = sphereDetail1 * sphereDetail2 * 6; int numTris = sphereDetail1 * sphereDetail2 * 2; // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Buffer = new VertexBuffer(device, geomStream.Stride * numVerts * objs.Count, Usage.WriteOnly, geomStream.Format, Pool.Managed); buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = objs.Count * numVerts; buffer.vBuffers[0].Format = geomStream.Format; buffer.iBuffers = new BufferedGeometryData.IndexData[1]; buffer.iBuffers[0] = new BufferedGeometryData.IndexData(); buffer.iBuffers[0].Desc = BufferedGeometryData.IndexData.Description.Geometry; buffer.iBuffers[0].NumPrimitives = objs.Count * numTris; buffer.iBuffers[0].PrimType = PrimitiveType.TriangleList; // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); // fill fields bool newWay = true; if (!newWay) { // create template sphere SphereMathHelper.SphereN sphere = SphereMathHelper.CalcSphereWNormals(sphereDetail1, sphereDetail2, 1.0f, new Vector3(), true); // clone and scale template for each size required Vector3 center = new Vector3(); Dictionary <int, Vector3[]> spheres = new Dictionary <int, Vector3[]>(); AtomShadingDesc aShading = coDesc.AtomShadingDesc; //int vertsIdx = 0; long pos = 0; foreach (IAtom atom in objs) { int period = 1; if (atom.Properties.ContainsKey("Period")) { period = (int)atom.Properties["Period"]; } // check for existing if (!spheres.ContainsKey(period)) { // scale template float size = period * _Scaling; Vector4[] vertices = Vector3.Transform(sphere.Positions, Matrix.Scaling(size, size, size)); Vector3[] vertices3 = new Vector3[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { vertices3[i] = new Vector3(vertices[i].X, vertices[i].Y, vertices[i].Z); } spheres.Add(period, vertices3); } Vector3[] sphereData = spheres[period]; // write to buffer IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); IMoleculeMaterial material = null; if (matTemp != null) { material = matTemp.BySymbol; } else { PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; if (pe != null) { material = lookup.GetBySeries(pe.ChemicalSerie); } } // copy sphere Vector3 atomSpace = new Vector3((float)atom.X3d, (float)atom.Y3d, (float)atom.Z3d); /*Vector4 clr = new Vector4((float)material.BaseColor.R / 255f, (float)material.BaseColor.G / 255f, * (float)material.BaseColor.B / 255f, (float)material.BaseColor.A / 255f);*/ int clr = material.BaseColor.ToArgb(); for (int v = 0; v < sphereData.Length; v++) { if (positionPos != -1) { Vector3 position = sphereData[v] + atomSpace; data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(position.X); data.Write(position.Y); data.Write(position.Z); } if (texPos != -1) { data.Seek(pos + texPos, SeekOrigin.Begin); data.Write(0f); //sphere.TexCoords[v].X); data.Write(0f); //sphere.TexCoords[v].Y); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(sphere.Normals[v].X); data.Write(sphere.Normals[v].Y); data.Write(sphere.Normals[v].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); /*data.Write(clr.X); * data.Write(clr.Y); * data.Write(clr.Z); * data.Write(clr.W);*/ data.Write((Int32)clr); } pos += geomStream.Stride; } } } else { Vector3[] Positions, normals; Vector2[] texCoords; SphereMathHelper.CreateSphereTriangles(new Vector3(), 1, sphereDetail1, out Positions, out normals, out texCoords); // clone and scale template for each size required Vector3 center = new Vector3(); Dictionary <int, Vector3[]> spheres = new Dictionary <int, Vector3[]>(); AtomShadingDesc aShading = coDesc.AtomShadingDesc; int vertsIdx = 0; long pos = 0; foreach (IAtom atom in objs) { int period = 1; if (atom.Properties.ContainsKey("Period")) { period = (int)atom.Properties["Period"]; } // check for existing if (!spheres.ContainsKey(period)) { // scale template float size = period * _Scaling; Vector4[] vertices = Vector3.Transform(Positions, Matrix.Scaling(size, size, size)); Vector3[] vertices3 = new Vector3[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { vertices3[i] = new Vector3(vertices[i].X, vertices[i].Y, vertices[i].Z); } spheres.Add(period, vertices3); } Vector3[] sphereData = spheres[period]; // write to buffer IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); IMoleculeMaterial material = null; if (matTemp != null) { material = matTemp.BySymbol; } else { PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; if (pe != null) { material = lookup.GetBySeries(pe.ChemicalSerie); } } // copy sphere Vector3 atomSpace = new Vector3((float)atom.X3d, (float)atom.Y3d, (float)atom.Z3d); int clr = material.BaseColor.ToArgb(); for (int v = 0; v < sphereData.Length; v++) { if (positionPos != -1) { Vector3 position = sphereData[v] + atomSpace; data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(position.X); data.Write(position.Y); data.Write(position.Z); } if (texPos != -1) { data.Seek(pos + texPos, SeekOrigin.Begin); data.Write(texCoords[v].X); data.Write(texCoords[v].Y); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(normals[v].X); data.Write(normals[v].Y); data.Write(normals[v].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); /*data.Write(clr.X); * data.Write(clr.Y); * data.Write(clr.Z); * data.Write(clr.W);*/ data.Write((Int32)clr); } pos += geomStream.Stride; } } } buffer.vBuffers[0].Buffer.Unlock(); }
/// <summary> /// Initialized the vertex & index buffers for this mesh scene /// </summary> public void ReInitialize() { if (m_noTexturing) { ReInitializeWithoutTexturing(); return; } // prepare vars m_coloredTrifans.Clear(); m_texturedTrifans.Clear(); // loop through the texturing info and determine for each of them what // type of decoration it is. m_decorations = new MeshDecoration[m_simpleMesh.TextureInfo.Length]; m_textures = new Texture[m_decorations.Length]; for (int i = 0; i < m_decorations.Length; i++) { m_decorations[i] = new MeshDecoration(m_simpleMesh.TextureInfo[i]); if (m_decorations[i].DecorationType == DecorationType.Texture) { Bitmap bmp = m_decorations[i].Texture.GetBitmap(); m_textures[i] = new Texture(m_device, bmp, 0, Pool.Managed); } } // we'll have to create two sets of index buffers: // one for textured trifans and one for colored trifans // we'll have to determine for each trifan to which of these it belongs List <VertexLookup> texturedVertexTable = new List <VertexLookup>(); List <VertexLookup> coloredVertexTable = new List <VertexLookup>(); List <ushort> texturedIndexList = new List <ushort>(); List <ushort> coloredIndexList = new List <ushort>(); for (int i = 0; i < (int)m_simpleMesh.SecondTrifanSet.TrifanCount; i++) { TrifanInfo trifan = m_simpleMesh.SecondTrifanSet.TrifanData[i]; bool drawSolidColor = false; drawSolidColor = (trifan.Flags & 0x04) == 0x04; // draw solid when this trifan is drawn using a solid color drawSolidColor = drawSolidColor || (m_decorations[(int)trifan.TextureIndex].DecorationType == DecorationType.SolidColor); if (drawSolidColor) { Color color = m_decorations[(int)trifan.TextureIndex].SolidColor; TrifanDrawInfo trifanInfo = new TrifanDrawInfo(); trifanInfo.IndexBufferStart = (ushort)coloredIndexList.Count; trifanInfo.PrimitiveCount = trifan.VertexCount - 2; for (int j = 0; j < trifan.VertexIndices.Length; j++) { VertexLookup lookup = new VertexLookup(trifan.VertexIndices[j], 0, color); ushort vertexIndex; if (!coloredVertexTable.Contains(lookup)) { coloredVertexTable.Add(lookup); } vertexIndex = (ushort)coloredVertexTable.IndexOf(lookup); coloredIndexList.Add(vertexIndex); } m_coloredTrifans.Add(i, trifanInfo); } else { TrifanDrawInfo trifanInfo = new TrifanDrawInfo(); trifanInfo.IndexBufferStart = (ushort)texturedIndexList.Count; trifanInfo.PrimitiveCount = trifan.VertexCount - 2; for (int j = 0; j < trifan.VertexIndices.Length; j++) { VertexLookup lookup = new VertexLookup(trifan.VertexIndices[j], trifan.UVIndex[j]); ushort vertexIndex; if (!texturedVertexTable.Contains(lookup)) { texturedVertexTable.Add(lookup); } vertexIndex = (ushort)texturedVertexTable.IndexOf(lookup); texturedIndexList.Add(vertexIndex); } m_texturedTrifans.Add(i, trifanInfo); } } // now create the actual index & vertex buffers // texture vb & ib if (texturedVertexTable.Count > 0) { m_vbTextured = new VertexBuffer(typeof(CustomVertex.PositionNormalTextured), texturedVertexTable.Count, m_device, Usage.WriteOnly, CustomVertex.PositionNormalTextured.Format, Pool.Managed); GraphicsStream stream = m_vbTextured.Lock(0, 0, LockFlags.None); foreach (VertexLookup lookup in texturedVertexTable) { VertexInfo vertex = m_simpleMesh.VertexInfo[(int)lookup.VertexId]; stream.Write(new CustomVertex.PositionNormalTextured(vertex.X, vertex.Y, vertex.Z, vertex.NX, vertex.NY, vertex.NZ, vertex.CUVData[lookup.UVIndex].U, vertex.CUVData[lookup.UVIndex].V)); } m_vbTextured.Unlock(); m_ibTextured = new IndexBuffer(typeof(ushort), texturedIndexList.Count, m_device, Usage.WriteOnly, Pool.Managed); stream = m_ibTextured.Lock(0, 0, LockFlags.None); stream.Write(texturedIndexList.ToArray()); m_ibTextured.Unlock(); } m_vbTexturedLength = texturedVertexTable.Count; // color vb & ib if (coloredVertexTable.Count > 0) { m_vbColored = new VertexBuffer(typeof(CustomVertex.PositionNormalColored), coloredVertexTable.Count, m_device, Usage.WriteOnly, CustomVertex.PositionNormalColored.Format, Pool.Managed); GraphicsStream stream = m_vbColored.Lock(0, 0, LockFlags.None); foreach (VertexLookup lookup in coloredVertexTable) { VertexInfo vertex = m_simpleMesh.VertexInfo[(int)lookup.VertexId]; stream.Write(new CustomVertex.PositionNormalColored(vertex.X, vertex.Y, vertex.Z, vertex.NX, vertex.NY, vertex.NZ, lookup.Color.ToArgb())); } m_vbColored.Unlock(); m_ibColored = new IndexBuffer(typeof(ushort), coloredIndexList.Count, m_device, Usage.WriteOnly, Pool.Managed); stream = m_ibColored.Lock(0, 0, LockFlags.None); stream.Write(coloredIndexList.ToArray()); m_ibColored.Unlock(); } m_vbColoredLength = coloredVertexTable.Count; }
private void DrawSolidBondDistinct(Vector3[] tCylinderPoints, Vector3[] tCylinderNormals, int[] tCylinderTris, IMoleculeMaterial matA, IMoleculeMaterial matB, Matrix final, GraphicsStream data, float xyScale, float bLen2, Matrix rotation, Vector3 bondInstance1, Vector3 directionUV, float midPos, int positionPos, int normalPos, int diffusePos, ref long pos, int stride) { // side 1 Vector4[] tfTriangles = Vector3.Transform(tCylinderPoints, final); //Vector4[] rtNormals = Vector3.Transform(tCylinderNormals, rotation); for (int point = 0; point < tCylinderTris.Length; point++) { int pointIdx = tCylinderTris[point]; if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(tfTriangles[pointIdx].X); data.Write(tfTriangles[pointIdx].Y); data.Write(tfTriangles[pointIdx].Z); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(tCylinderNormals[pointIdx].X); data.Write(tCylinderNormals[pointIdx].Y); data.Write(tCylinderNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal = new Vector3(rtNormals[pointIdx].X, // rtNormals[pointIdx].Y, // rtNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal.Normalize(); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(matA.BaseColor.ToArgb()); } pos += stride; } // side 2 final = Matrix.Scaling(xyScale, xyScale, bLen2) * rotation * Matrix.Translation(bondInstance1 + (directionUV * midPos)); tfTriangles = Vector3.Transform(tCylinderPoints, final); for (int point = 0; point < tCylinderTris.Length; point++) { int pointIdx = tCylinderTris[point]; if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(tfTriangles[pointIdx].X); data.Write(tfTriangles[pointIdx].Y); data.Write(tfTriangles[pointIdx].Z); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(tCylinderNormals[pointIdx].X); data.Write(tCylinderNormals[pointIdx].Y); data.Write(tCylinderNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal = new Vector3(rtNormals[pointIdx].X, // rtNormals[pointIdx].Y, // rtNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal.Normalize(); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(matB.BaseColor.ToArgb()); } pos += stride; } }
public override void CreateGeometryForObjects(Device device, ICollection <IAtom> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { if (spriteTexture == null) { Stream texstm = Assembly.GetExecutingAssembly().GetManifestResourceStream("NuGenSVisualLib.Resources.Atom.PNG"); spriteTexture = TextureLoader.FromStream(device, texstm); } // fillable fields int positionPos = -1; int sizePos = -1; int diffusePos = -1; // match field locations for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") { positionPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "DIFFUSE") { diffusePos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "POINTSIZE") { sizePos = geomStream.FieldPositions[gf]; } break; } } } // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Buffer = new VertexBuffer(typeof(PointSprite), objs.Count, device, Usage.WriteOnly, geomStream.Format, Pool.Managed); /*new VertexBuffer(device, geomStream.Stride * objs.Count, * Usage.None, geomStream.Format, Pool.Managed);*/ buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = objs.Count; buffer.vBuffers[0].Format = geomStream.Format; buffer.iBuffers = new BufferedGeometryData.IndexData[1]; buffer.iBuffers[0] = new BufferedGeometryData.IndexData(); buffer.iBuffers[0].Desc = BufferedGeometryData.IndexData.Description.Sprites; buffer.iBuffers[0].NumPrimitives = objs.Count; buffer.iBuffers[0].PrimType = PrimitiveType.PointList; buffer.iBuffers[0].Textures = new Texture[] { spriteTexture }; // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); AtomShadingDesc aShading = coDesc.AtomShadingDesc; long pos = 0; foreach (IAtom atom in objs) { if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write((float)atom.X3d); data.Write((float)atom.Y3d); data.Write((float)atom.Z3d); } if (sizePos != -1) { data.Seek(pos + sizePos, SeekOrigin.Begin); int period = 1; if (atom.Properties.ContainsKey("Period")) { period = (int)atom.Properties["Period"]; } data.Write((float)period * 0.4f); } if (diffusePos != -1) { IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); IMoleculeMaterial material = null; if (matTemp != null) { material = matTemp.BySymbol; } else { PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; if (pe != null) { material = lookup.GetBySeries(pe.ChemicalSerie); } } data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(material.BaseColor.ToArgb()); } pos += geomStream.Stride; } /*Dictionary<int, List<int>> atomSizeGroups = new Dictionary<int, List<int>>(); * // first split into group counts * int aIdx = 0; * foreach (IAtom[] atoms in atomSets) * { * foreach (IAtom atom in atoms) * { * int period = 1; * if (atom.Properties.ContainsKey("Period")) * period = (int)atom.Properties["Period"]; * * List<int> groupAtoms = null; * if (!atomSizeGroups.TryGetValue(period, out groupAtoms)) * atomSizeGroups.Add(period, groupAtoms = new List<int>()); * * groupAtoms.Add(aIdx++); * } * } * * int vertsIdx = 0; * Dictionary<int, List<int>>.Enumerator group = atomSizeGroups.GetEnumerator(); * sBuffer.groupLengths = new int[atomSizeGroups.Count]; * sBuffer.groupSizes = new int[atomSizeGroups.Count]; * sBuffer.groupStarts = new int[atomSizeGroups.Count]; * int bIdx = 0; * while (group.MoveNext()) * { * int groupPeriod = group.Current.Key; * List<int> groupMembers = group.Current.Value; * aIdx = 0; * int gIdx = 0; * sBuffer.groupSizes[bIdx] = groupPeriod; * sBuffer.groupStarts[bIdx] = vertsIdx; * sBuffer.groupLengths[bIdx] = groupMembers.Count; * foreach (IAtom[] atoms in atomSets) * { * foreach (IAtom atom in atoms) * { * if (aIdx == groupMembers[gIdx]) * { * IMoleculeMaterialLookup lookup = aShading.MoleculeMaterials; * IMoleculeMaterialTemplate matTemp = lookup.ResolveBySymbol(atom.Symbol); * IMoleculeMaterial material = null; * if (matTemp != null) * material = matTemp.BySymbol; * else * { * PeriodicTableElement pe = (PeriodicTableElement)atom.Properties["PeriodicTableElement"]; * if (pe != null) * material = lookup.GetBySeries(pe.ChemicalSerie); * } * * atomVerts[vertsIdx].Position = new Vector3((float)atom.X3d, (float)atom.Y3d, (float)atom.Z3d); * atomVerts[vertsIdx].Color = material.BaseColor.ToArgb(); * vertsIdx++; * gIdx++; * } * if (gIdx == groupMembers.Count) * break; * aIdx++; * } * if (gIdx == groupMembers.Count) * break; * } * bIdx++; * }*/ buffer.vBuffers[0].Buffer.Unlock(); }
/// <summary> /// Convierte el box en un TgcMesh /// </summary> /// <param name="meshName">Nombre de la malla que se va a crear</param> public TgcMesh toMesh(string meshName) { Device d3dDevice = GuiController.Instance.D3dDevice; //Obtener matriz para transformar vertices if (autoTransformEnable) { this.transform = Matrix.RotationYawPitchRoll(rotation.Y, rotation.X, rotation.Z) * Matrix.Translation(translation); } //Crear mesh con DiffuseMap if (texture != null) { //Crear Mesh Mesh d3dMesh = new Mesh(vertices.Length / 3, vertices.Length, MeshFlags.Managed, TgcSceneLoader.TgcSceneLoader.DiffuseMapVertexElements, d3dDevice); //Cargar VertexBuffer using (VertexBuffer vb = d3dMesh.VertexBuffer) { GraphicsStream data = vb.Lock(0, 0, LockFlags.None); for (int j = 0; j < vertices.Length; j++) { TgcSceneLoader.TgcSceneLoader.DiffuseMapVertex v = new TgcSceneLoader.TgcSceneLoader.DiffuseMapVertex(); CustomVertex.PositionColoredTextured vBox = vertices[j]; //vertices v.Position = Vector3.TransformCoordinate(vBox.Position, this.transform); //normals v.Normal = Vector3.Empty; //texture coordinates diffuseMap v.Tu = vBox.Tu; v.Tv = vBox.Tv; //color v.Color = vBox.Color; data.Write(v); } vb.Unlock(); } //Cargar IndexBuffer en forma plana using (IndexBuffer ib = d3dMesh.IndexBuffer) { short[] indices = new short[vertices.Length]; for (int j = 0; j < indices.Length; j++) { indices[j] = (short)j; } ib.SetData(indices, 0, LockFlags.None); } //Calcular normales d3dMesh.ComputeNormals(); //Malla de TGC TgcMesh tgcMesh = new TgcMesh(d3dMesh, meshName, TgcMesh.MeshRenderType.DIFFUSE_MAP); tgcMesh.DiffuseMaps = new TgcTexture[] { texture.clone() }; tgcMesh.Materials = new Material[] { TgcD3dDevice.DEFAULT_MATERIAL }; tgcMesh.createBoundingBox(); tgcMesh.Enabled = true; return(tgcMesh); } //Crear mesh con solo color else { //Crear Mesh Mesh d3dMesh = new Mesh(vertices.Length / 3, vertices.Length, MeshFlags.Managed, TgcSceneLoader.TgcSceneLoader.VertexColorVertexElements, d3dDevice); //Cargar VertexBuffer using (VertexBuffer vb = d3dMesh.VertexBuffer) { GraphicsStream data = vb.Lock(0, 0, LockFlags.None); for (int j = 0; j < vertices.Length; j++) { TgcSceneLoader.TgcSceneLoader.VertexColorVertex v = new TgcSceneLoader.TgcSceneLoader.VertexColorVertex(); CustomVertex.PositionColoredTextured vBox = vertices[j]; //vertices v.Position = Vector3.TransformCoordinate(vBox.Position, this.transform); //normals v.Normal = Vector3.Empty; //color v.Color = vBox.Color; data.Write(v); } vb.Unlock(); } //Cargar IndexBuffer en forma plana using (IndexBuffer ib = d3dMesh.IndexBuffer) { short[] indices = new short[vertices.Length]; for (int j = 0; j < indices.Length; j++) { indices[j] = (short)j; } ib.SetData(indices, 0, LockFlags.None); } //Malla de TGC TgcMesh tgcMesh = new TgcMesh(d3dMesh, meshName, TgcMesh.MeshRenderType.VERTEX_COLOR); tgcMesh.Materials = new Material[] { TgcD3dDevice.DEFAULT_MATERIAL }; tgcMesh.createBoundingBox(); tgcMesh.Enabled = true; return(tgcMesh); } }
public void render() { Device dev = this._device; //頂点データをセット GraphicsStream stm = this._vertex_buffer.Lock(0, 0, 0); stm.Write(this._vertex_array); stm.Dispose(); this._vertex_buffer.Unlock(); // D3dMaterial[] material = this._materials; for (int i = 0; i < material.Length; i++) { //カリング判定:何となくうまくいったから if ((0x100 & material[i].unknown) == 0x100) { dev.RenderState.CullMode = Cull.None; } else { dev.RenderState.CullMode = Cull.CounterClockwise; } /* if ((0x0f & material[i].unknown) == 0x02) * { * dev.RenderState.CullMode = Cull.None; * } * else * { * dev.RenderState.CullMode = Cull.CounterClockwise; * }*/ /* * if (material[i].material.DiffuseColor.Alpha < 1.0f && material[i].texture == null) * { * dev.RenderState.CullMode = Cull.None; * } * else * { * dev.RenderState.CullMode = Cull.CounterClockwise; * } */ dev.Material = material[i].material; if (material[i].texture != null) { dev.SetTexture(0, material[i].texture.d3d_texture); } else { dev.SetTexture(0, null); } //インデクスをセット dev.Indices = material[i].index_buf; dev.SetStreamSource(0, this._vertex_buffer, 0); dev.VertexFormat = CustomVertex.PositionNormalTextured.Format; dev.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, material[i].ulNumIndices, 0, material[i].ulNumIndices / 3); } return; }
private static void CopyTextureData(GraphicsStream srcData, int srcWidth, int srcHeight, OpsFormatHelper formatHelp, int srcPitch, GraphicsStream dstData, int dstPitch) { Byte[] rowData = new Byte[srcWidth * formatHelp.SizeInBytes]; for (int row = 0; row < srcHeight; row++) { srcData.Position = row * srcPitch; dstData.Position = row * dstPitch; srcData.Read(rowData, 0, rowData.Length); dstData.Write(rowData, 0, rowData.Length); } }
public Md3Model(string filename, Device d3dDevice, Q3ModelViewerForm parent) { this.d3dDevice = d3dDevice; this.parent = parent; int lastSlash = filename.LastIndexOf('/'); name = filename.Substring(lastSlash + 1); name = name.Substring(0, name.Length - 4); MemoryStream ms = new MemoryStream(); Q3FileSystem.WriteResourceToStream(filename, ms); header.FromUnsafe(( Md3HeaderUnsafe )ReadStruct(ms, typeof(Md3HeaderUnsafe))); // Frames ms.Position = header.framesStart; frames = new Md3Frame [header.numFrames]; for (int i = 0; i < header.numFrames; i++) { frames [i].FromUnsafe(( Md3FrameUnsafe )ReadStruct(ms, typeof(Md3FrameUnsafe))); } // Tags ms.Position = header.tagsStart; tags = new Md3Tag [header.numTags]; for (int i = 0; i < header.numTags; i++) { tags [i].FromUnsafe(( Md3TagUnsafe )ReadStruct(ms, typeof(Md3TagUnsafe))); } // Meshes int meshStart = header.meshesStart; ms.Position = meshStart; meshes = new Md3Mesh [header.numMeshes]; for (int i = 0; i < header.numMeshes; i++) { Md3Mesh md3Mesh = new Md3Mesh(); md3Mesh.FromUnsafe(( Md3MeshUnsafe )ReadStruct(ms, typeof(Md3MeshUnsafe))); // Mesh Textures ms.Position = meshStart + md3Mesh.texturesStart; md3Mesh.textures = new Md3Texture [md3Mesh.numTextures]; for (int j = 0; j < md3Mesh.numTextures; j++) { md3Mesh.textures [j].FromUnsafe(( Md3TextureUnsafe )ReadStruct(ms, typeof(Md3TextureUnsafe))); } // Mesh Faces ms.Position = meshStart + md3Mesh.facesStart; md3Mesh.faces = new Md3Face [md3Mesh.numFaces]; for (int j = 0; j < md3Mesh.numFaces; j++) { md3Mesh.faces [j].FromUnsafe(( Md3FaceUnsafe )ReadStruct(ms, typeof(Md3FaceUnsafe))); } // Mesh TexCoords ms.Position = meshStart + md3Mesh.texCoordsStart; md3Mesh.texCoords = new Md3TexCoord [md3Mesh.numVertices]; for (int j = 0; j < md3Mesh.numVertices; j++) { md3Mesh.texCoords [j] = ( Md3TexCoord )ReadStruct(ms, typeof(Md3TexCoord)); } // Vertices ms.Position = meshStart + md3Mesh.verticesStart; md3Mesh.vertices = new Md3PositionNormal [md3Mesh.numVertices]; for (int j = 0; j < md3Mesh.numVertices; j++) { md3Mesh.vertices [j].FromUnsafe(( Md3PositionNormalUnsafe )ReadStruct(ms, typeof(Md3PositionNormalUnsafe))); } meshes [i] = md3Mesh; ms.Position = meshStart + md3Mesh.size; meshStart = ( int )ms.Position; } // Load to dx mesh objects dxMeshes = new Mesh [meshes.Length]; radiuses = new float [meshes.Length]; centers = new Vector3 [meshes.Length]; for (int i = 0; i < meshes.Length; i++) { Md3Mesh md3Mesh = meshes [i]; Mesh mesh = new Mesh(md3Mesh.numFaces, md3Mesh.numVertices, MeshFlags.WriteOnly, CustomVertex.PositionNormalTextured.Format, d3dDevice); GraphicsStream vbStream = mesh.VertexBuffer.Lock(0, 0, LockFlags.Discard); for (int j = 0; j < md3Mesh.numVertices; j++) { Md3TexCoord texCoord = md3Mesh.texCoords [j]; vbStream.Write(new CustomVertex.PositionNormalTextured(md3Mesh.vertices [j].pos, Vector3.Empty, texCoord.u, texCoord.v)); } vbStream.Position = 0; radiuses [i] = Geometry.ComputeBoundingSphere(vbStream, md3Mesh.numVertices, CustomVertex.PositionNormalTextured.Format, out centers [i]); mesh.VertexBuffer.Unlock(); GraphicsStream ibStream = mesh.IndexBuffer.Lock(0, 0, LockFlags.Discard); for (int j = 0; j < md3Mesh.numFaces; j++) { Md3Face face = md3Mesh.faces [j]; ibStream.Write(( short )face.indices [0]); ibStream.Write(( short )face.indices [1]); ibStream.Write(( short )face.indices [2]); } mesh.IndexBuffer.Unlock(); dxMeshes [i] = mesh; // Load textures for (int j = 0; j < md3Mesh.numTextures; j++) { string realname = ""; Texture t = null; try { t = LoadTexture(md3Mesh.textures [j].name, out realname); } catch {} textures.Add(t != null ? t : parent.textureNotFound); realnames.Add(realname); } } if (header.numMeshes > 0) { totalCenter = centers [0]; totalRadius = radiuses [0]; for (int i = 1; i < centers.Length; i++) { totalCenter = (totalCenter + centers [i]) * 0.5f; totalRadius = ((totalCenter - centers [i]).Length() + totalRadius + radiuses [i]) / 2; } } }
/// <summary> /// Crea un mesh sin texturas, solo con VertexColors /// </summary> /// <param name="meshData"></param> private TgcMesh crearMeshSoloColor(TgcMeshData meshData) { //Crear Mesh Mesh mesh = new Mesh(meshData.coordinatesIndices.Length / 3, meshData.coordinatesIndices.Length, MeshFlags.Managed, VertexColorVertexElements, device); //Cargar VertexBuffer using (VertexBuffer vb = mesh.VertexBuffer) { GraphicsStream data = vb.Lock(0, 0, LockFlags.None); for (int j = 0; j < meshData.coordinatesIndices.Length; j++) { VertexColorVertex v = new VertexColorVertex(); //vertices int coordIdx = meshData.coordinatesIndices[j] * 3; v.Position = new Vector3( meshData.verticesCoordinates[coordIdx], meshData.verticesCoordinates[coordIdx + 1], meshData.verticesCoordinates[coordIdx + 2] ); //normals //puede haber una normal compartida para cada vertice del mesh if (meshData.verticesNormals.Length == meshData.verticesCoordinates.Length) { v.Normal = new Vector3( meshData.verticesNormals[coordIdx], meshData.verticesNormals[coordIdx + 1], meshData.verticesNormals[coordIdx + 2] ); } //o una normal propia por cada vertice de cada triangulo (version mejorada del exporter) else { int normalIdx = j * 3; v.Normal = new Vector3( meshData.verticesNormals[normalIdx], meshData.verticesNormals[normalIdx + 1], meshData.verticesNormals[normalIdx + 2] ); } //color int colorIdx = meshData.colorIndices[j]; v.Color = meshData.verticesColors[colorIdx]; data.Write(v); } vb.Unlock(); } //Cargar indexBuffer en forma plana using (IndexBuffer ib = mesh.IndexBuffer) { short[] indices = new short[meshData.coordinatesIndices.Length]; for (int i = 0; i < indices.Length; i++) { indices[i] = (short)i; } ib.SetData(indices, 0, LockFlags.None); } //Crear mesh de TGC TgcMesh tgcMesh = meshFactory.createNewMesh(mesh, meshData.name, TgcMesh.MeshRenderType.VERTEX_COLOR); return(tgcMesh); }
/// <summary> /// Crea un mesh con uno o varios DiffuseMap /// </summary> /// <returns></returns> private TgcMesh crearMeshDiffuseMap(TgcSceneLoaderMaterialAux[] materialsArray, TgcMeshData meshData) { //Crear Mesh Mesh mesh = new Mesh(meshData.coordinatesIndices.Length / 3, meshData.coordinatesIndices.Length, MeshFlags.Managed, DiffuseMapVertexElements, device); //Cargar VertexBuffer using (VertexBuffer vb = mesh.VertexBuffer) { GraphicsStream data = vb.Lock(0, 0, LockFlags.None); for (int j = 0; j < meshData.coordinatesIndices.Length; j++) { DiffuseMapVertex v = new DiffuseMapVertex(); //vertices int coordIdx = meshData.coordinatesIndices[j] * 3; v.Position = new Vector3( meshData.verticesCoordinates[coordIdx], meshData.verticesCoordinates[coordIdx + 1], meshData.verticesCoordinates[coordIdx + 2] ); //normals //puede haber una normal compartida para cada vertice del mesh if (meshData.verticesNormals.Length == meshData.verticesCoordinates.Length) { v.Normal = new Vector3( meshData.verticesNormals[coordIdx], meshData.verticesNormals[coordIdx + 1], meshData.verticesNormals[coordIdx + 2] ); } //o una normal propia por cada vertice de cada triangulo (version mejorada del exporter) else { int normalIdx = j * 3; v.Normal = new Vector3( meshData.verticesNormals[normalIdx], meshData.verticesNormals[normalIdx + 1], meshData.verticesNormals[normalIdx + 2] ); } //texture coordinates diffuseMap int texCoordIdx = meshData.texCoordinatesIndices[j] * 2; v.Tu = meshData.textureCoordinates[texCoordIdx]; v.Tv = meshData.textureCoordinates[texCoordIdx + 1]; //color int colorIdx = meshData.colorIndices[j]; v.Color = meshData.verticesColors[colorIdx]; data.Write(v); } vb.Unlock(); } //Cargar IndexBuffer en forma plana using (IndexBuffer ib = mesh.IndexBuffer) { short[] indices = new short[meshData.coordinatesIndices.Length]; for (int j = 0; j < indices.Length; j++) { indices[j] = (short)j; } ib.SetData(indices, 0, LockFlags.None); } //Configurar Material y Textura para un solo SubSet TgcSceneLoaderMaterialAux matAux = materialsArray[meshData.materialId]; Material[] meshMaterials; TgcTexture[] meshTextures; if (matAux.subMaterials == null) { meshMaterials = new Material[] { matAux.materialId }; meshTextures = new TgcTexture[] { TgcTexture.createTexture(device, matAux.textureFileName, matAux.texturePath) }; } //Configurar Material y Textura para varios SubSet else { //Cargar attributeBuffer con los id de las texturas de cada triángulo int[] attributeBuffer = mesh.LockAttributeBufferArray(LockFlags.None); Array.Copy(meshData.materialsIds, attributeBuffer, attributeBuffer.Length); mesh.UnlockAttributeBuffer(attributeBuffer); //Cargar array de Materials y Texturas meshMaterials = new Material[matAux.subMaterials.Length]; meshTextures = new TgcTexture[matAux.subMaterials.Length]; for (int m = 0; m < matAux.subMaterials.Length; m++) { meshMaterials[m] = matAux.subMaterials[m].materialId; meshTextures[m] = TgcTexture.createTexture(device, matAux.subMaterials[m].textureFileName, matAux.subMaterials[m].texturePath); } } //Crear mesh de TGC TgcMesh tgcMesh = meshFactory.createNewMesh(mesh, meshData.name, TgcMesh.MeshRenderType.DIFFUSE_MAP); tgcMesh.Materials = meshMaterials; tgcMesh.DiffuseMaps = meshTextures; return(tgcMesh); }
/// <summary> /// Renders 3D text /// </summary> public void Render3DText(string text, RenderFlags flags) { if (device == null) { throw new System.ArgumentNullException(); } // Set up renderstate savedStateBlock.Capture(); drawTextStateBlock.Apply(); device.VertexFormat = CustomVertex.PositionNormalTextured.Format; device.PixelShader = null; device.SetStreamSource(0, vertexBuffer, 0, VertexInformation.GetFormatSize(CustomVertex.PositionNormalTextured.Format)); // Set filter states if ((flags & RenderFlags.Filtered) != 0) { samplerState0.MinFilter = TextureFilter.Linear; samplerState0.MagFilter = TextureFilter.Linear; } // Position for each text element float x = 0.0f; float y = 0.0f; // Center the text block at the origin if ((flags & RenderFlags.Centered) != 0) { System.Drawing.SizeF sz = GetTextExtent(text); x = -(((float)sz.Width) / 10.0f) / 2.0f; y = -(((float)sz.Height) / 10.0f) / 2.0f; } // Turn off culling for two-sided text if ((flags & RenderFlags.TwoSided) != 0) { renderState.CullMode = Cull.None; } // Adjust for character spacing x -= spacingPerChar / 10.0f; float fStartX = x; // Fill vertex buffer GraphicsStream strm = vertexBuffer.Lock(0, 0, LockFlags.Discard); int numTriangles = 0; foreach (char c in text) { if (c == '\n') { x = fStartX; y -= (textureCoords[0, 3] - textureCoords[0, 1]) * textureHeight / 10.0f; } if ((c - 32) < 0 || (c - 32) >= 128 - 32) { continue; } float tx1 = textureCoords[c - 32, 0]; float ty1 = textureCoords[c - 32, 1]; float tx2 = textureCoords[c - 32, 2]; float ty2 = textureCoords[c - 32, 3]; float w = (tx2 - tx1) * textureWidth / (10.0f * textureScale); float h = (ty2 - ty1) * textureHeight / (10.0f * textureScale); if (c != ' ') { strm.Write(new CustomVertex.PositionNormalTextured(new Vector3(x + 0, y + 0, 0), new Vector3(0, 0, -1), tx1, ty2)); strm.Write(new CustomVertex.PositionNormalTextured(new Vector3(x + 0, y + h, 0), new Vector3(0, 0, -1), tx1, ty1)); strm.Write(new CustomVertex.PositionNormalTextured(new Vector3(x + w, y + 0, 0), new Vector3(0, 0, -1), tx2, ty2)); strm.Write(new CustomVertex.PositionNormalTextured(new Vector3(x + w, y + h, 0), new Vector3(0, 0, -1), tx2, ty1)); strm.Write(new CustomVertex.PositionNormalTextured(new Vector3(x + w, y + 0, 0), new Vector3(0, 0, -1), tx2, ty2)); strm.Write(new CustomVertex.PositionNormalTextured(new Vector3(x + 0, y + h, 0), new Vector3(0, 0, -1), tx1, ty1)); numTriangles += 2; if (numTriangles * 3 > (MaxNumfontVertices - 6)) { // Unlock, render, and relock the vertex buffer vertexBuffer.Unlock(); device.DrawPrimitives(PrimitiveType.TriangleList, 0, numTriangles); strm = vertexBuffer.Lock(0, 0, LockFlags.Discard); numTriangles = 0; } } x += w - (2 * spacingPerChar) / 10.0f; } // Unlock and render the vertex buffer vertexBuffer.Unlock(); if (numTriangles > 0) { device.DrawPrimitives(PrimitiveType.TriangleList, 0, numTriangles); } // Restore the modified renderstates savedStateBlock.Apply(); }
private void updateAxisVertices(DISPLAY_RANGE range, float height, float yOffset) { if (device == null || functionList == null) { return; } if (!validAxis) { // Update the axis grid vertices System.Single z = 0.5f; System.Single yMin = yOffset; System.Single yMax = height + yOffset; // Pick the timescale float timecale = (range.tMax - range.tMin > 15 ? 1 : 10); // Calculate the number of vertices // 2 vertices per line. 1 main major marker per second, 9 minor markers inbetween. int numMarkers = (int)(timecale * (range.tMax - range.tMin)); verticesAxis = new CustomVertex.TransformedColored[2 * numMarkers]; // Loop through creating the markers float firstMarkerTime = ((float)((int)(timecale * range.tMin))) / timecale; for (int i = 0; i < numMarkers; i++) { Single time = i * (1 / timecale) + firstMarkerTime; // Create this axis line if ((Single)((int)time) == time) { // Major marker verticesAxis[2 * i] = new CustomVertex.TransformedColored( (float) ((int) ((time - range.tMin) / (range.tMax - range.tMin) * (range.xMax - range.xMin) + range.xMin)), (float)((int)yMin), z, 1.0f, Color.FromArgb(150, 255, 150).ToArgb()); verticesAxis[2 * i + 1] = new CustomVertex.TransformedColored( (float) ((int) ((time - range.tMin) / (range.tMax - range.tMin) * (range.xMax - range.xMin) + range.xMin)), (float)((int)((yMax - yMin) / 2 + yMin)), z, 1.0f, Color.FromArgb(150, 255, 150).ToArgb()); } else { // Minor Marker verticesAxis[2 * i] = new CustomVertex.TransformedColored( (float) ((int) ((time - range.tMin) / (range.tMax - range.tMin) * (range.xMax - range.xMin) + range.xMin)), (float)((int)yMin), z, 1.0f, Color.FromArgb(100, 170, 100).ToArgb()); verticesAxis[2 * i + 1] = new CustomVertex.TransformedColored( (float) ((int) ((time - range.tMin) / (range.tMax - range.tMin) * (range.xMax - range.xMin) + range.xMin)), (float)((int)((yMax - yMin) / 4 + yMin)), z, 1.0f, Color.FromArgb(100, 170, 100).ToArgb()); } } // Write the vertex drawing buffers if (verticesAxis.Length > 0) { if (vertexBufferAxis != null) { vertexBufferAxis.Dispose(); } vertexBufferAxis = new VertexBuffer(typeof(CustomVertex.TransformedColored), verticesAxis.Length, device, 0, CustomVertex.TransformedColored.Format, Pool.Default); GraphicsStream stm = vertexBufferAxis.Lock(0, 0, 0); stm.Seek(0, SeekOrigin.Begin); stm.Write(verticesAxis); vertexBufferAxis.Unlock(); } validAxis = true; } }
/// <summary> /// Write myself to a vertex buffer as a pair of triangles /// </summary> /// <param name="stream"></param> private void Write(GraphicsStream stream) { // Get a local copy of the untransformed quad CustomVertex.PositionNormalTextured[] quad = new CustomVertex.PositionNormalTextured[4]; for (int v=0; v<4; v++) { quad[v] = info.quad[v]; } // calculate frame number if (info.frameRate!=0) // if no frame rate, frame represents an unanimated variant { frame += info.frameRate * Scene.ElapsedTime; frame %= info.numFrames; } float wholeFrame = (int)frame; // define the part of the texture to display this frame, in texture coordinates float left = wholeFrame * info.width / texWidth; // fraction of the texture at which this frame starts float right = (wholeFrame+1.0f) * info.width / texWidth; float top = info.top / texHeight; // fraction of the texture at which this row starts float bot = (info.top + info.height) / texHeight; const float border = 0.001f; // close in a little, to prevent overrunning sprite edges left += border; right -= border; top += border; bot -= border; quad[0].Tu = left; quad[0].Tv = top; quad[1].Tu = right; quad[1].Tv = top; quad[2].Tu = left; quad[2].Tv = bot; quad[3].Tu = right; quad[3].Tv = bot; // Get a matrix that will rotate to face camera (around yaw axis only) and then translate into world coordinates Matrix trans = facingMatrix * Matrix.Translation(location); // We have to transform the vertices ourselves, since there are many sprites in each vertex buffer for (int v=0; v<4; v++) { // Transform the vertex quad[v].Position = Vector3.TransformCoordinate(quad[v].Position,trans); // Transform the normal quad[v].Normal = Vector3.TransformNormal(quad[v].Normal,trans); } // Add this quad's two triangles to the vertex buffer stream.Write(quad[0]); stream.Write(quad[1]); stream.Write(quad[2]); stream.Write(quad[3]); stream.Write(quad[2]); stream.Write(quad[1]); }
private void updateSelectionVertices(double selectStart, double selectEnd, DISPLAY_RANGE range, float height, float yOffset, bool isSelected) { if (device == null || functionList == null) { return; } if (!validSelection) { int colour; if (isSelected) { colour = Color.FromArgb(80, 80, 80).ToArgb(); // A bit lighter gray } else { colour = Color.FromArgb(40, 40, 40).ToArgb(); // Very dark gray } // Update the selection vertices verticesSelectionBackground = new CustomVertex.TransformedColored[3 * 2]; // Two triangles for a box. // General parameters System.Single z = 0.5f; System.Single yMin = yOffset; System.Single yMax = height + yOffset; int i = 0; // Draw the background verticesSelectionBackground[i++] = new CustomVertex.TransformedColored( (float) (((selectStart - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin), yMin, z, 1.0f, colour); verticesSelectionBackground[i++] = new CustomVertex.TransformedColored( (float) (((selectEnd - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin), yMin, z, 1.0f, colour); verticesSelectionBackground[i++] = new CustomVertex.TransformedColored( (float) (((selectEnd - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin), yMax, z, 1.0f, colour); verticesSelectionBackground[i++] = new CustomVertex.TransformedColored( (float) (((selectStart - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin), yMin, z, 1.0f, colour); verticesSelectionBackground[i++] = new CustomVertex.TransformedColored( (float) (((selectStart - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin), yMax, z, 1.0f, colour); verticesSelectionBackground[i++] = new CustomVertex.TransformedColored( (float) (((selectEnd - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin), yMax, z, 1.0f, colour); if (vertexBufferSelectionBackground != null) { vertexBufferSelectionBackground.Dispose(); } vertexBufferSelectionBackground = new VertexBuffer(typeof(CustomVertex.TransformedColored), verticesSelectionBackground.Length, device, 0, CustomVertex.TransformedColored.Format, Pool.Default); GraphicsStream stm = vertexBufferSelectionBackground.Lock(0, 0, 0); stm.Seek(0, SeekOrigin.Begin); stm.Write(verticesSelectionBackground); vertexBufferSelectionBackground.Unlock(); validSelection = true; } }
private void makeCursorLODVB(ref VertexBuffer vb, ref uint numVerts, BTerrainVisual.eLODLevel lod) { VertexTypes.Pos[] verts = null; uint width = BTerrainQuadNode.getMaxNodeWidth(); uint vd = width * 2; uint tw = width; uint td = width; int counter = 0; switch (lod) { case BTerrainVisual.eLODLevel.cLOD0: { numVerts = (width + 1) * (width + 1); verts = new VertexTypes.Pos[numVerts]; vd = width * 2; tw = width; td = width; for (int z = 0; z < td; z++) { for (int x = 0; x < tw; x++) { int k = z + (int)(x * vd); verts[counter++].x = (k); } } } break; case BTerrainVisual.eLODLevel.cLOD1: { numVerts = (1 + (width >> 1)) * (1 + (width >> 1)); verts = new VertexTypes.Pos[numVerts]; tw = width >> 1; td = width >> 1; vd = 2 * (width >> 1); for (int x = 0; x < tw; x++) { for (int z = 0; z < td; z++) { int k = z + (int)(x * vd); verts[counter++].x = (k); } } } break; case BTerrainVisual.eLODLevel.cLOD2: { numVerts = (1 + (width >> 2)) * (1 + (width >> 2)); verts = new VertexTypes.Pos[numVerts]; tw = width >> 2; td = width >> 2; vd = 2 * (width >> 2); for (int x = 0; x < tw; x++) { for (int z = 0; z < td; z++) { int k = z + (int)(x * vd); verts[counter++].x = (k); } } } break; case BTerrainVisual.eLODLevel.cLOD3: { numVerts = (1 + (width >> 3)) * (1 + (width >> 3)); verts = new VertexTypes.Pos[numVerts]; tw = width >> 3; td = width >> 3; vd = 2 * (width >> 3); for (int x = 0; x < tw; x++) { for (int z = 0; z < td; z++) { int k = z + (int)(x * vd); verts[counter++].x = (k); } } } break; default: return; } vb = new VertexBuffer(typeof(VertexTypes.Pos), (int)numVerts, BRenderDevice.getDevice(), Usage.None, VertexFormats.Position, Pool.Managed); GraphicsStream stream = vb.Lock(0, (int)numVerts * sizeof(float) * 3, LockFlags.None); stream.Write(verts); vb.Unlock(); verts = null; }
private void updateLogPlotVertices(DISPLAY_RANGE range, float height, float yOffset, double cursorTime, double cursorWidth) { // Check that we have a valid device if (device != null && functionList != null) { // Load the data List <oSingleData> rawData = this.functionList.getData(); if (rawData != null && rawData.Count > 0) { if (!validLogPlot || lastCallCount != rawData.Count || vertexBufferLogPlot == null || vertexBufferLogPlot.Disposed || range.tMax != lastTime) { // Update the main visualizataion to show the new data // Gather the data List <oSingleData> data = functionList.getDataRange(range.tMax, cursorWidth * 2);; //List<oSingleData> data = functionList.getDataRange(range.tMax, range.tMax - lastTime); ; // Now tell the main visualization to redraw mainVisualization.update(data); // Calculate the viewing range information validAxis = false; lastTime = range.tMax; System.Single z = 0.5f; System.Single yMin = 1 + yOffset; System.Single yMax = height - 1 + yOffset; // Create a value array to go with the vertexes double[] functionCount = new double[(int)((range.tMaxDataset - range.tMinDataset) / timeWidth + 0.5)]; double[] times = new double[functionCount.Length]; for (int i = 0; i < functionCount.Count(); i++) { functionCount[i] = 0; times[i] = 0; } // Loop through the time, calculating the call count associated with each time frame double maxFunctionCount = 0; int index = 0; for (int i = 0; i < functionCount.Count(); i++) { // Process this time step int tmpCount = this.functionList.getDataSize(i * timeWidth + range.tMinDataset, timeWidth); // This time index record is associated with this vertex double count = Math.Log10(tmpCount + 1); double nextCount = 0.0; if (i + 2 < functionCount.Count()) { // Calculate the next count nextCount = Math.Log10(this.functionList.getDataSize((i + 1) * timeWidth + range.tMinDataset, timeWidth) + 1); } if (count < 0) { count = 0; } if (nextCount < 0) { nextCount = 0; } if ((index == 0 || functionCount[index - 1] != count) || (nextCount != count) || index == functionCount.Length - 1) { // Create a new vertex functionCount[index] = count; // Set the time for this call times[index] = i * timeWidth + range.tMinDataset; if (functionCount[index] > maxFunctionCount) { maxFunctionCount = functionCount[index]; } index++; } } // Generate the log-graph verticesLogPlot if (maxFunctionCount <= 1) { maxFunctionCount = 1; } // Initialize the vertex array verticesLogPlot = new CustomVertex.TransformedColored[index + 2]; // Generate the log-scale frequency plot verticesLogPlot System.Single x; System.Single y; for (int i = 0; i < index; i++) { // Generate this vertex x = (float)((((double)times[i] - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin); y = (float)((yMin - yMax) * (functionCount[i] / maxFunctionCount) + yMax); verticesLogPlot[i] = new CustomVertex.TransformedColored((float)((int)(x)), (float)((int)y), z, 1.0f, Color.FromArgb(255, 255, 255).ToArgb()); } // Create the last two vertices x = (float)range.xMax; y = (float)yMax; verticesLogPlot[index] = new CustomVertex.TransformedColored((float)((int)(x)), (float)((int)y), z, 1.0f, Color.FromArgb(255, 255, 255).ToArgb()); verticesLogPlot[index + 1] = new CustomVertex.TransformedColored((float)((int)(x)), (float)(10000000000), z, 1.0f, Color.FromArgb(0, 0, 0).ToArgb()); // Setup the vertex buffer if (vertexBufferLogPlot != null) { vertexBufferLogPlot.Dispose(); } vertexBufferLogPlot = new VertexBuffer(typeof(CustomVertex.TransformedColored), verticesLogPlot.Length, device, 0, CustomVertex.TransformedColored.Format, Pool.Default); lastCallCount = rawData.Count; try { GraphicsStream stm = vertexBufferLogPlot.Lock(0, 0, 0); stm.Seek(0, SeekOrigin.Begin); stm.Write(verticesLogPlot); vertexBufferLogPlot.Unlock(); } catch (Exception ex) { // Do nothing } } validLogPlot = true; } else { // An empty dataset vertexBufferLogPlot = null; } } }
public override void CreateGeometryForObjects(Device device, ICollection <IBond> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { // fillable fields int positionPos = -1; int normalPos = -1; int diffusePos = -1; int texPos = -1; // match field locations //int[] fieldsPos = new int[fields.Length]; for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") { positionPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "NORMAL") { normalPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "DIFFUSE") { diffusePos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "TEXTURE0") { texPos = geomStream.FieldPositions[gf]; } //fieldsPos[i] = geomStream.FieldPositions[gf]; break; } } } // count bond orders via preview data int numActualBonds = 0; foreach (IBond bond in objs) { numActualBonds += (int)bond.Order; } if (!coDesc.BondShadingDesc.BlendEndClrs) { numActualBonds *= 2; } int numTriangles = objs.Count * (numSides * 2); SphereMathHelper.EndType endType = SphereMathHelper.EndType.Open; float offset = 0.0f; switch (coDesc.BondShadingDesc.EndType) { case BondShadingDesc.BondEndTypes.Open: break; case BondShadingDesc.BondEndTypes.Closed: numTriangles += numActualBonds * (numSides * 2); endType = SphereMathHelper.EndType.Flat; break; case BondShadingDesc.BondEndTypes.Point: offset = 0.05f; numTriangles += numActualBonds * (numSides * 2); endType = SphereMathHelper.EndType.Flat; break; case BondShadingDesc.BondEndTypes.Rounded: offset = 0.075f; numTriangles += numActualBonds * (numSides * 6); endType = SphereMathHelper.EndType.Rounded; break; } // build template bond Vector3[] tCylinderPoints, tCylinderEndPoints1, tCylinderEndPoints2; Vector3[] tCylinderNormals, tCylinderEndNormals1, tCylinderEndNormals2; int[] tCylinderTris, tCylinderEndTris1, tCylinderEndTris2; SphereMathHelper.CalcCylinderTriangles(numSides, 1, 1.0f, new Vector3(0, 0, 0), new Vector3(0, 0, 1), true, endType, offset, out tCylinderPoints, out tCylinderNormals, out tCylinderTris, out tCylinderEndPoints1, out tCylinderEndNormals1, out tCylinderEndTris1, out tCylinderEndPoints2, out tCylinderEndNormals2, out tCylinderEndTris2); int numActualVerts = tCylinderPoints.Length + tCylinderEndPoints1.Length + tCylinderEndPoints2.Length; int numActualTris = tCylinderTris.Length + tCylinderEndTris1.Length + tCylinderEndTris2.Length; // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = numActualVerts; buffer.vBuffers[0].Format = geomStream.Format; buffer.vBuffers[0].NumElements = numActualVerts * numActualBonds; buffer.vBuffers[0].Buffer = new VertexBuffer(device, geomStream.Stride * numActualTris * numActualBonds * 3, Usage.WriteOnly, geomStream.Format, Pool.Managed); buffer.iBuffers = new BufferedGeometryData.IndexData[1]; buffer.iBuffers[0] = new BufferedGeometryData.IndexData(); buffer.iBuffers[0].Desc = BufferedGeometryData.IndexData.Description.Geometry; buffer.iBuffers[0].NumPrimitives = numActualTris; buffer.iBuffers[0].PrimType = PrimitiveType.TriangleList; buffer.iBuffers[0].NumPrimitives = (numActualTris * numActualBonds) / 3; /*buffer.iBuffers[0].Buffer = new IndexBuffer(typeof(int), numActualTris * numActualBonds, device, * Usage.WriteOnly, Pool.Managed);*/ // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); // write bonds to buffer Vector3 direction, directionUV; IAtom[] atoms; Vector3[] atomsPos; IMoleculeMaterial matA, matB; foreach (IBond bond in objs) { BondLinesBufferCreator.GenericBondSetup(bond, true, coDesc.BondShadingDesc, out direction, out directionUV, out atoms, out atomsPos, out matA, out matB); // calc bond positioning / instances Vector3[] bondInstances = null; float midPos; BondLinesBufferCreator.GenericBondCalcPositions(bond, coDesc.BondShadingDesc, direction, directionUV, atoms, atomsPos, 0.15f, out bondInstances, out midPos, false); long pos = 0; for (int bInst = 0; bInst < bondInstances.Length; bInst += 2) { // translation Matrix translate = Matrix.Translation(bondInstances[bInst]); // rotation double x = direction.X; double y = direction.Y; double z = direction.Z; double alpha = (z == 0) ? Math.PI / 2 : Math.Atan(x / z); double r = (alpha == 0) ? z : x / Math.Sin(alpha); float sign = 1f; if (z != 0) { sign *= Math.Sign(z); } else if (x != 0) { sign *= Math.Sign(x); } if (y != 0) { sign *= Math.Sign(y); } double theta = -sign *Math.Abs((r == 0)?Math.PI / 2 : Math.Atan(y / r)); Matrix rotation = Matrix.RotationX((float)theta) * Matrix.RotationY((float)alpha); // scaling float zScale; if (coDesc.BondShadingDesc.BlendEndClrs) { zScale = (bondInstances[1] - bondInstances[0]).Length();//(atomsPos[1] - atomsPos[0]).Length();//direction.Length(); } else { zScale = midPos; } float xyScale = 0.05f; // thickness Matrix scale = Matrix.Scaling(xyScale, xyScale, zScale); // rotate & translate ends if (tCylinderEndPoints1 != null) { Matrix endFinal = Matrix.Scaling(xyScale, xyScale, 1f) * rotation * translate; Vector4[] tfEndTriangles = Vector3.Transform(tCylinderEndPoints1, endFinal); // first end for (int point = 0; point < tCylinderEndTris1.Length; point++) { int pointIdx = tCylinderEndTris1[point]; if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(tfEndTriangles[pointIdx].X); data.Write(tfEndTriangles[pointIdx].Y); data.Write(tfEndTriangles[pointIdx].Z); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(tCylinderEndNormals1[pointIdx].X); data.Write(tCylinderEndNormals1[pointIdx].Y); data.Write(tCylinderEndNormals1[pointIdx].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(matA.BaseColor.ToArgb()); } pos += geomStream.Stride; } // second end endFinal = Matrix.Scaling(xyScale, xyScale, 1f) * rotation * Matrix.Translation(bondInstances[bInst + 1]); tfEndTriangles = Vector3.Transform(tCylinderEndPoints2, endFinal); // first end for (int point = 0; point < tCylinderEndTris2.Length; point++) { int pointIdx = tCylinderEndTris2[point]; if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(tfEndTriangles[pointIdx].X); data.Write(tfEndTriangles[pointIdx].Y); data.Write(tfEndTriangles[pointIdx].Z); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(tCylinderEndNormals2[pointIdx].X); data.Write(tCylinderEndNormals2[pointIdx].Y); data.Write(tCylinderEndNormals2[pointIdx].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(matB.BaseColor.ToArgb()); } pos += geomStream.Stride; } } Matrix final = scale * rotation * translate; if (coDesc.BondShadingDesc.BlendEndClrs) { DrawSolidBondBlended(tCylinderPoints, tCylinderNormals, tCylinderTris, matA, matB, final, data, positionPos, normalPos, diffusePos, ref pos, geomStream.Stride, rotation); } else { float bLen2 = (bondInstances[bInst + 1] - (bondInstances[bInst] + (directionUV * midPos))).Length(); DrawSolidBondDistinct(tCylinderPoints, tCylinderNormals, tCylinderTris, matA, matB, final, data, xyScale, bLen2, rotation, bondInstances[bInst], directionUV, midPos, positionPos, normalPos, diffusePos, ref pos, geomStream.Stride); } } } }
private void updateMouseVertices(int x, int y, double cursorWidth, DISPLAY_RANGE range, float height, float yOffset) { if (device == null || functionList == null) { return; } if (!validMouse) { System.Single yMin = yOffset; System.Single yMax = height + yOffset; // Check if the cursor is in this row bool inRow = false; if (y >= (int)yMin && y <= (int)yMax) { inRow = true; } // Set the mouse text values mouseTextPos = new Point(x + 2, (int)yMin + 3); mouseNumCalls = functionList.getDataSize( ((double)(x - range.xMin) / (double)(range.xMax - range.xMin)) * (range.tMax - range.tMin) + range.tMin, cursorWidth); if (inRow) { // Initialize the vertices verticesMouse = new CustomVertex.TransformedColored[4]; for (int n = 0; n < verticesMouse.Length; n++) { verticesMouse[n] = new CustomVertex.TransformedColored(0.0f, 0.0f, 0.0f, 1.0f, Color.FromArgb(0, 255, 0). ToArgb()); } // Set the vertice positions int i = 0; verticesMouse[i].X = x + 2; verticesMouse[i].Y = yMin; verticesMouse[i++].Z = 0.4f; verticesMouse[i].X = x + 2; verticesMouse[i].Y = yMax; verticesMouse[i++].Z = 0.4f; verticesMouse[i].X = x - 2; verticesMouse[i].Y = yMin; verticesMouse[i++].Z = 0.4f; verticesMouse[i].X = x - 2; verticesMouse[i].Y = yMax; verticesMouse[i++].Z = 0.4f; } else { // Create the vertex buffer for the current mouse location // Initialize the vertices verticesMouse = new CustomVertex.TransformedColored[2]; for (int n = 0; n < verticesMouse.Length; n++) { verticesMouse[n] = new CustomVertex.TransformedColored(0.0f, 0.0f, 0.0f, 1.0f, Color.FromArgb(0, 100, 0). ToArgb()); } // Set the vertice positions int i = 0; verticesMouse[i].X = x; verticesMouse[i].Y = yMin; verticesMouse[i++].Z = 0.4f; verticesMouse[i].X = x; verticesMouse[i].Y = yMax; verticesMouse[i++].Z = 0.4f; } // Write the vertex drawing buffers if (vertexBufferMouse != null) { vertexBufferMouse.Dispose(); } vertexBufferMouse = new VertexBuffer(typeof(CustomVertex.TransformedColored), verticesMouse.Length, device, 0, CustomVertex.TransformedColored.Format, Pool.Default); GraphicsStream stm = vertexBufferMouse.Lock(0, 0, 0); stm.Seek(0, SeekOrigin.Begin); stm.Write(verticesMouse); vertexBufferMouse.Unlock(); validMouse = true; } }
public override void CreateGeometryForObjects(Device device, ICollection <IAtom> objs, GeomDataBufferStream geomStream, int stream, ref BufferedGeometryData buffer, CompleteOutputDescription coDesc) { // fillable fields int positionPos = -1; int sizePos = -1; // match field locations for (int i = 0; i < fields.Length; i++) { for (int gf = 0; gf < geomStream.Fields.Length; gf++) { if (fields[i].Format == geomStream.Fields[gf]) { if (fields[i].Usage == "POSITION") { positionPos = geomStream.FieldPositions[gf]; } else if (fields[i].Usage == "POINTSIZE") { sizePos = geomStream.FieldPositions[gf]; } break; } } } // pre-scan for index groups Dictionary <string, List <int> > groups = new Dictionary <string, List <int> >(); int aIdx = 0; foreach (IAtom atom in objs) { if (!groups.ContainsKey(atom.Symbol)) { groups[atom.Symbol] = new List <int>(); } groups[atom.Symbol].Add(aIdx++); } // create buffers buffer = new BufferedGeometryData(device, objs.Count); buffer.vBuffers = new BufferedGeometryData.VertexData[1]; buffer.vBuffers[0] = new BufferedGeometryData.VertexData(); buffer.vBuffers[0].Buffer = new VertexBuffer(typeof(PointSprite), objs.Count, device, Usage.WriteOnly, geomStream.Format, Pool.Managed); buffer.vBuffers[0].Stride = geomStream.Stride; buffer.vBuffers[0].NumElements = objs.Count; buffer.vBuffers[0].Format = geomStream.Format; buffer.DataValidity = BufferedGeometryData.DataValidityType.View; ChemSymbolTextures cTex = ChemSymbolTextures.Instance; buffer.iBuffers = new BufferedGeometryData.IndexData[groups.Count]; int gIdx = 0; foreach (KeyValuePair <string, List <int> > group in groups) { buffer.iBuffers[gIdx] = new BufferedGeometryData.IndexData(); buffer.iBuffers[gIdx].Desc = BufferedGeometryData.IndexData.Description.Sprites; buffer.iBuffers[gIdx].NumPrimitives = group.Value.Count; buffer.iBuffers[gIdx].PrimType = PrimitiveType.PointList; buffer.iBuffers[gIdx].Textures = new Texture[] { cTex[group.Key] }; buffer.iBuffers[gIdx].Buffer = new IndexBuffer(typeof(int), group.Value.Count, device, Usage.WriteOnly, Pool.Managed); int[] indices = (int[])buffer.iBuffers[gIdx].Buffer.Lock(0, LockFlags.None); for (int i = 0; i < indices.Length; i++) { indices[i] = group.Value[i]; } buffer.iBuffers[gIdx].Buffer.Unlock(); gIdx++; } // lock stream GraphicsStream data = buffer.vBuffers[0].Buffer.Lock(0, 0, LockFlags.None); AtomShadingDesc aShading = coDesc.AtomShadingDesc; long pos = 0; foreach (IAtom atom in objs) { if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write((float)atom.X3d); data.Write((float)atom.Y3d); data.Write((float)atom.Z3d); } if (sizePos != -1) { data.Seek(pos + sizePos, SeekOrigin.Begin); int period = 1; if (atom.Properties.ContainsKey("Period")) { period = (int)atom.Properties["Period"]; } data.Write((float)period * 0.2f); } pos += geomStream.Stride; } buffer.vBuffers[0].Buffer.Unlock(); }
private void updateCursorVertices(double cursorTime, double cursorWidth, DISPLAY_RANGE range, float height, float yOffset, bool hasCursor) { if (device == null || functionList == null) { return; } if (!validCursor) { System.Single yMin = 2 + yOffset; System.Single yMax = height - 2 + yOffset; // If the cursor is in this row, tell the main visualization to redraw with our cursor data. if (hasCursor) { // Gather the data List <oSingleData> data; if (functionList != null) { data = functionList.getDataRange(cursorTime, cursorWidth); } else { data = new List <oSingleData>(0); } // Now tell the main visualization to redraw mainVisualization.update(data); // Create the vertex buffer for the current mouse location if (verticesCursor == null) { // Initialize the vertices verticesCursor = new CustomVertex.TransformedColored[2 * 5]; for (int n = 0; n < verticesCursor.Length; n++) { verticesCursor[n] = new CustomVertex.TransformedColored(0.0f, 0.0f, 0.4f, 1.0f, Color.FromArgb(255, 255, 0).ToArgb()); } } // Set the vertice positions int i = 0; float xEnd = (float)((cursorTime - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin; float xStart = (float)((cursorTime - cursorWidth - range.tMin) / (range.tMax - range.tMin)) * (range.xMax - range.xMin) + range.xMin; verticesCursor[i].X = xEnd - 3; verticesCursor[i++].Y = yMin; verticesCursor[i].X = xEnd + 3; verticesCursor[i++].Y = yMin; verticesCursor[i].X = xEnd - 3; verticesCursor[i++].Y = yMax; verticesCursor[i].X = xEnd + 3; verticesCursor[i++].Y = yMax; verticesCursor[i].X = xEnd; verticesCursor[i++].Y = yMin; verticesCursor[i].X = xEnd; verticesCursor[i++].Y = yMax; verticesCursor[i].X = xStart; verticesCursor[i++].Y = (yMax - yMin) / 2 + yMin; verticesCursor[i].X = xEnd; verticesCursor[i++].Y = (yMax - yMin) / 2 + yMin; verticesCursor[i].X = xStart; verticesCursor[i++].Y = (yMax - yMin) * 0.4f + yMin; verticesCursor[i].X = xStart; verticesCursor[i++].Y = (yMax - yMin) * 0.6f + yMin; // Write the vertex drawing buffers if (vertexBufferCursor != null) { vertexBufferCursor.Dispose(); } vertexBufferCursor = new VertexBuffer(typeof(CustomVertex.TransformedColored), verticesCursor.Length, device, 0, CustomVertex.TransformedColored.Format, Pool.Default); GraphicsStream stm = vertexBufferCursor.Lock(0, 0, 0); stm.Seek(0, SeekOrigin.Begin); stm.Write(verticesCursor); vertexBufferCursor.Unlock(); } else { // Cursor is not in this row vertexBufferCursor = null; } validCursor = true; } }
/// <summary> /// Convierte el Triángulo en un TgcMesh /// </summary> /// <param name="meshName">Nombre de la malla que se va a crear</param> public TgcMesh toMesh(string meshName) { Device d3dDevice = GuiController.Instance.D3dDevice; //Crear Mesh con solo color Mesh d3dMesh = new Mesh(1, 3, MeshFlags.Managed, TgcSceneLoader.TgcSceneLoader.VertexColorVertexElements, d3dDevice); //Calcular normal: left-handed Vector3 normal = computeNormal(); int ci = color.ToArgb(); //Cargar VertexBuffer using (VertexBuffer vb = d3dMesh.VertexBuffer) { GraphicsStream data = vb.Lock(0, 0, LockFlags.None); TgcSceneLoader.TgcSceneLoader.VertexColorVertex v; //a v = new TgcSceneLoader.TgcSceneLoader.VertexColorVertex(); v.Position = a; v.Normal = normal; v.Color = ci; data.Write(v); //b v = new TgcSceneLoader.TgcSceneLoader.VertexColorVertex(); v.Position = b; v.Normal = normal; v.Color = ci; data.Write(v); //c v = new TgcSceneLoader.TgcSceneLoader.VertexColorVertex(); v.Position = c; v.Normal = normal; v.Color = ci; data.Write(v); vb.Unlock(); } //Cargar IndexBuffer en forma plana using (IndexBuffer ib = d3dMesh.IndexBuffer) { short[] indices = new short[3]; for (int j = 0; j < indices.Length; j++) { indices[j] = (short)j; } ib.SetData(indices, 0, LockFlags.None); } //Malla de TGC TgcMesh tgcMesh = new TgcMesh(d3dMesh, meshName, TgcMesh.MeshRenderType.VERTEX_COLOR); tgcMesh.Materials = new Material[] { TgcD3dDevice.DEFAULT_MATERIAL }; tgcMesh.createBoundingBox(); tgcMesh.Enabled = true; return(tgcMesh); }
/// <summary> /// Direct 3D 디바이스 /// </summary> /// <param name="toplevelForm"></param> /// <returns></returns> /// <summary> /// 어플리케이션 초기화 /// </summary> /// <param name="toplevelForm"></param> /// <returns>모든 초기화가 OK라면 true, 하나라도 실패하면 false를 돌려준다.</returns> /// <remarks> /// false를 돌려주었을 경우는, 자동으로 어플ㄹ리케이션이 종료됨 /// </remarks> public bool InitializeApplication(Main toplevelForm) //메인 폼 로드 { //폼의 참조를 보관유지 this._form = toplevelForm; #region 메인 설정 //입력 이벤트 작성 //this.CreateDevice(toplevelForm); //폰트의 작성 DirectXPartial.cs로 옮김 //카메라의 설정 DirectXPartial.cs로 옮김 //키보드 입력 DirectXPartial.cs로 옮김 //마우스 이동 이벤트 toplevelForm.MouseMove += new MouseEventHandler(this.form_MouseMove); //키보드 인풋 this.CreateInputEvent(toplevelForm); try { // 디바이스의 작성 this.CreateDevice(toplevelForm); //폰트의작성 this.CreateFont(); } catch (DirectXException ex) { // 예외 발생 MessageBox.Show(ex.ToString(), "에러", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } //1. 사각ㅎㅇ 작성 //this.CreateSquarePolygon(); //2.상자를 작성하기 위한 정점 버퍼를 구성 //상자의 정점은 8개 this._vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionColored), 8, this._device, Usage.None, CustomVertex.PositionColored.Format, Pool.Managed); //8개의 정보를 보관하기 위한 메모리를 확보 CustomVertex.PositionColored[] vertices = new CustomVertex.PositionColored[8]; //각 정점을 설정 //vertices[0] = new CustomVertex.PositionColored(-2.0f, 2.0f, 2.0f, Color.Yellow.ToArgb()); //vertices[1] = new CustomVertex.PositionColored(2.0f, 2.0f, 2.0f, Color.Gray.ToArgb()); //vertices[2] = new CustomVertex.PositionColored(-2.0f, 2.0f, -2.0f, Color.Purple.ToArgb()); //vertices[3] = new CustomVertex.PositionColored(2.0f, 2.0f, -2.0f, Color.Red.ToArgb()); //vertices[4] = new CustomVertex.PositionColored(-2.0f, -2.0f, 2.0f, Color.SkyBlue.ToArgb()); //vertices[5] = new CustomVertex.PositionColored(2.0f, -2.0f, 2.0f, Color.Orange.ToArgb()); //vertices[6] = new CustomVertex.PositionColored(-2.0f, -2.0f, -2.0f, Color.Green.ToArgb()); //vertices[7] = new CustomVertex.PositionColored(2.0f, -2.0f, -2.0f, Color.Blue.ToArgb()); vertices[0] = new CustomVertex.PositionColored(-2.0f, 2.0f, 2.0f, Color.Yellow.ToArgb()); vertices[1] = new CustomVertex.PositionColored(2.0f, 2.0f, 2.0f, Color.Yellow.ToArgb()); vertices[2] = new CustomVertex.PositionColored(-2.0f, 2.0f, -2.0f, Color.Yellow.ToArgb()); vertices[3] = new CustomVertex.PositionColored(2.0f, 2.0f, -2.0f, Color.Yellow.ToArgb()); vertices[4] = new CustomVertex.PositionColored(-2.0f, -2.0f, 2.0f, Color.Blue.ToArgb()); vertices[5] = new CustomVertex.PositionColored(2.0f, -2.0f, 2.0f, Color.Blue.ToArgb()); vertices[6] = new CustomVertex.PositionColored(-2.0f, -2.0f, -2.0f, Color.Blue.ToArgb()); vertices[7] = new CustomVertex.PositionColored(2.0f, -2.0f, -2.0f, Color.Blue.ToArgb()); //정점 버퍼를 잠근다? using (GraphicsStream data = this._vertexBuffer.Lock(0, 0, LockFlags.None)) { //정점 데이터를 정점 버퍼에 씁니다. data.Write(vertices); //정점 버퍼의 락을 해제합니다. this._vertexBuffer.Unlock(); } //index buffer의 작성 //제2의 인수의 수치는 (삼각 다각형의수)*(하나의 삼각 다각형의 정점수)* (16비트의 인덱스 사이즈(2bytes)) this._indexBuffer = new IndexBuffer(this._device, 12 * 3 * 2, Usage.WriteOnly, Pool.Managed, true); //index buffer를 잠근다. using (GraphicsStream data = this._indexBuffer.Lock(0, 0, LockFlags.None)) { data.Write(_vertexIndices); this._indexBuffer.Unlock(); } //투영변환을 설정 this._device.Transform.Projection = Matrix.PerspectiveFovLH(Geometry.DegreeToRadian(60.0f), (float)this._device.Viewport.Width / (float)this._device.Viewport.Height, 1.0f, 100.0f); //CullMode를 none 로 해 다각형의 뒷면도 그려준다. //this._device.RenderState.CullMode = Cull.None; //라이트를 끔(현재는 true 로 하면 다각형이 새까맣게 될지 모른다) this._device.RenderState.Lighting = false; return(true); #endregion }
/// <summary> /// Initializes Direct3D with a render target and backbuffer size. /// </summary> /// <param name="renderWindow">Window to render to.</param> /// <param name="screenWidth">Width of the screen in pixels.</param> /// <param name="screenHeight">Height of the screen in pixels.</param> /// <param name="vsync">Should the renderer wait for a vsync before drawing?</param> /// <returns>true if successful, false otherwise.</returns> public bool Initialize(Control renderWindow, int screenWidth, int screenHeight, bool vsync) { // Verify that the device has not been initialized if (m_Device != null) { return(false); } // Set up the Direct3D device try { // Set the present parameters m_PresentParams = new PresentParameters( ); m_PresentParams.BackBufferWidth = screenWidth; m_PresentParams.BackBufferHeight = screenHeight; m_PresentParams.BackBufferFormat = Format.Unknown; m_PresentParams.BackBufferCount = 1; m_PresentParams.MultiSample = MultiSampleType.None; m_PresentParams.MultiSampleQuality = 0; m_PresentParams.SwapEffect = SwapEffect.Copy; m_PresentParams.DeviceWindow = renderWindow; m_PresentParams.Windowed = true; m_PresentParams.EnableAutoDepthStencil = false; m_PresentParams.FullScreenRefreshRateInHz = 0; m_PresentParams.PresentationInterval = (vsync) ? PresentInterval.Default : PresentInterval.Immediate; // Create the device m_Device = new Device(0, DeviceType.Hardware, renderWindow, CreateFlags.HardwareVertexProcessing, m_PresentParams); // Add the window to the render target list m_RenderTargets.Add(new RenderTarget(m_Device, m_PresentParams)); } catch (Exception ex) { DialogResult r = MessageBox.Show("Failed to Create D3D Device\n\n" + ex.Message, "ManagedDirect3D::Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return(false); } // Set up the Sprite object try { m_Sprite = new Sprite(m_Device); } catch (Exception ex) { DialogResult r = MessageBox.Show("Failed to Create the Sprite object\n\n" + ex.Message, "ManagedDirect3D::Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return(false); } // Set up the Texture for rectangles & lines try { // Allocate the texture m_Texture = new Texture(m_Device, 1, 1, 1, Usage.None, Format.A8R8G8B8, Pool.Managed); // Set the pixel color to White GraphicsStream stream = m_Texture.LockRectangle(0, LockFlags.Discard); byte[] color = new byte[4]; for (int i = 0; i < 4; i++) { color[i] = 0xFF; } stream.Write(color, 0, 4); m_Texture.UnlockRectangle(0); } catch (Exception ex) { DialogResult r = MessageBox.Show("Failed to Create the Texture Object\n\n" + ex.Message, "ManagedDirect3D::Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return(false); } // Set up the Font object try { m_FontDescription.FaceName = "Arial"; m_FontDescription.Quality = FontQuality.Default; m_FontDescription.Weight = FontWeight.SemiBold; m_Font = new Microsoft.DirectX.Direct3D.Font(m_Device, m_FontDescription); } catch (Exception ex) { DialogResult r = MessageBox.Show("Failed to Create the font Object\n\n" + ex.Message, "ManagedDirect3D::Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return(false); } return(true); }
public static VolumeTexture GenerateVolumeTexture(string path, string name, Device device, int width, int height, int depth, int levels, NoisePresetValues settings, Usage usage, Pool pool) { PerlinModuleWrapper noiseModule = new PerlinModuleWrapper(); // apply any presets if (settings != null) { if (settings.Seed != -1) { noiseModule.Seed = settings.Seed; } if (!double.IsNaN(settings.Frequency)) { noiseModule.Frequency = settings.Frequency; } if (!double.IsNaN(settings.Lacunarity)) { noiseModule.Lacunarity = settings.Lacunarity; } if (!double.IsNaN(settings.OctaveCount)) { noiseModule.OctaveCount = settings.OctaveCount; } if (!double.IsNaN(settings.Persistence)) { noiseModule.Persistence = settings.Persistence; } if (settings.Quality != (PerlinModuleWrapper.NoiseQuality)(int) - 1) { noiseModule.Quality = settings.Quality; } } // generate slices // vol needs to be 32-bit stride //VolumeTexture volumeTex = new VolumeTexture(device, 2, 2, 2, 1, usage, Format.A8B8G8R8, pool); float sliceStep = 0; if (levels > 1) { sliceStep = (float)depth / (levels - 1); } float z = depth; for (int level = 0; level < levels; level++) { // sample texels for slice //Volume vol = volumeTex.GetVolumeLevel(level); Texture tex = new Texture(device, width, height, 1, Usage.None, Format.X8R8G8B8, Pool.Managed); //GraphicsStream lvlStream = vol.LockBox(LockFlags.None); GraphicsStream lvlStream = tex.LockRectangle(0, LockFlags.None); for (float x = 0; x < width; x++) { for (float y = 0; y < height; y++) { // sample texel value double value = noiseModule.GetPerlinNoiseValue(x / 3f, y / 3f, z / 3f); // convert to colour data // just write in direct range of -1 -> 1 as 32-bit float //float valueF = (float)value; //lvlStream.Write(valueF); value++; if (value < 0) { value = 0; } if (value > 2) { value = 2; } byte R = (byte)(value * 127f); lvlStream.Write((byte)255); lvlStream.Write(R); lvlStream.Write(R); lvlStream.Write(R); } } tex.UnlockRectangle(0); TextureLoader.Save(path + name + level.ToString() + ".dds", ImageFileFormat.Dds, tex); tex.Dispose(); //vol.UnlockBox(); z += sliceStep; } return(null);// volumeTex; }
private void DrawSolidBondBlended(Vector3[] tCylinderPoints, Vector3[] tCylinderNormals, int[] tCylinderTris, IMoleculeMaterial matA, IMoleculeMaterial matB, Matrix final, GraphicsStream data, int positionPos, int normalPos, int diffusePos, ref long pos, int stride, Matrix rotation) { // write transformed template to buffer Vector4[] tfTriangles = Vector3.Transform(tCylinderPoints, final); //Vector4[] rtNormals = Vector3.Transform(tCylinderNormals, rotation); int halfWay = tfTriangles.Length / 2; for (int point = 0; point < tCylinderTris.Length; point++) { int pointIdx = tCylinderTris[point]; if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(tfTriangles[pointIdx].X); data.Write(tfTriangles[pointIdx].Y); data.Write(tfTriangles[pointIdx].Z); } if (normalPos != -1) { data.Seek(pos + normalPos, SeekOrigin.Begin); data.Write(tCylinderNormals[pointIdx].X); data.Write(tCylinderNormals[pointIdx].Y); data.Write(tCylinderNormals[pointIdx].Z); //bondsVerts[vertsIdx].Normal = new Vector3(rtNormals[pointIdx].X, // rtNormals[pointIdx].Y, // rtNormals[pointIdx].Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); if (pointIdx < halfWay) data.Write(matA.BaseColor.ToArgb()); else data.Write(matB.BaseColor.ToArgb()); } pos += stride; } }
private void ExportThread() { //create timer so we can check how long it takes to create the whole file Stopwatch stopwatch = new Stopwatch(); // Begin timing stopwatch.Start(); //for (int i = 0; i < _refLibrary.Count; i++) for (int i = Convert.ToInt16(text_test_framemin.Text); i < Convert.ToInt16(text_test_framemax.Text); i++) { showRefImage = false; //turns off the ref image while we render the new library nud_frame.Value = i; //just setting this value and then calling Render() is enough to cycle through the frames backgroundColour = Color.Black; //set the background to black so the crop code can detect the blank areas and remove pure black pixels from the image, if set to any other colour the image will have a solid colour background and not become transparent UpdateTextBoxes(); //this will set the _selectedRefImage for the current frame Render(); #region Save Snapshot of the Directx panel try { Surface backbuffer = device.GetBackBuffer(0, 0, BackBufferType.Mono); //SurfaceLoader.Save("Screenshot.bmp", ImageFileFormat.Bmp, backbuffer); //saves file (to test it is working) //if you continue to Render the DirectX panel while updating the GraphicsStream it causes the device to be lost and crashes //so I just call Render(); when I need to update the panel instead of using the infinite loop thread #region Graphics Lock GraphicsStream gs = backbuffer.LockRectangle(LockFlags.Discard); gs.Position = 0; //set start position int bytesPerPixel = 4; int currentPosition = 0; int heightInPixels = 250; int widthInPixels = 250; //Crop offsets int XMin = 249; int XMax = 0; int YMin = 249; int YMax = 0; for (int y = 0; y < heightInPixels; y++) { //couldn't use the Parallel.For loop as it would overwrite the GraphicsStream.Position because it was working on two or //more pixels at once causing a speckled effect as it misses pixels (well I think that is what was causing the errors I was having) //Parallel.For(0, heightInPixels, y => //{ //int currentLine = (y * ((widthInPixels * bytesPerPixel) + (4 *12))); //4*12 is how many pixels (12 for 500pixel image) was missing from each row (not sure why 12 but I guess the backbuffer extends beyond the screen) int currentLine = (y * (widthInPixels * bytesPerPixel) + (y * (4 * 6))); //4*6 is how many pixels (6 for 250pixel image) was missing from each row (not sure why 6 but I guess the backbuffer extends beyond the screen) for (int x = 0; x < widthInPixels; x++) { byte[] bu = new byte[4]; //new byte to store current pixel data currentPosition = currentLine + (x * bytesPerPixel); //calculate current position gs.Position = currentPosition; //set pixel position in GraphicsStream gs.Read(bu, 0, 4); //read image pixel data //gets RGB values int r = bu[2]; int g = bu[1]; int b = bu[0]; Color c = Color.FromArgb(r, g, b); if (c.R != backgroundColour.R && c.G != backgroundColour.G && c.B != backgroundColour.B) //if not the same as backgroundColour set the min/max values { if (XMin > x) { XMin = x; } if (XMax < x) { XMax = x; } if (YMin > y) { YMin = y; } if (YMax < y) { YMax = y; } } //if (y == YMin) //this is a way to show where the image is cropped //{ // bu[2] = 255; // bu[1] = 0; // bu[0] = 0; //} gs.Position = currentPosition; //sets the position back to the starting pixel gs.Write(bu, 0, 4); //updates the GraphicsStream with the new changes } //}); //end of Parallel.For loop } //Shows the detected bounds of the image for testing //MessageBox.Show("XMin: " + XMin // + Environment.NewLine + "XMax: " + XMax // + Environment.NewLine + "YMin: " + YMin // + Environment.NewLine + "YMax: " + YMax // + Environment.NewLine + "Width: " + (XMax - XMin) // + Environment.NewLine + "Height: " + (YMax - YMin)); backbuffer.UnlockRectangle(); gs.Dispose(); #endregion Bitmap Preview = new Bitmap(SurfaceLoader.SaveToStream(ImageFileFormat.Bmp, backbuffer)); #region crop //create target image and draw cropped part of the Preview image to the target image Bitmap target = new Bitmap((XMax - XMin) + 1, (YMax - YMin) + 1, PixelFormat.Format32bppArgb); using (Graphics g = Graphics.FromImage(target)) { g.DrawImage(Preview, new RectangleF(0, 0, target.Width, target.Height), new RectangleF(XMin, YMin, (XMax - XMin) + 1, (YMax - YMin) + 1), GraphicsUnit.Pixel); } #endregion //Add Image and offsets to the _library _library.AddImage(target, (short)(XMin - characterGlobalOffsetX), (short)(YMin - characterGlobalOffsetY)); //target.Save("Test1.PNG", ImageFormat.Png); //testing screen capture and crop image from directx works by saving to file target.Dispose(); Preview.Dispose(); backbuffer.Dispose(); } catch (Direct3DXException ee) //Display error Messages with the DirectX code { MessageBox.Show("Message: " + ee.Message + Environment.NewLine + "ErrorString: " + ee.ErrorString + Environment.NewLine + "ErrorCode: " + ee.ErrorCode + Environment.NewLine + "StackTrace: " + ee.StackTrace ); } #endregion toolStripProgressBar.Value = i + 1; } //save file as normal .lib (true = reference file, false = normal .lib) _library.Save(false); stopwatch.Stop(); MessageBox.Show(string.Format("Time Taken: {0:n0} Seconds", stopwatch.Elapsed.TotalMilliseconds / 1000)); toolStripProgressBar.Value = 0; showRefImage = true; nud_frame.Value = 0; Render(); }
/// <summary> /// 頂点をDirect3Dバッファに書き込みます。 /// </summary> /// <param name="device">device</param> public void WriteBuffer(Device device) { Vector3[] normals = new Vector3[vertices.Count]; foreach (MqoFace face in faces) { Vector3 v1 = vertices[face.a].position - vertices[face.c].position; Vector3 v2 = vertices[face.b].position - vertices[face.c].position; Vector3 n = Vector3.Normalize(Vector3.Cross(v2, v1)); normals[face.a] += n; normals[face.b] += n; normals[face.c] += n; } { int i = 0; foreach (UVertex v in vertices) { v.normal = Vector3.Normalize(normals[i]); i++; } } UVertexHeap heap = new UVertexHeap(); List <ushort> indices = new List <ushort>(faces.Count * 3); { int face_len = 0; MqoAttributeRange ar = at.Start(face_len, faces[0].mtl); foreach (MqoFace face in faces) { if (face.mtl != ar.mtl) { face_len += indices.Count / 3; ar = at.Next(face_len, face.mtl); } UVertex a = new UVertex(vertices[face.a].position, vertices[face.a].normal, face.ta.X, 1 - face.ta.Y, face.mtl); UVertex b = new UVertex(vertices[face.b].position, vertices[face.b].normal, face.tb.X, 1 - face.tb.Y, face.mtl); UVertex c = new UVertex(vertices[face.c].position, vertices[face.c].normal, face.tc.X, 1 - face.tc.Y, face.mtl); indices.Add(heap.Add(a)); indices.Add(heap.Add(c)); indices.Add(heap.Add(b)); } { face_len += indices.Count / 3; at.Finish(face_len); ar = null; } } if (dm != null) { dm.Dispose(); dm = null; } dm = new Mesh(at.FaceCount, heap.Count, MeshFlags.Managed | MeshFlags.WriteOnly, ve, device); // // rewrite vertex buffer // { GraphicsStream gs = dm.LockVertexBuffer(LockFlags.None); { foreach (UVertex v in heap.ary) { gs.Write(v.position); gs.Write(1.0f); gs.Write(0.0f); gs.Write(0.0f); gs.Write(0.0f); gs.Write(0); gs.Write(v.normal); gs.Write(v.u); gs.Write(v.v); } } dm.UnlockVertexBuffer(); } // // rewrite index buffer // { GraphicsStream gs = dm.LockIndexBuffer(LockFlags.None); { foreach (ushort idx in indices) { gs.Write(idx); } } dm.UnlockIndexBuffer(); } // // rewrite attribute buffer // { int[] attribBuffer = dm.LockAttributeBufferArray(LockFlags.None); foreach (MqoAttributeRange ar in at.Ranges) { for (int i = 0; i < ar.FaceCount; i++) { attribBuffer[ar.FaceStart + i] = ar.AttributeId; } } dm.UnlockAttributeBuffer(attribBuffer); dm.SetAttributeTable(at.GenerateAttributeTable(0, heap.Count)); } }
/// <summary> /// This event-handler is a good place to create and initialize any /// Direct3D related objects, which may become invalid during a /// device reset. /// </summary> public void OnResetDevice(object sender, EventArgs e) { logMessageToFile("Reset device"); Device device = (Device)sender; if (device == null) { return; } this.Invalidate(); device.RenderState.FillMode = getFillMode(); device.RenderState.ZBufferEnable = true; setupShaders(); vertexBuffers.Clear(); indexBuffers.Clear(); // // Create a vertex buffer... // uint numPolygons = 0; uint numVertices = 0; for (int i = 0; i < models.Count; i++) { if (models[i] != null && models[i].numVertices > 0) { numPolygons += models[i].numPolygons; numVertices += models[i].numVertices; vertexDeclaration = new VertexDeclaration(device, MadScience.Render.vertex.Elements); VertexBuffer vertexBuffer = new VertexBuffer(typeof(MadScience.Render.vertex), (int)models[i].numVertices, device, Usage.Dynamic | Usage.WriteOnly, MadScience.Render.vertex.FVF_Flags, Pool.Default); GraphicsStream gStream = vertexBuffer.Lock(0, 0, LockFlags.None); // Now, copy the vertex data into the vertex buffer gStream.Write(models[i].vertexData.ToArray()); vertexBuffer.Unlock(); vertexBuffers.Add(vertexBuffer); // // Create an index buffer to use with our indexed vertex buffer... // IndexBuffer indexBuffer = new IndexBuffer(typeof(int), (int)(models[i].faceData.Count * 2), device, Usage.WriteOnly, Pool.Default); gStream = indexBuffer.Lock(0, 0, LockFlags.None); // Now, copy the indices data into the index buffer gStream.Write(models[i].faceData.ToArray()); indexBuffer.Unlock(); indexBuffers.Add(indexBuffer); } } this.statusLabel.Text = "Model loaded. " + models.Count.ToString() + " part(s), total " + String.Format("{0:0} polygons, ", numPolygons) + String.Format("{0:0} vertices", numVertices); }
/* * ar.AttributeId = 0; * ar.FaceStart = 0; * ar.FaceCount = 0; * ar.VertexStart = 0; * ar.VertexCount = 0; */ public void LoadMesh() { foreach (TSOMesh tm in meshes) { foreach (TSOMesh tm_sub in tm.sub_meshes) { int numVertices = tm_sub.vertices.Length; int numFaces = numVertices - 2; tm_sub.dm = new Mesh(numFaces, numVertices, MeshFlags.Managed | MeshFlags.WriteOnly, ve, device); // // rewrite vertex buffer // { GraphicsStream gs = tm_sub.dm.LockVertexBuffer(LockFlags.None); { for (int i = 0; i < tm_sub.vertices.Length; i++) { vertex_field tv = tm_sub.vertices[i]; gs.Write(tv.position); for (int j = 0; j < 4; j++) { gs.Write(tv.skin_weights[j].weight); } gs.Write(tv.skin_weight_indices); gs.Write(tv.normal); gs.Write(tv.u); gs.Write(1 - tv.v); } } tm_sub.dm.UnlockVertexBuffer(); } // // rewrite index buffer // { GraphicsStream gs = tm_sub.dm.LockIndexBuffer(LockFlags.None); { for (int i = 2; i < tm_sub.vertices.Length; i++) { if (i % 2 != 0) { gs.Write((short)(i - 0)); gs.Write((short)(i - 1)); gs.Write((short)(i - 2)); } else { gs.Write((short)(i - 2)); gs.Write((short)(i - 1)); gs.Write((short)(i - 0)); } } } tm_sub.dm.UnlockIndexBuffer(); } // // rewrite attribute buffer // { tm_sub.dm.SetAttributeTable(new AttributeRange[] { ar }); } } } }
/// <summary> /// Crear vertices para la cara Up /// </summary> private void cargarVerticesUp(GraphicsStream data, int color) { TgcSceneLoader.DiffuseMapVertex v; Vector3 n = new Vector3(0, 1, 0); v = new TgcSceneLoader.DiffuseMapVertex(); v.Position = new Vector3( center.X - size.X / 2 - skyEpsilon, center.Y + size.Y / 2, center.Z - size.Z / 2 - skyEpsilon ); v.Normal = n; v.Color = color; v.Tu = 1; v.Tv = 0; data.Write(v); v = new TgcSceneLoader.DiffuseMapVertex(); v.Position = new Vector3( center.X - size.X / 2 - skyEpsilon, center.Y + size.Y / 2, center.Z + size.Z / 2 + skyEpsilon ); v.Normal = n; v.Color = color; v.Tu = 0; v.Tv = 0; data.Write(v); v = new TgcSceneLoader.DiffuseMapVertex(); v.Position = new Vector3( center.X + size.X / 2 + skyEpsilon, center.Y + size.Y / 2, center.Z + size.Z / 2 + skyEpsilon ); v.Normal = n; v.Color = color; v.Tu = 0; v.Tv = 1; data.Write(v); v = new TgcSceneLoader.DiffuseMapVertex(); v.Position = new Vector3( center.X + size.X / 2 + skyEpsilon, center.Y + size.Y / 2, center.Z - size.Z / 2 - skyEpsilon ); v.Normal = n; v.Color = color; v.Tu = 1; v.Tv = 1; data.Write(v); }
private void GenericDrawBondSolidBlended(Vector3 start, Vector3 end, IMoleculeMaterial matA, IMoleculeMaterial matB, GraphicsStream data, ref long pos, int stride, int positionPos, int diffusePos) { if (positionPos != -1) { data.Seek(pos + positionPos, SeekOrigin.Begin); data.Write(start.X); data.Write(start.Y); data.Write(start.Z); data.Seek(pos + stride + positionPos, SeekOrigin.Begin); data.Write(end.X); data.Write(end.Y); data.Write(end.Z); } if (diffusePos != -1) { data.Seek(pos + diffusePos, SeekOrigin.Begin); data.Write(matA.BaseColor.ToArgb()); data.Seek(pos + stride + diffusePos, SeekOrigin.Begin); data.Write(matB.BaseColor.ToArgb()); } pos += stride * 2; }