2 * Sixth 3D engine. Author: Svjatoslav Agejenko.
3 * This project is released under Creative Commons Zero (CC0) license.
8 package eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.solidpolygon;
10 import eu.svjatoslav.sixth.e3d.geometry.Point2D;
11 import eu.svjatoslav.sixth.e3d.geometry.Point3D;
12 import eu.svjatoslav.sixth.e3d.gui.RenderingContext;
13 import eu.svjatoslav.sixth.e3d.gui.humaninput.MouseInteractionController;
14 import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
15 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.AbstractCoordinateShape;
17 import static eu.svjatoslav.sixth.e3d.geometry.Polygon.pointWithinPolygon;
19 public class SolidPolygon extends AbstractCoordinateShape {
21 private final static LineInterpolator polygonBoundary1 = new LineInterpolator();
22 private final static LineInterpolator polygonBoundary2 = new LineInterpolator();
23 private final static LineInterpolator polygonBoundary3 = new LineInterpolator();
26 public SolidPolygon(final Point3D point1, final Point3D point2,
27 final Point3D point3, final Color color) {
28 super(point1, point2, point3);
32 public static void drawHorizontalLine(final LineInterpolator line1,
33 final LineInterpolator line2, final int y,
34 final RenderingContext renderBuffer, final Color color) {
36 int x1 = line1.getX(y);
37 int x2 = line2.getX(y);
48 if (x2 >= renderBuffer.width)
49 x2 = renderBuffer.width - 1;
51 final int width = x2 - x1;
53 int offset = ((y * renderBuffer.width) + x1) * 4;
54 final byte[] offSreenBufferBytes = renderBuffer.pixels;
56 final int polygonAlpha = color.a;
57 final int b = color.b;
58 final int g = color.g;
59 final int r = color.r;
61 if (polygonAlpha == 255)
62 for (int i = 0; i < width; i++) {
63 offSreenBufferBytes[offset] = (byte) 255;
65 offSreenBufferBytes[offset] = (byte) b;
67 offSreenBufferBytes[offset] = (byte) g;
69 offSreenBufferBytes[offset] = (byte) r;
73 final int backgroundAlpha = 255 - polygonAlpha;
75 final int blueWithAlpha = b * polygonAlpha;
76 final int greenWithAlpha = g * polygonAlpha;
77 final int redWithAlpha = r * polygonAlpha;
79 for (int i = 0; i < width; i++) {
80 offSreenBufferBytes[offset] = (byte) 255;
82 offSreenBufferBytes[offset] = (byte) ((((offSreenBufferBytes[offset] & 0xff) * backgroundAlpha) + blueWithAlpha) / 256);
84 offSreenBufferBytes[offset] = (byte) ((((offSreenBufferBytes[offset] & 0xff) * backgroundAlpha) + greenWithAlpha) / 256);
86 offSreenBufferBytes[offset] = (byte) ((((offSreenBufferBytes[offset] & 0xff) * backgroundAlpha) + redWithAlpha) / 256);
94 public static void drawPolygon(final RenderingContext context,
95 final Point2D onScreenPoint1, final Point2D onScreenPoint2,
96 final Point2D onScreenPoint3,
97 final MouseInteractionController mouseInteractionController,
100 onScreenPoint1.roundToInteger();
101 onScreenPoint2.roundToInteger();
102 onScreenPoint3.roundToInteger();
104 if (mouseInteractionController != null)
105 if (context.getMouseEvent() != null)
106 if (pointWithinPolygon(context.getMouseEvent().coordinate,
107 onScreenPoint1, onScreenPoint2, onScreenPoint3))
108 context.setObjectUnderMouse(mouseInteractionController);
110 if (color.isTransparent())
113 // find top-most point
114 int yTop = (int) onScreenPoint1.y;
116 if (onScreenPoint2.y < yTop)
117 yTop = (int) onScreenPoint2.y;
119 if (onScreenPoint3.y < yTop)
120 yTop = (int) onScreenPoint3.y;
125 // find bottom-most point
126 int yBottom = (int) onScreenPoint1.y;
128 if (onScreenPoint2.y > yBottom)
129 yBottom = (int) onScreenPoint2.y;
131 if (onScreenPoint3.y > yBottom)
132 yBottom = (int) onScreenPoint3.y;
134 if (yBottom >= context.height)
135 yBottom = context.height - 1;
138 polygonBoundary1.setPoints(onScreenPoint1, onScreenPoint2);
139 polygonBoundary2.setPoints(onScreenPoint1, onScreenPoint3);
140 polygonBoundary3.setPoints(onScreenPoint2, onScreenPoint3);
142 final LineInterpolator[] is = new LineInterpolator[3];
143 is[0] = polygonBoundary1;
144 is[1] = polygonBoundary2;
145 is[2] = polygonBoundary3;
147 java.util.Arrays.sort(is);
149 for (int y = yTop; y < yBottom; y++)
150 if (is[0].containsY(y)) {
152 if (is[1].containsY(y))
153 drawHorizontalLine(is[0], is[1], y, context, color);
154 else if (is[2].containsY(y))
155 drawHorizontalLine(is[0], is[2], y, context, color);
156 } else if (is[1].containsY(y))
157 if (is[2].containsY(y))
158 drawHorizontalLine(is[1], is[2], y, context, color);
161 public Color getColor() {
165 public void setColor(final Color color) {
170 public void paint(final RenderingContext renderBuffer) {
172 final Point2D onScreenPoint1 = coordinates[0].onScreenCoordinate;
173 final Point2D onScreenPoint2 = coordinates[1].onScreenCoordinate;
174 final Point2D onScreenPoint3 = coordinates[2].onScreenCoordinate;
176 drawPolygon(renderBuffer, onScreenPoint1, onScreenPoint2,
177 onScreenPoint3, mouseInteractionController, color);