2 * Sixth 3D engine. Author: Svjatoslav Agejenko.
3 * This project is released under Creative Commons Zero (CC0) license.
5 package eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.solidpolygon;
7 import eu.svjatoslav.sixth.e3d.geometry.Point2D;
8 import eu.svjatoslav.sixth.e3d.geometry.Point3D;
9 import eu.svjatoslav.sixth.e3d.gui.RenderingContext;
10 import eu.svjatoslav.sixth.e3d.gui.humaninput.MouseInteractionController;
11 import eu.svjatoslav.sixth.e3d.math.Vertex;
12 import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
13 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.AbstractCoordinateShape;
15 import static eu.svjatoslav.sixth.e3d.geometry.Polygon.pointWithinPolygon;
18 * polygon with solid color.
20 public class SolidPolygon extends AbstractCoordinateShape {
22 private final static LineInterpolator polygonBoundary1 = new LineInterpolator();
23 private final static LineInterpolator polygonBoundary2 = new LineInterpolator();
24 private final static LineInterpolator polygonBoundary3 = new LineInterpolator();
27 public SolidPolygon(final Point3D point1, final Point3D point2,
28 final Point3D point3, final Color color) {
37 public static void drawHorizontalLine(final LineInterpolator line1,
38 final LineInterpolator line2, final int y,
39 final RenderingContext renderBuffer, final Color color) {
41 int x1 = line1.getX(y);
42 int x2 = line2.getX(y);
53 if (x2 >= renderBuffer.width)
54 x2 = renderBuffer.width - 1;
56 final int width = x2 - x1;
58 int offset = ((y * renderBuffer.width) + x1) * 4;
59 final byte[] offScreenBufferBytes = renderBuffer.pixels;
61 final int polygonAlpha = color.a;
62 final int b = color.b;
63 final int g = color.g;
64 final int r = color.r;
66 if (polygonAlpha == 255)
67 for (int i = 0; i < width; i++) {
68 offScreenBufferBytes[offset] = (byte) 255;
70 offScreenBufferBytes[offset] = (byte) b;
72 offScreenBufferBytes[offset] = (byte) g;
74 offScreenBufferBytes[offset] = (byte) r;
78 final int backgroundAlpha = 255 - polygonAlpha;
80 final int blueWithAlpha = b * polygonAlpha;
81 final int greenWithAlpha = g * polygonAlpha;
82 final int redWithAlpha = r * polygonAlpha;
84 for (int i = 0; i < width; i++) {
85 offScreenBufferBytes[offset] = (byte) 255;
87 offScreenBufferBytes[offset] = (byte) ((((offScreenBufferBytes[offset] & 0xff) * backgroundAlpha) + blueWithAlpha) / 256);
89 offScreenBufferBytes[offset] = (byte) ((((offScreenBufferBytes[offset] & 0xff) * backgroundAlpha) + greenWithAlpha) / 256);
91 offScreenBufferBytes[offset] = (byte) ((((offScreenBufferBytes[offset] & 0xff) * backgroundAlpha) + redWithAlpha) / 256);
99 public static void drawPolygon(final RenderingContext context,
100 final Point2D onScreenPoint1, final Point2D onScreenPoint2,
101 final Point2D onScreenPoint3,
102 final MouseInteractionController mouseInteractionController,
105 onScreenPoint1.roundToInteger();
106 onScreenPoint2.roundToInteger();
107 onScreenPoint3.roundToInteger();
109 if (mouseInteractionController != null)
110 if (context.getMouseEvent() != null)
111 if (pointWithinPolygon(context.getMouseEvent().coordinate,
112 onScreenPoint1, onScreenPoint2, onScreenPoint3))
113 context.setCurrentObjectUnderMouseCursor(mouseInteractionController);
115 if (color.isTransparent())
118 // find top-most point
119 int yTop = (int) onScreenPoint1.y;
121 if (onScreenPoint2.y < yTop)
122 yTop = (int) onScreenPoint2.y;
124 if (onScreenPoint3.y < yTop)
125 yTop = (int) onScreenPoint3.y;
130 // find bottom-most point
131 int yBottom = (int) onScreenPoint1.y;
133 if (onScreenPoint2.y > yBottom)
134 yBottom = (int) onScreenPoint2.y;
136 if (onScreenPoint3.y > yBottom)
137 yBottom = (int) onScreenPoint3.y;
139 if (yBottom >= context.height)
140 yBottom = context.height - 1;
143 polygonBoundary1.setPoints(onScreenPoint1, onScreenPoint2);
144 polygonBoundary2.setPoints(onScreenPoint1, onScreenPoint3);
145 polygonBoundary3.setPoints(onScreenPoint2, onScreenPoint3);
147 final LineInterpolator[] is = new LineInterpolator[3];
148 is[0] = polygonBoundary1;
149 is[1] = polygonBoundary2;
150 is[2] = polygonBoundary3;
152 java.util.Arrays.sort(is);
154 for (int y = yTop; y < yBottom; y++)
155 if (is[0].containsY(y)) {
157 if (is[1].containsY(y))
158 drawHorizontalLine(is[0], is[1], y, context, color);
159 else if (is[2].containsY(y))
160 drawHorizontalLine(is[0], is[2], y, context, color);
161 } else if (is[1].containsY(y))
162 if (is[2].containsY(y))
163 drawHorizontalLine(is[1], is[2], y, context, color);
166 public Color getColor() {
170 public void setColor(final Color color) {
175 public void paint(final RenderingContext renderBuffer) {
177 final Point2D onScreenPoint1 = coordinates[0].onScreenCoordinate;
178 final Point2D onScreenPoint2 = coordinates[1].onScreenCoordinate;
179 final Point2D onScreenPoint3 = coordinates[2].onScreenCoordinate;
181 drawPolygon(renderBuffer, onScreenPoint1, onScreenPoint2,
182 onScreenPoint3, mouseInteractionController, color);