// This is called resets when the device is reset // (when resized or display adapter was changed) public void ReloadResource() { float radius = VisualVertex.DEFAULT_SIZE * General.Settings.GZVertexScale3D; WorldVertex c = new WorldVertex(); WorldVertex v0 = new WorldVertex(-radius, -radius, -radius); WorldVertex v1 = new WorldVertex(-radius, radius, -radius); WorldVertex v2 = new WorldVertex(radius, radius, -radius); WorldVertex v3 = new WorldVertex(radius, -radius, -radius); WorldVertex v4 = new WorldVertex(-radius, -radius, radius); WorldVertex v5 = new WorldVertex(-radius, radius, radius); WorldVertex v6 = new WorldVertex(radius, radius, radius); WorldVertex v7 = new WorldVertex(radius, -radius, radius); WorldVertex[] vu = new [] { c, v0, c, v1, c, v2, c, v3, v0, v1, v1, v2, v2, v3, v3, v0 }; upper = new VertexBuffer(General.Map.Graphics.Device, WorldVertex.Stride * vu.Length, Usage.WriteOnly | Usage.Dynamic, VertexFormat.None, Pool.Default); upper.Lock(0, WorldVertex.Stride * vu.Length, LockFlags.None).WriteRange(vu); upper.Unlock(); WorldVertex[] vl = new[] { c, v4, c, v5, c, v6, c, v7, v4, v5, v5, v6, v6, v7, v7, v4 }; lower = new VertexBuffer(General.Map.Graphics.Device, WorldVertex.Stride * vl.Length, Usage.WriteOnly | Usage.Dynamic, VertexFormat.None, Pool.Default); lower.Lock(0, WorldVertex.Stride * vl.Length, LockFlags.None).WriteRange(vl); lower.Unlock(); }
// villsa 9/15/11 private void SetupThingArrow() { const int totalvertices = 6; WorldVertex[] tv = new WorldVertex[totalvertices]; tv[0] = new WorldVertex(0.0f, 0.0f, 0.5f); tv[1] = new WorldVertex(0.0f, 1.35f, 0.5f); tv[2] = new WorldVertex(0.0f, 1.35f, 0.5f); tv[3] = new WorldVertex(0.175f, 1.1f, 0.5f); tv[4] = new WorldVertex(0.0f, 1.35f, 0.5f); tv[5] = new WorldVertex(-0.175f, 1.1f, 0.5f); // Create vertexbuffer thingarrow = new VertexBuffer(General.Map.Graphics.Device, WorldVertex.Stride * totalvertices, Usage.WriteOnly | Usage.Dynamic, VertexFormat.None, Pool.Default); DataStream bufferstream = thingarrow.Lock(0, WorldVertex.Stride * totalvertices, LockFlags.Discard); bufferstream.WriteRange <WorldVertex>(tv); thingarrow.Unlock(); bufferstream.Dispose(); }
// Called when all resource must be reloaded public void ReloadResource() { foreach (KeyValuePair <int, SurfaceBufferSet> set in sets) { // Rebuild vertex buffers for (int i = 0; i < set.Value.buffersizes.Count; i++) { // Make the new buffer! VertexBuffer b = new VertexBuffer(General.Map.Graphics.Device, FlatVertex.Stride * set.Value.buffersizes[i], Usage.WriteOnly | Usage.Dynamic, VertexFormat.None, Pool.Default); // Start refilling the buffer with sector geometry int vertexoffset = 0; DataStream bstream = b.Lock(0, FlatVertex.Stride * set.Value.buffersizes[i], LockFlags.Discard); foreach (SurfaceEntry e in set.Value.entries) { if (e.bufferindex == i) { // Fill buffer bstream.Seek(e.vertexoffset * FlatVertex.Stride, SeekOrigin.Begin); bstream.WriteRange(e.floorvertices); bstream.WriteRange(e.ceilvertices); } } // Unlock buffer b.Unlock(); bstream.Dispose(); // Add to list set.Value.buffers[i] = b; } } resourcesunloaded = false; }
// This updates the text if needed public void Update(float translatex, float translatey, float scalex, float scaley) { // Check if transformation changed and needs to be updated if (transformcoords && (translatex != lasttranslatex || translatey != lasttranslatey || scalex != lastscalex || scaley != lastscaley)) { lasttranslatex = translatex; //mxd lasttranslatey = translatey; //mxd lastscalex = scalex; //mxd lastscaley = scaley; //mxd updateneeded = true; } // Update if needed if (updateneeded || textureupdateneeded) { // Only build when there are any vertices if (text.Length > 0) { // Transform? Vector2D abspos = (transformcoords ? location.GetTransformed(translatex, translatey, scalex, scaley) : location); // Update text and texture sizes if (textsize.IsEmpty || texturesize.IsEmpty) { textorigin = new PointF(4, 3); textrect = new RectangleF(textorigin, General.Interface.MeasureString(text, font)); textrect.Width = (float)Math.Round(textrect.Width); textrect.Height = (float)Math.Round(textrect.Height); bgrect = new RectangleF(0, 0, textrect.Width + textorigin.X * 2, textrect.Height + textorigin.Y * 2); // Store calculated text size... textsize = new SizeF(textrect.Width + textorigin.X * 2, textrect.Height + textorigin.Y * 2); // Make PO2 image, for speed and giggles... texturesize = new Size(General.NextPowerOf2((int)textsize.Width), General.NextPowerOf2((int)textsize.Height)); switch (alignx) { case TextAlignmentX.Center: bgrect.X = (texturesize.Width - bgrect.Width) / 2; break; case TextAlignmentX.Right: bgrect.X = texturesize.Width - bgrect.Width; break; } switch (aligny) { case TextAlignmentY.Middle: bgrect.Y = (texturesize.Height - bgrect.Height) / 2; break; case TextAlignmentY.Bottom: bgrect.Y = texturesize.Height - bgrect.Height; break; } textrect.X += bgrect.X; textrect.Y += bgrect.Y; } // Align the text horizontally float beginx = 0; switch (alignx) { case TextAlignmentX.Left: beginx = abspos.x; break; case TextAlignmentX.Center: beginx = abspos.x - texturesize.Width * 0.5f; break; case TextAlignmentX.Right: beginx = abspos.x - texturesize.Width; break; } // Align the text vertically float beginy = 0; switch (aligny) { case TextAlignmentY.Top: beginy = abspos.y; break; case TextAlignmentY.Middle: beginy = abspos.y - texturesize.Height * 0.5f; break; case TextAlignmentY.Bottom: beginy = abspos.y - texturesize.Height; break; } //mxd. Skip when not on screen... RectangleF abssize = new RectangleF(beginx, beginy, texturesize.Width, texturesize.Height); Size windowsize = General.Map.Graphics.RenderTarget.ClientSize; skiprendering = (abssize.Right < 0.1f) || (abssize.Left > windowsize.Width) || (abssize.Bottom < 0.1f) || (abssize.Top > windowsize.Height); if (skiprendering) { return; } //mxd. Update texture if needed if (textureupdateneeded) { // Get rid of old texture if (texture != null) { texture.Dispose(); texture = null; } // Create label image Bitmap img = CreateLabelImage(text, font, color, backcolor, drawbg, textrect, bgrect, texturesize, textorigin); //texturesize = img.Size; // Create texture MemoryStream memstream = new MemoryStream((img.Size.Width * img.Size.Height * 4) + 4096); img.Save(memstream, ImageFormat.Bmp); memstream.Seek(0, SeekOrigin.Begin); texture = Texture.FromStream(General.Map.Graphics.Device, memstream, (int)memstream.Length, img.Size.Width, img.Size.Height, 1, Usage.None, Format.Unknown, Pool.Managed, General.Map.Graphics.PostFilter, General.Map.Graphics.MipGenerateFilter, 0); } //mxd. Create the buffer if (textbuffer == null || textbuffer.Disposed) { textbuffer = new VertexBuffer(General.Map.Graphics.Device, 4 * FlatVertex.Stride, Usage.Dynamic | Usage.WriteOnly, VertexFormat.None, Pool.Default); } //mxd. Lock the buffer using (DataStream stream = textbuffer.Lock(0, 4 * FlatVertex.Stride, LockFlags.Discard | LockFlags.NoSystemLock)) { FlatQuad quad = new FlatQuad(PrimitiveType.TriangleStrip, beginx, beginy, beginx + texturesize.Width, beginy + texturesize.Height); stream.WriteRange(quad.Vertices); } // Done filling the vertex buffer textbuffer.Unlock(); } else { // No faces in polygon textsize = SizeF.Empty; //mxd texturesize = Size.Empty; //mxd skiprendering = true; //mxd } // Text updated updateneeded = false; textureupdateneeded = false; //mxd } }
// This sets up the thing cage private void SetupThingCage() { const int totalvertices = 36; WorldVertex[] tv = new WorldVertex[totalvertices]; float x0 = -1.0f; float x1 = 1.0f; float y0 = -1.0f; float y1 = 1.0f; float z0 = 0.0f; float z1 = 1.0f; float u0 = 0.0f; float u1 = 1.0f; float v0 = 0.0f; float v1 = 1.0f; int c = -1; // Front tv[0] = new WorldVertex(x0, y0, z0, c, u0, v0); tv[1] = new WorldVertex(x0, y0, z1, c, u0, v1); tv[2] = new WorldVertex(x1, y0, z0, c, u1, v0); tv[3] = new WorldVertex(x1, y0, z0, c, u1, v0); tv[4] = new WorldVertex(x0, y0, z1, c, u0, v1); tv[5] = new WorldVertex(x1, y0, z1, c, u1, v1); // Right tv[6] = new WorldVertex(x1, y0, z0, c, u0, v0); tv[7] = new WorldVertex(x1, y0, z1, c, u0, v1); tv[8] = new WorldVertex(x1, y1, z0, c, u1, v0); tv[9] = new WorldVertex(x1, y1, z0, c, u1, v0); tv[10] = new WorldVertex(x1, y0, z1, c, u0, v1); tv[11] = new WorldVertex(x1, y1, z1, c, u1, v1); // Back tv[12] = new WorldVertex(x1, y1, z0, c, u0, v0); tv[13] = new WorldVertex(x1, y1, z1, c, u0, v1); tv[14] = new WorldVertex(x0, y1, z0, c, u1, v0); tv[15] = new WorldVertex(x0, y1, z0, c, u1, v0); tv[16] = new WorldVertex(x1, y1, z1, c, u0, v1); tv[17] = new WorldVertex(x0, y1, z1, c, u1, v1); // Left tv[18] = new WorldVertex(x0, y1, z0, c, u0, v1); tv[19] = new WorldVertex(x0, y1, z1, c, u0, v0); tv[20] = new WorldVertex(x0, y0, z1, c, u1, v0); tv[21] = new WorldVertex(x0, y1, z0, c, u1, v0); tv[22] = new WorldVertex(x0, y0, z1, c, u0, v1); tv[23] = new WorldVertex(x0, y0, z0, c, u1, v1); // Top tv[24] = new WorldVertex(x0, y0, z1, c, u0, v0); tv[25] = new WorldVertex(x0, y1, z1, c, u0, v1); tv[26] = new WorldVertex(x1, y0, z1, c, u1, v0); tv[27] = new WorldVertex(x1, y0, z1, c, u1, v0); tv[28] = new WorldVertex(x0, y1, z1, c, u0, v1); tv[29] = new WorldVertex(x1, y1, z1, c, u1, v1); // Bottom tv[30] = new WorldVertex(x1, y0, z0, c, u1, v0); tv[31] = new WorldVertex(x0, y1, z0, c, u0, v1); tv[32] = new WorldVertex(x0, y0, z0, c, u0, v0); tv[33] = new WorldVertex(x1, y0, z0, c, u1, v0); tv[34] = new WorldVertex(x1, y1, z0, c, u1, v1); tv[35] = new WorldVertex(x0, y1, z0, c, u0, v1); // Create vertexbuffer thingcage = new VertexBuffer(General.Map.Graphics.Device, WorldVertex.Stride * totalvertices, Usage.WriteOnly | Usage.Dynamic, VertexFormat.None, Pool.Default); DataStream bufferstream = thingcage.Lock(0, WorldVertex.Stride * totalvertices, LockFlags.Discard); bufferstream.WriteRange <WorldVertex>(tv); thingcage.Unlock(); bufferstream.Dispose(); }
// This updates the text if needed internal void Update(float translatex, float translatey, float scalex, float scaley) { RectangleF absview; float beginx = 0; float beginy = 0; byte[] textbytes; DataStream stream; // Check if transformation changed and needs to be updated if (transformcoords) { if ((translatex != lasttranslatex) || (translatey != lasttranslatey) || (scalex != lastscalex) || (scaley != lastscaley)) { updateneeded = true; } } // Update if needed if (updateneeded) { // Only build when there are any vertices if (text.Length > 0) { // Do we have to make a new buffer? if ((textbuffer == null) || (text.Length > capacity)) { // Dispose previous if (textbuffer != null) { textbuffer.Dispose(); } // Determine new capacity if (capacity < text.Length) { capacity = text.Length; } // Create the buffer textbuffer = new VertexBuffer(General.Map.Graphics.Device, capacity * 12 * FlatVertex.Stride, Usage.Dynamic | Usage.WriteOnly, VertexFormat.None, Pool.Default); } // Transform? if (transformcoords) { // Calculate absolute coordinates Vector2D lt = new Vector2D(rect.Left, rect.Top); Vector2D rb = new Vector2D(rect.Right, rect.Bottom); lt = lt.GetTransformed(translatex, translatey, scalex, scaley); rb = rb.GetTransformed(translatex, translatey, scalex, scaley); absview = new RectangleF(lt.x, lt.y, rb.x - lt.x, rb.y - lt.y); } else { // Fixed coordinates absview = rect; } // Calculate text dimensions size = General.Map.Graphics.Font.GetTextSize(text, scale); // Align the text horizontally switch (alignx) { case TextAlignmentX.Left: beginx = absview.X; break; case TextAlignmentX.Center: beginx = absview.X + (absview.Width - size.Width) * 0.5f; break; case TextAlignmentX.Right: beginx = absview.X + absview.Width - size.Width; break; } // Align the text vertically switch (aligny) { case TextAlignmentY.Top: beginy = absview.Y; break; case TextAlignmentY.Middle: beginy = absview.Y + (absview.Height - size.Height) * 0.5f; break; case TextAlignmentY.Bottom: beginy = absview.Y + absview.Height - size.Height; break; } // Get the ASCII bytes for the text textbytes = Encoding.ASCII.GetBytes(text); // Lock the buffer stream = textbuffer.Lock(0, capacity * 12 * FlatVertex.Stride, LockFlags.Discard | LockFlags.NoSystemLock); // Go for all chars in text to create the backgrounds float textx = beginx; foreach (byte b in textbytes) { General.Map.Graphics.Font.SetupVertices(stream, b, scale, backcolor.ToInt(), ref textx, beginy, size.Height, 0.5f); } // Go for all chars in text to create the text textx = beginx; foreach (byte b in textbytes) { General.Map.Graphics.Font.SetupVertices(stream, b, scale, color.ToInt(), ref textx, beginy, size.Height, 0.0f); } // Done filling the vertex buffer textbuffer.Unlock(); stream.Dispose(); // Calculate number of triangles numfaces = text.Length * 4; } else { // No faces in polygon numfaces = 0; size = new SizeF(0f, 0f); } // Text updated updateneeded = false; } }