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==================================================================================
}