2 * Sixth 3D engine. Copyright ©2012-2018, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 3 of the GNU Lesser General Public License
6 * or later as published by the Free Software Foundation.
10 package eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.solidpolygon;
12 import eu.svjatoslav.sixth.e3d.geometry.Point2D;
13 import eu.svjatoslav.sixth.e3d.geometry.Point3D;
14 import eu.svjatoslav.sixth.e3d.gui.RenderingContext;
15 import eu.svjatoslav.sixth.e3d.gui.humaninput.MouseInteractionController;
16 import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
17 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.AbstractCoordinateShape;
19 import static eu.svjatoslav.sixth.e3d.geometry.Polygon.pointWithinPolygon;
21 public class SolidPolygon extends AbstractCoordinateShape {
23 private final static LineInterpolator polygonBoundary1 = new LineInterpolator();
24 private final static LineInterpolator polygonBoundary2 = new LineInterpolator();
25 private final static LineInterpolator polygonBoundary3 = new LineInterpolator();
28 public SolidPolygon(final Point3D point1, final Point3D point2,
29 final Point3D point3, final Color color) {
30 super(point1, point2, point3);
34 public static void drawHorizontalLine(final LineInterpolator line1,
35 final LineInterpolator line2, final int y,
36 final RenderingContext renderBuffer, final Color color) {
38 int x1 = line1.getX(y);
39 int x2 = line2.getX(y);
50 if (x2 >= renderBuffer.width)
51 x2 = renderBuffer.width - 1;
53 final int width = x2 - x1;
55 int offset = ((y * renderBuffer.width) + x1) * 4;
56 final byte[] offSreenBufferBytes = renderBuffer.pixels;
58 final int polygonAlpha = color.a;
59 final int b = color.b;
60 final int g = color.g;
61 final int r = color.r;
63 if (polygonAlpha == 255)
64 for (int i = 0; i < width; i++) {
65 offSreenBufferBytes[offset] = (byte) 255;
67 offSreenBufferBytes[offset] = (byte) b;
69 offSreenBufferBytes[offset] = (byte) g;
71 offSreenBufferBytes[offset] = (byte) r;
75 final int backgroundAlpha = 255 - polygonAlpha;
77 final int blueWithAlpha = b * polygonAlpha;
78 final int greenWithAlpha = g * polygonAlpha;
79 final int redWithAlpha = r * polygonAlpha;
81 for (int i = 0; i < width; i++) {
82 offSreenBufferBytes[offset] = (byte) 255;
84 offSreenBufferBytes[offset] = (byte) ((((offSreenBufferBytes[offset] & 0xff) * backgroundAlpha) + blueWithAlpha) / 256);
86 offSreenBufferBytes[offset] = (byte) ((((offSreenBufferBytes[offset] & 0xff) * backgroundAlpha) + greenWithAlpha) / 256);
88 offSreenBufferBytes[offset] = (byte) ((((offSreenBufferBytes[offset] & 0xff) * backgroundAlpha) + redWithAlpha) / 256);
96 public static void drawPolygon(final RenderingContext context,
97 final Point2D onScreenPoint1, final Point2D onScreenPoint2,
98 final Point2D onScreenPoint3,
99 final MouseInteractionController mouseInteractionController,
102 onScreenPoint1.roundToInteger();
103 onScreenPoint2.roundToInteger();
104 onScreenPoint3.roundToInteger();
106 if (mouseInteractionController != null)
107 if (context.getMouseEvent() != null)
108 if (pointWithinPolygon(context.getMouseEvent().coordinate,
109 onScreenPoint1, onScreenPoint2, onScreenPoint3))
110 context.setObjectUnderMouse(mouseInteractionController);
112 if (color.isTransparent())
115 // find top-most point
116 int yTop = (int) onScreenPoint1.y;
118 if (onScreenPoint2.y < yTop)
119 yTop = (int) onScreenPoint2.y;
121 if (onScreenPoint3.y < yTop)
122 yTop = (int) onScreenPoint3.y;
127 // find bottom-most point
128 int yBottom = (int) onScreenPoint1.y;
130 if (onScreenPoint2.y > yBottom)
131 yBottom = (int) onScreenPoint2.y;
133 if (onScreenPoint3.y > yBottom)
134 yBottom = (int) onScreenPoint3.y;
136 if (yBottom >= context.height)
137 yBottom = context.height - 1;
140 polygonBoundary1.setPoints(onScreenPoint1, onScreenPoint2);
141 polygonBoundary2.setPoints(onScreenPoint1, onScreenPoint3);
142 polygonBoundary3.setPoints(onScreenPoint2, onScreenPoint3);
144 final LineInterpolator[] is = new LineInterpolator[3];
145 is[0] = polygonBoundary1;
146 is[1] = polygonBoundary2;
147 is[2] = polygonBoundary3;
149 java.util.Arrays.sort(is);
151 for (int y = yTop; y < yBottom; y++)
152 if (is[0].containsY(y)) {
154 if (is[1].containsY(y))
155 drawHorizontalLine(is[0], is[1], y, context, color);
156 else if (is[2].containsY(y))
157 drawHorizontalLine(is[0], is[2], y, context, color);
158 } else if (is[1].containsY(y))
159 if (is[2].containsY(y))
160 drawHorizontalLine(is[1], is[2], y, context, color);
163 public Color getColor() {
167 public void setColor(final Color color) {
172 public void paint(final RenderingContext renderBuffer) {
174 final Point2D onScreenPoint1 = coordinates[0].onScreenCoordinate;
175 final Point2D onScreenPoint2 = coordinates[1].onScreenCoordinate;
176 final Point2D onScreenPoint3 = coordinates[2].onScreenCoordinate;
178 drawPolygon(renderBuffer, onScreenPoint1, onScreenPoint2,
179 onScreenPoint3, mouseInteractionController, color);