1 package org.newdawn.slick.geom;
2
3 import org.newdawn.slick.Image;
4 import org.newdawn.slick.ShapeFill;
5 import org.newdawn.slick.opengl.Texture;
6 import org.newdawn.slick.opengl.TextureImpl;
7 import org.newdawn.slick.opengl.renderer.LineStripRenderer;
8 import org.newdawn.slick.opengl.renderer.Renderer;
9 import org.newdawn.slick.opengl.renderer.SGL;
10
11 import javax.annotation.Nonnull;
12 import javax.annotation.Nullable;
13
14
15
16
17
18
19 public final class ShapeRenderer {
20
21 private static final SGL GL = Renderer.get();
22
23 private static final LineStripRenderer LSR = Renderer.getLineStripRenderer();
24
25
26
27
28
29
30
31 public static final void draw(@Nonnull Shape shape) {
32 Texture t = TextureImpl.getLastBind();
33 TextureImpl.bindNone();
34
35 float points[] = shape.getPoints();
36
37 LSR.start();
38 for(int i=0;i<points.length;i+=2) {
39 LSR.vertex(points[i], points[i + 1]);
40 }
41
42 if (shape.closed()) {
43 LSR.vertex(points[0], points[1]);
44 }
45
46 LSR.end();
47
48 if (t == null) {
49 TextureImpl.bindNone();
50 } else {
51 t.bind();
52 }
53 }
54
55
56
57
58
59
60
61
62 public static final void draw(@Nonnull Shape shape, @Nonnull ShapeFill fill) {
63 float points[] = shape.getPoints();
64
65 Texture t = TextureImpl.getLastBind();
66 TextureImpl.bindNone();
67
68 shape.getCenter();
69 GL.glBegin(SGL.GL_LINE_STRIP);
70 for(int i=0;i<points.length;i+=2) {
71 fill.colorAt(shape, points[i], points[i + 1]).bind();
72 Vector2f offset = fill.getOffsetAt(shape, points[i], points[i + 1]);
73 GL.glVertex2f(points[i] + offset.x, points[i + 1] + offset.y);
74 }
75
76 if (shape.closed()) {
77 fill.colorAt(shape, points[0], points[1]).bind();
78 Vector2f offset = fill.getOffsetAt(shape, points[0], points[1]);
79 GL.glVertex2f(points[0] + offset.x, points[1] + offset.y);
80 }
81 GL.glEnd();
82
83 if (t == null) {
84 TextureImpl.bindNone();
85 } else {
86 t.bind();
87 }
88 }
89
90
91
92
93
94
95
96 private static boolean validFill(@Nonnull Shape shape) {
97 if (shape.getTriangles() == null) {
98 return false;
99 }
100 return shape.getTriangles().getTriangleCount() != 0;
101 }
102
103
104
105
106
107
108
109 public static final void fill(@Nonnull Shape shape) {
110 if (!validFill(shape)) {
111 return;
112 }
113
114 Texture t = TextureImpl.getLastBind();
115 TextureImpl.bindNone();
116
117 fill(shape, (shape1, x, y) -> null);
118
119 if (t == null) {
120 TextureImpl.bindNone();
121 } else {
122 t.bind();
123 }
124 }
125
126
127
128
129
130
131
132
133 private static final void fill(@Nonnull Shape shape, @Nonnull PointCallback callback) {
134 Triangulator tris = shape.getTriangles();
135
136 GL.glBegin(SGL.GL_TRIANGLES);
137 for (int i=0;i<tris.getTriangleCount();i++) {
138 for (int p=0;p<3;p++) {
139 float[] pt = tris.getTrianglePoint(i, p);
140 float[] np = callback.preRenderPoint(shape, pt[0],pt[1]);
141
142 if (np == null) {
143 GL.glVertex2f(pt[0],pt[1]);
144 } else {
145 GL.glVertex2f(np[0],np[1]);
146 }
147 }
148 }
149 GL.glEnd();
150 }
151
152
153
154
155
156
157
158
159 public static final void texture(@Nonnull Shape shape, @Nonnull Image image) {
160 texture(shape, image, 0.01f, 0.01f);
161 }
162
163
164
165
166
167
168
169
170
171 public static final void textureFit(@Nonnull Shape shape, @Nonnull Image image) {
172 textureFit(shape, image,1f,1f);
173 }
174
175
176
177
178
179
180
181
182
183
184 public static final void texture(@Nonnull Shape shape, @Nonnull final Image image, final float scaleX, final float scaleY) {
185 if (!validFill(shape)) {
186 return;
187 }
188
189 final Texture t = TextureImpl.getLastBind();
190 image.getTexture().bind();
191
192 fill(shape, (shape1, x, y) -> {
193 float tx = x * scaleX;
194 float ty = y * scaleY;
195
196 tx = image.getTextureOffsetX() + (image.getTextureWidth() * tx);
197 ty = image.getTextureOffsetY() + (image.getTextureHeight() * ty);
198
199 GL.glTexCoord2f(tx, ty);
200 return null;
201 });
202
203 shape.getPoints();
204
205 if (t == null) {
206 TextureImpl.bindNone();
207 } else {
208 t.bind();
209 }
210 }
211
212
213
214
215
216
217
218
219
220
221
222 public static final void textureFit(@Nonnull Shape shape, @Nonnull final Image image, final float scaleX, final float scaleY) {
223 if (!validFill(shape)) {
224 return;
225 }
226
227 shape.getPoints();
228
229 Texture t = TextureImpl.getLastBind();
230 image.getTexture().bind();
231
232 shape.getX();
233 shape.getY();
234 shape.getMaxX();
235 shape.getMaxY();
236
237 fill(shape, (shape1, x, y) -> {
238 x -= shape1.getMinX();
239 y -= shape1.getMinY();
240
241 x /= (shape1.getMaxX() - shape1.getMinX());
242 y /= (shape1.getMaxY() - shape1.getMinY());
243
244 float tx = x * scaleX;
245 float ty = y * scaleY;
246
247 tx = image.getTextureOffsetX() + (image.getTextureWidth() * tx);
248 ty = image.getTextureOffsetY() + (image.getTextureHeight() * ty);
249
250 GL.glTexCoord2f(tx, ty);
251 return null;
252 });
253
254 if (t == null) {
255 TextureImpl.bindNone();
256 } else {
257 t.bind();
258 }
259 }
260
261
262
263
264
265
266
267
268 public static final void fill(@Nonnull final Shape shape, @Nonnull final ShapeFill fill) {
269 if (!validFill(shape)) {
270 return;
271 }
272
273 Texture t = TextureImpl.getLastBind();
274 TextureImpl.bindNone();
275
276 shape.getCenter();
277 fill(shape, (shape1, x, y) -> {
278 fill.colorAt(shape1, x, y).bind();
279 Vector2f offset = fill.getOffsetAt(shape1, x, y);
280
281 return new float[] {offset.x + x,offset.y + y};
282 });
283
284 if (t == null) {
285 TextureImpl.bindNone();
286 } else {
287 t.bind();
288 }
289 }
290
291
292
293
294
295
296
297
298
299
300
301
302 public static final void texture(@Nonnull final Shape shape, @Nonnull final Image image, final float scaleX, final float scaleY, @Nonnull final ShapeFill fill) {
303 if (!validFill(shape)) {
304 return;
305 }
306
307 Texture t = TextureImpl.getLastBind();
308 image.getTexture().bind();
309
310 final float center[] = shape.getCenter();
311 fill(shape, (shape1, x, y) -> {
312 fill.colorAt(shape1, x - center[0], y - center[1]).bind();
313 Vector2f offset = fill.getOffsetAt(shape1, x, y);
314
315 x += offset.x;
316 y += offset.y;
317
318 float tx = x * scaleX;
319 float ty = y * scaleY;
320
321 tx = image.getTextureOffsetX() + (image.getTextureWidth() * tx);
322 ty = image.getTextureOffsetY() + (image.getTextureHeight() * ty);
323
324 GL.glTexCoord2f(tx, ty);
325
326 return new float[] {offset.x + x,offset.y + y};
327 });
328
329 if (t == null) {
330 TextureImpl.bindNone();
331 } else {
332 t.bind();
333 }
334 }
335
336
337
338
339
340
341
342
343 public static final void texture(@Nonnull final Shape shape, @Nonnull Image image, @Nonnull final TexCoordGenerator gen) {
344 Texture t = TextureImpl.getLastBind();
345
346 image.getTexture().bind();
347
348 shape.getCenter();
349 fill(shape, (shape1, x, y) -> {
350 Vector2f tex = gen.getCoordFor(x, y);
351 GL.glTexCoord2f(tex.x, tex.y);
352
353 return new float[] {x,y};
354 });
355
356 if (t == null) {
357 TextureImpl.bindNone();
358 } else {
359 t.bind();
360 }
361 }
362
363
364
365
366
367
368 private static interface PointCallback {
369
370
371
372
373
374
375
376
377 @Nullable
378 float[] preRenderPoint(Shape shape, float x, float y);
379 }
380 }