Exemple #1
0
 public static extern void bgfx_alloc_transient_index_buffer(out TransientIndexBuffer tib, int num);
Exemple #2
0
 public static extern void bgfx_set_transient_index_buffer(ref TransientIndexBuffer tib, int startIndex, int numIndices);
Exemple #3
0
 public static extern bool bgfx_alloc_transient_buffers(out TransientVertexBuffer tvb, ref VertexLayout.Data decl, ushort numVertices, out TransientIndexBuffer tib, ushort numIndices);
Exemple #4
0
 public void SetIndexBuffer(TransientIndexBuffer ib, int startIndex = 0, int count = -1)
 {
     Bgfx.SetIndexBuffer(ib, startIndex, count);
 }
Exemple #5
0
        public void End()
        {
            if (currentProgram == null)
            {
                throw new ApplicationException("Unexpected End call, start a new batch with Begin()");
            }

            if (spriteBatch.Count == 0)
            {
                currentProgram = null;
                return;
            }

            VertexTextureColor[] vertices = new VertexTextureColor[4];
            ushort[]             indices  = new ushort[6];

            Array.Copy(rectangleVertices, vertices, 4);
            Array.Copy(rectangleIndices, indices, 6);

            GCHandle handleVertices = GCHandle.Alloc(vertices, GCHandleType.Pinned);

            TransientVertexBuffer vertexBuffer = new TransientVertexBuffer();
            TransientIndexBuffer  indexBuffer  = new TransientIndexBuffer();

            for (int i = 0, batchLeft = 0, batchSize = 0; i < spriteBatch.Count; i++)
            {
                Sprite    sprite  = spriteBatch[i];
                Texture2D texture = sprite.texture;

                if (batchLeft == 0)
                {
                    for (int j = i; j < spriteBatch.Count; j++)
                    {
                        if (spriteBatch[j].texture != texture)
                        {
                            break;
                        }

                        batchLeft++;
                    }

                    batchLeft = Math.Min(batchLeft, ushort.MaxValue / 4);

                    vertexBuffer = new TransientVertexBuffer(batchLeft * 4, VertexTextureColor.vertexLayout);
                    indexBuffer  = new TransientIndexBuffer(batchLeft * 6);
                }

                vertices[0].x = vertices[0].u = 0.0f;
                vertices[0].y = vertices[0].v = 0.0f;
                vertices[1].u = 1.0f;
                vertices[1].y = vertices[1].v = 0.0f;
                vertices[2].u = 1.0f;
                vertices[2].v = 1.0f;
                vertices[3].x = vertices[3].u = 0.0f;
                vertices[3].v = 1.0f;

                vertices[1].x = vertices[2].x = sprite.size.x;
                vertices[2].y = vertices[3].y = sprite.size.y;

                // translation and rotation
                if (sprite.rotation == 0.0f)
                {
                    for (int j = 0; j < 4; ++j)
                    {
                        vertices[j].x    += sprite.position.x;
                        vertices[j].y    += sprite.position.y;
                        vertices[j].color = sprite.color;
                    }
                }
                else
                {
                    for (int j = 0; j < 4; ++j)
                    {
                        double cosRot = Math.Cos(sprite.rotation);
                        double sinRot = Math.Sin(sprite.rotation);

                        double rotX = sprite.originX + (vertices[j].x - sprite.originX) * cosRot
                                      - (vertices[j].y - sprite.originY) * sinRot;
                        double rotY = sprite.originY + (vertices[j].x - sprite.originX) * sinRot
                                      + (vertices[j].y - sprite.originY) * cosRot;

                        vertices[j].x     = (float)(rotX + sprite.position.x - (int)sprite.originX);
                        vertices[j].y     = (float)(rotY + sprite.position.y - (int)sprite.originY);
                        vertices[j].color = sprite.color;
                    }
                }

                // texture coordinates
                if (texture != null)
                {
                    float left   = sprite.sourceRect.x;
                    float top    = sprite.sourceRect.y;
                    float right  = sprite.sourceRect.x + sprite.sourceRect.width;
                    float bottom = sprite.sourceRect.y + sprite.sourceRect.height;

                    if (sprite.size == sprite.sourceRect.size)
                    {
                        vertices[0].u = vertices[3].u = left / texture.width;
                        vertices[0].v = vertices[1].v = top / texture.height;
                        vertices[2].u = vertices[1].u = right / texture.width;
                        vertices[2].v = vertices[3].v = bottom / texture.height;
                    }
                    else
                    {
                        // when stretching textures, texture sampling points needs to be adjusted
                        // by half pixel in order to prevent neighbouring subtextures bleeding
                        // around the edges.
                        vertices[0].u = vertices[3].u = (left + 0.5f) / texture.width;
                        vertices[0].v = vertices[1].v = (top + 0.5f) / texture.height;
                        vertices[2].u = vertices[1].u = (right - 0.5f) / texture.width;
                        vertices[2].v = vertices[3].v = (bottom - 0.5f) / texture.height;
                    }
                }

                // copy data to buffers
                unsafe
                {
                    int offset = (batchSize * 4);
                    VertexTextureColor *vertexData = (VertexTextureColor *)handleVertices.AddrOfPinnedObject();
                    VertexTextureColor *vbData     = (VertexTextureColor *)(vertexBuffer.Data) + offset;
                    ushort *            ibData     = (ushort *)(indexBuffer.Data) + (batchSize * 6);

                    for (int j = 0; j < 4; ++j)
                    {
                        *vbData = *vertexData;
                        vbData++;
                        vertexData++;
                    }
                    for (int j = 0; j < 6; ++j)
                    {
                        *ibData = (ushort)(indices[j] + offset);
                        ibData++;
                    }
                }

                batchSize++;
                batchLeft--;
                if (batchLeft == 0)
                {
                    // draw current batch

                    renderer.SetRenderState(Renderer.AlphaBlendNoDepth);
                    renderer.SetVertexBuffer(vertexBuffer, 0, batchSize * 4);
                    renderer.SetIndexBuffer(indexBuffer, 0, batchSize * 6);

                    if (texture != null)
                    {
                        renderer.SetTexture(0, texture, textureFlags);
                    }

                    renderer.Submit(currentViewport, currentProgram);
                    batchSize = 0;
                }
            }

            handleVertices.Free();
            spriteBatch.Clear();

            currentViewport++;
            currentProgram = null;
        }
