Subversion Repositories AndroidProjects

Rev

Rev 1309 | Blame | Compare with Previous | Last modification | View Log | RSS feed

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using BauzoidNET.math;
using BauzoidNET.graphics;
using BauzoidNET.graphics.model;
using BauzoidNET.graphics.renderstates;
using BauzoidNET.graphics.sprite;

namespace BauzoidNET.graphics
{
    public class RenderUtil
    {
        private RenderUtil() { }

        // Constants========================================================================================
       
            public const int NUM_ELLIPSE_STEPS = 16;

            // Embedded Types===================================================================================

            // Fields===========================================================================================

            // Methods==========================================================================================

        /** Render a line in world space. */
        public static void drawLine(Graphics graphics, Line2 line, Vector4 color)
        {
            drawLine(graphics, line.a.x, line.a.y, line.b.x, line.b.y, color);
        }
       
            /** Render a line in world space. */
            public static void drawLine(Graphics graphics, float x1, float y1, float x2, float y2, Vector4 color)
            {
                    float[] vertices = {x1, y1, 0.0f, x2, y2, 0.0f};
               
                    renderPrimitives(graphics, vertices, Matrix4.createIdentity(), color);
            }

        /** Render a line in world space. */
        public static void drawLine(Graphics graphics, Line2 line, SpriteTransform transform, Vector4 color)
        {
            drawLine(graphics, line.a.x, line.a.y, line.b.x, line.b.y, transform, color);
        }
       
            /** Render a line in pixel sprite space. */
            public static void drawLine(Graphics graphics, float x1, float y1, float x2, float y2, SpriteTransform transform, Vector4 color)
            {
                    float[] vertices = {x1, y1, 0.0f, x2, y2, 0.0f};
               
                    renderPrimitives(graphics, vertices, transform.getTransform(), color);
            }
       
            /** Render an arrow in world space from startX/startY to endX/endY. */
            public static void drawArrow(Graphics graphics, float startX, float startY, float endX, float endY, Vector4 color)
            {
                    renderPrimitives(graphics, generateArrowVertices(startX, startY, endX, endY), Matrix4.createIdentity(), color);
            }
       
            /** Render an arrow in world space from startX/startY to endX/endY. */
            public static void drawArrow(Graphics graphics, float startX, float startY, float endX, float endY, SpriteTransform transform, Vector4 color)
            {
                    renderPrimitives(graphics, generateArrowVertices(startX, startY, endX, endY), transform.getTransform(), color);
            }
       
            private static float[] generateArrowVertices(float startX, float startY, float endX, float endY)
            {
                    // vector in reverse direction
                    float dx = startX - endX;
                    float dy = startY - endY;
            float d = (float)Math.Sqrt((dx*dx) + (dy*dy));
                    dx /= d;
                    dy /= d;
               
                    float arrowSize = Math.Min(d / 4.0f, 20.0f);
               
                    // side vector (normal to reverse vector)
                    float sideX = dy;
                    float sideY = -dx;
               
                    // two arrow sides
                    float arrowLeftX = endX + dx * arrowSize + sideX * arrowSize;
                    float arrowLeftY = endY + dy * arrowSize + sideY * arrowSize;
               
                    float arrowRightX = endX + dx * arrowSize - sideX * arrowSize;
                    float arrowRightY = endY + dy * arrowSize - sideY * arrowSize;
               
                    float[] vertices = {
                            startX, startY, 0.0f,
                            endX, endY, 0.0f,
                            arrowLeftX, arrowLeftY, 0.0f,
                            endX, endY, 0.0f,
                            arrowRightX, arrowRightY, 0.0f
                    };
               
                    return vertices;
            }
       
            /** Render a quad in world space. */
            public static void drawQuad(Graphics graphics, float x1, float y1, float x2, float y2, Vector4 color)
            {
                    float[] vertices =
                    {
                            x1, y1, 0.0f,
                            x2, y1, 0.0f,
                            x2, y2, 0.0f,
                            x1, y2, 0.0f,
                            x1, y1, 0.0f,
                    };
               
                    renderPrimitives(graphics, vertices, Matrix4.createIdentity(), color);
            }
       
