Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epoxy
GitHub Repository: epoxy/proj11
Path: blob/master/SLICK_HOME/src/org/newdawn/slick/geom/ShapeRenderer.java
1461 views
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
/**
12
* @author Mark Bernard
13
*
14
* Use this class to render shpaes directly to OpenGL. Allows you to bypass the Graphics class.
15
*/
16
public final class ShapeRenderer {
17
/** The renderer to use for all GL operations */
18
private static SGL GL = Renderer.get();
19
/** The renderer to use line strips */
20
private static LineStripRenderer LSR = Renderer.getLineStripRenderer();
21
22
/**
23
* Draw the outline of the given shape. Only the vertices are set.
24
* The colour has to be set independently of this method.
25
*
26
* @param shape The shape to draw.
27
*/
28
public static final void draw(Shape shape) {
29
Texture t = TextureImpl.getLastBind();
30
TextureImpl.bindNone();
31
32
float points[] = shape.getPoints();
33
34
LSR.start();
35
for(int i=0;i<points.length;i+=2) {
36
LSR.vertex(points[i], points[i + 1]);
37
}
38
39
if (shape.closed()) {
40
LSR.vertex(points[0], points[1]);
41
}
42
43
LSR.end();
44
45
if (t == null) {
46
TextureImpl.bindNone();
47
} else {
48
t.bind();
49
}
50
}
51
52
/**
53
* Draw the outline of the given shape. Only the vertices are set.
54
* The colour has to be set independently of this method.
55
*
56
* @param shape The shape to draw.
57
* @param fill The fill to apply
58
*/
59
public static final void draw(Shape shape, ShapeFill fill) {
60
float points[] = shape.getPoints();
61
62
Texture t = TextureImpl.getLastBind();
63
TextureImpl.bindNone();
64
65
float center[] = shape.getCenter();
66
GL.glBegin(SGL.GL_LINE_STRIP);
67
for(int i=0;i<points.length;i+=2) {
68
fill.colorAt(shape, points[i], points[i + 1]).bind();
69
Vector2f offset = fill.getOffsetAt(shape, points[i], points[i + 1]);
70
GL.glVertex2f(points[i] + offset.x, points[i + 1] + offset.y);
71
}
72
73
if (shape.closed()) {
74
fill.colorAt(shape, points[0], points[1]).bind();
75
Vector2f offset = fill.getOffsetAt(shape, points[0], points[1]);
76
GL.glVertex2f(points[0] + offset.x, points[1] + offset.y);
77
}
78
GL.glEnd();
79
80
if (t == null) {
81
TextureImpl.bindNone();
82
} else {
83
t.bind();
84
}
85
}
86
87
/**
88
* Check there are enough points to fill
89
*
90
* @param shape THe shape we're drawing
91
* @return True if the fill is valid
92
*/
93
public static boolean validFill(Shape shape) {
94
if (shape.getTriangles() == null) {
95
return false;
96
}
97
return shape.getTriangles().getTriangleCount() != 0;
98
}
99
100
/**
101
* Draw the the given shape filled in. Only the vertices are set.
102
* The colour has to be set independently of this method.
103
*
104
* @param shape The shape to fill.
105
*/
106
public static final void fill(Shape shape) {
107
if (!validFill(shape)) {
108
return;
109
}
110
111
Texture t = TextureImpl.getLastBind();
112
TextureImpl.bindNone();
113
114
fill(shape, new PointCallback() {
115
public float[] preRenderPoint(Shape shape, float x, float y) {
116
// do nothing, we're just filling the shape this time
117
return null;
118
}
119
});
120
121
if (t == null) {
122
TextureImpl.bindNone();
123
} else {
124
t.bind();
125
}
126
}
127
128
/**
129
* Draw the the given shape filled in. Only the vertices are set.
130
* The colour has to be set independently of this method.
131
*
132
* @param shape The shape to fill.
133
* @param callback The callback that will be invoked for each shape point
134
*/
135
private static final void fill(Shape shape, PointCallback callback) {
136
Triangulator tris = shape.getTriangles();
137
138
GL.glBegin(SGL.GL_TRIANGLES);
139
for (int i=0;i<tris.getTriangleCount();i++) {
140
for (int p=0;p<3;p++) {
141
float[] pt = tris.getTrianglePoint(i, p);
142
float[] np = callback.preRenderPoint(shape, pt[0],pt[1]);
143
144
if (np == null) {
145
GL.glVertex2f(pt[0],pt[1]);
146
} else {
147
GL.glVertex2f(np[0],np[1]);
148
}
149
}
150
}
151
GL.glEnd();
152
}
153
154
/**
155
* Draw the the given shape filled in with a texture. Only the vertices are set.
156
* The colour has to be set independently of this method.
157
*
158
* @param shape The shape to texture.
159
* @param image The image to tile across the shape
160
*/
161
public static final void texture(Shape shape, Image image) {
162
texture(shape, image, 0.01f, 0.01f);
163
}
164
165
/**
166
* Draw the the given shape filled in with a texture. Only the vertices are set.
167
* The colour has to be set independently of this method. This method is required to
168
* fit the texture once across the shape.
169
*
170
* @param shape The shape to texture.
171
* @param image The image to tile across the shape
172
*/
173
public static final void textureFit(Shape shape, Image image) {
174
textureFit(shape, image,1f,1f);
175
}
176
177
/**
178
* Draw the the given shape filled in with a texture. Only the vertices are set.
179
* The colour has to be set independently of this method.
180
*
181
* @param shape The shape to texture.
182
* @param image The image to tile across the shape
183
* @param scaleX The scale to apply on the x axis for texturing
184
* @param scaleY The scale to apply on the y axis for texturing
185
*/
186
public static final void texture(Shape shape, final Image image, final float scaleX, final float scaleY) {
187
if (!validFill(shape)) {
188
return;
189
}
190
191
final Texture t = TextureImpl.getLastBind();
192
image.getTexture().bind();
193
194
fill(shape, new PointCallback() {
195
public float[] preRenderPoint(Shape shape, float x, float y) {
196
float tx = x * scaleX;
197
float ty = y * scaleY;
198
199
tx = image.getTextureOffsetX() + (image.getTextureWidth() * tx);
200
ty = image.getTextureOffsetY() + (image.getTextureHeight() * ty);
201
202
GL.glTexCoord2f(tx, ty);
203
return null;
204
}
205
});
206
207
float points[] = shape.getPoints();
208
209
if (t == null) {
210
TextureImpl.bindNone();
211
} else {
212
t.bind();
213
}
214
}
215
216
/**
217
* Draw the the given shape filled in with a texture. Only the vertices are set.
218
* The colour has to be set independently of this method. This method is required to
219
* fit the texture scaleX times across the shape and scaleY times down the shape.
220
*
221
* @param shape The shape to texture.
222
* @param image The image to tile across the shape
223
* @param scaleX The scale to apply on the x axis for texturing
224
* @param scaleY The scale to apply on the y axis for texturing
225
*/
226
public static final void textureFit(Shape shape, final Image image, final float scaleX, final float scaleY) {
227
if (!validFill(shape)) {
228
return;
229
}
230
231
float points[] = shape.getPoints();
232
233
Texture t = TextureImpl.getLastBind();
234
image.getTexture().bind();
235
236
final float minX = shape.getX();
237
final float minY = shape.getY();
238
final float maxX = shape.getMaxX() - minX;
239
final float maxY = shape.getMaxY() - minY;
240
241
fill(shape, new PointCallback() {
242
public float[] preRenderPoint(Shape shape, float x, float y) {
243
x -= shape.getMinX();
244
y -= shape.getMinY();
245
246
x /= (shape.getMaxX() - shape.getMinX());
247
y /= (shape.getMaxY() - shape.getMinY());
248
249
float tx = x * scaleX;
250
float ty = y * scaleY;
251
252
tx = image.getTextureOffsetX() + (image.getTextureWidth() * tx);
253
ty = image.getTextureOffsetY() + (image.getTextureHeight() * ty);
254
255
GL.glTexCoord2f(tx, ty);
256
return null;
257
}
258
});
259
260
if (t == null) {
261
TextureImpl.bindNone();
262
} else {
263
t.bind();
264
}
265
}
266
267
/**
268
* Draw the the given shape filled in. Only the vertices are set.
269
* The colour has to be set independently of this method.
270
*
271
* @param shape The shape to fill.
272
* @param fill The fill to apply
273
*/
274
public static final void fill(final Shape shape, final ShapeFill fill) {
275
if (!validFill(shape)) {
276
return;
277
}
278
279
Texture t = TextureImpl.getLastBind();
280
TextureImpl.bindNone();
281
282
final float center[] = shape.getCenter();
283
fill(shape, new PointCallback() {
284
public float[] preRenderPoint(Shape shape, float x, float y) {
285
fill.colorAt(shape, x, y).bind();
286
Vector2f offset = fill.getOffsetAt(shape, x, y);
287
288
return new float[] {offset.x + x,offset.y + y};
289
}
290
});
291
292
if (t == null) {
293
TextureImpl.bindNone();
294
} else {
295
t.bind();
296
}
297
}
298
299
300
/**
301
* Draw the the given shape filled in with a texture. Only the vertices are set.
302
* The colour has to be set independently of this method.
303
*
304
* @param shape The shape to texture.
305
* @param image The image to tile across the shape
306
* @param scaleX The scale to apply on the x axis for texturing
307
* @param scaleY The scale to apply on the y axis for texturing
308
* @param fill The fill to apply
309
*/
310
public static final void texture(final Shape shape, final Image image, final float scaleX, final float scaleY, final ShapeFill fill) {
311
if (!validFill(shape)) {
312
return;
313
}
314
315
Texture t = TextureImpl.getLastBind();
316
image.getTexture().bind();
317
318
final float center[] = shape.getCenter();
319
fill(shape, new PointCallback() {
320
public float[] preRenderPoint(Shape shape, float x, float y) {
321
fill.colorAt(shape, x - center[0], y - center[1]).bind();
322
Vector2f offset = fill.getOffsetAt(shape, x, y);
323
324
x += offset.x;
325
y += offset.y;
326
327
float tx = x * scaleX;
328
float ty = y * scaleY;
329
330
tx = image.getTextureOffsetX() + (image.getTextureWidth() * tx);
331
ty = image.getTextureOffsetY() + (image.getTextureHeight() * ty);
332
333
GL.glTexCoord2f(tx, ty);
334
335
return new float[] {offset.x + x,offset.y + y};
336
}
337
});
338
339
if (t == null) {
340
TextureImpl.bindNone();
341
} else {
342
t.bind();
343
}
344
}
345
/**
346
* Draw the the given shape filled in with a texture. Only the vertices are set.
347
* The colour has to be set independently of this method.
348
*
349
* @param shape The shape to texture.
350
* @param image The image to tile across the shape
351
* @param gen The texture coordinate generator to create coordiantes for the shape
352
*/
353
public static final void texture(final Shape shape, Image image, final TexCoordGenerator gen) {
354
Texture t = TextureImpl.getLastBind();
355
356
image.getTexture().bind();
357
358
final float center[] = shape.getCenter();
359
fill(shape, new PointCallback() {
360
public float[] preRenderPoint(Shape shape, float x, float y) {
361
Vector2f tex = gen.getCoordFor(x, y);
362
GL.glTexCoord2f(tex.x, tex.y);
363
364
return new float[] {x,y};
365
}
366
});
367
368
if (t == null) {
369
TextureImpl.bindNone();
370
} else {
371
t.bind();
372
}
373
}
374
375
/**
376
* Description of some feature that will be applied to each point render
377
*
378
* @author kevin
379
*/
380
private static interface PointCallback {
381
/**
382
* Apply feature before the call to glVertex
383
*
384
* @param shape The shape the point belongs to
385
* @param x The x poisiton the vertex will be at
386
* @param y The y position the vertex will be at
387
* @return The new coordinates of null
388
*/
389
float[] preRenderPoint(Shape shape, float x, float y);
390
}
391
}
392
393