Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epoxy
GitHub Repository: epoxy/proj11
Path: blob/master/SLICK_HOME/src/org/newdawn/slick/Graphics.java
1456 views
1
package org.newdawn.slick;
2
3
import java.nio.ByteBuffer;
4
import java.nio.DoubleBuffer;
5
import java.nio.FloatBuffer;
6
import java.security.AccessController;
7
import java.security.PrivilegedAction;
8
import java.util.ArrayList;
9
10
import org.lwjgl.BufferUtils;
11
import org.lwjgl.opengl.GL11;
12
import org.newdawn.slick.geom.Rectangle;
13
import org.newdawn.slick.geom.Shape;
14
import org.newdawn.slick.geom.ShapeRenderer;
15
import org.newdawn.slick.opengl.TextureImpl;
16
import org.newdawn.slick.opengl.renderer.LineStripRenderer;
17
import org.newdawn.slick.opengl.renderer.Renderer;
18
import org.newdawn.slick.opengl.renderer.SGL;
19
import org.newdawn.slick.util.FastTrig;
20
import org.newdawn.slick.util.Log;
21
22
/**
23
* A graphics context that can be used to render primatives to the accelerated
24
* canvas provided by LWJGL.
25
*
26
* @author kevin
27
*/
28
public class Graphics {
29
/** The renderer to use for all GL operations */
30
protected static SGL GL = Renderer.get();
31
/** The renderer to use line strips */
32
private static LineStripRenderer LSR = Renderer.getLineStripRenderer();
33
34
/** The normal drawing mode */
35
public static int MODE_NORMAL = 1;
36
37
/** Draw to the alpha map */
38
public static int MODE_ALPHA_MAP = 2;
39
40
/** Draw using the alpha blending */
41
public static int MODE_ALPHA_BLEND = 3;
42
43
/** Draw multiplying the source and destination colours */
44
public static int MODE_COLOR_MULTIPLY = 4;
45
46
/** Draw adding the existing colour to the new colour */
47
public static int MODE_ADD = 5;
48
49
/** Draw blending the new image into the old one by a factor of it's colour */
50
public static int MODE_SCREEN = 6;
51
52
/** The default number of segments that will be used when drawing an oval */
53
private static final int DEFAULT_SEGMENTS = 50;
54
55
/** The last graphics context in use */
56
protected static Graphics currentGraphics = null;
57
58
/** The default font to use */
59
protected static Font DEFAULT_FONT;
60
61
/** The last set scale */
62
private float sx = 1;
63
/** The last set scale */
64
private float sy = 1;
65
66
/**
67
* Set the current graphics context in use
68
*
69
* @param current The graphics context that should be considered current
70
*/
71
public static void setCurrent(Graphics current) {
72
if (currentGraphics != current) {
73
if (currentGraphics != null) {
74
currentGraphics.disable();
75
}
76
currentGraphics = current;
77
currentGraphics.enable();
78
}
79
}
80
81
/** The font in use */
82
private Font font;
83
84
/** The current color */
85
private Color currentColor = Color.white;
86
87
/** The width of the screen */
88
protected int screenWidth;
89
90
/** The height of the screen */
91
protected int screenHeight;
92
93
/** True if the matrix has been pushed to the stack */
94
private boolean pushed;
95
96
/** The graphics context clipping */
97
private Rectangle clip;
98
99
/** Buffer used for setting the world clip */
100
private DoubleBuffer worldClip = BufferUtils.createDoubleBuffer(4);
101
102
/** The buffer used to read a screen pixel */
103
private ByteBuffer readBuffer = BufferUtils.createByteBuffer(4);
104
105
/** True if we're antialias */
106
private boolean antialias;
107
108
/** The world clip recorded since last set */
109
private Rectangle worldClipRecord;
110
111
/** The current drawing mode */
112
private int currentDrawingMode = MODE_NORMAL;
113
114
/** The current line width */
115
private float lineWidth = 1;
116
117
/** The matrix stack */
118
private ArrayList stack = new ArrayList();
119
/** The index into the stack we're using */
120
private int stackIndex;
121
122
/**
123
* Default constructor for sub-classes
124
*/
125
public Graphics() {
126
}
127
128
/**
129
* Create a new graphics context. Only the container should be doing this
130
* really
131
*
132
* @param width
133
* The width of the screen for this context
134
* @param height
135
* The height of the screen for this context
136
*/
137
public Graphics(int width, int height) {
138
if (DEFAULT_FONT == null) {
139
AccessController.doPrivileged(new PrivilegedAction() {
140
public Object run() {
141
try {
142
DEFAULT_FONT = new AngelCodeFont(
143
"org/newdawn/slick/data/defaultfont.fnt",
144
"org/newdawn/slick/data/defaultfont.png");
145
} catch (SlickException e) {
146
Log.error(e);
147
}
148
return null; // nothing to return
149
}
150
});
151
}
152
153
this.font = DEFAULT_FONT;
154
screenWidth = width;
155
screenHeight = height;
156
}
157
158
/**
159
* Set the dimensions considered by the graphics context
160
*
161
* @param width The width of the graphics context
162
* @param height The height of the graphics context
163
*/
164
void setDimensions(int width, int height) {
165
screenWidth = width;
166
screenHeight = height;
167
}
168
169
/**
170
* Set the drawing mode to use. This mode defines how pixels are drawn to
171
* the graphics context. It can be used to draw into the alpha map.
172
*
173
* The mode supplied should be one of {@link Graphics#MODE_NORMAL} or
174
* {@link Graphics#MODE_ALPHA_MAP} or {@link Graphics#MODE_ALPHA_BLEND}
175
*
176
* @param mode
177
* The mode to apply.
178
*/
179
public void setDrawMode(int mode) {
180
predraw();
181
currentDrawingMode = mode;
182
if (currentDrawingMode == MODE_NORMAL) {
183
GL.glEnable(SGL.GL_BLEND);
184
GL.glColorMask(true, true, true, true);
185
GL.glBlendFunc(SGL.GL_SRC_ALPHA, SGL.GL_ONE_MINUS_SRC_ALPHA);
186
}
187
if (currentDrawingMode == MODE_ALPHA_MAP) {
188
GL.glDisable(SGL.GL_BLEND);
189
GL.glColorMask(false, false, false, true);
190
}
191
if (currentDrawingMode == MODE_ALPHA_BLEND) {
192
GL.glEnable(SGL.GL_BLEND);
193
GL.glColorMask(true, true, true, false);
194
GL.glBlendFunc(GL11.GL_DST_ALPHA, GL11.GL_ONE_MINUS_DST_ALPHA);
195
}
196
if (currentDrawingMode == MODE_COLOR_MULTIPLY) {
197
GL.glEnable(SGL.GL_BLEND);
198
GL.glColorMask(true, true, true, true);
199
GL.glBlendFunc(GL11.GL_ONE_MINUS_SRC_COLOR, GL11.GL_SRC_COLOR);
200
}
201
if (currentDrawingMode == MODE_ADD) {
202
GL.glEnable(SGL.GL_BLEND);
203
GL.glColorMask(true, true, true, true);
204
GL.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE);
205
}
206
if (currentDrawingMode == MODE_SCREEN) {
207
GL.glEnable(SGL.GL_BLEND);
208
GL.glColorMask(true, true, true, true);
209
GL.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_COLOR);
210
}
211
postdraw();
212
}
213
214
/**
215
* Clear the state of the alpha map across the entire screen. This sets
216
* alpha to 0 everywhere, meaning in {@link Graphics#MODE_ALPHA_BLEND}
217
* nothing will be drawn.
218
*/
219
public void clearAlphaMap() {
220
pushTransform();
221
GL.glLoadIdentity();
222
223
int originalMode = currentDrawingMode;
224
setDrawMode(MODE_ALPHA_MAP);
225
setColor(new Color(0,0,0,0));
226
fillRect(0, 0, screenWidth, screenHeight);
227
setColor(currentColor);
228
setDrawMode(originalMode);
229
230
popTransform();
231
}
232
233
/**
234
* Must be called before all OpenGL operations to maintain context for
235
* dynamic images
236
*/
237
private void predraw() {
238
setCurrent(this);
239
}
240
241
/**
242
* Must be called after all OpenGL operations to maintain context for
243
* dynamic images
244
*/
245
private void postdraw() {
246
}
247
248
/**
249
* Enable rendering to this graphics context
250
*/
251
protected void enable() {
252
}
253
254
/**
255
* Flush this graphics context to the underlying rendering context
256
*/
257
public void flush() {
258
if (currentGraphics == this) {
259
currentGraphics.disable();
260
currentGraphics = null;
261
}
262
}
263
264
/**
265
* Disable rendering to this graphics context
266
*/
267
protected void disable() {
268
}
269
270
/**
271
* Get the current font
272
*
273
* @return The current font
274
*/
275
public Font getFont() {
276
return font;
277
}
278
279
/**
280
* Set the background colour of the graphics context
281
*
282
* @param color
283
* The background color of the graphics context
284
*/
285
public void setBackground(Color color) {
286
predraw();
287
GL.glClearColor(color.r, color.g, color.b, color.a);
288
postdraw();
289
}
290
291
/**
292
* Get the current graphics context background color
293
*
294
* @return The background color of this graphics context
295
*/
296
public Color getBackground() {
297
predraw();
298
FloatBuffer buffer = BufferUtils.createFloatBuffer(16);
299
GL.glGetFloat(SGL.GL_COLOR_CLEAR_VALUE, buffer);
300
postdraw();
301
302
return new Color(buffer);
303
}
304
305
/**
306
* Clear the graphics context
307
*/
308
public void clear() {
309
predraw();
310
GL.glClear(SGL.GL_COLOR_BUFFER_BIT);
311
postdraw();
312
}
313
314
/**
315
* Reset the transformation on this graphics context
316
*/
317
public void resetTransform() {
318
sx = 1;
319
sy = 1;
320
321
if (pushed) {
322
predraw();
323
GL.glPopMatrix();
324
pushed = false;
325
postdraw();
326
}
327
}
328
329
/**
330
* Check if we've pushed the previous matrix, if not then push it now.
331
*/
332
private void checkPush() {
333
if (!pushed) {
334
predraw();
335
GL.glPushMatrix();
336
pushed = true;
337
postdraw();
338
}
339
}
340
341
/**
342
* Apply a scaling factor to everything drawn on the graphics context
343
*
344
* @param sx
345
* The scaling factor to apply to the x axis
346
* @param sy
347
* The scaling factor to apply to the y axis
348
*/
349
public void scale(float sx, float sy) {
350
this.sx = this.sx * sx;
351
this.sy = this.sy * sy;
352
353
checkPush();
354
355
predraw();
356
GL.glScalef(sx, sy, 1);
357
postdraw();
358
}
359
360
/**
361
* Apply a rotation to everything draw on the graphics context
362
*
363
* @param rx
364
* The x coordinate of the center of rotation
365
* @param ry
366
* The y coordinate of the center of rotation
367
* @param ang
368
* The angle (in degrees) to rotate by
369
*/
370
public void rotate(float rx, float ry, float ang) {
371
checkPush();
372
373
predraw();
374
translate(rx, ry);
375
GL.glRotatef(ang, 0, 0, 1);
376
translate(-rx, -ry);
377
postdraw();
378
}
379
380
/**
381
* Apply a translation to everything drawn to the context
382
*
383
* @param x
384
* The amount to translate on the x-axis
385
* @param y
386
* The amount of translate on the y-axis
387
*/
388
public void translate(float x, float y) {
389
checkPush();
390
391
predraw();
392
GL.glTranslatef(x, y, 0);
393
postdraw();
394
}
395
396
/**
397
* Set the font to be used when rendering text
398
*
399
* @param font
400
* The font to be used when rendering text
401
*/
402
public void setFont(Font font) {
403
this.font = font;
404
}
405
406
/**
407
* Reset to using the default font for this context
408
*/
409
public void resetFont() {
410
font = DEFAULT_FONT;
411
}
412
413
/**
414
* Set the color to use when rendering to this context
415
*
416
* @param color
417
* The color to use when rendering to this context
418
*/
419
public void setColor(Color color) {
420
if (color == null) {
421
return;
422
}
423
424
currentColor = new Color(color);
425
predraw();
426
currentColor.bind();
427
postdraw();
428
}
429
430
/**
431
* Get the color in use by this graphics context
432
*
433
* @return The color in use by this graphics context
434
*/
435
public Color getColor() {
436
return new Color(currentColor);
437
}
438
439
/**
440
* Draw a line on the canvas in the current colour
441
*
442
* @param x1
443
* The x coordinate of the start point
444
* @param y1
445
* The y coordinate of the start point
446
* @param x2
447
* The x coordinate of the end point
448
* @param y2
449
* The y coordinate of the end point
450
*/
451
public void drawLine(float x1, float y1, float x2, float y2) {
452
float lineWidth = this.lineWidth - 1;
453
454
if (LSR.applyGLLineFixes()) {
455
if (x1 == x2) {
456
if (y1 > y2) {
457
float temp = y2;
458
y2 = y1;
459
y1 = temp;
460
}
461
float step = 1 / sy;
462
lineWidth = lineWidth / sy;
463
fillRect(x1-(lineWidth/2.0f),y1-(lineWidth/2.0f),lineWidth+step,(y2-y1)+lineWidth+step);
464
return;
465
} else if (y1 == y2) {
466
if (x1 > x2) {
467
float temp = x2;
468
x2 = x1;
469
x1 = temp;
470
}
471
float step = 1 / sx;
472
lineWidth = lineWidth / sx;
473
fillRect(x1-(lineWidth/2.0f),y1-(lineWidth/2.0f),(x2-x1)+lineWidth+step,lineWidth+step);
474
return;
475
}
476
}
477
478
predraw();
479
currentColor.bind();
480
TextureImpl.bindNone();
481
482
LSR.start();
483
LSR.vertex(x1,y1);
484
LSR.vertex(x2,y2);
485
LSR.end();
486
487
postdraw();
488
}
489
490
/**
491
* Draw the outline of the given shape.
492
*
493
* @param shape
494
* The shape to draw.
495
* @param fill
496
* The fill type to apply
497
*/
498
public void draw(Shape shape, ShapeFill fill) {
499
predraw();
500
TextureImpl.bindNone();
501
502
ShapeRenderer.draw(shape, fill);
503
504
currentColor.bind();
505
postdraw();
506
}
507
508
/**
509
* Draw the the given shape filled in.
510
*
511
* @param shape
512
* The shape to fill.
513
* @param fill
514
* The fill type to apply
515
*/
516
public void fill(Shape shape, ShapeFill fill) {
517
predraw();
518
TextureImpl.bindNone();
519
520
ShapeRenderer.fill(shape, fill);
521
522
currentColor.bind();
523
postdraw();
524
}
525
526
/**
527
* Draw the outline of the given shape.
528
*
529
* @param shape
530
* The shape to draw.
531
*/
532
public void draw(Shape shape) {
533
predraw();
534
TextureImpl.bindNone();
535
currentColor.bind();
536
537
ShapeRenderer.draw(shape);
538
539
postdraw();
540
}
541
542
/**
543
* Draw the the given shape filled in.
544
*
545
* @param shape
546
* The shape to fill.
547
*/
548
public void fill(Shape shape) {
549
predraw();
550
TextureImpl.bindNone();
551
currentColor.bind();
552
553
ShapeRenderer.fill(shape);
554
555
postdraw();
556
}
557
558
/**
559
* Draw the the given shape filled in with a texture
560
*
561
* @param shape
562
* The shape to texture.
563
* @param image
564
* The image to tile across the shape
565
*/
566
public void texture(Shape shape, Image image) {
567
texture(shape, image, 0.01f, 0.01f, false);
568
}
569
570
/**
571
* Draw the the given shape filled in with a texture
572
*
573
* @param shape
574
* The shape to texture.
575
* @param image
576
* The image to tile across the shape
577
* @param fill
578
* The shape fill to apply
579
*/
580
public void texture(Shape shape, Image image, ShapeFill fill) {
581
texture(shape, image, 0.01f, 0.01f, fill);
582
}
583
584
/**
585
* Draw the the given shape filled in with a texture
586
*
587
* @param shape
588
* The shape to texture.
589
* @param image
590
* The image to tile across the shape
591
* @param fit
592
* True if we want to fit the image on to the shape
593
*/
594
public void texture(Shape shape, Image image, boolean fit) {
595
if (fit) {
596
texture(shape, image, 1, 1, true);
597
} else {
598
texture(shape, image, 0.01f, 0.01f, false);
599
}
600
}
601
602
/**
603
* Draw the the given shape filled in with a texture
604
*
605
* @param shape
606
* The shape to texture.
607
* @param image
608
* The image to tile across the shape
609
* @param scaleX
610
* The scale to apply on the x axis for texturing
611
* @param scaleY
612
* The scale to apply on the y axis for texturing
613
*/
614
public void texture(Shape shape, Image image, float scaleX, float scaleY) {
615
texture(shape, image, scaleX, scaleY, false);
616
}
617
618
/**
619
* Draw the the given shape filled in with a texture
620
*
621
* @param shape
622
* The shape to texture.
623
* @param image
624
* The image to tile across the shape
625
* @param scaleX
626
* The scale to apply on the x axis for texturing
627
* @param scaleY
628
* The scale to apply on the y axis for texturing
629
* @param fit
630
* True if we want to fit the image on to the shape
631
*/
632
public void texture(Shape shape, Image image, float scaleX, float scaleY,
633
boolean fit) {
634
predraw();
635
TextureImpl.bindNone();
636
currentColor.bind();
637
638
if (fit) {
639
ShapeRenderer.textureFit(shape, image, scaleX, scaleY);
640
} else {
641
ShapeRenderer.texture(shape, image, scaleX, scaleY);
642
}
643
644
postdraw();
645
}
646
647
/**
648
* Draw the the given shape filled in with a texture
649
*
650
* @param shape
651
* The shape to texture.
652
* @param image
653
* The image to tile across the shape
654
* @param scaleX
655
* The scale to apply on the x axis for texturing
656
* @param scaleY
657
* The scale to apply on the y axis for texturing
658
* @param fill
659
* The shape fill to apply
660
*/
661
public void texture(Shape shape, Image image, float scaleX, float scaleY,
662
ShapeFill fill) {
663
predraw();
664
TextureImpl.bindNone();
665
currentColor.bind();
666
667
ShapeRenderer.texture(shape, image, scaleX, scaleY, fill);
668
669
postdraw();
670
}
671
672
/**
673
* Draw a rectangle to the canvas in the current colour
674
*
675
* @param x1
676
* The x coordinate of the top left corner
677
* @param y1
678
* The y coordinate of the top left corner
679
* @param width
680
* The width of the rectangle to draw
681
* @param height
682
* The height of the rectangle to draw
683
*/
684
public void drawRect(float x1, float y1, float width, float height) {
685
float lineWidth = getLineWidth();
686
687
drawLine(x1,y1,x1+width,y1);
688
drawLine(x1+width,y1,x1+width,y1+height);
689
drawLine(x1+width,y1+height,x1,y1+height);
690
drawLine(x1,y1+height,x1,y1);
691
}
692
693
/**
694
* Clear the clipping being applied. This will allow graphics to be drawn
695
* anywhere on the screen
696
*/
697
public void clearClip() {
698
clip = null;
699
predraw();
700
GL.glDisable(SGL.GL_SCISSOR_TEST);
701
postdraw();
702
}
703
704
/**
705
* Set clipping that controls which areas of the world will be drawn to.
706
* Note that world clip is different from standard screen clip in that it's
707
* defined in the space of the current world coordinate - i.e. it's affected
708
* by translate, rotate, scale etc.
709
*
710
* @param x
711
* The x coordinate of the top left corner of the allowed area
712
* @param y
713
* The y coordinate of the top left corner of the allowed area
714
* @param width
715
* The width of the allowed area
716
* @param height
717
* The height of the allowed area
718
*/
719
public void setWorldClip(float x, float y, float width, float height) {
720
predraw();
721
worldClipRecord = new Rectangle(x, y, width, height);
722
723
GL.glEnable(SGL.GL_CLIP_PLANE0);
724
worldClip.put(1).put(0).put(0).put(-x).flip();
725
GL.glClipPlane(SGL.GL_CLIP_PLANE0, worldClip);
726
GL.glEnable(SGL.GL_CLIP_PLANE1);
727
worldClip.put(-1).put(0).put(0).put(x + width).flip();
728
GL.glClipPlane(SGL.GL_CLIP_PLANE1, worldClip);
729
730
GL.glEnable(SGL.GL_CLIP_PLANE2);
731
worldClip.put(0).put(1).put(0).put(-y).flip();
732
GL.glClipPlane(SGL.GL_CLIP_PLANE2, worldClip);
733
GL.glEnable(SGL.GL_CLIP_PLANE3);
734
worldClip.put(0).put(-1).put(0).put(y + height).flip();
735
GL.glClipPlane(SGL.GL_CLIP_PLANE3, worldClip);
736
postdraw();
737
}
738
739
/**
740
* Clear world clipping setup. This does not effect screen clipping
741
*/
742
public void clearWorldClip() {
743
predraw();
744
worldClipRecord = null;
745
GL.glDisable(SGL.GL_CLIP_PLANE0);
746
GL.glDisable(SGL.GL_CLIP_PLANE1);
747
GL.glDisable(SGL.GL_CLIP_PLANE2);
748
GL.glDisable(SGL.GL_CLIP_PLANE3);
749
postdraw();
750
}
751
752
/**
753
* Set the world clip to be applied
754
*
755
* @see #setWorldClip(float, float, float, float)
756
* @param clip
757
* The area still visible
758
*/
759
public void setWorldClip(Rectangle clip) {
760
if (clip == null) {
761
clearWorldClip();
762
} else {
763
setWorldClip(clip.getX(), clip.getY(), clip.getWidth(), clip
764
.getHeight());
765
}
766
}
767
768
/**
769
* Get the last set world clip or null of the world clip isn't set
770
*
771
* @return The last set world clip rectangle
772
*/
773
public Rectangle getWorldClip() {
774
return worldClipRecord;
775
}
776
777
/**
778
* Set the clipping to apply to the drawing. Note that this clipping takes
779
* no note of the transforms that have been applied to the context and is
780
* always in absolute screen space coordinates.
781
*
782
* @param x
783
* The x coordinate of the top left corner of the allowed area
784
* @param y
785
* The y coordinate of the top left corner of the allowed area
786
* @param width
787
* The width of the allowed area
788
* @param height
789
* The height of the allowed area
790
*/
791
public void setClip(int x, int y, int width, int height) {
792
predraw();
793
794
if (clip == null) {
795
GL.glEnable(SGL.GL_SCISSOR_TEST);
796
clip = new Rectangle(x, y, width, height);
797
} else {
798
clip.setBounds(x,y,width,height);
799
}
800
801
GL.glScissor(x, screenHeight - y - height, width, height);
802
postdraw();
803
}
804
805
/**
806
* Set the clipping to apply to the drawing. Note that this clipping takes
807
* no note of the transforms that have been applied to the context and is
808
* always in absolute screen space coordinates.
809
*
810
* @param rect
811
* The rectangle describing the clipped area in screen
812
* coordinates
813
*/
814
public void setClip(Rectangle rect) {
815
if (rect == null) {
816
clearClip();
817
return;
818
}
819
820
setClip((int) rect.getX(), (int) rect.getY(), (int) rect.getWidth(),
821
(int) rect.getHeight());
822
}
823
824
/**
825
* Return the currently applied clipping rectangle
826
*
827
* @return The current applied clipping rectangle or null if no clipping is
828
* applied
829
*/
830
public Rectangle getClip() {
831
return clip;
832
}
833
834
/**
835
* Tile a rectangle with a pattern specifing the offset from the top corner
836
* that one tile should match
837
*
838
* @param x
839
* The x coordinate of the rectangle
840
* @param y
841
* The y coordinate of the rectangle
842
* @param width
843
* The width of the rectangle
844
* @param height
845
* The height of the rectangle
846
* @param pattern
847
* The image to tile across the rectangle
848
* @param offX
849
* The offset on the x axis from the top left corner
850
* @param offY
851
* The offset on the y axis from the top left corner
852
*/
853
public void fillRect(float x, float y, float width, float height,
854
Image pattern, float offX, float offY) {
855
int cols = ((int) Math.ceil(width / pattern.getWidth())) + 2;
856
int rows = ((int) Math.ceil(height / pattern.getHeight())) + 2;
857
858
Rectangle preClip = getWorldClip();
859
setWorldClip(x, y, width, height);
860
861
predraw();
862
// Draw all the quads we need
863
for (int c = 0; c < cols; c++) {
864
for (int r = 0; r < rows; r++) {
865
pattern.draw(c * pattern.getWidth() + x - offX, r
866
* pattern.getHeight() + y - offY);
867
}
868
}
869
postdraw();
870
871
setWorldClip(preClip);
872
}
873
874
/**
875
* Fill a rectangle on the canvas in the current color
876
*
877
* @param x1
878
* The x coordinate of the top left corner
879
* @param y1
880
* The y coordinate of the top left corner
881
* @param width
882
* The width of the rectangle to fill
883
* @param height
884
* The height of the rectangle to fill
885
*/
886
public void fillRect(float x1, float y1, float width, float height) {
887
predraw();
888
TextureImpl.bindNone();
889
currentColor.bind();
890
891
GL.glBegin(SGL.GL_QUADS);
892
GL.glVertex2f(x1, y1);
893
GL.glVertex2f(x1 + width, y1);
894
GL.glVertex2f(x1 + width, y1 + height);
895
GL.glVertex2f(x1, y1 + height);
896
GL.glEnd();
897
postdraw();
898
}
899
900
/**
901
* Draw an oval to the canvas
902
*
903
* @param x1
904
* The x coordinate of the top left corner of a box containing
905
* the oval
906
* @param y1
907
* The y coordinate of the top left corner of a box containing
908
* the oval
909
* @param width
910
* The width of the oval
911
* @param height
912
* The height of the oval
913
*/
914
public void drawOval(float x1, float y1, float width, float height) {
915
drawOval(x1, y1, width, height, DEFAULT_SEGMENTS);
916
}
917
918
/**
919
* Draw an oval to the canvas
920
*
921
* @param x1
922
* The x coordinate of the top left corner of a box containing
923
* the oval
924
* @param y1
925
* The y coordinate of the top left corner of a box containing
926
* the oval
927
* @param width
928
* The width of the oval
929
* @param height
930
* The height of the oval
931
* @param segments
932
* The number of line segments to use when drawing the oval
933
*/
934
public void drawOval(float x1, float y1, float width, float height,
935
int segments) {
936
drawArc(x1, y1, width, height, segments, 0, 360);
937
}
938
939
/**
940
* Draw an oval to the canvas
941
*
942
* @param x1
943
* The x coordinate of the top left corner of a box containing
944
* the arc
945
* @param y1
946
* The y coordinate of the top left corner of a box containing
947
* the arc
948
* @param width
949
* The width of the arc
950
* @param height
951
* The height of the arc
952
* @param start
953
* The angle the arc starts at
954
* @param end
955
* The angle the arc ends at
956
*/
957
public void drawArc(float x1, float y1, float width, float height,
958
float start, float end) {
959
drawArc(x1, y1, width, height, DEFAULT_SEGMENTS, start, end);
960
}
961
962
/**
963
* Draw an oval to the canvas
964
*
965
* @param x1
966
* The x coordinate of the top left corner of a box containing
967
* the arc
968
* @param y1
969
* The y coordinate of the top left corner of a box containing
970
* the arc
971
* @param width
972
* The width of the arc
973
* @param height
974
* The height of the arc
975
* @param segments
976
* The number of line segments to use when drawing the arc
977
* @param start
978
* The angle the arc starts at
979
* @param end
980
* The angle the arc ends at
981
*/
982
public void drawArc(float x1, float y1, float width, float height,
983
int segments, float start, float end) {
984
predraw();
985
TextureImpl.bindNone();
986
currentColor.bind();
987
988
while (end < start) {
989
end += 360;
990
}
991
992
float cx = x1 + (width / 2.0f);
993
float cy = y1 + (height / 2.0f);
994
995
LSR.start();
996
int step = 360 / segments;
997
998
for (int a = (int) start; a < (int) (end + step); a += step) {
999
float ang = a;
1000
if (ang > end) {
1001
ang = end;
1002
}
1003
float x = (float) (cx + (FastTrig.cos(Math.toRadians(ang)) * width / 2.0f));
1004
float y = (float) (cy + (FastTrig.sin(Math.toRadians(ang)) * height / 2.0f));
1005
1006
LSR.vertex(x,y);
1007
}
1008
LSR.end();
1009
postdraw();
1010
}
1011
1012
/**
1013
* Fill an oval to the canvas
1014
*
1015
* @param x1
1016
* The x coordinate of the top left corner of a box containing
1017
* the oval
1018
* @param y1
1019
* The y coordinate of the top left corner of a box containing
1020
* the oval
1021
* @param width
1022
* The width of the oval
1023
* @param height
1024
* The height of the oval
1025
*/
1026
public void fillOval(float x1, float y1, float width, float height) {
1027
fillOval(x1, y1, width, height, DEFAULT_SEGMENTS);
1028
}
1029
1030
/**
1031
* Fill an oval to the canvas
1032
*
1033
* @param x1
1034
* The x coordinate of the top left corner of a box containing
1035
* the oval
1036
* @param y1
1037
* The y coordinate of the top left corner of a box containing
1038
* the oval
1039
* @param width
1040
* The width of the oval
1041
* @param height
1042
* The height of the oval
1043
* @param segments
1044
* The number of line segments to use when filling the oval
1045
*/
1046
public void fillOval(float x1, float y1, float width, float height,
1047
int segments) {
1048
fillArc(x1, y1, width, height, segments, 0, 360);
1049
}
1050
1051
/**
1052
* Fill an arc to the canvas (a wedge)
1053
*
1054
* @param x1
1055
* The x coordinate of the top left corner of a box containing
1056
* the arc
1057
* @param y1
1058
* The y coordinate of the top left corner of a box containing
1059
* the arc
1060
* @param width
1061
* The width of the arc
1062
* @param height
1063
* The height of the arc
1064
* @param start
1065
* The angle the arc starts at
1066
* @param end
1067
* The angle the arc ends at
1068
*/
1069
public void fillArc(float x1, float y1, float width, float height,
1070
float start, float end) {
1071
fillArc(x1, y1, width, height, DEFAULT_SEGMENTS, start, end);
1072
}
1073
1074
/**
1075
* Fill an arc to the canvas (a wedge)
1076
*
1077
* @param x1
1078
* The x coordinate of the top left corner of a box containing
1079
* the arc
1080
* @param y1
1081
* The y coordinate of the top left corner of a box containing
1082
* the arc
1083
* @param width
1084
* The width of the arc
1085
* @param height
1086
* The height of the arc
1087
* @param segments
1088
* The number of line segments to use when filling the arc
1089
* @param start
1090
* The angle the arc starts at
1091
* @param end
1092
* The angle the arc ends at
1093
*/
1094
public void fillArc(float x1, float y1, float width, float height,
1095
int segments, float start, float end) {
1096
predraw();
1097
TextureImpl.bindNone();
1098
currentColor.bind();
1099
1100
while (end < start) {
1101
end += 360;
1102
}
1103
1104
float cx = x1 + (width / 2.0f);
1105
float cy = y1 + (height / 2.0f);
1106
1107
GL.glBegin(SGL.GL_TRIANGLE_FAN);
1108
int step = 360 / segments;
1109
1110
GL.glVertex2f(cx, cy);
1111
1112
for (int a = (int) start; a < (int) (end + step); a += step) {
1113
float ang = a;
1114
if (ang > end) {
1115
ang = end;
1116
}
1117
1118
float x = (float) (cx + (FastTrig.cos(Math.toRadians(ang)) * width / 2.0f));
1119
float y = (float) (cy + (FastTrig.sin(Math.toRadians(ang)) * height / 2.0f));
1120
1121
GL.glVertex2f(x, y);
1122
}
1123
GL.glEnd();
1124
1125
if (antialias) {
1126
GL.glBegin(SGL.GL_TRIANGLE_FAN);
1127
GL.glVertex2f(cx, cy);
1128
if (end != 360) {
1129
end -= 10;
1130
}
1131
1132
for (int a = (int) start; a < (int) (end + step); a += step) {
1133
float ang = a;
1134
if (ang > end) {
1135
ang = end;
1136
}
1137
1138
float x = (float) (cx + (FastTrig.cos(Math.toRadians(ang + 10))
1139
* width / 2.0f));
1140
float y = (float) (cy + (FastTrig.sin(Math.toRadians(ang + 10))
1141
* height / 2.0f));
1142
1143
GL.glVertex2f(x, y);
1144
}
1145
GL.glEnd();
1146
}
1147
1148
postdraw();
1149
}
1150
1151
/**
1152
* Draw a rounded rectangle
1153
*
1154
* @param x
1155
* The x coordinate of the top left corner of the rectangle
1156
* @param y
1157
* The y coordinate of the top left corner of the rectangle
1158
* @param width
1159
* The width of the rectangle
1160
* @param height
1161
* The height of the rectangle
1162
* @param cornerRadius
1163
* The radius of the rounded edges on the corners
1164
*/
1165
public void drawRoundRect(float x, float y, float width, float height,
1166
int cornerRadius) {
1167
drawRoundRect(x, y, width, height, cornerRadius, DEFAULT_SEGMENTS);
1168
}
1169
1170
/**
1171
* Draw a rounded rectangle
1172
*
1173
* @param x
1174
* The x coordinate of the top left corner of the rectangle
1175
* @param y
1176
* The y coordinate of the top left corner of the rectangle
1177
* @param width
1178
* The width of the rectangle
1179
* @param height
1180
* The height of the rectangle
1181
* @param cornerRadius
1182
* The radius of the rounded edges on the corners
1183
* @param segs
1184
* The number of segments to make the corners out of
1185
*/
1186
public void drawRoundRect(float x, float y, float width, float height,
1187
int cornerRadius, int segs) {
1188
if (cornerRadius < 0)
1189
throw new IllegalArgumentException("corner radius must be > 0");
1190
if (cornerRadius == 0) {
1191
drawRect(x, y, width, height);
1192
return;
1193
}
1194
1195
int mr = (int) Math.min(width, height) / 2;
1196
// make sure that w & h are larger than 2*cornerRadius
1197
if (cornerRadius > mr) {
1198
cornerRadius = mr;
1199
}
1200
1201
drawLine(x + cornerRadius, y, x + width - cornerRadius, y);
1202
drawLine(x, y + cornerRadius, x, y + height - cornerRadius);
1203
drawLine(x + width, y + cornerRadius, x + width, y + height
1204
- cornerRadius);
1205
drawLine(x + cornerRadius, y + height, x + width - cornerRadius, y
1206
+ height);
1207
1208
float d = cornerRadius * 2;
1209
// bottom right - 0, 90
1210
drawArc(x + width - d, y + height - d, d, d, segs, 0, 90);
1211
// bottom left - 90, 180
1212
drawArc(x, y + height - d, d, d, segs, 90, 180);
1213
// top right - 270, 360
1214
drawArc(x + width - d, y, d, d, segs, 270, 360);
1215
// top left - 180, 270
1216
drawArc(x, y, d, d, segs, 180, 270);
1217
}
1218
1219
/**
1220
* Fill a rounded rectangle
1221
*
1222
* @param x
1223
* The x coordinate of the top left corner of the rectangle
1224
* @param y
1225
* The y coordinate of the top left corner of the rectangle
1226
* @param width
1227
* The width of the rectangle
1228
* @param height
1229
* The height of the rectangle
1230
* @param cornerRadius
1231
* The radius of the rounded edges on the corners
1232
*/
1233
public void fillRoundRect(float x, float y, float width, float height,
1234
int cornerRadius) {
1235
fillRoundRect(x, y, width, height, cornerRadius, DEFAULT_SEGMENTS);
1236
}
1237
1238
/**
1239
* Fill a rounded rectangle
1240
*
1241
* @param x
1242
* The x coordinate of the top left corner of the rectangle
1243
* @param y
1244
* The y coordinate of the top left corner of the rectangle
1245
* @param width
1246
* The width of the rectangle
1247
* @param height
1248
* The height of the rectangle
1249
* @param cornerRadius
1250
* The radius of the rounded edges on the corners
1251
* @param segs
1252
* The number of segments to make the corners out of
1253
*/
1254
public void fillRoundRect(float x, float y, float width, float height,
1255
int cornerRadius, int segs) {
1256
if (cornerRadius < 0)
1257
throw new IllegalArgumentException("corner radius must be > 0");
1258
if (cornerRadius == 0) {
1259
fillRect(x, y, width, height);
1260
return;
1261
}
1262
1263
int mr = (int) Math.min(width, height) / 2;
1264
// make sure that w & h are larger than 2*cornerRadius
1265
if (cornerRadius > mr) {
1266
cornerRadius = mr;
1267
}
1268
1269
float d = cornerRadius * 2;
1270
1271
fillRect(x + cornerRadius, y, width - d, cornerRadius);
1272
fillRect(x, y + cornerRadius, cornerRadius, height - d);
1273
fillRect(x + width - cornerRadius, y + cornerRadius, cornerRadius,
1274
height - d);
1275
fillRect(x + cornerRadius, y + height - cornerRadius, width - d,
1276
cornerRadius);
1277
fillRect(x + cornerRadius, y + cornerRadius, width - d, height - d);
1278
1279
// bottom right - 0, 90
1280
fillArc(x + width - d, y + height - d, d, d, segs, 0, 90);
1281
// bottom left - 90, 180
1282
fillArc(x, y + height - d, d, d, segs, 90, 180);
1283
// top right - 270, 360
1284
fillArc(x + width - d, y, d, d, segs, 270, 360);
1285
// top left - 180, 270
1286
fillArc(x, y, d, d, segs, 180, 270);
1287
}
1288
1289
/**
1290
* Set the with of the line to be used when drawing line based primitives
1291
*
1292
* @param width
1293
* The width of the line to be used when drawing line based
1294
* primitives
1295
*/
1296
public void setLineWidth(float width) {
1297
predraw();
1298
this.lineWidth = width;
1299
LSR.setWidth(width);
1300
GL.glPointSize(width);
1301
postdraw();
1302
}
1303
1304
/**
1305
* Get the width of lines being drawn in this context
1306
*
1307
* @return The width of lines being draw in this context
1308
*/
1309
public float getLineWidth() {
1310
return lineWidth;
1311
}
1312
1313
/**
1314
* Reset the line width in use to the default for this graphics context
1315
*/
1316
public void resetLineWidth() {
1317
predraw();
1318
1319
Renderer.getLineStripRenderer().setWidth(1.0f);
1320
GL.glLineWidth(1.0f);
1321
GL.glPointSize(1.0f);
1322
1323
postdraw();
1324
}
1325
1326
/**
1327
* Indicate if we should antialias as we draw primitives
1328
*
1329
* @param anti
1330
* True if we should antialias
1331
*/
1332
public void setAntiAlias(boolean anti) {
1333
predraw();
1334
antialias = anti;
1335
LSR.setAntiAlias(anti);
1336
if (anti) {
1337
GL.glEnable(SGL.GL_POLYGON_SMOOTH);
1338
} else {
1339
GL.glDisable(SGL.GL_POLYGON_SMOOTH);
1340
}
1341
postdraw();
1342
}
1343
1344
/**
1345
* True if antialiasing has been turned on for this graphics context
1346
*
1347
* @return True if antialiasing has been turned on for this graphics context
1348
*/
1349
public boolean isAntiAlias() {
1350
return antialias;
1351
}
1352
1353
/**
1354
* Draw a string to the screen using the current font
1355
*
1356
* @param str
1357
* The string to draw
1358
* @param x
1359
* The x coordinate to draw the string at
1360
* @param y
1361
* The y coordinate to draw the string at
1362
*/
1363
public void drawString(String str, float x, float y) {
1364
predraw();
1365
font.drawString(x, y, str, currentColor);
1366
postdraw();
1367
}
1368
1369
/**
1370
* Draw an image to the screen
1371
*
1372
* @param image
1373
* The image to draw to the screen
1374
* @param x
1375
* The x location at which to draw the image
1376
* @param y
1377
* The y location at which to draw the image
1378
* @param col
1379
* The color to apply to the image as a filter
1380
*/
1381
public void drawImage(Image image, float x, float y, Color col) {
1382
predraw();
1383
image.draw(x, y, col);
1384
currentColor.bind();
1385
postdraw();
1386
}
1387
1388
/**
1389
* Draw an animation to this graphics context
1390
*
1391
* @param anim
1392
* The animation to be drawn
1393
* @param x
1394
* The x position to draw the animation at
1395
* @param y
1396
* The y position to draw the animation at
1397
*/
1398
public void drawAnimation(Animation anim, float x, float y) {
1399
drawAnimation(anim, x, y, Color.white);
1400
}
1401
1402
/**
1403
* Draw an animation to this graphics context
1404
*
1405
* @param anim
1406
* The animation to be drawn
1407
* @param x
1408
* The x position to draw the animation at
1409
* @param y
1410
* The y position to draw the animation at
1411
* @param col
1412
* The color to apply to the animation as a filter
1413
*/
1414
public void drawAnimation(Animation anim, float x, float y, Color col) {
1415
predraw();
1416
anim.draw(x, y, col);
1417
currentColor.bind();
1418
postdraw();
1419
}
1420
1421
/**
1422
* Draw an image to the screen
1423
*
1424
* @param image
1425
* The image to draw to the screen
1426
* @param x
1427
* The x location at which to draw the image
1428
* @param y
1429
* The y location at which to draw the image
1430
*/
1431
public void drawImage(Image image, float x, float y) {
1432
drawImage(image, x, y, Color.white);
1433
}
1434
1435
/**
1436
* Draw a section of an image at a particular location and scale on the
1437
* screen
1438
*
1439
* @param image
1440
* The image to draw a section of
1441
* @param x
1442
* The x position to draw the image
1443
* @param y
1444
* The y position to draw the image
1445
* @param x2
1446
* The x position of the bottom right corner of the drawn image
1447
* @param y2
1448
* The y position of the bottom right corner of the drawn image
1449
* @param srcx
1450
* The x position of the rectangle to draw from this image (i.e.
1451
* relative to the image)
1452
* @param srcy
1453
* The y position of the rectangle to draw from this image (i.e.
1454
* relative to the image)
1455
* @param srcx2
1456
* The x position of the bottom right cornder of rectangle to
1457
* draw from this image (i.e. relative to the image)
1458
* @param srcy2
1459
* The t position of the bottom right cornder of rectangle to
1460
* draw from this image (i.e. relative to the image)
1461
*/
1462
public void drawImage(Image image, float x, float y, float x2, float y2,
1463
float srcx, float srcy, float srcx2, float srcy2) {
1464
predraw();
1465
image.draw(x, y, x2, y2, srcx, srcy, srcx2, srcy2);
1466
currentColor.bind();
1467
postdraw();
1468
}
1469
1470
/**
1471
* Draw a section of an image at a particular location and scale on the
1472
* screen
1473
*
1474
* @param image
1475
* The image to draw a section of
1476
* @param x
1477
* The x position to draw the image
1478
* @param y
1479
* The y position to draw the image
1480
* @param srcx
1481
* The x position of the rectangle to draw from this image (i.e.
1482
* relative to the image)
1483
* @param srcy
1484
* The y position of the rectangle to draw from this image (i.e.
1485
* relative to the image)
1486
* @param srcx2
1487
* The x position of the bottom right cornder of rectangle to
1488
* draw from this image (i.e. relative to the image)
1489
* @param srcy2
1490
* The t position of the bottom right cornder of rectangle to
1491
* draw from this image (i.e. relative to the image)
1492
*/
1493
public void drawImage(Image image, float x, float y, float srcx,
1494
float srcy, float srcx2, float srcy2) {
1495
drawImage(image, x, y, x + image.getWidth(), y + image.getHeight(),
1496
srcx, srcy, srcx2, srcy2);
1497
}
1498
1499
/**
1500
* Copy an area of the rendered screen into an image. The width and height
1501
* of the area are assumed to match that of the image
1502
*
1503
* @param target
1504
* The target image
1505
* @param x
1506
* The x position to copy from
1507
* @param y
1508
* The y position to copy from
1509
*/
1510
public void copyArea(Image target, int x, int y) {
1511
int format = target.getTexture().hasAlpha() ? SGL.GL_RGBA : SGL.GL_RGB;
1512
target.bind();
1513
GL.glCopyTexImage2D(SGL.GL_TEXTURE_2D, 0, format, x, screenHeight
1514
- (y + target.getHeight()), target.getTexture()
1515
.getTextureWidth(), target.getTexture().getTextureHeight(), 0);
1516
target.ensureInverted();
1517
}
1518
1519
/**
1520
* Translate an unsigned int into a signed integer
1521
*
1522
* @param b
1523
* The byte to convert
1524
* @return The integer value represented by the byte
1525
*/
1526
private int translate(byte b) {
1527
if (b < 0) {
1528
return 256 + b;
1529
}
1530
1531
return b;
1532
}
1533
1534
/**
1535
* Get the colour of a single pixel in this graphics context
1536
*
1537
* @param x
1538
* The x coordinate of the pixel to read
1539
* @param y
1540
* The y coordinate of the pixel to read
1541
* @return The colour of the pixel at the specified location
1542
*/
1543
public Color getPixel(int x, int y) {
1544
predraw();
1545
GL.glReadPixels(x, screenHeight - y, 1, 1, SGL.GL_RGBA,
1546
SGL.GL_UNSIGNED_BYTE, readBuffer);
1547
postdraw();
1548
1549
return new Color(translate(readBuffer.get(0)), translate(readBuffer
1550
.get(1)), translate(readBuffer.get(2)), translate(readBuffer
1551
.get(3)));
1552
}
1553
1554
/**
1555
* Get an ara of pixels as RGBA values into a buffer
1556
*
1557
* @param x The x position in the context to grab from
1558
* @param y The y position in the context to grab from
1559
* @param width The width of the area to grab from
1560
* @param height The hiehgt of the area to grab from
1561
* @param target The target buffer to grab into
1562
*/
1563
public void getArea(int x, int y, int width, int height, ByteBuffer target)
1564
{
1565
if (target.capacity() < width * height * 4)
1566
{
1567
throw new IllegalArgumentException("Byte buffer provided to get area is not big enough");
1568
}
1569
1570
predraw();
1571
GL.glReadPixels(x, screenHeight - y - height, width, height, SGL.GL_RGBA,
1572
SGL.GL_UNSIGNED_BYTE, target);
1573
postdraw();
1574
}
1575
1576
/**
1577
* Draw a section of an image at a particular location and scale on the
1578
* screen
1579
*
1580
* @param image
1581
* The image to draw a section of
1582
* @param x
1583
* The x position to draw the image
1584
* @param y
1585
* The y position to draw the image
1586
* @param x2
1587
* The x position of the bottom right corner of the drawn image
1588
* @param y2
1589
* The y position of the bottom right corner of the drawn image
1590
* @param srcx
1591
* The x position of the rectangle to draw from this image (i.e.
1592
* relative to the image)
1593
* @param srcy
1594
* The y position of the rectangle to draw from this image (i.e.
1595
* relative to the image)
1596
* @param srcx2
1597
* The x position of the bottom right cornder of rectangle to
1598
* draw from this image (i.e. relative to the image)
1599
* @param srcy2
1600
* The t position of the bottom right cornder of rectangle to
1601
* draw from this image (i.e. relative to the image)
1602
* @param col
1603
* The color to apply to the image as a filter
1604
*/
1605
public void drawImage(Image image, float x, float y, float x2, float y2,
1606
float srcx, float srcy, float srcx2, float srcy2, Color col) {
1607
predraw();
1608
image.draw(x, y, x2, y2, srcx, srcy, srcx2, srcy2, col);
1609
currentColor.bind();
1610
postdraw();
1611
}
1612
1613
/**
1614
* Draw a section of an image at a particular location and scale on the
1615
* screen
1616
*
1617
* @param image
1618
* The image to draw a section of
1619
* @param x
1620
* The x position to draw the image
1621
* @param y
1622
* The y position to draw the image
1623
* @param srcx
1624
* The x position of the rectangle to draw from this image (i.e.
1625
* relative to the image)
1626
* @param srcy
1627
* The y position of the rectangle to draw from this image (i.e.
1628
* relative to the image)
1629
* @param srcx2
1630
* The x position of the bottom right cornder of rectangle to
1631
* draw from this image (i.e. relative to the image)
1632
* @param srcy2
1633
* The t position of the bottom right cornder of rectangle to
1634
* draw from this image (i.e. relative to the image)
1635
* @param col
1636
* The color to apply to the image as a filter
1637
*/
1638
public void drawImage(Image image, float x, float y, float srcx,
1639
float srcy, float srcx2, float srcy2, Color col) {
1640
drawImage(image, x, y, x + image.getWidth(), y + image.getHeight(),
1641
srcx, srcy, srcx2, srcy2, col);
1642
}
1643
1644
/**
1645
* Draw a line with a gradient between the two points.
1646
*
1647
* @param x1
1648
* The starting x position to draw the line
1649
* @param y1
1650
* The starting y position to draw the line
1651
* @param red1
1652
* The starting position's shade of red
1653
* @param green1
1654
* The starting position's shade of green
1655
* @param blue1
1656
* The starting position's shade of blue
1657
* @param alpha1
1658
* The starting position's alpha value
1659
* @param x2
1660
* The ending x position to draw the line
1661
* @param y2
1662
* The ending y position to draw the line
1663
* @param red2
1664
* The ending position's shade of red
1665
* @param green2
1666
* The ending position's shade of green
1667
* @param blue2
1668
* The ending position's shade of blue
1669
* @param alpha2
1670
* The ending position's alpha value
1671
*/
1672
public void drawGradientLine(float x1, float y1, float red1, float green1,
1673
float blue1, float alpha1, float x2, float y2, float red2,
1674
float green2, float blue2, float alpha2) {
1675
predraw();
1676
1677
TextureImpl.bindNone();
1678
1679
GL.glBegin(SGL.GL_LINES);
1680
1681
GL.glColor4f(red1, green1, blue1, alpha1);
1682
GL.glVertex2f(x1, y1);
1683
1684
GL.glColor4f(red2, green2, blue2, alpha2);
1685
GL.glVertex2f(x2, y2);
1686
1687
GL.glEnd();
1688
1689
postdraw();
1690
}
1691
1692
/**
1693
* Draw a line with a gradient between the two points.
1694
*
1695
* @param x1
1696
* The starting x position to draw the line
1697
* @param y1
1698
* The starting y position to draw the line
1699
* @param Color1
1700
* The starting position's color
1701
* @param x2
1702
* The ending x position to draw the line
1703
* @param y2
1704
* The ending y position to draw the line
1705
* @param Color2
1706
* The ending position's color
1707
*/
1708
public void drawGradientLine(float x1, float y1, Color Color1, float x2,
1709
float y2, Color Color2) {
1710
predraw();
1711
1712
TextureImpl.bindNone();
1713
1714
GL.glBegin(SGL.GL_LINES);
1715
1716
Color1.bind();
1717
GL.glVertex2f(x1, y1);
1718
1719
Color2.bind();
1720
GL.glVertex2f(x2, y2);
1721
1722
GL.glEnd();
1723
1724
postdraw();
1725
}
1726
1727
/**
1728
* Push the current state of the transform from this graphics contexts
1729
* onto the underlying graphics stack's transform stack. An associated
1730
* popTransform() must be performed to restore the state before the end
1731
* of the rendering loop.
1732
*/
1733
public void pushTransform() {
1734
predraw();
1735
1736
FloatBuffer buffer;
1737
if (stackIndex >= stack.size()) {
1738
buffer = BufferUtils.createFloatBuffer(18);
1739
stack.add(buffer);
1740
} else {
1741
buffer = (FloatBuffer) stack.get(stackIndex);
1742
}
1743
1744
GL.glGetFloat(GL11.GL_MODELVIEW_MATRIX, buffer);
1745
buffer.put(16, sx);
1746
buffer.put(17, sy);
1747
stackIndex++;
1748
1749
postdraw();
1750
}
1751
1752
/**
1753
* Pop a previously pushed transform from the stack to the current. This should
1754
* only be called if a transform has been previously pushed.
1755
*/
1756
public void popTransform() {
1757
if (stackIndex == 0) {
1758
throw new RuntimeException("Attempt to pop a transform that hasn't be pushed");
1759
}
1760
1761
predraw();
1762
1763
stackIndex--;
1764
FloatBuffer oldBuffer = (FloatBuffer) stack.get(stackIndex);
1765
GL.glLoadMatrix(oldBuffer);
1766
sx = oldBuffer.get(16);
1767
sy = oldBuffer.get(17);
1768
1769
postdraw();
1770
}
1771
1772
/**
1773
* Dispose this graphics context, this will release any underlying resourses. However
1774
* this will also invalidate it's use
1775
*/
1776
public void destroy() {
1777
1778
}
1779
}
1780
1781