            /** Render a quad in pixel sprite space. */
            public static void drawQuad(Graphics graphics, float x1, float y1, float x2, float y2, SpriteTransform transform, Vector4 color)
            {
                    float[] vertices =
                    {
                            x1, y1, 0.0f,
                            x2, y1, 0.0f,
                            x2, y2, 0.0f,
                            x1, y2, 0.0f,
                            x1, y1, 0.0f,
                    };
               
                    renderPrimitives(graphics, vertices, transform.getTransform(), color);
            }
       
            /** Render a quad that has the same position, size, rotation, etc. as a Sprite given by a SpriteTransform. */
            public static void drawQuad(Graphics graphics, SpriteTransform transform, Vector4 color)
            {
                    float[] vertices =
                    {
                            -1, -1, 0.0f,
                             1, -1, 0.0f,
                             1,  1, 0.0f,
                            -1,  1, 0.0f,
                            -1, -1, 0.0f,
                    };
               
                    renderPrimitives(graphics, vertices, transform.getNormalizedTransform(), color);
            }
       
            /** Render an ellipse in world space. */
            public static void drawEllipse(Graphics graphics, float x1, float y1, float x2, float y2, Vector4 color)
            {          
                    float centerX = (x1 + x2)/2;
                    float centerY = (y1 + y2)/2;
               
                    float radiusX = Math.Abs(x2-x1)/2;
                    float radiusY = Math.Abs(y2-y1)/2;
       
                    renderPrimitives(graphics, createEllipseData(centerX, centerY, radiusX, radiusY), Matrix4.createIdentity(), color);
            }
       
            /** Render an ellipse in pixel sprite space. */
            public static void drawEllipse(Graphics graphics, float x1, float y1, float x2, float y2, SpriteTransform transform, Vector4 color)
            {
                    float centerX = (x1 + x2)/2;
                    float centerY = (y1 + y2)/2;

            float radiusX = Math.Abs(x2 - x1) / 2;
            float radiusY = Math.Abs(y2 - y1) / 2;
               
                    renderPrimitives(graphics, createEllipseData(centerX, centerY, radiusX, radiusY), transform.getTransform(), color);
            }
       
            /** Render an ellipse that has the same position, size, rotation, etc. as a Sprite given by a SpriteTransform. */
            public static void drawEllipse(Graphics graphics, SpriteTransform transform, Vector4 color)
            {
                    renderPrimitives(graphics, createEllipseData(0.0f, 0.0f, 1.0f, 1.0f), transform.getNormalizedTransform(), color);
            }
       
            public static float[] createEllipseData(float centerX, float centerY, float radiusX, float radiusY)
            {
                    float angleStep = 360.0f / NUM_ELLIPSE_STEPS;
               
                    float[] vertices = new float[3 * (NUM_ELLIPSE_STEPS+1)];
               
                    for (int i = 0; i < NUM_ELLIPSE_STEPS; i++)
                    {
                            vertices[i*3+0] = centerX + MathUtil.sin(angleStep * (float)i) * radiusX;
                            vertices[i*3+1] = centerY + MathUtil.cos(angleStep * (float)i) * radiusY;
                            vertices[i*3+2] = 0.0f;
                    }
               
                    vertices[NUM_ELLIPSE_STEPS*3+0] = vertices[0];
                    vertices[NUM_ELLIPSE_STEPS*3+1] = vertices[1];
                    vertices[NUM_ELLIPSE_STEPS*3+2] = vertices[2];
               
                    return vertices;
            }
       
            public static void renderPrimitives(Graphics graphics, float[] vertices, Matrix4 transform, Vector4 color)
            {
                    RenderStates rs = graphics.renderStates;
                    PrimitiveShader shader = graphics.getPrimitiveShader();
               
                    SimpleGeometry geom = new SimpleGeometry(graphics, Geometry.PrimitiveType.LINE_STRIP);
                    geom.setPositions(vertices);
               
                    rs.pushModelMatrix();
                    {
                            rs.model = transform;
               
                            shader.activate(color);
                            {
                                    geom.render();
                            }
                            shader.deactivate();
                    }
                    rs.popModelMatrix();
               
                    geom.dispose();
            }


    }
}