2 * Sixth 3D engine. Copyright ©2012-2016, 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.geometry.Polygon;
15 import eu.svjatoslav.sixth.e3d.gui.RenderingContext;
16 import eu.svjatoslav.sixth.e3d.gui.humaninput.MouseInteractionController;
17 import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
18 import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.AbstractCoordinateShape;
20 public class SolidPolygon extends AbstractCoordinateShape {
22 final static LineInterpolator polygonBoundary1 = new LineInterpolator();
23 final static LineInterpolator polygonBoundary2 = new LineInterpolator();
24 final static LineInterpolator polygonBoundary3 = new LineInterpolator();
27 public SolidPolygon(final Point3D point1, final Point3D point2,
28 final Point3D point3, final Color color) {
29 super(point1, point2, point3);
33 public static void drawHorizontalLine(final LineInterpolator line1,
34 final LineInterpolator line2, final int y,
35 final RenderingContext renderBuffer, final Color color) {
37 int x1 = line1.getX(y);
38 int x2 = line2.getX(y);
49 if (x2 >= renderBuffer.width)
50 x2 = renderBuffer.width - 1;
52 final int width = x2 - x1;
54 int offset = ((y * renderBuffer.width) + x1) * 4;
55 final byte[] offSreenBufferBytes = renderBuffer.bytes;
57 final int polygonAlpha = color.a;
58 final int b = color.b;
59 final int g = color.g;
60 final int r = color.r;
62 if (polygonAlpha == 255)
63 for (int i = 0; i < width; i++) {
64 offSreenBufferBytes[offset] = (byte) 255;
66 offSreenBufferBytes[offset] = (byte) b;
68 offSreenBufferBytes[offset] = (byte) g;
70 offSreenBufferBytes[offset] = (byte) r;
74 final int backgroundAlpha = 255 - polygonAlpha;
76 final int blueWithAlpha = b * polygonAlpha;
77 final int greenWithAlpha = g * polygonAlpha;
78 final int redWithAlpha = r * polygonAlpha;
80 for (int i = 0; i < width; i++) {
81 offSreenBufferBytes[offset] = (byte) 255;
83 offSreenBufferBytes[offset] = (byte) ((((offSreenBufferBytes[offset] & 0xff) * backgroundAlpha) + blueWithAlpha) / 256);
85 offSreenBufferBytes[offset] = (byte) ((((offSreenBufferBytes[offset] & 0xff) * backgroundAlpha) + greenWithAlpha) / 256);
87 offSreenBufferBytes[offset] = (byte) ((((offSreenBufferBytes[offset] & 0xff) * backgroundAlpha) + redWithAlpha) / 256);
95 public static void drawPolygon(final RenderingContext context,
96 final Point2D onScreenPoint1, final Point2D onScreenPoint2,
97 final Point2D onScreenPoint3,
98 final MouseInteractionController mouseInteractionController,
101 onScreenPoint1.roundToInteger();
102 onScreenPoint2.roundToInteger();
103 onScreenPoint3.roundToInteger();
105 if (mouseInteractionController != null)
106 if (context.mouseClick != null)
107 if (Polygon.pointWithinPolygon(context.mouseClick.coordinate,
108 onScreenPoint1, onScreenPoint2, onScreenPoint3))
109 context.clickedItem = mouseInteractionController;
111 if (color.isTransparent())
114 // find top-most point
115 int yTop = (int) onScreenPoint1.y;
117 if (onScreenPoint2.y < yTop)
118 yTop = (int) onScreenPoint2.y;
120 if (onScreenPoint3.y < yTop)
121 yTop = (int) onScreenPoint3.y;
126 // find bottom-most point
127 int yBottom = (int) onScreenPoint1.y;
129 if (onScreenPoint2.y > yBottom)
130 yBottom = (int) onScreenPoint2.y;
132 if (onScreenPoint3.y > yBottom)
133 yBottom = (int) onScreenPoint3.y;
135 if (yBottom >= context.height)
136 yBottom = context.height - 1;
139 polygonBoundary1.setPoints(onScreenPoint1, onScreenPoint2);
140 polygonBoundary2.setPoints(onScreenPoint1, onScreenPoint3);
141 polygonBoundary3.setPoints(onScreenPoint2, onScreenPoint3);
143 final LineInterpolator[] is = new LineInterpolator[3];
144 is[0] = polygonBoundary1;
145 is[1] = polygonBoundary2;
146 is[2] = polygonBoundary3;
148 java.util.Arrays.sort(is);
150 for (int y = yTop; y < yBottom; y++)
151 if (is[0].containsY(y)) {
153 if (is[1].containsY(y))
154 drawHorizontalLine(is[0], is[1], y, context, color);
155 else if (is[2].containsY(y))
156 drawHorizontalLine(is[0], is[2], y, context, color);
157 } else if (is[1].containsY(y))
158 if (is[2].containsY(y))
159 drawHorizontalLine(is[1], is[2], y, context, color);
162 public Color getColor() {
166 public void setColor(final Color color) {
171 public void paint(final RenderingContext renderBuffer) {
173 final Point2D onScreenPoint1 = coordinates[0].onScreenCoordinate;
174 final Point2D onScreenPoint2 = coordinates[1].onScreenCoordinate;
175 final Point2D onScreenPoint3 = coordinates[2].onScreenCoordinate;
177 drawPolygon(renderBuffer, onScreenPoint1, onScreenPoint2,
178 onScreenPoint3, mouseInteractionController, color);