Subversion Repositories AndroidProjects

Rev

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

package com.gebauz.bauzoid.graphics;

import com.gebauz.bauzoid.graphics.model.Geometry.PrimitiveType;
import com.gebauz.bauzoid.graphics.model.SimpleGeometry;
import com.gebauz.bauzoid.graphics.renderstates.RenderStates;
import com.gebauz.bauzoid.graphics.sprite.SpriteTransform;
import com.gebauz.bauzoid.math.MathUtil;
import com.gebauz.bauzoid.math.Matrix4;
import com.gebauz.bauzoid.math.Vector4;

/** Various (potentially slow) render utilities. */
public class RenderUtil
{
        // Constants========================================================================================
       
        public static final int NUM_ELLIPSE_STEPS = 16;

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

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

        // Methods==========================================================================================
       
        /** 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 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;
               
                final 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)
        {
                final 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.getRenderStates();
                PrimitiveShader shader = graphics.getPrimitiveShader();
               
                SimpleGeometry geom = new SimpleGeometry(graphics, PrimitiveType.LINE_STRIP);
                geom.setPositions(vertices);
               
                rs.pushModelMatrix();
                {
                        rs.model = transform;
               
                        shader.activate(color);
                        {
                                geom.render();
                        }
                        shader.deactivate();
                }
                rs.popModelMatrix();
               
                geom.dispose();
        }

        // Getters/Setters==================================================================================

}