Exemple #6
0
 /// <summary>
 /// Sets the index buffer to use for drawing primitives.
 /// </summary>
 /// <param name="indexBuffer">The index buffer to set.</param>
 /// <param name="firstIndex">The first index in the buffer to use.</param>
 /// <param name="count">The number of indices to pull from the buffer.</param>
 public static void SetIndexBuffer(TransientIndexBuffer indexBuffer, int firstIndex = 0, int count = -1)
 {
     NativeMethods.bgfx_set_transient_index_buffer(ref indexBuffer, firstIndex, count);
 }
Exemple #7
0
 /// <summary>
 /// Attempts to allocate both a transient vertex buffer and index buffer.
 /// </summary>
 /// <param name="vertexCount">The number of vertices to allocate.</param>
 /// <param name="layout">The layout of each vertex.</param>
 /// <param name="indexCount">The number of indices to allocate.</param>
 /// <param name="vertexBuffer">Returns the allocated transient vertex buffer.</param>
 /// <param name="indexBuffer">Returns the allocated transient index buffer.</param>
 /// <returns><c>true</c> if both space requirements are satisfied and the buffers were allocated.</returns>
 public static bool AllocateTransientBuffers(int vertexCount, VertexLayout layout, int indexCount, out TransientVertexBuffer vertexBuffer, out TransientIndexBuffer indexBuffer)
 {
     return NativeMethods.bgfx_alloc_transient_buffers(out vertexBuffer, ref layout.data, (ushort)vertexCount, out indexBuffer, (ushort)indexCount);
 }