Ejemplo n.º 1
0
        /// <summary>
        /// Uses the VisualServer to draw each of an entity's split sprites, by:
        ///     1. Obtaining the Node2D that is designated to play host to a given split sprite
        ///     2. Changing the Node2D's (TileMap) parent if required
        ///     3. Creating an RID for the canvas item (the sprite drawing) and storing it so it can be freed later
        /// </summary>
        /// <param name="tileMaps"></param>
        /// <param name="tileMapZIndex"></param>
        /// <param name="entityPos"></param>
        /// <param name="entityDrawPos">Offsets the sprite upwards. Used for drawing entities falling/jumping.</param>
        public void DrawSplitSprites(TileMapList tileMaps, int tileMapZIndex, Vector2 entityPos, float entityDrawPos /*State goes here*/)
        {
            List <SplitSpriteSheetValue> splitSprites = this._splitSpriteSheet.GetSplitSpriteInfoForAnim("idle", 0); //TODO match to entity anim state

            foreach (SplitSpriteSheetValue splitSprite in splitSprites)
            {
                Node2D  splitNode2D = this._idToSplitNodes[splitSprite.splitIndex];
                TileMap tileMap     = tileMaps[tileMapZIndex + splitSprite.zIndex];
                if (splitNode2D.GetParent() != tileMap)
                {
                    if (splitNode2D.GetParent() != null)
                    {
                        splitNode2D.GetParent().RemoveChild(splitNode2D);
                    }
                    tileMap.AddChild(splitNode2D);
                }

                RID splitSpriteRID = VisualServer.CanvasItemCreate();
                this._drawnSprites.Add(splitSpriteRID);
                VisualServer.CanvasItemSetParent(splitSpriteRID, splitNode2D.GetCanvasItem());

                VisualServer.CanvasItemAddTextureRectRegion(splitSpriteRID,
                                                            new Rect2(Vector2.Zero, splitSprite.size),
                                                            this._splitSpriteSheet.GetSpriteSheetRID(),
                                                            new Rect2(splitSprite.sheetPos, splitSprite.size),
                                                            new Color(1, 1, 1, 1),
                                                            false,
                                                            this._splitSpriteSheet.GetSpriteSheetRID());

                VisualServer.CanvasItemSetTransform(splitSpriteRID, new Transform2D(0, this._relativePos - new Vector2(Globals.TileWidth / 2, Globals.TileHeight / 2) + new Vector2(0, entityDrawPos)));

                splitNode2D.Position = entityPos + splitSprite.splitPos + new Vector2(Globals.TileWidth / 2, Globals.TileHeight / 2);
            }
        }
Ejemplo n.º 2
0
    private static void RenderDrawData(ImDrawDataPtr drawData, RID parent)
    {
        // allocate and clear out our CanvasItem pool as needed
        int neededNodes = 0;

        for (int i = 0; i < drawData.CmdListsCount; i++)
        {
            neededNodes += drawData.CmdListsRange[i].CmdBuffer.Size;
        }

        while (_children.Count < neededNodes)
        {
            RID newChild = VisualServer.CanvasItemCreate();
            VisualServer.CanvasItemSetParent(newChild, parent);
            VisualServer.CanvasItemSetDrawIndex(newChild, _children.Count);
            _children.Add(newChild);
            _meshes.Add(new ArrayMesh());
        }

        // trim unused nodes to reduce draw calls
        while (_children.Count > neededNodes)
        {
            int idx = _children.Count - 1;
            VisualServer.FreeRid(_children[idx]);
            _children.RemoveAt(idx);
            _meshes.RemoveAt(idx);
        }

        // render
        drawData.ScaleClipRects(ImGui.GetIO().DisplayFramebufferScale);
        int nodeN = 0;

        for (int n = 0; n < drawData.CmdListsCount; n++)
        {
            ImDrawListPtr cmdList   = drawData.CmdListsRange[n];
            int           idxOffset = 0;

            int nVert = cmdList.VtxBuffer.Size;

            Godot.Vector2[] vertices = new Godot.Vector2[nVert];
            Godot.Color[]   colors   = new Godot.Color[nVert];
            Godot.Vector2[] uvs      = new Godot.Vector2[nVert];

            for (int i = 0; i < cmdList.VtxBuffer.Size; i++)
            {
                var v = cmdList.VtxBuffer[i];
                vertices[i] = new Godot.Vector2(v.pos.X, v.pos.Y);
                // need to reverse the color bytes
                byte[] col = BitConverter.GetBytes(v.col);
                colors[i] = Godot.Color.Color8(col[0], col[1], col[2], col[3]);
                uvs[i]    = new Godot.Vector2(v.uv.X, v.uv.Y);
            }

            for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++, nodeN++)
            {
                ImDrawCmdPtr drawCmd = cmdList.CmdBuffer[cmdi];

                int[] indices = new int[drawCmd.ElemCount];
                for (int i = idxOffset, j = 0; i < idxOffset + drawCmd.ElemCount; i++, j++)
                {
                    indices[j] = cmdList.IdxBuffer[i];
                }

                var arrays = new Godot.Collections.Array();
                arrays.Resize((int)ArrayMesh.ArrayType.Max);
                arrays[(int)ArrayMesh.ArrayType.Vertex] = vertices;
                arrays[(int)ArrayMesh.ArrayType.Color]  = colors;
                arrays[(int)ArrayMesh.ArrayType.TexUv]  = uvs;
                arrays[(int)ArrayMesh.ArrayType.Index]  = indices;

                var mesh = _meshes[nodeN];
                while (mesh.GetSurfaceCount() > 0)
                {
                    mesh.SurfaceRemove(0);
                }
                mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays);

                RID child = _children[nodeN];

                Texture tex = GetTexture(drawCmd.TextureId);
                VisualServer.CanvasItemClear(child);
                VisualServer.CanvasItemSetClip(child, true);
                VisualServer.CanvasItemSetCustomRect(child, true, new Godot.Rect2(
                                                         drawCmd.ClipRect.X,
                                                         drawCmd.ClipRect.Y,
                                                         drawCmd.ClipRect.Z - drawCmd.ClipRect.X,
                                                         drawCmd.ClipRect.W - drawCmd.ClipRect.Y)
                                                     );
                VisualServer.CanvasItemAddMesh(child, mesh.GetRid(), null, null, tex.GetRid(), new RID(null));

                // why doesn't this quite work?
                // VisualServer.CanvasItemAddTriangleArray(child, indices, vertices, colors, uvs, null, null, tex.GetRid(), -1, new RID(null));

                idxOffset += (int)drawCmd.ElemCount;
            }
        }
    }