public IsometricRenderer(Game game) { _input = game.Services.GetService<IInputState>(); _spriteBatch = new SpriteBatch3D(game); _vectors = new VectorRenderer(game.GraphicsDevice, game.Content); PickType = PickTypes.PickNothing; _vertexBufferStretched = new VertexPositionNormalTextureHue[] { new VertexPositionNormalTextureHue(new Vector3(), new Vector3(), new Vector3(0, 0, 0)), new VertexPositionNormalTextureHue(new Vector3(), new Vector3(), new Vector3(1, 0, 0)), new VertexPositionNormalTextureHue(new Vector3(), new Vector3(), new Vector3(0, 1, 0)), new VertexPositionNormalTextureHue(new Vector3(), new Vector3(), new Vector3(1, 1, 0)) }; }
public static void RenderObjects(SpriteBatch3D sb) { foreach (MapObjectPrerendered obj in _objects) obj.Prerender(sb); _objects.Clear(); }
public SpriteBatchUI(Game game) { _sb = new SpriteBatch3D(game); }
protected abstract void Prerender(SpriteBatch3D sb);
private bool Draw3DStretched(SpriteBatch3D sb, Vector3 drawPosition, MouseOverList molist, PickTypes pickType, int maxAlt) { // this is an isometric stretched tile and needs a specialized draw routine. _vertexBufferAlternate[0].Position = drawPosition + _vertex0_yOffset; _vertexBufferAlternate[1].Position = drawPosition + _vertex1_yOffset; _vertexBufferAlternate[2].Position = drawPosition + _vertex2_yOffset; _vertexBufferAlternate[3].Position = drawPosition + _vertex3_yOffset; if (!sb.Draw(_draw_texture, _vertexBufferAlternate)) return false; if ((pickType & _pickType) == _pickType) if (molist.IsMouseInObjectIsometric(_vertexBufferAlternate)) { MouseOverItem item = new MouseOverItem(_draw_texture, _vertexBufferAlternate[0].Position, this); item.Vertices = new Vector3[4] { _vertexBufferAlternate[0].Position, _vertexBufferAlternate[1].Position, _vertexBufferAlternate[2].Position, _vertexBufferAlternate[3].Position }; molist.Add2DItem(item); } return true; }
internal override bool Draw(SpriteBatch3D sb, Vector3 drawPosition, MouseOverList molist, PickTypes pickType, int maxAlt) { _draw_Y = (int)(Z * 4) + _draw_height - 44; if (_noDraw) return false; return base.Draw(sb, drawPosition, molist, pickType, maxAlt); }
internal override bool Draw(SpriteBatch3D sb, Vector3 drawPosition, MouseOverList molist, PickTypes pickType, int maxAlt) { return base.Draw(sb, drawPosition, molist, pickType, maxAlt); }
internal override bool Draw(SpriteBatch3D sb, Vector3 drawPosition, MouseOverList molist, PickTypes pickType, int maxAlt) { if (_noDraw || _mustUpdateSurroundings || !IsometricRenderer.DrawTerrain) return false; if (!_draw_3DStretched) return base.Draw(sb, drawPosition, molist, pickType, 255); else return Draw3DStretched(sb, drawPosition, molist, pickType, 255); }
internal override bool Draw(SpriteBatch3D sb, Vector3 drawPosition, MouseOverList molist, PickTypes pickType, int maxAlt) { sb.Draw(_texture, Vertices); return false; }
internal virtual bool Draw(SpriteBatch3D sb, Vector3 drawPosition, MouseOverList molist, PickTypes pickType, int maxAlt) { VertexPositionNormalTextureHue[] vertexBuffer; if (Z >= maxAlt) return false; if (_draw_flip) { // 2 0 // |\ | // | \| // 3 1 vertexBuffer = VertexPositionNormalTextureHue.PolyBufferFlipped; vertexBuffer[0].Position = drawPosition; vertexBuffer[0].Position.X += _draw_X + 44; vertexBuffer[0].Position.Y -= _draw_Y; vertexBuffer[1].Position = vertexBuffer[0].Position; vertexBuffer[1].Position.Y += _draw_height; vertexBuffer[2].Position = vertexBuffer[0].Position; vertexBuffer[2].Position.X -= _draw_width; vertexBuffer[3].Position = vertexBuffer[1].Position; vertexBuffer[3].Position.X -= _draw_width; } else { // 0---1 // / // / // 2---3 vertexBuffer = VertexPositionNormalTextureHue.PolyBuffer; vertexBuffer[0].Position = drawPosition; vertexBuffer[0].Position.X -= _draw_X; vertexBuffer[0].Position.Y -= _draw_Y; vertexBuffer[1].Position = vertexBuffer[0].Position; vertexBuffer[1].Position.X += _draw_width; vertexBuffer[2].Position = vertexBuffer[0].Position; vertexBuffer[2].Position.Y += _draw_height; vertexBuffer[3].Position = vertexBuffer[1].Position; vertexBuffer[3].Position.Y += _draw_height; } if (vertexBuffer[0].Hue != _draw_hue) vertexBuffer[0].Hue = vertexBuffer[1].Hue = vertexBuffer[2].Hue = vertexBuffer[3].Hue = _draw_hue; if (!sb.Draw(_draw_texture, vertexBuffer)) { return false; } if (_draw_IsometricOverlap) { drawIsometricOverlap(sb, vertexBuffer, new Vector2(drawPosition.X, drawPosition.Y - (Z * 4))); } if ((pickType & _pickType) == _pickType) { if (((!_draw_flip) && molist.IsMouseInObject(vertexBuffer[0].Position, vertexBuffer[3].Position)) || ((_draw_flip) && molist.IsMouseInObject(vertexBuffer[2].Position, vertexBuffer[1].Position))) { MouseOverItem item; if (!_draw_flip) { item = new MouseOverItem(_draw_texture, vertexBuffer[0].Position, this); item.Vertices = new Vector3[4] { vertexBuffer[0].Position, vertexBuffer[1].Position, vertexBuffer[2].Position, vertexBuffer[3].Position }; } else { item = new MouseOverItem(_draw_texture, vertexBuffer[2].Position, this); item.Vertices = new Vector3[4] { vertexBuffer[2].Position, vertexBuffer[0].Position, vertexBuffer[3].Position, vertexBuffer[1].Position }; } molist.Add2DItem(item); } } return true; }
/// <summary> /// drawIsometricOverlap will create deferred objects that will be drawn in places where a MapObject /// might be overlapped by subsequently drawn objects in the world. NOTE that the vertices of the /// deferred objects created by this routine are NOT perfect - they may have UV coords that are greater /// than 1.0f or less than 0.0f. This would create graphical artifacts, but we rely on our HLSL shader /// to ignore these. /// </summary> /// <param name="sb">The SpriteBatch3D instance passed to the calling Draw() routine.</param> /// <param name="vertices">The Vertices that were drawn by the calling MapObject.</param> /// <param name="drawPosition">The upper-left hand corner of the tile where the calling MapObject was drawn.</param> private void drawIsometricOverlap(SpriteBatch3D sb, VertexPositionNormalTextureHue[] vertices, Vector2 screenPosition) { Vector2 overlapCurrent = new Vector2(screenPosition.X + 22, screenPosition.Y + 44); Vector2 overlapToHere = _draw_flip ? new Vector2(vertices[1].Position.X, vertices[1].Position.Y) : new Vector2(vertices[3].Position.X, vertices[3].Position.Y); int tileX, tileY; MapTile tile; MapObjectDeferred deferred; VertexPositionNormalTextureHue[] verts; if (overlapToHere.Y > (overlapCurrent.Y - 22)) { tileX = Position.X; tileY = Position.Y + (int)Math.Ceiling((overlapToHere.Y - (overlapCurrent.Y - 22)) / 22f); // Get the tile associated with this (x, y) position. If the tile is not loaded, don't add a deferred object // (it'll be offscreen so it doesn't matter). tile = IsometricRenderer.InternalMap.GetMapTile(tileX, tileY, false); if (tile != null) { deferred = new MapObjectDeferred(_draw_texture, this); deferred.Position.X = tileX; deferred.Position.Y = tileY; verts = deferred.Vertices; if (_draw_flip) { // 0 // / \ // / 1 // / / // 2---3 verts[0].Position = new Vector3(overlapCurrent, 0) + new Vector3(-22, -22, 0); verts[0].TextureCoordinate = new Vector3((overlapToHere.X - verts[0].Position.X) / _draw_texture.Width, 1f - (overlapToHere.Y - verts[0].Position.Y) / _draw_texture.Height, 0); verts[1].Position = new Vector3(overlapCurrent, 0); verts[1].TextureCoordinate = new Vector3((overlapToHere.X - verts[1].Position.X) / _draw_texture.Width, 1f - (overlapToHere.Y - verts[1].Position.Y) / _draw_texture.Height, 0); verts[2].Position = new Vector3(verts[0].Position.X - (overlapToHere.Y - verts[0].Position.Y), overlapToHere.Y, 0); verts[2].TextureCoordinate = new Vector3((overlapToHere.X - verts[2].Position.X) / _draw_texture.Width, 1f - (overlapToHere.Y - verts[2].Position.Y) / _draw_texture.Height, 0); verts[3].Position = new Vector3(verts[1].Position.X - (overlapToHere.Y - verts[1].Position.Y), overlapToHere.Y, 0); verts[3].TextureCoordinate = new Vector3((overlapToHere.X - verts[3].Position.X) / _draw_texture.Width, 1f - (overlapToHere.Y - verts[3].Position.Y) / _draw_texture.Height, 0); } else { // 1 // / \ // / 3 // / / // 0---2 verts[1].Position = new Vector3(overlapCurrent, 0) + new Vector3(-22, -22, 0); verts[1].TextureCoordinate = new Vector3(1f - (overlapToHere.X - verts[1].Position.X) / _draw_texture.Width, 1f - (overlapToHere.Y - verts[1].Position.Y) / _draw_texture.Height, 0); verts[3].Position = new Vector3(overlapCurrent, 0); verts[3].TextureCoordinate = new Vector3(1f - (overlapToHere.X - verts[3].Position.X) / _draw_texture.Width, 1f - (overlapToHere.Y - verts[3].Position.Y) / _draw_texture.Height, 0); verts[0].Position = new Vector3(verts[1].Position.X - (overlapToHere.Y - verts[1].Position.Y), overlapToHere.Y, 0); verts[0].TextureCoordinate = new Vector3(1f - (overlapToHere.X - verts[0].Position.X) / _draw_texture.Width, 1f - (overlapToHere.Y - verts[0].Position.Y) / _draw_texture.Height, 0); verts[2].Position = new Vector3(verts[3].Position.X - (overlapToHere.Y - verts[3].Position.Y), overlapToHere.Y, 0); verts[2].TextureCoordinate = new Vector3(1f - (overlapToHere.X - verts[2].Position.X) / _draw_texture.Width, 1f - (overlapToHere.Y - verts[2].Position.Y) / _draw_texture.Height, 0); } verts[0].Normal = verts[1].Normal = verts[2].Normal = verts[3].Normal = vertices[0].Normal; verts[0].Hue = verts[1].Hue = verts[2].Hue = verts[3].Hue = vertices[0].Hue; tile.AddMapObject(deferred); } } // reset the tile position for the upcoming loop. tileX = Position.X; tileY = Position.Y; while (true) { // We are drawing each subsequent deferred object at (x+1, y+1) relative to the last one. tileX += 1; tileY += 1; // Get the tile associated with this (x, y) position. If the tile is not loaded, don't add a deferred object // (it'll be offscreen so it doesn't matter). tile = IsometricRenderer.InternalMap.GetMapTile(tileX, tileY, false); if (tile == null) break; // find the vertical and | // horizontal edges that | <- V // we are drawing to. H -> ------+ Vector3 verticalEdgeOverlapPt = new Vector3(overlapToHere.X, overlapCurrent.Y - (overlapToHere.X - overlapCurrent.X), 0); Vector3 horizEdgeOverlapPt = new Vector3(overlapCurrent.X - (overlapToHere.Y - overlapCurrent.Y), overlapToHere.Y, 0); if (horizEdgeOverlapPt.X > overlapToHere.X && verticalEdgeOverlapPt.Y > overlapToHere.Y) break; float extendX = overlapToHere.X - horizEdgeOverlapPt.X; if (extendX > 44) extendX = 44; float extendY = overlapToHere.Y - verticalEdgeOverlapPt.Y; if (extendY > 44) extendY = 44; deferred = new MapObjectDeferred(_draw_texture, this); deferred.Position.X = tileX; deferred.Position.Y = tileY; verts = deferred.Vertices; if (_draw_flip) { // 0 // /| // / 1 // / / // 2---3 verts[0].Position = verticalEdgeOverlapPt; verts[0].TextureCoordinate = new Vector3(0f, (verts[0].Position.Y - vertices[0].Position.Y) / _draw_texture.Height, 0); verts[1].Position = verticalEdgeOverlapPt + new Vector3(0, extendY, 0); verts[1].TextureCoordinate = new Vector3(0f, (verts[1].Position.Y - vertices[0].Position.Y) / _draw_texture.Height, 0); verts[2].Position = horizEdgeOverlapPt; verts[2].TextureCoordinate = new Vector3(1f - (verts[2].Position.X - vertices[2].Position.X) / _draw_texture.Width, 1f, 0); verts[3].Position = horizEdgeOverlapPt + new Vector3(extendX, 0, 0); verts[3].TextureCoordinate = new Vector3(1f - (verts[3].Position.X - vertices[2].Position.X) / _draw_texture.Width, 1f, 0); } else { // 1 // /| // / 3 // / / // 0---2 verts[0].Position = horizEdgeOverlapPt; verts[0].TextureCoordinate = new Vector3((verts[0].Position.X - vertices[0].Position.X) / _draw_texture.Width, 1, 0); verts[1].Position = verticalEdgeOverlapPt; verts[1].TextureCoordinate = new Vector3(1, (verts[1].Position.Y - vertices[1].Position.Y) / _draw_texture.Height, 0); verts[2].Position = horizEdgeOverlapPt + new Vector3(extendX, 0, 0); verts[2].TextureCoordinate = new Vector3((verts[2].Position.X - vertices[0].Position.X) / _draw_texture.Width, 1, 0); verts[3].Position = verticalEdgeOverlapPt + new Vector3(0, extendY, 0); verts[3].TextureCoordinate = new Vector3(1, (verts[3].Position.Y - vertices[1].Position.Y) / _draw_texture.Height, 0); } verts[0].Normal = verts[1].Normal = verts[2].Normal = verts[3].Normal = vertices[0].Normal; verts[0].Hue = verts[1].Hue = verts[2].Hue = verts[3].Hue = vertices[0].Hue; overlapCurrent.X += 22; overlapCurrent.Y += 22; tile.AddMapObject(deferred); } }
protected override void Prerender(SpriteBatch3D sb) { if (_layerCount == 1) { _draw_hue = Utility.GetHueVector(_layers[0].Hue); _draw_texture = _layers[0].Frame.Texture; _mobile_drawCenterX = _layers[0].Frame.Center.X; _mobile_drawCenterY = _layers[0].Frame.Center.Y; } else { _draw_hue = Utility.GetHueVector(0); int hash = createHashFromLayers(); _draw_texture = MapObjectPrerendered.RestorePrerenderedTexture(hash, out _mobile_drawCenterX, out _mobile_drawCenterY); if (_draw_texture == null) { int minX = 0, minY = 0; int maxX = 0, maxY = 0; for (int i = 0; i < _layerCount; i++) { if (_layers[i].Frame != null) { int x, y, w, h; x = _layers[i].Frame.Center.X; y = _layers[i].Frame.Center.Y; w = _layers[i].Frame.Texture.Width; h = _layers[i].Frame.Texture.Height; if (minX < x) minX = x; if (maxX < w - x) maxX = w - x; if (minY < h + y) minY = h + y; if (maxY > y) maxY = y; } } _mobile_drawCenterX = minX; _mobile_drawCenterY = maxY; RenderTarget2D renderTarget = new RenderTarget2D(sb.Game.GraphicsDevice, minX + maxX, minY - maxY, false, SurfaceFormat.Color, DepthFormat.None); sb.Game.GraphicsDevice.SetRenderTarget(renderTarget); sb.Game.GraphicsDevice.Clear(Color.Transparent); for (int i = 0; i < _layerCount; i++) if (_layers[i].Frame != null) sb.DrawSimple(_layers[i].Frame.Texture, new Vector3( minX - _layers[i].Frame.Center.X, renderTarget.Height - _layers[i].Frame.Texture.Height + maxY - _layers[i].Frame.Center.Y, 0), Utility.GetHueVector(_layers[i].Hue)); sb.Flush(); _draw_texture = renderTarget; MapObjectPrerendered.SavePrerenderedTexture(_draw_texture, hash, _mobile_drawCenterX, _mobile_drawCenterY); sb.Game.GraphicsDevice.SetRenderTarget(null); } } }
internal override bool Draw(SpriteBatch3D sb, Vector3 drawPosition, MouseOverList molist, PickTypes pickType, int maxAlt) { _draw_width = _draw_texture.Width; _draw_height = _draw_texture.Height; if (_draw_flip) { _draw_X = _mobile_drawCenterX - 22 + (int)((Position.X_offset - Position.Y_offset) * 22); _draw_Y = _mobile_drawCenterY + (int)((Position.Z_offset + Z) * 4) + _draw_height - 22 - (int)((Position.X_offset + Position.Y_offset) * 22); } else { _draw_X = _mobile_drawCenterX - 22 - (int)((Position.X_offset - Position.Y_offset) * 22); _draw_Y = _mobile_drawCenterY + (int)((Position.Z_offset + Z) * 4) + _draw_height - 22 - (int)((Position.X_offset + Position.Y_offset) * 22); } if (ClientVars.EngineVars.LastTarget != null && ClientVars.EngineVars.LastTarget == OwnerSerial) _draw_hue = new Vector2(((Entities.Mobile)OwnerEntity).NotorietyHue - 1, 1); // !!! Test highlight code. bool isHighlight = false; if (isHighlight) { Vector2 savedHue = _draw_hue; int savedX = _draw_X, savedY = _draw_Y; _draw_hue = Utility.GetHueVector(1288); int offset = 1; _draw_X = savedX - offset; base.Draw(sb, drawPosition, molist, pickType, maxAlt); _draw_X = savedX + offset; base.Draw(sb, drawPosition, molist, pickType, maxAlt); _draw_X = savedX; _draw_Y = savedY - offset; base.Draw(sb, drawPosition, molist, pickType, maxAlt); _draw_Y = savedY + offset; base.Draw(sb, drawPosition, molist, pickType, maxAlt); _draw_hue = savedHue; _draw_X = savedX; _draw_Y = savedY; } bool isDrawn = base.Draw(sb, drawPosition, molist, pickType, maxAlt); return isDrawn; }