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,
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
;
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();
}
}
}