propane 3.4.0-java → 3.7.0.pre-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/extensions.xml +1 -2
  3. data/.mvn/wrapper/MavenWrapperDownloader.java +2 -2
  4. data/.mvn/wrapper/maven-wrapper.properties +2 -2
  5. data/.travis.yml +2 -2
  6. data/CHANGELOG.md +12 -0
  7. data/Gemfile +2 -0
  8. data/README.md +17 -8
  9. data/Rakefile +10 -11
  10. data/bin/propane +3 -1
  11. data/lib/propane.rb +6 -4
  12. data/lib/propane/app.rb +20 -10
  13. data/lib/propane/creators/sketch_class.rb +7 -1
  14. data/lib/propane/creators/sketch_factory.rb +4 -2
  15. data/lib/propane/creators/sketch_writer.rb +1 -0
  16. data/lib/propane/helper_methods.rb +23 -24
  17. data/lib/propane/helpers/numeric.rb +2 -0
  18. data/lib/propane/helpers/version_error.rb +1 -0
  19. data/lib/propane/library.rb +5 -1
  20. data/lib/propane/library_loader.rb +2 -0
  21. data/lib/propane/native_folder.rb +10 -9
  22. data/lib/propane/native_loader.rb +3 -0
  23. data/lib/propane/runner.rb +14 -6
  24. data/lib/propane/version.rb +2 -1
  25. data/library/boids/boids.rb +21 -11
  26. data/library/color_group/color_group.rb +28 -0
  27. data/library/control_panel/control_panel.rb +8 -5
  28. data/library/dxf/dxf.rb +6 -0
  29. data/library/file_chooser/chooser.rb +10 -9
  30. data/library/file_chooser/file_chooser.rb +10 -9
  31. data/library/library_proxy/library_proxy.rb +2 -0
  32. data/library/net/net.rb +7 -0
  33. data/library/simplex_noise/simplex_noise.rb +2 -0
  34. data/library/slider/slider.rb +23 -22
  35. data/library/vector_utils/vector_utils.rb +4 -0
  36. data/library/video_event/video_event.rb +4 -1
  37. data/pom.rb +37 -36
  38. data/pom.xml +7 -7
  39. data/propane.gemspec +16 -12
  40. data/src/main/java/monkstone/ColorUtil.java +13 -1
  41. data/src/main/java/monkstone/MathToolModule.java +253 -203
  42. data/src/main/java/monkstone/PropaneLibrary.java +2 -2
  43. data/src/main/java/monkstone/fastmath/Deglut.java +1 -1
  44. data/src/main/java/monkstone/filechooser/Chooser.java +2 -1
  45. data/src/main/java/monkstone/noise/SimplexNoise.java +2 -2
  46. data/src/main/java/monkstone/slider/CustomHorizontalSlider.java +1 -1
  47. data/src/main/java/monkstone/slider/CustomVerticalSlider.java +1 -1
  48. data/src/main/java/monkstone/slider/SimpleHorizontalSlider.java +1 -1
  49. data/src/main/java/monkstone/slider/SimpleVerticalSlider.java +1 -1
  50. data/src/main/java/monkstone/slider/SliderBar.java +1 -1
  51. data/src/main/java/monkstone/slider/SliderGroup.java +1 -1
  52. data/src/main/java/monkstone/slider/WheelHandler.java +7 -6
  53. data/src/main/java/monkstone/vecmath/package-info.java +1 -1
  54. data/src/main/java/monkstone/vecmath/vec2/Vec2.java +1 -1
  55. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +3 -3
  56. data/src/main/java/monkstone/videoevent/CaptureEvent.java +27 -0
  57. data/src/main/java/monkstone/videoevent/{VideoInterface.java → MovieEvent.java} +11 -27
  58. data/src/main/java/monkstone/videoevent/package-info.java +1 -1
  59. data/src/main/java/processing/awt/PGraphicsJava2D.java +781 -285
  60. data/src/main/java/processing/awt/PImageAWT.java +377 -0
  61. data/src/main/java/processing/awt/PShapeJava2D.java +56 -52
  62. data/src/main/java/processing/awt/PSurfaceAWT.java +309 -209
  63. data/src/main/java/processing/awt/ShimAWT.java +581 -0
  64. data/src/main/java/processing/core/PApplet.java +4510 -4503
  65. data/src/main/java/processing/core/PConstants.java +477 -447
  66. data/src/main/java/processing/core/PFont.java +914 -880
  67. data/src/main/java/processing/core/PGraphics.java +193 -177
  68. data/src/main/java/processing/core/PImage.java +611 -309
  69. data/src/main/java/processing/core/PMatrix.java +172 -159
  70. data/src/main/java/processing/core/PMatrix2D.java +478 -415
  71. data/src/main/java/processing/core/PMatrix3D.java +762 -735
  72. data/src/main/java/processing/core/PShape.java +2888 -2652
  73. data/src/main/java/processing/core/PShapeOBJ.java +97 -92
  74. data/src/main/java/processing/core/PShapeSVG.java +1705 -1490
  75. data/src/main/java/processing/core/PStyle.java +40 -37
  76. data/src/main/java/processing/core/PSurface.java +139 -97
  77. data/src/main/java/processing/core/PSurfaceNone.java +296 -218
  78. data/src/main/java/processing/core/PVector.java +997 -965
  79. data/src/main/java/processing/core/ThinkDifferent.java +15 -13
  80. data/src/main/java/processing/data/DoubleDict.java +756 -710
  81. data/src/main/java/processing/data/DoubleList.java +749 -696
  82. data/src/main/java/processing/data/FloatDict.java +748 -702
  83. data/src/main/java/processing/data/FloatList.java +751 -697
  84. data/src/main/java/processing/data/IntDict.java +720 -673
  85. data/src/main/java/processing/data/IntList.java +699 -633
  86. data/src/main/java/processing/data/JSONArray.java +931 -873
  87. data/src/main/java/processing/data/JSONObject.java +1262 -1165
  88. data/src/main/java/processing/data/JSONTokener.java +351 -341
  89. data/src/main/java/processing/data/LongDict.java +710 -663
  90. data/src/main/java/processing/data/LongList.java +701 -635
  91. data/src/main/java/processing/data/Sort.java +37 -41
  92. data/src/main/java/processing/data/StringDict.java +525 -486
  93. data/src/main/java/processing/data/StringList.java +626 -580
  94. data/src/main/java/processing/data/Table.java +3690 -3510
  95. data/src/main/java/processing/data/TableRow.java +182 -183
  96. data/src/main/java/processing/data/XML.java +957 -883
  97. data/src/main/java/processing/dxf/RawDXF.java +404 -0
  98. data/src/main/java/processing/event/Event.java +87 -67
  99. data/src/main/java/processing/event/KeyEvent.java +48 -41
  100. data/src/main/java/processing/event/MouseEvent.java +88 -113
  101. data/src/main/java/processing/event/TouchEvent.java +10 -6
  102. data/src/main/java/processing/javafx/PGraphicsFX2D.java +20 -345
  103. data/src/main/java/processing/javafx/PSurfaceFX.java +149 -121
  104. data/src/main/java/processing/net/Client.java +744 -0
  105. data/src/main/java/processing/net/Server.java +388 -0
  106. data/src/main/java/processing/opengl/FontTexture.java +289 -270
  107. data/src/main/java/processing/opengl/FrameBuffer.java +386 -364
  108. data/src/main/java/processing/opengl/LinePath.java +547 -500
  109. data/src/main/java/processing/opengl/LineStroker.java +588 -581
  110. data/src/main/java/processing/opengl/PGL.java +3047 -2914
  111. data/src/main/java/processing/opengl/PGraphics2D.java +408 -315
  112. data/src/main/java/processing/opengl/PGraphics3D.java +107 -72
  113. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +12378 -12075
  114. data/src/main/java/processing/opengl/PJOGL.java +1753 -1670
  115. data/src/main/java/processing/opengl/PShader.java +1266 -1257
  116. data/src/main/java/processing/opengl/PShapeOpenGL.java +4678 -4580
  117. data/src/main/java/processing/opengl/PSurfaceJOGL.java +1114 -1027
  118. data/src/main/java/processing/opengl/Texture.java +1492 -1401
  119. data/src/main/java/processing/opengl/VertexBuffer.java +57 -55
  120. data/test/create_test.rb +21 -20
  121. data/test/deglut_spec_test.rb +4 -2
  122. data/test/helper_methods_test.rb +49 -20
  123. data/test/math_tool_test.rb +39 -32
  124. data/test/native_folder.rb +47 -0
  125. data/test/respond_to_test.rb +3 -2
  126. data/test/sketches/key_event.rb +2 -2
  127. data/test/sketches/library/my_library/my_library.rb +3 -0
  128. data/test/test_helper.rb +2 -0
  129. data/test/vecmath_spec_test.rb +35 -22
  130. data/vendors/Rakefile +33 -62
  131. metadata +56 -48
  132. data/src/main/java/processing/core/util/image/ImageLoadFacade.java +0 -161
  133. data/src/main/java/processing/core/util/image/ImageSaveFacade.java +0 -169
  134. data/src/main/java/processing/core/util/image/constants/TifConstants.java +0 -45
  135. data/src/main/java/processing/core/util/image/load/AwtImageLoadStrategy.java +0 -80
  136. data/src/main/java/processing/core/util/image/load/Base64StringImageLoadStrategy.java +0 -73
  137. data/src/main/java/processing/core/util/image/load/FallbackImageLoadStrategy.java +0 -70
  138. data/src/main/java/processing/core/util/image/load/ImageIoImageLoadStrategy.java +0 -132
  139. data/src/main/java/processing/core/util/image/load/ImageLoadStrategy.java +0 -48
  140. data/src/main/java/processing/core/util/image/load/ImageLoadUtil.java +0 -45
  141. data/src/main/java/processing/core/util/image/load/TgaImageLoadStrategy.java +0 -255
  142. data/src/main/java/processing/core/util/image/load/TiffImageLoadStrategy.java +0 -98
  143. data/src/main/java/processing/core/util/image/save/ImageSaveStrategy.java +0 -49
  144. data/src/main/java/processing/core/util/image/save/ImageSaveUtil.java +0 -48
  145. data/src/main/java/processing/core/util/image/save/ImageWriterImageSaveStrategy.java +0 -179
  146. data/src/main/java/processing/core/util/image/save/SaveImageException.java +0 -41
  147. data/src/main/java/processing/core/util/image/save/TgaImageSaveStrategy.java +0 -198
  148. data/src/main/java/processing/core/util/image/save/TiffImageSaveStrategy.java +0 -91
  149. data/src/main/java/processing/core/util/image/save/TiffNakedFilenameImageSaveStrategy.java +0 -57
  150. data/src/main/java/processing/core/util/io/InputFactory.java +0 -285
  151. data/src/main/java/processing/core/util/io/PathUtil.java +0 -109
  152. data/src/main/java/processing/opengl/shaders/LightVert-brcm.glsl +0 -154
  153. data/src/main/java/processing/opengl/shaders/LightVert-vc4.glsl +0 -154
  154. data/src/main/java/processing/opengl/shaders/TexLightVert-brcm.glsl +0 -160
  155. data/src/main/java/processing/opengl/shaders/TexLightVert-vc4.glsl +0 -160
@@ -1,3 +1,5 @@
1
+ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
+
1
3
  /*
2
4
  Part of the Processing project - http://processing.org
3
5
 
@@ -18,9 +20,11 @@
18
20
  Public License along with this library; if not, write to the
19
21
  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20
22
  Boston, MA 02111-1307 USA
21
- */
23
+ */
24
+
22
25
  package processing.opengl;
23
26
 
27
+ import java.lang.reflect.InvocationTargetException;
24
28
  import processing.core.PApplet;
25
29
  import processing.core.PConstants;
26
30
  import processing.core.PGraphics;
@@ -34,1572 +38,1659 @@ import java.util.LinkedList;
34
38
  import java.util.NoSuchElementException;
35
39
 
36
40
  /**
37
- * This class wraps an OpenGL texture. By Andres Colubri
41
+ * This class wraps an OpenGL texture.
42
+ * By Andres Colubri
38
43
  *
39
44
  */
40
45
  public class Texture implements PConstants {
46
+ /**
47
+ * Texture with normalized UV.
48
+ */
49
+ protected static final int TEX2D = 0;
50
+ /**
51
+ * Texture with un-normalized UV.
52
+ */
53
+ protected static final int TEXRECT = 1;
54
+
55
+ /** Point sampling: both magnification and minification filtering are set
56
+ * to nearest */
57
+ protected static final int POINT = 2;
58
+ /** Linear sampling: magnification filtering is nearest, minification set
59
+ * to linear */
60
+ protected static final int LINEAR = 3;
61
+ /** Bilinear sampling: both magnification filtering is set to linear and
62
+ * minification either to linear-mipmap-nearest (linear interpolation is used
63
+ * within a mipmap, but not between different mipmaps). */
64
+ protected static final int BILINEAR = 4;
65
+ /** Trilinear sampling: magnification filtering set to linear, minification to
66
+ * linear-mipmap-linear, which offers the best mipmap quality since linear
67
+ * interpolation to compute the value in each of two maps and then
68
+ * interpolates linearly between these two values. */
69
+ protected static final int TRILINEAR = 5;
70
+
71
+
72
+ // This constant controls how many times pixelBuffer and rgbaPixels can be
73
+ // accessed before they are not released anymore. The idea is that if they
74
+ // have been used only a few times, it doesn't make sense to keep them around.
75
+ protected static final int MAX_UPDATES = 10;
76
+
77
+ // The minimum amount of free JVM's memory (in MB) before pixelBuffer and
78
+ // rgbaPixels are released every time after they are used.
79
+ protected static final int MIN_MEMORY = 5;
80
+
81
+ public int width, height;
82
+
83
+ public int glName;
84
+ public int glTarget;
85
+ public int glFormat;
86
+ public int glMinFilter;
87
+ public int glMagFilter;
88
+ public int glWrapS;
89
+ public int glWrapT;
90
+ public int glWidth;
91
+ public int glHeight;
92
+ private GLResourceTexture glres;
93
+
94
+ protected PGraphicsOpenGL pg;
95
+ protected PGL pgl; // The interface between Processing and OpenGL.
96
+ protected int context; // The context that created this texture.
97
+ protected boolean colorBuffer; // true if it is the color attachment of
98
+ // FrameBuffer object.
99
+
100
+ protected boolean usingMipmaps;
101
+ protected boolean usingRepeat;
102
+ protected float maxTexcoordU;
103
+ protected float maxTexcoordV;
104
+ protected boolean bound;
105
+
106
+ protected boolean invertedX;
107
+ protected boolean invertedY;
108
+
109
+ protected int[] rgbaPixels = null;
110
+ protected IntBuffer pixelBuffer = null;
111
+
112
+ protected int[] edgePixels = null;
113
+ protected IntBuffer edgeBuffer = null;
114
+
115
+ protected FrameBuffer tempFbo = null;
116
+ protected int pixBufUpdateCount = 0;
117
+ protected int rgbaPixUpdateCount = 0;
118
+
119
+ /** Modified portion of the texture */
120
+ protected boolean modified;
121
+ protected int mx1, my1, mx2, my2;
122
+
123
+ protected Object bufferSource;
124
+ protected LinkedList<BufferData> bufferCache = null;
125
+ protected LinkedList<BufferData> usedBuffers = null;
126
+ protected Method disposeBufferMethod;
127
+ public static final int MAX_BUFFER_CACHE_SIZE = 3;
128
+
129
+ ////////////////////////////////////////////////////////////
130
+
131
+ // Constructors.
132
+
133
+
134
+ public Texture(PGraphicsOpenGL pg) {
135
+ this.pg = pg;
136
+ pgl = pg.pgl;
137
+ context = pgl.createEmptyContext();
138
+
139
+ colorBuffer = false;
140
+
141
+ glName = 0;
142
+ }
143
+
144
+
145
+ /**
146
+ * Creates an instance of PTexture with size width x height.The texture is
147
+ initialized (empty) to that size.
148
+ * @param pg
149
+ * @param width int
150
+ * @param height int
151
+ */
152
+ public Texture(PGraphicsOpenGL pg, int width, int height) {
153
+ this(pg, width, height, new Parameters());
154
+ }
155
+
156
+
157
+ /**
158
+ * Creates an instance of PTexture with size width x height and with the
159
+ * specified parameters.The texture is initialized (empty) to that size.
160
+ * @param pg
161
+ * @param width int
162
+ * @param height int
163
+ * @param params Parameters
164
+ */
165
+ public Texture(PGraphicsOpenGL pg, int width, int height, Object params) {
166
+ this.pg = pg;
167
+ pgl = pg.pgl;
168
+ context = pgl.createEmptyContext();
169
+
170
+ colorBuffer = false;
171
+
172
+ glName = 0;
173
+
174
+ init(width, height, (Parameters)params);
175
+ }
176
+
177
+
178
+ ////////////////////////////////////////////////////////////
179
+
180
+ // Init, resize methods
181
+
182
+
183
+ /**
184
+ * Sets the size of the image and texture to width x height. If the texture is
185
+ * already initialized, it first destroys the current OpenGL texture object
186
+ * and then creates a new one with the specified size.
187
+ * @param width int
188
+ * @param height int
189
+ */
190
+ public void init(int width, int height) {
191
+ Parameters params;
192
+ if (0 < glName) {
193
+ // Re-initializing a pre-existing texture.
194
+ // We use the current parameters as default:
195
+ params = getParameters();
196
+ } else {
197
+ // Just built-in default parameters otherwise:
198
+ params = new Parameters();
199
+ }
200
+ init(width, height, params);
201
+ }
41
202
 
42
- /**
43
- * Texture with normalized UV.
44
- */
45
- protected static final int TEX2D = 0;
46
- /**
47
- * Texture with un-normalized UV.
48
- */
49
- protected static final int TEXRECT = 1;
50
203
 
51
- /**
52
- * Point sampling: both magnification and minification filtering are set to
53
- * nearest
54
- */
55
- protected static final int POINT = 2;
56
- /**
57
- * Linear sampling: magnification filtering is nearest, minification set to
58
- * linear
59
- */
60
- protected static final int LINEAR = 3;
61
- /**
62
- * Bilinear sampling: both magnification filtering is set to linear and
63
- * minification either to linear-mipmap-nearest (linear interpolation is
64
- * used within a mipmap, but not between different mipmaps).
65
- */
66
- protected static final int BILINEAR = 4;
67
- /**
68
- * Trilinear sampling: magnification filtering set to linear, minification
69
- * to linear-mipmap-linear, which offers the best mipmap quality since
70
- * linear interpolation to compute the value in each of two maps and then
71
- * interpolates linearly between these two values.
72
- */
73
- protected static final int TRILINEAR = 5;
74
-
75
- // This constant controls how many times pixelBuffer and rgbaPixels can be
76
- // accessed before they are not released anymore. The idea is that if they
77
- // have been used only a few times, it doesn't make sense to keep them around.
78
- protected static final int MAX_UPDATES = 10;
79
-
80
- // The minimum amount of free JVM's memory (in MB) before pixelBuffer and
81
- // rgbaPixels are released every time after they are used.
82
- protected static final int MIN_MEMORY = 5;
83
-
84
- public int width, height;
85
-
86
- public int glName;
87
- public int glTarget;
88
- public int glFormat;
89
- public int glMinFilter;
90
- public int glMagFilter;
91
- public int glWrapS;
92
- public int glWrapT;
93
- public int glWidth;
94
- public int glHeight;
95
- private GLResourceTexture glres;
96
-
97
- protected PGraphicsOpenGL pg;
98
- protected PGL pgl; // The interface between Processing and OpenGL.
99
- protected int context; // The context that created this texture.
100
- protected boolean colorBuffer; // true if it is the color attachment of
101
- // FrameBuffer object.
102
-
103
- protected boolean usingMipmaps;
104
- protected boolean usingRepeat;
105
- protected float maxTexcoordU;
106
- protected float maxTexcoordV;
107
- protected boolean bound;
108
-
109
- protected boolean invertedX;
110
- protected boolean invertedY;
111
-
112
- protected int[] rgbaPixels = null;
113
- protected IntBuffer pixelBuffer = null;
114
-
115
- protected int[] edgePixels = null;
116
- protected IntBuffer edgeBuffer = null;
117
-
118
- protected FrameBuffer tempFbo = null;
119
- protected int pixBufUpdateCount = 0;
120
- protected int rgbaPixUpdateCount = 0;
204
+ /**
205
+ * Sets the size of the image and texture to width x height, and the
206
+ * parameters of the texture to params. If the texture is already initialized,
207
+ * it first destroys the current OpenGL texture object and then creates a new
208
+ * one with the specified size.
209
+ * @param width int
210
+ * @param height int
211
+ * @param params GLTextureParameters
212
+ */
213
+ public void init(int width, int height, Parameters params) {
214
+ setParameters(params);
215
+ setSize(width, height);
216
+ allocate();
217
+ }
121
218
 
122
- /**
123
- * Modified portion of the texture
124
- */
125
- protected boolean modified;
126
- protected int mx1, my1, mx2, my2;
127
219
 
128
- protected Object bufferSource;
129
- protected LinkedList<BufferData> bufferCache = null;
130
- protected LinkedList<BufferData> usedBuffers = null;
131
- protected Method disposeBufferMethod;
132
- public static final int MAX_BUFFER_CACHE_SIZE = 3;
220
+ /**
221
+ * Initializes the texture using GL parameters
222
+ */
223
+ public void init(int width, int height,
224
+ int glName, int glTarget, int glFormat,
225
+ int glWidth, int glHeight,
226
+ int glMinFilter, int glMagFilter,
227
+ int glWrapS, int glWrapT) {
228
+ this.width = width;
229
+ this.height = height;
133
230
 
134
- ////////////////////////////////////////////////////////////
135
- // Constructors.
136
- public Texture(PGraphicsOpenGL pg) {
137
- this.pg = pg;
138
- pgl = pg.pgl;
139
- context = pgl.createEmptyContext();
231
+ this.glName = glName;
232
+ this.glTarget = glTarget;
233
+ this.glFormat = glFormat;
234
+ this.glWidth = glWidth;
235
+ this.glHeight = glHeight;
236
+ this.glMinFilter = glMinFilter;
237
+ this.glMagFilter = glMagFilter;
238
+ this.glWrapS = glWrapS;
239
+ this.glWrapT = glWrapT;
140
240
 
141
- colorBuffer = false;
241
+ maxTexcoordU = (float)width / glWidth;
242
+ maxTexcoordV = (float)height / glHeight;
142
243
 
143
- glName = 0;
144
- }
244
+ usingMipmaps = glMinFilter == PGL.LINEAR_MIPMAP_NEAREST ||
245
+ glMinFilter == PGL.LINEAR_MIPMAP_LINEAR;
145
246
 
146
- /**
147
- * Creates an instance of PTexture with size width x height. The texture is
148
- * initialized (empty) to that size.
149
- *
150
- * @param width int
151
- * @param height int
152
- */
153
- public Texture(PGraphicsOpenGL pg, int width, int height) {
154
- this(pg, width, height, new Parameters());
155
- }
247
+ usingRepeat = glWrapS == PGL.REPEAT || glWrapT == PGL.REPEAT;
248
+ }
156
249
 
157
- /**
158
- * Creates an instance of PTexture with size width x height and with the
159
- * specified parameters. The texture is initialized (empty) to that size.
160
- *
161
- * @param width int
162
- * @param height int
163
- * @param params Parameters
164
- */
165
- public Texture(PGraphicsOpenGL pg, int width, int height, Object params) {
166
- this.pg = pg;
167
- pgl = pg.pgl;
168
- context = pgl.createEmptyContext();
169
250
 
170
- colorBuffer = false;
251
+ public void resize(int wide, int high) {
252
+ // Disposing current resources.
253
+ dispose();
171
254
 
172
- glName = 0;
255
+ // Creating new texture with the appropriate size.
256
+ Texture tex = new Texture(pg, wide, high, getParameters());
173
257
 
174
- init(width, height, (Parameters) params);
175
- }
258
+ // Copying the contents of this texture into tex.
259
+ tex.set(this);
176
260
 
177
- ////////////////////////////////////////////////////////////
178
- // Init, resize methods
179
- /**
180
- * Sets the size of the image and texture to width x height. If the texture
181
- * is already initialized, it first destroys the current OpenGL texture
182
- * object and then creates a new one with the specified size.
183
- *
184
- * @param width int
185
- * @param height int
186
- */
187
- public void init(int width, int height) {
188
- Parameters params;
189
- if (0 < glName) {
190
- // Re-initializing a pre-existing texture.
191
- // We use the current parameters as default:
192
- params = getParameters();
193
- } else {
194
- // Just built-in default parameters otherwise:
195
- params = new Parameters();
196
- }
197
- init(width, height, params);
198
- }
261
+ // Now, overwriting "this" with tex.
262
+ copyObject(tex);
199
263
 
200
- /**
201
- * Sets the size of the image and texture to width x height, and the
202
- * parameters of the texture to params. If the texture is already
203
- * initialized, it first destroys the current OpenGL texture object and then
204
- * creates a new one with the specified size.
205
- *
206
- * @param width int
207
- * @param height int
208
- * @param params GLTextureParameters
209
- */
210
- public void init(int width, int height, Parameters params) {
211
- setParameters(params);
212
- setSize(width, height);
213
- allocate();
214
- }
264
+ // Nullifying some utility objects so they are recreated with the
265
+ // appropriate size when needed.
266
+ tempFbo = null;
267
+ }
215
268
 
216
- /**
217
- * Initializes the texture using GL parameters
218
- */
219
- public void init(int width, int height,
220
- int glName, int glTarget, int glFormat,
221
- int glWidth, int glHeight,
222
- int glMinFilter, int glMagFilter,
223
- int glWrapS, int glWrapT) {
224
- this.width = width;
225
- this.height = height;
226
269
 
227
- this.glName = glName;
228
- this.glTarget = glTarget;
229
- this.glFormat = glFormat;
230
- this.glWidth = glWidth;
231
- this.glHeight = glHeight;
232
- this.glMinFilter = glMinFilter;
233
- this.glMagFilter = glMagFilter;
234
- this.glWrapS = glWrapS;
235
- this.glWrapT = glWrapT;
270
+ /**
271
+ * Returns true if the texture has been initialized.
272
+ * @return boolean
273
+ */
274
+ public boolean available() {
275
+ return 0 < glName;
276
+ }
236
277
 
237
- maxTexcoordU = (float) width / glWidth;
238
- maxTexcoordV = (float) height / glHeight;
239
278
 
240
- usingMipmaps = glMinFilter == PGL.LINEAR_MIPMAP_NEAREST
241
- || glMinFilter == PGL.LINEAR_MIPMAP_LINEAR;
279
+ ////////////////////////////////////////////////////////////
242
280
 
243
- usingRepeat = glWrapS == PGL.REPEAT || glWrapT == PGL.REPEAT;
244
- }
281
+ // Set methods
245
282
 
246
- public void resize(int wide, int high) {
247
- // Disposing current resources.
248
- dispose();
249
283
 
250
- // Creating new texture with the appropriate size.
251
- Texture tex = new Texture(pg, wide, high, getParameters());
284
+ public void set(Texture tex) {
285
+ copyTexture(tex, 0, 0, tex.width, tex.height, true);
286
+ }
252
287
 
253
- // Copying the contents of this texture into tex.
254
- tex.set(this);
255
288
 
256
- // Now, overwriting "this" with tex.
257
- copyObject(tex);
289
+ public void set(Texture tex, int x, int y, int w, int h) {
290
+ copyTexture(tex, x, y, w, h, true);
291
+ }
258
292
 
259
- // Nullifying some utility objects so they are recreated with the
260
- // appropriate size when needed.
261
- tempFbo = null;
262
- }
263
293
 
264
- /**
265
- * Returns true if the texture has been initialized.
266
- *
267
- * @return boolean
268
- */
269
- public boolean available() {
270
- return 0 < glName;
271
- }
294
+ public void set(int texTarget, int texName, int texWidth, int texHeight,
295
+ int w, int h) {
296
+ copyTexture(texTarget, texName, texWidth, texHeight, 0, 0, w, h, true);
297
+ }
272
298
 
273
- ////////////////////////////////////////////////////////////
274
- // Set methods
275
- public void set(Texture tex) {
276
- copyTexture(tex, 0, 0, tex.width, tex.height, true);
277
- }
278
299
 
279
- public void set(Texture tex, int x, int y, int w, int h) {
280
- copyTexture(tex, x, y, w, h, true);
281
- }
300
+ public void set(int texTarget, int texName, int texWidth, int texHeight,
301
+ int target, int tex, int x, int y, int w, int h) {
302
+ copyTexture(texTarget, texName, texWidth, texHeight, x, y, w, h, true);
303
+ }
282
304
 
283
- public void set(int texTarget, int texName, int texWidth, int texHeight,
284
- int w, int h) {
285
- copyTexture(texTarget, texName, texWidth, texHeight, 0, 0, w, h, true);
286
- }
287
305
 
288
- public void set(int texTarget, int texName, int texWidth, int texHeight,
289
- int target, int tex, int x, int y, int w, int h) {
290
- copyTexture(texTarget, texName, texWidth, texHeight, x, y, w, h, true);
291
- }
306
+ public void set(int[] pixels) {
307
+ set(pixels, 0, 0, width, height, ARGB);
308
+ }
292
309
 
293
- public void set(int[] pixels) {
294
- set(pixels, 0, 0, width, height, ARGB);
295
- }
296
310
 
297
- public void set(int[] pixels, int format) {
298
- set(pixels, 0, 0, width, height, format);
299
- }
311
+ public void set(int[] pixels, int format) {
312
+ set(pixels, 0, 0, width, height, format);
313
+ }
300
314
 
301
- public void set(int[] pixels, int x, int y, int w, int h) {
302
- set(pixels, x, y, w, h, ARGB);
303
- }
304
315
 
305
- public void set(int[] pixels, int x, int y, int w, int h, int format) {
306
- if (pixels == null) {
307
- PGraphics.showWarning("The pixels array is null.");
308
- return;
309
- }
310
- if (pixels.length < w * h) {
311
- PGraphics.showWarning("The pixel array has a length of "
312
- + pixels.length + ", but it should be at least "
313
- + w * h);
314
- return;
315
- }
316
+ public void set(int[] pixels, int x, int y, int w, int h) {
317
+ set(pixels, x, y, w, h, ARGB);
318
+ }
316
319
 
317
- if (pixels.length == 0 || w == 0 || h == 0) {
318
- return;
319
- }
320
320
 
321
- boolean enabledTex = false;
322
- if (!pgl.texturingIsEnabled(glTarget)) {
323
- pgl.enableTexturing(glTarget);
324
- enabledTex = true;
325
- }
326
- pgl.bindTexture(glTarget, glName);
321
+ public void set(int[] pixels, int x, int y, int w, int h, int format) {
322
+ if (pixels == null) {
323
+ PGraphics.showWarning("The pixels array is null.");
324
+ return;
325
+ }
326
+ if (pixels.length < w * h) {
327
+ PGraphics.showWarning("The pixel array has a length of " +
328
+ pixels.length + ", but it should be at least " +
329
+ w * h);
330
+ return;
331
+ }
327
332
 
328
- loadPixels(w * h);
329
- convertToRGBA(pixels, format, w, h);
330
- if (invertedX) {
331
- flipArrayOnX(rgbaPixels, 1);
332
- }
333
- if (invertedY) {
334
- flipArrayOnY(rgbaPixels, 1);
335
- }
336
- updatePixelBuffer(rgbaPixels);
337
- pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE,
338
- pixelBuffer);
339
- fillEdges(x, y, w, h);
340
-
341
- if (usingMipmaps) {
342
- if (PGraphicsOpenGL.autoMipmapGenSupported) {
343
- pgl.generateMipmap(glTarget);
344
- } else {
345
- manualMipmap();
346
- }
347
- }
333
+ if (pixels.length == 0 || w == 0 || h == 0) {
334
+ return;
335
+ }
348
336
 
349
- pgl.bindTexture(glTarget, 0);
350
- if (enabledTex) {
351
- pgl.disableTexturing(glTarget);
352
- }
337
+ boolean enabledTex = false;
338
+ if (!pgl.texturingIsEnabled(glTarget)) {
339
+ pgl.enableTexturing(glTarget);
340
+ enabledTex = true;
341
+ }
342
+ pgl.bindTexture(glTarget, glName);
353
343
 
354
- releasePixelBuffer();
355
- releaseRGBAPixels();
344
+ loadPixels(w * h);
345
+ convertToRGBA(pixels, format, w, h);
346
+ if (invertedX) flipArrayOnX(rgbaPixels, 1);
347
+ if (invertedY) flipArrayOnY(rgbaPixels, 1);
348
+ updatePixelBuffer(rgbaPixels);
349
+ pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE,
350
+ pixelBuffer);
351
+ fillEdges(x, y, w, h);
356
352
 
357
- updateTexels(x, y, w, h);
353
+ if (usingMipmaps) {
354
+ if (PGraphicsOpenGL.autoMipmapGenSupported) {
355
+ pgl.generateMipmap(glTarget);
356
+ } else {
357
+ manualMipmap();
358
+ }
358
359
  }
359
360
 
360
- ////////////////////////////////////////////////////////////
361
- // Native set methods
362
- public void setNative(int[] pixels) {
363
- setNative(pixels, 0, 0, width, height);
361
+ pgl.bindTexture(glTarget, 0);
362
+ if (enabledTex) {
363
+ pgl.disableTexturing(glTarget);
364
364
  }
365
365
 
366
- public void setNative(int[] pixels, int x, int y, int w, int h) {
367
- updatePixelBuffer(pixels);
368
- setNative(pixelBuffer, x, y, w, h);
369
- releasePixelBuffer();
370
- }
366
+ releasePixelBuffer();
367
+ releaseRGBAPixels();
371
368
 
372
- public void setNative(IntBuffer pixBuf, int x, int y, int w, int h) {
373
- if (pixBuf == null) {
374
- pixBuf = null;
375
- PGraphics.showWarning("The pixel buffer is null.");
376
- return;
377
- }
378
- if (pixBuf.capacity() < w * h) {
379
- PGraphics.showWarning("The pixel bufer has a length of "
380
- + pixBuf.capacity() + ", but it should be at least "
381
- + w * h);
382
- return;
383
- }
369
+ updateTexels(x, y, w, h);
370
+ }
384
371
 
385
- if (pixBuf.capacity() == 0) {
386
- // Nothing to do (means that w == h == 0) but not an erroneous situation
387
- return;
388
- }
389
372
 
390
- boolean enabledTex = false;
391
- if (!pgl.texturingIsEnabled(glTarget)) {
392
- pgl.enableTexturing(glTarget);
393
- enabledTex = true;
394
- }
395
- pgl.bindTexture(glTarget, glName);
396
-
397
- pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE,
398
- pixBuf);
399
- fillEdges(x, y, w, h);
400
-
401
- if (usingMipmaps) {
402
- if (PGraphicsOpenGL.autoMipmapGenSupported) {
403
- pgl.generateMipmap(glTarget);
404
- } else {
405
- manualMipmap();
406
- }
407
- }
408
- pgl.bindTexture(glTarget, 0);
409
- if (enabledTex) {
410
- pgl.disableTexturing(glTarget);
411
- }
373
+ ////////////////////////////////////////////////////////////
412
374
 
413
- updateTexels(x, y, w, h);
414
- }
375
+ // Native set methods
415
376
 
416
- ////////////////////////////////////////////////////////////
417
- // Get methods
418
- /**
419
- * Copy texture to pixels. Involves video memory to main memory transfer
420
- * (slow).
421
- */
422
- public void get(int[] pixels) {
423
- if (pixels == null) {
424
- throw new RuntimeException("Trying to copy texture to null pixels array");
425
- }
426
- if (pixels.length != width * height) {
427
- throw new RuntimeException("Trying to copy texture to pixels array of "
428
- + "wrong size");
429
- }
430
377
 
431
- if (tempFbo == null) {
432
- tempFbo = new FrameBuffer(pg, glWidth, glHeight);
433
- }
378
+ public void setNative(int[] pixels) {
379
+ setNative(pixels, 0, 0, width, height);
380
+ }
434
381
 
435
- // Attaching the texture to the color buffer of a FBO, binding the FBO and
436
- // reading the pixels from the current draw buffer (which is the color
437
- // buffer of the FBO).
438
- tempFbo.setColorBuffer(this);
439
- pg.pushFramebuffer();
440
- pg.setFramebuffer(tempFbo);
441
- tempFbo.readPixels();
442
- pg.popFramebuffer();
443
382
 
444
- tempFbo.getPixels(pixels);
445
- convertToARGB(pixels);
383
+ public void setNative(int[] pixels, int x, int y, int w, int h) {
384
+ updatePixelBuffer(pixels);
385
+ setNative(pixelBuffer, x, y, w, h);
386
+ releasePixelBuffer();
387
+ }
446
388
 
447
- if (invertedX) {
448
- flipArrayOnX(pixels, 1);
449
- }
450
- if (invertedY) {
451
- flipArrayOnY(pixels, 1);
452
- }
453
- }
454
389
 
455
- ////////////////////////////////////////////////////////////
456
- // Put methods (the source texture is not resized to cover the entire
457
- // destination).
458
- public void put(Texture tex) {
459
- copyTexture(tex, 0, 0, tex.width, tex.height, false);
390
+ public void setNative(IntBuffer pixBuf, int x, int y, int w, int h) {
391
+ if (pixBuf == null) {
392
+ pixBuf = null;
393
+ PGraphics.showWarning("The pixel buffer is null.");
394
+ return;
460
395
  }
461
-
462
- public void put(Texture tex, int x, int y, int w, int h) {
463
- copyTexture(tex, x, y, w, h, false);
396
+ if (pixBuf.capacity() < w * h) {
397
+ PGraphics.showWarning("The pixel bufer has a length of " +
398
+ pixBuf.capacity() + ", but it should be at least " +
399
+ w * h);
400
+ return;
464
401
  }
465
402
 
466
- public void put(int texTarget, int texName, int texWidth, int texHeight,
467
- int w, int h) {
468
- copyTexture(texTarget, texName, texWidth, texHeight, 0, 0, w, h, false);
403
+ if (pixBuf.capacity() == 0) {
404
+ // Nothing to do (means that w == h == 0) but not an erroneous situation
405
+ return;
469
406
  }
470
407
 
471
- public void put(int texTarget, int texName, int texWidth, int texHeight,
472
- int target, int tex, int x, int y, int w, int h) {
473
- copyTexture(texTarget, texName, texWidth, texHeight, x, y, w, h, false);
408
+ boolean enabledTex = false;
409
+ if (!pgl.texturingIsEnabled(glTarget)) {
410
+ pgl.enableTexturing(glTarget);
411
+ enabledTex = true;
474
412
  }
413
+ pgl.bindTexture(glTarget, glName);
475
414
 
476
- ////////////////////////////////////////////////////////////
477
- // Get OpenGL parameters
478
- /**
479
- * Returns true or false whether or not the texture is using mipmaps.
480
- *
481
- * @return boolean
482
- */
483
- public boolean usingMipmaps() {
484
- return usingMipmaps;
485
- }
486
-
487
- public void usingMipmaps(boolean mipmaps, int sampling) {
488
- int glMagFilter0 = glMagFilter;
489
- int glMinFilter0 = glMinFilter;
490
- if (mipmaps) {
491
- if (sampling == POINT) {
492
- glMagFilter = PGL.NEAREST;
493
- glMinFilter = PGL.NEAREST;
494
- usingMipmaps = false;
495
- } else if (sampling == LINEAR) {
496
- glMagFilter = PGL.NEAREST;
497
- glMinFilter
498
- = PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR;
499
- usingMipmaps = true;
500
- } else if (sampling == BILINEAR) {
501
- glMagFilter = PGL.LINEAR;
502
- glMinFilter
503
- = PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR;
504
- usingMipmaps = true;
505
- } else if (sampling == TRILINEAR) {
506
- glMagFilter = PGL.LINEAR;
507
- glMinFilter
508
- = PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_LINEAR : PGL.LINEAR;
509
- usingMipmaps = true;
510
- } else {
511
- throw new RuntimeException("Unknown texture filtering mode");
512
- }
513
- } else {
514
- usingMipmaps = false;
515
- if (sampling == POINT) {
516
- glMagFilter = PGL.NEAREST;
517
- glMinFilter = PGL.NEAREST;
518
- } else if (sampling == LINEAR) {
519
- glMagFilter = PGL.NEAREST;
520
- glMinFilter = PGL.LINEAR;
521
- } else if (sampling == BILINEAR || sampling == TRILINEAR) {
522
- glMagFilter = PGL.LINEAR;
523
- glMinFilter = PGL.LINEAR;
524
- } else {
525
- throw new RuntimeException("Unknown texture filtering mode");
526
- }
527
- }
415
+ pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE,
416
+ pixBuf);
417
+ fillEdges(x, y, w, h);
528
418
 
529
- if (glMagFilter0 != glMagFilter || glMinFilter0 != glMinFilter) {
530
- bind();
531
- pgl.texParameteri(glTarget, PGL.TEXTURE_MIN_FILTER, glMinFilter);
532
- pgl.texParameteri(glTarget, PGL.TEXTURE_MAG_FILTER, glMagFilter);
533
- if (usingMipmaps) {
534
- if (PGraphicsOpenGL.autoMipmapGenSupported) {
535
- pgl.generateMipmap(glTarget);
536
- } else {
537
- manualMipmap();
538
- }
539
- }
540
- unbind();
541
- }
419
+ if (usingMipmaps) {
420
+ if (PGraphicsOpenGL.autoMipmapGenSupported) {
421
+ pgl.generateMipmap(glTarget);
422
+ } else {
423
+ manualMipmap();
424
+ }
542
425
  }
543
-
544
- /**
545
- * Returns true or false whether or not the texture is using repeat wrap
546
- * mode along either U or V directions.
547
- *
548
- * @return boolean
549
- */
550
- public boolean usingRepeat() {
551
- return usingRepeat;
426
+ pgl.bindTexture(glTarget, 0);
427
+ if (enabledTex) {
428
+ pgl.disableTexturing(glTarget);
552
429
  }
553
430
 
554
- public void usingRepeat(boolean repeat) {
555
- if (repeat) {
556
- glWrapS = PGL.REPEAT;
557
- glWrapT = PGL.REPEAT;
558
- usingRepeat = true;
559
- } else {
560
- glWrapS = PGL.CLAMP_TO_EDGE;
561
- glWrapT = PGL.CLAMP_TO_EDGE;
562
- usingRepeat = false;
563
- }
431
+ updateTexels(x, y, w, h);
432
+ }
564
433
 
565
- bind();
566
- pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_S, glWrapS);
567
- pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_T, glWrapT);
568
- unbind();
569
- }
570
434
 
571
- /**
572
- * Returns the maximum possible value for the texture coordinate U
573
- * (horizontal).
574
- *
575
- * @return float
576
- */
577
- public float maxTexcoordU() {
578
- return maxTexcoordU;
579
- }
435
+ ////////////////////////////////////////////////////////////
580
436
 
581
- /**
582
- * Returns the maximum possible value for the texture coordinate V
583
- * (vertical).
584
- *
585
- * @return float
586
- */
587
- public float maxTexcoordV() {
588
- return maxTexcoordV;
589
- }
437
+ // Get methods
590
438
 
591
- /**
592
- * Returns true if the texture is inverted along the horizontal direction.
593
- *
594
- * @return boolean;
595
- */
596
- public boolean invertedX() {
597
- return invertedX;
598
- }
599
439
 
600
- /**
601
- * Sets the texture as inverted or not along the horizontal direction.
602
- *
603
- * @param v boolean;
604
- */
605
- public void invertedX(boolean v) {
606
- invertedX = v;
440
+ /**
441
+ * Copy texture to pixels.Involves video memory to main memory transfer (slow).
442
+ * @param pixels
443
+ */
444
+ public void get(int[] pixels) {
445
+ if (pixels == null) {
446
+ throw new RuntimeException("Trying to copy texture to null pixels array");
607
447
  }
608
-
609
- /**
610
- * Returns true if the texture is inverted along the vertical direction.
611
- *
612
- * @return boolean;
613
- */
614
- public boolean invertedY() {
615
- return invertedY;
448
+ if (pixels.length != width * height) {
449
+ throw new RuntimeException("Trying to copy texture to pixels array of " +
450
+ "wrong size");
616
451
  }
617
452
 
618
- /**
619
- * Sets the texture as inverted or not along the vertical direction.
620
- *
621
- * @param v boolean;
622
- */
623
- public void invertedY(boolean v) {
624
- invertedY = v;
625
- }
626
-
627
- public int currentSampling() {
628
- if (glMagFilter == PGL.NEAREST && glMinFilter == PGL.NEAREST) {
629
- return POINT;
630
- } else if (glMagFilter == PGL.NEAREST
631
- && glMinFilter == (PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR)) {
632
- return LINEAR;
633
- } else if (glMagFilter == PGL.LINEAR
634
- && glMinFilter == (PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR)) {
635
- return BILINEAR;
636
- } else if (glMagFilter == PGL.LINEAR
637
- && glMinFilter == PGL.LINEAR_MIPMAP_LINEAR) {
638
- return TRILINEAR;
639
- } else {
640
- return -1;
641
- }
453
+ if (tempFbo == null) {
454
+ tempFbo = new FrameBuffer(pg, glWidth, glHeight);
642
455
  }
643
456
 
644
- ////////////////////////////////////////////////////////////
645
- // Bind/unbind
646
- public void bind() {
647
- // Binding a texture automatically enables texturing for the
648
- // texture target from that moment onwards. Unbinding the texture
649
- // won't disable texturing.
650
- if (!pgl.texturingIsEnabled(glTarget)) {
651
- pgl.enableTexturing(glTarget);
652
- }
653
- pgl.bindTexture(glTarget, glName);
654
- bound = true;
655
- }
656
-
657
- public void unbind() {
658
- if (pgl.textureIsBound(glTarget, glName)) {
659
- // We don't want to unbind another texture
660
- // that might be bound instead of this one.
661
- if (!pgl.texturingIsEnabled(glTarget)) {
662
- pgl.enableTexturing(glTarget);
663
- pgl.bindTexture(glTarget, 0);
664
- pgl.disableTexturing(glTarget);
665
- } else {
666
- pgl.bindTexture(glTarget, 0);
667
- }
668
- }
669
- bound = false;
670
- }
457
+ // Attaching the texture to the color buffer of a FBO, binding the FBO and
458
+ // reading the pixels from the current draw buffer (which is the color
459
+ // buffer of the FBO).
460
+ tempFbo.setColorBuffer(this);
461
+ pg.pushFramebuffer();
462
+ pg.setFramebuffer(tempFbo);
463
+ tempFbo.readPixels();
464
+ pg.popFramebuffer();
671
465
 
672
- public boolean bound() {
673
- // A true result might not necessarily mean that texturing is enabled
674
- // (a texture can be bound to the target, but texturing is disabled).
675
- return bound;
676
- }
466
+ tempFbo.getPixels(pixels);
467
+ convertToARGB(pixels);
677
468
 
678
- //////////////////////////////////////////////////////////////
679
- // Modified flag
680
- public boolean isModified() {
681
- return modified;
682
- }
469
+ if (invertedX) flipArrayOnX(pixels, 1);
470
+ if (invertedY) flipArrayOnY(pixels, 1);
471
+ }
683
472
 
684
- public void setModified() {
685
- modified = true;
686
- }
687
473
 
688
- public void setModified(boolean m) {
689
- modified = m;
474
+ ////////////////////////////////////////////////////////////
475
+
476
+ // Put methods (the source texture is not resized to cover the entire
477
+ // destination).
478
+
479
+
480
+ public void put(Texture tex) {
481
+ copyTexture(tex, 0, 0, tex.width, tex.height, false);
482
+ }
483
+
484
+
485
+ public void put(Texture tex, int x, int y, int w, int h) {
486
+ copyTexture(tex, x, y, w, h, false);
487
+ }
488
+
489
+
490
+ public void put(int texTarget, int texName, int texWidth, int texHeight,
491
+ int w, int h) {
492
+ copyTexture(texTarget, texName, texWidth, texHeight, 0, 0, w, h, false);
493
+ }
494
+
495
+
496
+ public void put(int texTarget, int texName, int texWidth, int texHeight,
497
+ int target, int tex, int x, int y, int w, int h) {
498
+ copyTexture(texTarget, texName, texWidth, texHeight, x, y, w, h, false);
499
+ }
500
+
501
+
502
+ ////////////////////////////////////////////////////////////
503
+
504
+ // Get OpenGL parameters
505
+
506
+
507
+ /**
508
+ * Returns true or false whether or not the texture is using mipmaps.
509
+ * @return boolean
510
+ */
511
+ public boolean usingMipmaps() {
512
+ return usingMipmaps;
513
+ }
514
+
515
+
516
+ public void usingMipmaps(boolean mipmaps, int sampling) {
517
+ int glMagFilter0 = glMagFilter;
518
+ int glMinFilter0 = glMinFilter;
519
+ if (mipmaps) {
520
+ switch (sampling) {
521
+ case POINT:
522
+ glMagFilter = PGL.NEAREST;
523
+ glMinFilter = PGL.NEAREST;
524
+ usingMipmaps = false;
525
+ break;
526
+ case LINEAR:
527
+ glMagFilter = PGL.NEAREST;
528
+ glMinFilter =
529
+ PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR;
530
+ usingMipmaps = true;
531
+ break;
532
+ case BILINEAR:
533
+ glMagFilter = PGL.LINEAR;
534
+ glMinFilter =
535
+ PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR;
536
+ usingMipmaps = true;
537
+ break;
538
+ case TRILINEAR:
539
+ glMagFilter = PGL.LINEAR;
540
+ glMinFilter =
541
+ PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_LINEAR : PGL.LINEAR;
542
+ usingMipmaps = true;
543
+ break;
544
+ default:
545
+ throw new RuntimeException("Unknown texture filtering mode");
546
+ }
547
+ } else {
548
+ usingMipmaps = false;
549
+ switch (sampling) {
550
+ case POINT:
551
+ glMagFilter = PGL.NEAREST;
552
+ glMinFilter = PGL.NEAREST;
553
+ break;
554
+ case LINEAR:
555
+ glMagFilter = PGL.NEAREST;
556
+ glMinFilter = PGL.LINEAR;
557
+ break;
558
+ case BILINEAR:
559
+ case TRILINEAR:
560
+ glMagFilter = PGL.LINEAR;
561
+ glMinFilter = PGL.LINEAR;
562
+ break;
563
+ default:
564
+ throw new RuntimeException("Unknown texture filtering mode");
565
+ }
566
+ }
567
+
568
+ if (glMagFilter0 != glMagFilter || glMinFilter0 != glMinFilter) {
569
+ bind();
570
+ pgl.texParameteri(glTarget, PGL.TEXTURE_MIN_FILTER, glMinFilter);
571
+ pgl.texParameteri(glTarget, PGL.TEXTURE_MAG_FILTER, glMagFilter);
572
+ if (usingMipmaps) {
573
+ if (PGraphicsOpenGL.autoMipmapGenSupported) {
574
+ pgl.generateMipmap(glTarget);
575
+ } else {
576
+ manualMipmap();
577
+ }
578
+ }
579
+ unbind();
580
+ }
581
+ }
582
+
583
+
584
+ /**
585
+ * Returns true or false whether or not the texture is using repeat wrap mode
586
+ * along either U or V directions.
587
+ * @return boolean
588
+ */
589
+ public boolean usingRepeat() {
590
+ return usingRepeat;
591
+ }
592
+
593
+
594
+ public void usingRepeat(boolean repeat) {
595
+ if (repeat) {
596
+ glWrapS = PGL.REPEAT;
597
+ glWrapT = PGL.REPEAT;
598
+ usingRepeat = true;
599
+ } else {
600
+ glWrapS = PGL.CLAMP_TO_EDGE;
601
+ glWrapT = PGL.CLAMP_TO_EDGE;
602
+ usingRepeat = false;
603
+ }
604
+
605
+ bind();
606
+ pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_S, glWrapS);
607
+ pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_T, glWrapT);
608
+ unbind();
609
+ }
610
+
611
+
612
+ /**
613
+ * Returns the maximum possible value for the texture coordinate U
614
+ * (horizontal).
615
+ * @return float
616
+ */
617
+ public float maxTexcoordU() {
618
+ return maxTexcoordU;
619
+ }
620
+
621
+
622
+ /**
623
+ * Returns the maximum possible value for the texture coordinate V (vertical).
624
+ * @return float
625
+ */
626
+ public float maxTexcoordV() {
627
+ return maxTexcoordV;
628
+ }
629
+
630
+
631
+ /**
632
+ * Returns true if the texture is inverted along the horizontal direction.
633
+ * @return boolean;
634
+ */
635
+ public boolean invertedX() {
636
+ return invertedX;
637
+ }
638
+
639
+
640
+ /**
641
+ * Sets the texture as inverted or not along the horizontal direction.
642
+ * @param v boolean;
643
+ */
644
+ public void invertedX(boolean v) {
645
+ invertedX = v;
646
+ }
647
+
648
+
649
+ /**
650
+ * Returns true if the texture is inverted along the vertical direction.
651
+ * @return boolean;
652
+ */
653
+ public boolean invertedY() {
654
+ return invertedY;
655
+ }
656
+
657
+
658
+ /**
659
+ * Sets the texture as inverted or not along the vertical direction.
660
+ * @param v boolean;
661
+ */
662
+ public void invertedY(boolean v) {
663
+ invertedY = v;
664
+ }
665
+
666
+
667
+ public int currentSampling() {
668
+ if (glMagFilter == PGL.NEAREST && glMinFilter == PGL.NEAREST) {
669
+ return POINT;
670
+ } else if (glMagFilter == PGL.NEAREST &&
671
+ glMinFilter == (PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR)) {
672
+ return LINEAR;
673
+ } else if (glMagFilter == PGL.LINEAR &&
674
+ glMinFilter == (PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR)) {
675
+ return BILINEAR;
676
+ } else if (glMagFilter == PGL.LINEAR &&
677
+ glMinFilter == PGL.LINEAR_MIPMAP_LINEAR) {
678
+ return TRILINEAR;
679
+ } else {
680
+ return -1;
681
+ }
682
+ }
683
+
684
+ ////////////////////////////////////////////////////////////
685
+
686
+ // Bind/unbind
687
+
688
+
689
+ public void bind() {
690
+ // Binding a texture automatically enables texturing for the
691
+ // texture target from that moment onwards. Unbinding the texture
692
+ // won't disable texturing.
693
+ if (!pgl.texturingIsEnabled(glTarget)) {
694
+ pgl.enableTexturing(glTarget);
695
+ }
696
+ pgl.bindTexture(glTarget, glName);
697
+ bound = true;
698
+ }
699
+
700
+
701
+ public void unbind() {
702
+ if (pgl.textureIsBound(glTarget, glName)) {
703
+ // We don't want to unbind another texture
704
+ // that might be bound instead of this one.
705
+ if (!pgl.texturingIsEnabled(glTarget)) {
706
+ pgl.enableTexturing(glTarget);
707
+ pgl.bindTexture(glTarget, 0);
708
+ pgl.disableTexturing(glTarget);
709
+ } else {
710
+ pgl.bindTexture(glTarget, 0);
711
+ }
690
712
  }
713
+ bound = false;
714
+ }
691
715
 
692
- public int getModifiedX1() {
693
- return mx1;
694
- }
695
716
 
696
- public int getModifiedX2() {
697
- return mx2;
698
- }
717
+ public boolean bound() {
718
+ // A true result might not necessarily mean that texturing is enabled
719
+ // (a texture can be bound to the target, but texturing is disabled).
720
+ return bound;
721
+ }
699
722
 
700
- public int getModifiedY1() {
701
- return my1;
702
- }
703
723
 
704
- public int getModifiedY2() {
705
- return my2;
706
- }
724
+ //////////////////////////////////////////////////////////////
707
725
 
708
- public void updateTexels() {
709
- updateTexelsImpl(0, 0, width, height);
710
- }
726
+ // Modified flag
711
727
 
712
- public void updateTexels(int x, int y, int w, int h) {
713
- updateTexelsImpl(x, y, w, h);
714
- }
715
728
 
716
- protected void updateTexelsImpl(int x, int y, int w, int h) {
717
- int x2 = x + w;
718
- int y2 = y + h;
729
+ public boolean isModified() {
730
+ return modified;
731
+ }
719
732
 
720
- if (!modified) {
721
- mx1 = PApplet.max(0, x);
722
- mx2 = PApplet.min(width - 1, x2);
723
- my1 = PApplet.max(0, y);
724
- my2 = PApplet.min(height - 1, y2);
725
- modified = true;
726
733
 
727
- } else {
728
- if (x < mx1) {
729
- mx1 = PApplet.max(0, x);
730
- }
731
- if (x > mx2) {
732
- mx2 = PApplet.min(width - 1, x);
733
- }
734
- if (y < my1) {
735
- my1 = PApplet.max(0, y);
736
- }
737
- if (y > my2) {
738
- my2 = y;
739
- }
740
-
741
- if (x2 < mx1) {
742
- mx1 = PApplet.max(0, x2);
743
- }
744
- if (x2 > mx2) {
745
- mx2 = PApplet.min(width - 1, x2);
746
- }
747
- if (y2 < my1) {
748
- my1 = PApplet.max(0, y2);
749
- }
750
- if (y2 > my2) {
751
- my2 = PApplet.min(height - 1, y2);
752
- }
753
- }
754
- }
734
+ public void setModified() {
735
+ modified = true;
736
+ }
755
737
 
756
- protected void loadPixels(int len) {
757
- if (rgbaPixels == null || rgbaPixels.length < len) {
758
- rgbaPixels = new int[len];
759
- }
760
- }
761
738
 
762
- protected void updatePixelBuffer(int[] pixels) {
763
- pixelBuffer = PGL.updateIntBuffer(pixelBuffer, pixels, true);
764
- pixBufUpdateCount++;
765
- }
739
+ public void setModified(boolean m) {
740
+ modified = m;
741
+ }
766
742
 
767
- protected void manualMipmap() {
768
- // TODO: finish manual mipmap generation,
769
- // https://github.com/processing/processing/issues/3335
770
- }
771
743
 
772
- ////////////////////////////////////////////////////////////
773
- // Buffer sink interface.
774
- public void setBufferSource(Object source) {
775
- bufferSource = source;
776
- getSourceMethods();
777
- }
744
+ public int getModifiedX1() {
745
+ return mx1;
746
+ }
778
747
 
779
- public void copyBufferFromSource(Object natRef, ByteBuffer byteBuf,
780
- int w, int h) {
781
- if (bufferCache == null) {
782
- bufferCache = new LinkedList<BufferData>();
783
- }
784
748
 
785
- if (bufferCache.size() + 1 <= MAX_BUFFER_CACHE_SIZE) {
786
- bufferCache.add(new BufferData(natRef, byteBuf.asIntBuffer(), w, h));
787
- } else {
788
- // The buffer cache reached the maximum size, so we just dispose
789
- // the new buffer by adding it to the list of used buffers.
790
- try {
791
- usedBuffers.add(new BufferData(natRef, byteBuf.asIntBuffer(), w, h));
792
- } catch (Exception e) {
793
- e.printStackTrace();
794
- }
795
- }
796
- }
749
+ public int getModifiedX2() {
750
+ return mx2;
751
+ }
797
752
 
798
- public void disposeSourceBuffer() {
799
- if (usedBuffers == null) {
800
- return;
801
- }
802
753
 
803
- while (0 < usedBuffers.size()) {
804
- BufferData data = null;
805
- try {
806
- data = usedBuffers.remove(0);
807
- } catch (NoSuchElementException ex) {
808
- PGraphics.showWarning("Cannot remove used buffer");
809
- }
810
- if (data != null) {
811
- data.dispose();
812
- }
813
- }
814
- }
754
+ public int getModifiedY1() {
755
+ return my1;
756
+ }
815
757
 
816
- public void getBufferPixels(int[] pixels) {
817
- // We get the buffer either from the used buffers or the cache, giving
818
- // priority to the used buffers. Why? Because the used buffer was already
819
- // transferred to the texture, so the pixels should be in sync with the
820
- // texture.
821
- BufferData data = null;
822
- if (usedBuffers != null && 0 < usedBuffers.size()) {
823
- data = usedBuffers.getLast();
824
- } else if (bufferCache != null && 0 < bufferCache.size()) {
825
- data = bufferCache.getLast();
826
- }
827
- if (data != null) {
828
- if ((data.w != width) || (data.h != height)) {
829
- init(data.w, data.h);
830
- }
831
-
832
- data.rgbBuf.rewind();
833
- data.rgbBuf.get(pixels);
834
- convertToARGB(pixels);
835
-
836
- // In order to avoid a cached buffer to overwrite the texture when the
837
- // renderer draws the texture, and hence put the pixels put of sync, we
838
- // simply empty the cache.
839
- if (usedBuffers == null) {
840
- usedBuffers = new LinkedList<BufferData>();
841
- }
842
- while (0 < bufferCache.size()) {
843
- data = bufferCache.remove(0);
844
- usedBuffers.add(data);
845
- }
846
- }
847
- }
848
758
 
849
- public boolean hasBufferSource() {
850
- return bufferSource != null;
851
- }
759
+ public int getModifiedY2() {
760
+ return my2;
761
+ }
852
762
 
853
- public boolean hasBuffers() {
854
- return bufferSource != null && bufferCache != null
855
- && 0 < bufferCache.size();
856
- }
857
763
 
858
- protected boolean bufferUpdate() {
859
- BufferData data = null;
860
- try {
861
- data = bufferCache.remove(0);
862
- } catch (NoSuchElementException ex) {
863
- PGraphics.showWarning("Don't have pixel data to copy to texture");
864
- }
764
+ public void updateTexels() {
765
+ updateTexelsImpl(0, 0, width, height);
766
+ }
865
767
 
866
- if (data != null) {
867
- if ((data.w != width) || (data.h != height)) {
868
- init(data.w, data.h);
869
- }
870
- data.rgbBuf.rewind();
871
- setNative(data.rgbBuf, 0, 0, width, height);
872
-
873
- // Putting the buffer in the used buffers list to dispose at the end of
874
- // draw.
875
- if (usedBuffers == null) {
876
- usedBuffers = new LinkedList<BufferData>();
877
- }
878
- usedBuffers.add(data);
879
-
880
- return true;
881
- } else {
882
- return false;
883
- }
884
- }
885
768
 
886
- protected void getSourceMethods() {
887
- try {
888
- disposeBufferMethod = bufferSource.getClass().
889
- getMethod("disposeBuffer", new Class[]{Object.class});
890
- } catch (Exception e) {
891
- throw new RuntimeException("Provided source object doesn't have a "
892
- + "disposeBuffer method.");
893
- }
894
- }
769
+ public void updateTexels(int x, int y, int w, int h) {
770
+ updateTexelsImpl(x, y, w, h);
771
+ }
895
772
 
896
- ////////////////////////////////////////////////////////////
897
- // Utilities
898
- /**
899
- * Flips intArray along the X axis.
900
- *
901
- * @param intArray int[]
902
- * @param mult int
903
- */
904
- protected void flipArrayOnX(int[] intArray, int mult) {
905
- int index = 0;
906
- int xindex = mult * (width - 1);
907
- for (int x = 0; x < width / 2; x++) {
908
- for (int y = 0; y < height; y++) {
909
- int i = index + mult * y * width;
910
- int j = xindex + mult * y * width;
911
-
912
- for (int c = 0; c < mult; c++) {
913
- int temp = intArray[i];
914
- intArray[i] = intArray[j];
915
- intArray[j] = temp;
916
-
917
- i++;
918
- j++;
919
- }
920
-
921
- }
922
- index += mult;
923
- xindex -= mult;
924
- }
925
- }
926
773
 
927
- /**
928
- * Flips intArray along the Y axis.
929
- *
930
- * @param intArray int[]
931
- * @param mult int
932
- */
933
- protected void flipArrayOnY(int[] intArray, int mult) {
934
- int index = 0;
935
- int yindex = mult * (height - 1) * width;
936
- for (int y = 0; y < height / 2; y++) {
937
- for (int x = 0; x < mult * width; x++) {
938
- int temp = intArray[index];
939
- intArray[index] = intArray[yindex];
940
- intArray[yindex] = temp;
941
-
942
- index++;
943
- yindex++;
944
- }
945
- yindex -= mult * width * 2;
946
- }
947
- }
774
+ protected void updateTexelsImpl(int x, int y, int w, int h) {
775
+ int x2 = x + w;
776
+ int y2 = y + h;
948
777
 
949
- /**
950
- * Reorders a pixel array in the given format into the order required by
951
- * OpenGL (RGBA) and stores it into rgbaPixels. The width and height
952
- * parameters are used in the YUV420 to RBGBA conversion.
953
- *
954
- * @param pixels int[]
955
- * @param format int
956
- * @param w int
957
- * @param h int
958
- */
959
- protected void convertToRGBA(int[] pixels, int format, int w, int h) {
960
- if (PGL.BIG_ENDIAN) {
961
- switch (format) {
962
- case ALPHA:
963
- // Converting from xxxA into RGBA. RGB is set to white
964
- // (0xFFFFFF, i.e.: (255, 255, 255))
965
- for (int i = 0; i < pixels.length; i++) {
966
- rgbaPixels[i] = 0xFFFFFF00 | pixels[i];
967
- }
968
- break;
969
- case RGB:
970
- // Converting xRGB into RGBA. A is set to 0xFF (255, full opacity).
971
- for (int i = 0; i < pixels.length; i++) {
972
- int pixel = pixels[i];
973
- rgbaPixels[i] = (pixel << 8) | 0xFF;
974
- }
975
- break;
976
- case ARGB:
977
- // Converting ARGB into RGBA. Shifting RGB to 8 bits to the left,
978
- // and bringing A to the first byte.
979
- for (int i = 0; i < pixels.length; i++) {
980
- int pixel = pixels[i];
981
- rgbaPixels[i] = (pixel << 8) | ((pixel >> 24) & 0xFF);
982
- }
983
- break;
984
- }
985
- } else {
986
- // LITTLE_ENDIAN
987
- // ARGB native, and RGBA opengl means ABGR on windows
988
- // for the most part just need to swap two components here
989
- // the sun.cpu.endian here might be "false", oddly enough..
990
- // (that's why just using an "else", rather than check for "little")
991
- switch (format) {
992
- case ALPHA:
993
- // Converting xxxA into ARGB, with RGB set to white.
994
- for (int i = 0; i < pixels.length; i++) {
995
- rgbaPixels[i] = (pixels[i] << 24) | 0x00FFFFFF;
996
- }
997
- break;
998
- case RGB:
999
- // We need to convert xRGB into ABGR,
1000
- // so R and B must be swapped, and the x just made 0xFF.
1001
- for (int i = 0; i < pixels.length; i++) {
1002
- int pixel = pixels[i];
1003
- rgbaPixels[i] = 0xFF000000
1004
- | ((pixel & 0xFF) << 16) | ((pixel & 0xFF0000) >> 16)
1005
- | (pixel & 0x0000FF00);
1006
- }
1007
- break;
1008
- case ARGB:
1009
- // We need to convert ARGB into ABGR,
1010
- // so R and B must be swapped, A and G just brought back in.
1011
- for (int i = 0; i < pixels.length; i++) {
1012
- int pixel = pixels[i];
1013
- rgbaPixels[i] = ((pixel & 0xFF) << 16) | ((pixel & 0xFF0000) >> 16)
1014
- | (pixel & 0xFF00FF00);
1015
- }
1016
- break;
1017
- }
1018
- }
1019
- rgbaPixUpdateCount++;
778
+ if (!modified) {
779
+ mx1 = PApplet.max(0, x);
780
+ mx2 = PApplet.min(width - 1, x2);
781
+ my1 = PApplet.max(0, y);
782
+ my2 = PApplet.min(height - 1, y2);
783
+ modified = true;
784
+
785
+ } else {
786
+ if (x < mx1) mx1 = PApplet.max(0, x);
787
+ if (x > mx2) mx2 = PApplet.min(width - 1, x);
788
+ if (y < my1) my1 = PApplet.max(0, y);
789
+ if (y > my2) my2 = y;
790
+
791
+ if (x2 < mx1) mx1 = PApplet.max(0, x2);
792
+ if (x2 > mx2) mx2 = PApplet.min(width - 1, x2);
793
+ if (y2 < my1) my1 = PApplet.max(0, y2);
794
+ if (y2 > my2) my2 = PApplet.min(height - 1, y2);
1020
795
  }
796
+ }
1021
797
 
1022
- /**
1023
- * Reorders an OpenGL pixel array (RGBA) into ARGB. The array must be of
1024
- * size width * height.
1025
- *
1026
- * @param pixels int[]
1027
- */
1028
- protected void convertToARGB(int[] pixels) {
1029
- int t = 0;
1030
- int p = 0;
1031
- if (PGL.BIG_ENDIAN) {
1032
- // RGBA to ARGB conversion: shifting RGB 8 bits to the right,
1033
- // and placing A 24 bits to the left.
1034
- for (int y = 0; y < height; y++) {
1035
- for (int x = 0; x < width; x++) {
1036
- int pixel = pixels[p++];
1037
- pixels[t++] = (pixel >>> 8) | ((pixel << 24) & 0xFF000000);
1038
- }
1039
- }
1040
- } else {
1041
- // We have to convert ABGR into ARGB, so R and B must be swapped,
1042
- // A and G just brought back in.
1043
- for (int y = 0; y < height; y++) {
1044
- for (int x = 0; x < width; x++) {
1045
- int pixel = pixels[p++];
1046
- pixels[t++] = ((pixel & 0xFF) << 16) | ((pixel & 0xFF0000) >> 16)
1047
- | (pixel & 0xFF00FF00);
1048
- }
1049
- }
1050
- }
798
+
799
+ protected void loadPixels(int len) {
800
+ if (rgbaPixels == null || rgbaPixels.length < len) {
801
+ rgbaPixels = new int[len];
1051
802
  }
803
+ }
1052
804
 
1053
- ///////////////////////////////////////////////////////////
1054
- // Allocate/release texture.
1055
- protected void setSize(int w, int h) {
1056
- width = w;
1057
- height = h;
1058
805
 
1059
- if (PGraphicsOpenGL.npotTexSupported) {
1060
- glWidth = w;
1061
- glHeight = h;
1062
- } else {
1063
- glWidth = PGL.nextPowerOfTwo(w);
1064
- glHeight = PGL.nextPowerOfTwo(h);
1065
- }
806
+ protected void updatePixelBuffer(int[] pixels) {
807
+ pixelBuffer = PGL.updateIntBuffer(pixelBuffer, pixels, true);
808
+ pixBufUpdateCount++;
809
+ }
1066
810
 
1067
- if (glWidth > PGraphicsOpenGL.maxTextureSize
1068
- || glHeight > PGraphicsOpenGL.maxTextureSize) {
1069
- glWidth = glHeight = 0;
1070
- throw new RuntimeException("Image width and height cannot be"
1071
- + " larger than "
1072
- + PGraphicsOpenGL.maxTextureSize
1073
- + " with this graphics card.");
1074
- }
1075
811
 
1076
- // If non-power-of-two textures are not supported, and the specified width
1077
- // or height is non-power-of-two, then glWidth (glHeight) will be greater
1078
- // than w (h) because it is chosen to be the next power of two, and this
1079
- // quotient will give the appropriate maximum texture coordinate value given
1080
- // this situation.
1081
- maxTexcoordU = (float) width / glWidth;
1082
- maxTexcoordV = (float) height / glHeight;
1083
- }
812
+ protected void manualMipmap() {
813
+ // TODO: finish manual mipmap generation,
814
+ // https://github.com/processing/processing/issues/3335
815
+ }
1084
816
 
1085
- /**
1086
- * Allocates the opengl texture object.
1087
- */
1088
- protected void allocate() {
1089
- dispose(); // Just in the case this object is being re-allocated.
1090
817
 
1091
- boolean enabledTex = false;
1092
- if (!pgl.texturingIsEnabled(glTarget)) {
1093
- pgl.enableTexturing(glTarget);
1094
- enabledTex = true;
1095
- }
818
+ ////////////////////////////////////////////////////////////
1096
819
 
1097
- context = pgl.getCurrentContext();
1098
- glres = new GLResourceTexture(this);
1099
-
1100
- pgl.bindTexture(glTarget, glName);
1101
- pgl.texParameteri(glTarget, PGL.TEXTURE_MIN_FILTER, glMinFilter);
1102
- pgl.texParameteri(glTarget, PGL.TEXTURE_MAG_FILTER, glMagFilter);
1103
- pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_S, glWrapS);
1104
- pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_T, glWrapT);
1105
- if (PGraphicsOpenGL.anisoSamplingSupported) {
1106
- pgl.texParameterf(glTarget, PGL.TEXTURE_MAX_ANISOTROPY,
1107
- PGraphicsOpenGL.maxAnisoAmount);
1108
- }
820
+ // Buffer sink interface.
1109
821
 
1110
- // First, we use glTexImage2D to set the full size of the texture (glW/glH
1111
- // might be diff from w/h in the case that the GPU doesn't support NPOT
1112
- // textures)
1113
- pgl.texImage2D(glTarget, 0, glFormat, glWidth, glHeight, 0,
1114
- PGL.RGBA, PGL.UNSIGNED_BYTE, null);
1115
822
 
1116
- // Makes sure that the texture buffer in video memory doesn't contain
1117
- // any garbage.
1118
- pgl.initTexture(glTarget, PGL.RGBA, width, height);
823
+ public void setBufferSource(Object source) {
824
+ bufferSource = source;
825
+ getSourceMethods();
826
+ }
1119
827
 
1120
- pgl.bindTexture(glTarget, 0);
1121
- if (enabledTex) {
1122
- pgl.disableTexturing(glTarget);
1123
- }
1124
- bound = false;
1125
- }
1126
828
 
1127
- /**
1128
- * Marks the texture object for deletion.
1129
- */
1130
- protected void dispose() {
1131
- if (glres != null) {
1132
- glres.dispose();
1133
- glres = null;
1134
- glName = 0;
1135
- }
829
+ public void copyBufferFromSource(Object natRef, ByteBuffer byteBuf,
830
+ int w, int h) {
831
+ if (bufferCache == null) {
832
+ bufferCache = new LinkedList<>();
1136
833
  }
1137
834
 
1138
- protected boolean contextIsOutdated() {
1139
- boolean outdated = !pgl.contextIsCurrent(context);
1140
- if (outdated) {
1141
- dispose();
1142
- }
1143
- return outdated;
835
+ if (bufferCache.size() + 1 <= MAX_BUFFER_CACHE_SIZE) {
836
+ bufferCache.add(new BufferData(natRef, byteBuf.asIntBuffer(), w, h));
837
+ } else {
838
+ // The buffer cache reached the maximum size, so we just dispose
839
+ // the new buffer by adding it to the list of used buffers.
840
+ try {
841
+ usedBuffers.add(new BufferData(natRef, byteBuf.asIntBuffer(), w, h));
842
+ } catch (Exception e) {
843
+ }
1144
844
  }
845
+ }
1145
846
 
1146
- public void colorBuffer(boolean value) {
1147
- colorBuffer = value;
847
+
848
+ public void disposeSourceBuffer() {
849
+ if (usedBuffers == null) return;
850
+
851
+ while (0 < usedBuffers.size()) {
852
+ BufferData data = null;
853
+ try {
854
+ data = usedBuffers.remove(0);
855
+ } catch (NoSuchElementException ex) {
856
+ PGraphics.showWarning("Cannot remove used buffer");
857
+ }
858
+ if (data != null) {
859
+ data.dispose();
860
+ }
1148
861
  }
862
+ }
1149
863
 
1150
- public boolean colorBuffer() {
1151
- return colorBuffer;
864
+ public void getBufferPixels(int[] pixels) {
865
+ // We get the buffer either from the used buffers or the cache, giving
866
+ // priority to the used buffers. Why? Because the used buffer was already
867
+ // transferred to the texture, so the pixels should be in sync with the
868
+ // texture.
869
+ BufferData data = null;
870
+ if (usedBuffers != null && 0 < usedBuffers.size()) {
871
+ data = usedBuffers.getLast();
872
+ } else if (bufferCache != null && 0 < bufferCache.size()) {
873
+ data = bufferCache.getLast();
1152
874
  }
875
+ if (data != null) {
876
+ if ((data.w != width) || (data.h != height)) {
877
+ init(data.w, data.h);
878
+ }
1153
879
 
1154
- ///////////////////////////////////////////////////////////
1155
- // Utilities.
1156
- // Copies source texture tex into this.
1157
- protected void copyTexture(Texture tex, int x, int y, int w, int h,
1158
- boolean scale) {
1159
- if (tex == null) {
1160
- throw new RuntimeException("Source texture is null");
1161
- }
880
+ data.rgbBuf.rewind();
881
+ data.rgbBuf.get(pixels);
882
+ convertToARGB(pixels);
1162
883
 
1163
- if (tempFbo == null) {
1164
- tempFbo = new FrameBuffer(pg, glWidth, glHeight);
1165
- }
884
+ // In order to avoid a cached buffer to overwrite the texture when the
885
+ // renderer draws the texture, and hence put the pixels put of sync, we
886
+ // simply empty the cache.
887
+ if (usedBuffers == null) {
888
+ usedBuffers = new LinkedList<>();
889
+ }
890
+ while (0 < bufferCache.size()) {
891
+ data = bufferCache.remove(0);
892
+ usedBuffers.add(data);
893
+ }
894
+ }
895
+ }
1166
896
 
1167
- // This texture is the color (destination) buffer of the FBO.
1168
- tempFbo.setColorBuffer(this);
1169
- tempFbo.disableDepthTest();
1170
-
1171
- // FBO copy:
1172
- pg.pushFramebuffer();
1173
- pg.setFramebuffer(tempFbo);
1174
- // Replaces anything that this texture might contain in the area being
1175
- // replaced by the new one.
1176
- pg.pushStyle();
1177
- pg.blendMode(REPLACE);
1178
- if (scale) {
1179
- // Rendering tex into "this", and scaling the source rectangle
1180
- // to cover the entire destination region.
1181
- pgl.drawTexture(tex.glTarget, tex.glName, tex.glWidth, tex.glHeight,
1182
- 0, 0, tempFbo.width, tempFbo.height, 1,
1183
- x, y, x + w, y + h, 0, 0, width, height);
1184
897
 
1185
- } else {
1186
- // Rendering tex into "this" but without scaling so the contents
1187
- // of the source texture fall in the corresponding texels of the
1188
- // destination.
1189
- pgl.drawTexture(tex.glTarget, tex.glName, tex.glWidth, tex.glHeight,
1190
- 0, 0, tempFbo.width, tempFbo.height, 1,
1191
- x, y, x + w, y + h, x, y, x + w, y + h);
1192
- }
1193
- pgl.flush(); // Needed to make sure that the change in this texture is
1194
- // available immediately.
1195
- pg.popStyle();
1196
- pg.popFramebuffer();
1197
- updateTexels(x, y, w, h);
1198
- }
1199
-
1200
- // Copies source texture tex into this.
1201
- protected void copyTexture(int texTarget, int texName,
1202
- int texWidth, int texHeight,
1203
- int x, int y, int w, int h, boolean scale) {
1204
- if (tempFbo == null) {
1205
- tempFbo = new FrameBuffer(pg, glWidth, glHeight);
1206
- }
898
+ public boolean hasBufferSource() {
899
+ return bufferSource != null;
900
+ }
1207
901
 
1208
- // This texture is the color (destination) buffer of the FBO.
1209
- tempFbo.setColorBuffer(this);
1210
- tempFbo.disableDepthTest();
1211
-
1212
- // FBO copy:
1213
- pg.pushFramebuffer();
1214
- pg.setFramebuffer(tempFbo);
1215
- // Replaces anything that this texture might contain in the area being
1216
- // replaced by the new one.
1217
- pg.pushStyle();
1218
- pg.blendMode(REPLACE);
1219
- if (scale) {
1220
- // Rendering tex into "this", and scaling the source rectangle
1221
- // to cover the entire destination region.
1222
- pgl.drawTexture(texTarget, texName, texWidth, texHeight,
1223
- 0, 0, tempFbo.width, tempFbo.height,
1224
- x, y, w, h, 0, 0, width, height);
1225
902
 
1226
- } else {
1227
- // Rendering tex into "this" but without scaling so the contents
1228
- // of the source texture fall in the corresponding texels of the
1229
- // destination.
1230
- pgl.drawTexture(texTarget, texName, texWidth, texHeight,
1231
- 0, 0, tempFbo.width, tempFbo.height,
1232
- x, y, w, h, x, y, w, h);
1233
- }
1234
- pgl.flush(); // Needed to make sure that the change in this texture is
1235
- // available immediately.
1236
- pg.popStyle();
1237
- pg.popFramebuffer();
1238
- updateTexels(x, y, w, h);
1239
- }
903
+ public boolean hasBuffers() {
904
+ return bufferSource != null && bufferCache != null &&
905
+ 0 < bufferCache.size();
906
+ }
1240
907
 
1241
- protected void copyObject(Texture src) {
1242
- // The OpenGL texture of this object is replaced with the one from the
1243
- // source object, so we delete the former to avoid resource wasting.
1244
- dispose();
1245
908
 
1246
- width = src.width;
1247
- height = src.height;
909
+ protected boolean bufferUpdate() {
910
+ BufferData data = null;
911
+ try {
912
+ data = bufferCache.remove(0);
913
+ } catch (NoSuchElementException ex) {
914
+ PGraphics.showWarning("Don't have pixel data to copy to texture");
915
+ }
916
+
917
+ if (data != null) {
918
+ if ((data.w != width) || (data.h != height)) {
919
+ init(data.w, data.h);
920
+ }
921
+ data.rgbBuf.rewind();
922
+ setNative(data.rgbBuf, 0, 0, width, height);
923
+
924
+ // Putting the buffer in the used buffers list to dispose at the end of
925
+ // draw.
926
+ if (usedBuffers == null) {
927
+ usedBuffers = new LinkedList<>();
928
+ }
929
+ usedBuffers.add(data);
930
+
931
+ return true;
932
+ } else {
933
+ return false;
934
+ }
935
+ }
936
+
937
+
938
+ protected void getSourceMethods() {
939
+ try {
940
+ disposeBufferMethod = bufferSource.getClass().
941
+ getMethod("disposeBuffer", Object.class);
942
+ } catch (NoSuchMethodException | SecurityException e) {
943
+ throw new RuntimeException("Provided source object doesn't have a " +
944
+ "disposeBuffer method.");
945
+ }
946
+ }
947
+
948
+
949
+ ////////////////////////////////////////////////////////////
950
+
951
+ // Utilities
952
+
953
+
954
+ /**
955
+ * Flips intArray along the X axis.
956
+ * @param intArray int[]
957
+ * @param mult int
958
+ */
959
+ protected void flipArrayOnX(int[] intArray, int mult) {
960
+ int index = 0;
961
+ int xindex = mult * (width - 1);
962
+ for (int x = 0; x < width / 2; x++) {
963
+ for (int y = 0; y < height; y++) {
964
+ int i = index + mult * y * width;
965
+ int j = xindex + mult * y * width;
966
+
967
+ for (int c = 0; c < mult; c++) {
968
+ int temp = intArray[i];
969
+ intArray[i] = intArray[j];
970
+ intArray[j] = temp;
971
+
972
+ i++;
973
+ j++;
974
+ }
975
+
976
+ }
977
+ index += mult;
978
+ xindex -= mult;
979
+ }
980
+ }
981
+
982
+
983
+ /**
984
+ * Flips intArray along the Y axis.
985
+ * @param intArray int[]
986
+ * @param mult int
987
+ */
988
+ protected void flipArrayOnY(int[] intArray, int mult) {
989
+ int index = 0;
990
+ int yindex = mult * (height - 1) * width;
991
+ for (int y = 0; y < height / 2; y++) {
992
+ for (int x = 0; x < mult * width; x++) {
993
+ int temp = intArray[index];
994
+ intArray[index] = intArray[yindex];
995
+ intArray[yindex] = temp;
996
+
997
+ index++;
998
+ yindex++;
999
+ }
1000
+ yindex -= mult * width * 2;
1001
+ }
1002
+ }
1003
+
1004
+
1005
+ /**
1006
+ * Reorders a pixel array in the given format into the order required by
1007
+ * OpenGL (RGBA) and stores it into rgbaPixels. The width and height
1008
+ * parameters are used in the YUV420 to RBGBA conversion.
1009
+ * @param pixels int[]
1010
+ * @param format int
1011
+ * @param w int
1012
+ * @param h int
1013
+ */
1014
+ protected void convertToRGBA(int[] pixels, int format, int w, int h) {
1015
+ if (PGL.BIG_ENDIAN) {
1016
+ switch (format) {
1017
+ case ALPHA:
1018
+ // Converting from xxxA into RGBA. RGB is set to white
1019
+ // (0xFFFFFF, i.e.: (255, 255, 255))
1020
+ for (int i = 0; i< pixels.length; i++) {
1021
+ rgbaPixels[i] = 0xFFFFFF00 | pixels[i];
1022
+ }
1023
+ break;
1024
+ case RGB:
1025
+ // Converting xRGB into RGBA. A is set to 0xFF (255, full opacity).
1026
+ for (int i = 0; i< pixels.length; i++) {
1027
+ int pixel = pixels[i];
1028
+ rgbaPixels[i] = (pixel << 8) | 0xFF;
1029
+ }
1030
+ break;
1031
+ case ARGB:
1032
+ // Converting ARGB into RGBA. Shifting RGB to 8 bits to the left,
1033
+ // and bringing A to the first byte.
1034
+ for (int i = 0; i< pixels.length; i++) {
1035
+ int pixel = pixels[i];
1036
+ rgbaPixels[i] = (pixel << 8) | ((pixel >> 24) & 0xFF);
1037
+ }
1038
+ break;
1039
+ }
1040
+ } else {
1041
+ // LITTLE_ENDIAN
1042
+ // ARGB native, and RGBA opengl means ABGR on windows
1043
+ // for the most part just need to swap two components here
1044
+ // the sun.cpu.endian here might be "false", oddly enough..
1045
+ // (that's why just using an "else", rather than check for "little")
1046
+ switch (format) {
1047
+ case ALPHA:
1048
+ // Converting xxxA into ARGB, with RGB set to white.
1049
+ for (int i = 0; i< pixels.length; i++) {
1050
+ rgbaPixels[i] = (pixels[i] << 24) | 0x00FFFFFF;
1051
+ }
1052
+ break;
1053
+ case RGB:
1054
+ // We need to convert xRGB into ABGR,
1055
+ // so R and B must be swapped, and the x just made 0xFF.
1056
+ for (int i = 0; i< pixels.length; i++) {
1057
+ int pixel = pixels[i];
1058
+ rgbaPixels[i] = 0xFF000000 |
1059
+ ((pixel & 0xFF) << 16) | ((pixel & 0xFF0000) >> 16) |
1060
+ (pixel & 0x0000FF00);
1061
+ }
1062
+ break;
1063
+ case ARGB:
1064
+ // We need to convert ARGB into ABGR,
1065
+ // so R and B must be swapped, A and G just brought back in.
1066
+ for (int i = 0; i < pixels.length; i++) {
1067
+ int pixel = pixels[i];
1068
+ rgbaPixels[i] = ((pixel & 0xFF) << 16) | ((pixel & 0xFF0000) >> 16) |
1069
+ (pixel & 0xFF00FF00);
1070
+ }
1071
+ break;
1072
+ }
1073
+ }
1074
+ rgbaPixUpdateCount++;
1075
+ }
1076
+
1077
+
1078
+ /**
1079
+ * Reorders an OpenGL pixel array (RGBA) into ARGB. The array must be
1080
+ * of size width * height.
1081
+ * @param pixels int[]
1082
+ */
1083
+ protected void convertToARGB(int[] pixels) {
1084
+ int t = 0;
1085
+ int p = 0;
1086
+ if (PGL.BIG_ENDIAN) {
1087
+ // RGBA to ARGB conversion: shifting RGB 8 bits to the right,
1088
+ // and placing A 24 bits to the left.
1089
+ for (int y = 0; y < height; y++) {
1090
+ for (int x = 0; x < width; x++) {
1091
+ int pixel = pixels[p++];
1092
+ pixels[t++] = (pixel >>> 8) | ((pixel << 24) & 0xFF000000);
1093
+ }
1094
+ }
1095
+ } else {
1096
+ // We have to convert ABGR into ARGB, so R and B must be swapped,
1097
+ // A and G just brought back in.
1098
+ for (int y = 0; y < height; y++) {
1099
+ for (int x = 0; x < width; x++) {
1100
+ int pixel = pixels[p++];
1101
+ pixels[t++] = ((pixel & 0xFF) << 16) | ((pixel & 0xFF0000) >> 16) |
1102
+ (pixel & 0xFF00FF00);
1103
+ }
1104
+ }
1105
+ }
1106
+ }
1107
+
1108
+
1109
+ ///////////////////////////////////////////////////////////
1110
+
1111
+ // Allocate/release texture.
1112
+
1113
+
1114
+ protected void setSize(int w, int h) {
1115
+ width = w;
1116
+ height = h;
1117
+
1118
+ if (PGraphicsOpenGL.npotTexSupported) {
1119
+ glWidth = w;
1120
+ glHeight = h;
1121
+ } else {
1122
+ glWidth = PGL.nextPowerOfTwo(w);
1123
+ glHeight = PGL.nextPowerOfTwo(h);
1124
+ }
1125
+
1126
+ if (glWidth > PGraphicsOpenGL.maxTextureSize ||
1127
+ glHeight > PGraphicsOpenGL.maxTextureSize) {
1128
+ glWidth = glHeight = 0;
1129
+ throw new RuntimeException("Image width and height cannot be" +
1130
+ " larger than " +
1131
+ PGraphicsOpenGL.maxTextureSize +
1132
+ " with this graphics card.");
1133
+ }
1248
1134
 
1249
- glName = src.glName;
1250
- glTarget = src.glTarget;
1251
- glFormat = src.glFormat;
1252
- glMinFilter = src.glMinFilter;
1253
- glMagFilter = src.glMagFilter;
1135
+ // If non-power-of-two textures are not supported, and the specified width
1136
+ // or height is non-power-of-two, then glWidth (glHeight) will be greater
1137
+ // than w (h) because it is chosen to be the next power of two, and this
1138
+ // quotient will give the appropriate maximum texture coordinate value given
1139
+ // this situation.
1140
+ maxTexcoordU = (float)width / glWidth;
1141
+ maxTexcoordV = (float)height / glHeight;
1142
+ }
1254
1143
 
1255
- glWidth = src.glWidth;
1256
- glHeight = src.glHeight;
1257
1144
 
1258
- usingMipmaps = src.usingMipmaps;
1259
- usingRepeat = src.usingRepeat;
1260
- maxTexcoordU = src.maxTexcoordU;
1261
- maxTexcoordV = src.maxTexcoordV;
1145
+ /**
1146
+ * Allocates the opengl texture object.
1147
+ */
1148
+ protected void allocate() {
1149
+ dispose(); // Just in the case this object is being re-allocated.
1262
1150
 
1263
- invertedX = src.invertedX;
1264
- invertedY = src.invertedY;
1151
+ boolean enabledTex = false;
1152
+ if (!pgl.texturingIsEnabled(glTarget)) {
1153
+ pgl.enableTexturing(glTarget);
1154
+ enabledTex = true;
1265
1155
  }
1266
1156
 
1267
- // Releases the memory used by pixelBuffer either if the buffer hasn't been
1268
- // used many times yet, or if the JVM is running low in free memory.
1269
- protected void releasePixelBuffer() {
1270
- double freeMB = Runtime.getRuntime().freeMemory() / 1E6;
1271
- if (pixBufUpdateCount < MAX_UPDATES || freeMB < MIN_MEMORY) {
1272
- pixelBuffer = null;
1273
- }
1274
- }
1157
+ context = pgl.getCurrentContext();
1158
+ glres = new GLResourceTexture(this);
1275
1159
 
1276
- // Releases the memory used by rgbaPixels either if the array hasn't been
1277
- // used many times yet, or if the JVM is running low in free memory.
1278
- protected void releaseRGBAPixels() {
1279
- double freeMB = Runtime.getRuntime().freeMemory() / 1E6;
1280
- if (rgbaPixUpdateCount < MAX_UPDATES || freeMB < MIN_MEMORY) {
1281
- rgbaPixels = null;
1282
- }
1160
+ pgl.bindTexture(glTarget, glName);
1161
+ pgl.texParameteri(glTarget, PGL.TEXTURE_MIN_FILTER, glMinFilter);
1162
+ pgl.texParameteri(glTarget, PGL.TEXTURE_MAG_FILTER, glMagFilter);
1163
+ pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_S, glWrapS);
1164
+ pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_T, glWrapT);
1165
+ if (PGraphicsOpenGL.anisoSamplingSupported) {
1166
+ pgl.texParameterf(glTarget, PGL.TEXTURE_MAX_ANISOTROPY,
1167
+ PGraphicsOpenGL.maxAnisoAmount);
1283
1168
  }
1284
1169
 
1285
- ///////////////////////////////////////////////////////////
1286
- // Parameter handling
1287
- public Parameters getParameters() {
1288
- Parameters res = new Parameters();
1289
-
1290
- if (glTarget == PGL.TEXTURE_2D) {
1291
- res.target = TEX2D;
1292
- }
1293
-
1294
- if (glFormat == PGL.RGB) {
1295
- res.format = RGB;
1296
- } else if (glFormat == PGL.RGBA) {
1297
- res.format = ARGB;
1298
- } else if (glFormat == PGL.ALPHA) {
1299
- res.format = ALPHA;
1300
- }
1170
+ // First, we use glTexImage2D to set the full size of the texture (glW/glH
1171
+ // might be diff from w/h in the case that the GPU doesn't support NPOT
1172
+ // textures)
1173
+ pgl.texImage2D(glTarget, 0, glFormat, glWidth, glHeight, 0,
1174
+ PGL.RGBA, PGL.UNSIGNED_BYTE, null);
1301
1175
 
1302
- if (glMagFilter == PGL.NEAREST && glMinFilter == PGL.NEAREST) {
1303
- res.sampling = POINT;
1304
- res.mipmaps = false;
1305
- } else if (glMagFilter == PGL.NEAREST && glMinFilter == PGL.LINEAR) {
1306
- res.sampling = LINEAR;
1307
- res.mipmaps = false;
1308
- } else if (glMagFilter == PGL.NEAREST
1309
- && glMinFilter == PGL.LINEAR_MIPMAP_NEAREST) {
1310
- res.sampling = LINEAR;
1311
- res.mipmaps = true;
1312
- } else if (glMagFilter == PGL.LINEAR && glMinFilter == PGL.LINEAR) {
1313
- res.sampling = BILINEAR;
1314
- res.mipmaps = false;
1315
- } else if (glMagFilter == PGL.LINEAR
1316
- && glMinFilter == PGL.LINEAR_MIPMAP_NEAREST) {
1317
- res.sampling = BILINEAR;
1318
- res.mipmaps = true;
1319
- } else if (glMagFilter == PGL.LINEAR
1320
- && glMinFilter == PGL.LINEAR_MIPMAP_LINEAR) {
1321
- res.sampling = TRILINEAR;
1322
- res.mipmaps = true;
1323
- }
1176
+ // Makes sure that the texture buffer in video memory doesn't contain
1177
+ // any garbage.
1178
+ pgl.initTexture(glTarget, PGL.RGBA, width, height);
1324
1179
 
1325
- if (glWrapS == PGL.CLAMP_TO_EDGE) {
1326
- res.wrapU = CLAMP;
1327
- } else if (glWrapS == PGL.REPEAT) {
1328
- res.wrapU = REPEAT;
1329
- }
1180
+ pgl.bindTexture(glTarget, 0);
1181
+ if (enabledTex) {
1182
+ pgl.disableTexturing(glTarget);
1183
+ }
1184
+ bound = false;
1185
+ }
1330
1186
 
1331
- if (glWrapT == PGL.CLAMP_TO_EDGE) {
1332
- res.wrapV = CLAMP;
1333
- } else if (glWrapT == PGL.REPEAT) {
1334
- res.wrapV = REPEAT;
1335
- }
1336
1187
 
1337
- return res;
1188
+ /**
1189
+ * Marks the texture object for deletion.
1190
+ */
1191
+ protected void dispose() {
1192
+ if (glres != null) {
1193
+ glres.dispose();
1194
+ glres = null;
1195
+ glName = 0;
1338
1196
  }
1197
+ }
1339
1198
 
1340
- /**
1341
- * Sets texture target and internal format according to the target and type
1342
- * specified.
1343
- *
1344
- * @param target int
1345
- * @param params GLTextureParameters
1346
- */
1347
- protected void setParameters(Parameters params) {
1348
- if (params.target == TEX2D) {
1349
- glTarget = PGL.TEXTURE_2D;
1350
- } else {
1351
- throw new RuntimeException("Unknown texture target");
1352
- }
1353
1199
 
1354
- if (params.format == RGB) {
1355
- glFormat = PGL.RGB;
1356
- } else if (params.format == ARGB) {
1357
- glFormat = PGL.RGBA;
1358
- } else if (params.format == ALPHA) {
1359
- glFormat = PGL.ALPHA;
1360
- } else {
1361
- throw new RuntimeException("Unknown texture format");
1362
- }
1200
+ protected boolean contextIsOutdated() {
1201
+ boolean outdated = !pgl.contextIsCurrent(context);
1202
+ if (outdated) {
1203
+ dispose();
1204
+ }
1205
+ return outdated;
1206
+ }
1363
1207
 
1364
- boolean mipmaps = params.mipmaps && PGL.MIPMAPS_ENABLED;
1365
- if (mipmaps && !PGraphicsOpenGL.autoMipmapGenSupported) {
1366
- PGraphics.showWarning("Mipmaps were requested but automatic mipmap "
1367
- + "generation is not supported and manual "
1368
- + "generation still not implemented, so mipmaps "
1369
- + "will be disabled.");
1370
- mipmaps = false;
1371
- }
1372
1208
 
1373
- if (params.sampling == POINT) {
1374
- glMagFilter = PGL.NEAREST;
1375
- glMinFilter = PGL.NEAREST;
1376
- } else if (params.sampling == LINEAR) {
1377
- glMagFilter = PGL.NEAREST;
1378
- glMinFilter = mipmaps ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR;
1379
- } else if (params.sampling == BILINEAR) {
1380
- glMagFilter = PGL.LINEAR;
1381
- glMinFilter = mipmaps ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR;
1382
- } else if (params.sampling == TRILINEAR) {
1383
- glMagFilter = PGL.LINEAR;
1384
- glMinFilter = mipmaps ? PGL.LINEAR_MIPMAP_LINEAR : PGL.LINEAR;
1385
- } else {
1386
- throw new RuntimeException("Unknown texture filtering mode");
1387
- }
1209
+ public void colorBuffer(boolean value) {
1210
+ colorBuffer = value;
1211
+ }
1212
+
1213
+
1214
+ public boolean colorBuffer() {
1215
+ return colorBuffer;
1216
+ }
1217
+
1218
+
1219
+ ///////////////////////////////////////////////////////////
1220
+
1221
+ // Utilities.
1222
+
1223
+
1224
+ // Copies source texture tex into this.
1225
+ protected void copyTexture(Texture tex, int x, int y, int w, int h,
1226
+ boolean scale) {
1227
+ if (tex == null) {
1228
+ throw new RuntimeException("Source texture is null");
1229
+ }
1230
+
1231
+ if (tempFbo == null) {
1232
+ tempFbo = new FrameBuffer(pg, glWidth, glHeight);
1233
+ }
1234
+
1235
+ // This texture is the color (destination) buffer of the FBO.
1236
+ tempFbo.setColorBuffer(this);
1237
+ tempFbo.disableDepthTest();
1238
+
1239
+ // FBO copy:
1240
+ pg.pushFramebuffer();
1241
+ pg.setFramebuffer(tempFbo);
1242
+ // Replaces anything that this texture might contain in the area being
1243
+ // replaced by the new one.
1244
+ pg.pushStyle();
1245
+ pg.blendMode(REPLACE);
1246
+ if (scale) {
1247
+ // Rendering tex into "this", and scaling the source rectangle
1248
+ // to cover the entire destination region.
1249
+ pgl.drawTexture(tex.glTarget, tex.glName, tex.glWidth, tex.glHeight,
1250
+ 0, 0, tempFbo.width, tempFbo.height, 1,
1251
+ x, y, x + w, y + h, 0, 0, width, height);
1252
+
1253
+ } else {
1254
+ // Rendering tex into "this" but without scaling so the contents
1255
+ // of the source texture fall in the corresponding texels of the
1256
+ // destination.
1257
+ pgl.drawTexture(tex.glTarget, tex.glName, tex.glWidth, tex.glHeight,
1258
+ 0, 0, tempFbo.width, tempFbo.height, 1,
1259
+ x, y, x + w, y + h, x, y, x + w, y + h);
1260
+ }
1261
+ pgl.flush(); // Needed to make sure that the change in this texture is
1262
+ // available immediately.
1263
+ pg.popStyle();
1264
+ pg.popFramebuffer();
1265
+ updateTexels(x, y, w, h);
1266
+ }
1267
+
1388
1268
 
1389
- if (params.wrapU == CLAMP) {
1390
- glWrapS = PGL.CLAMP_TO_EDGE;
1391
- } else if (params.wrapU == REPEAT) {
1392
- glWrapS = PGL.REPEAT;
1393
- } else {
1394
- throw new RuntimeException("Unknown wrapping mode");
1395
- }
1269
+ // Copies source texture tex into this.
1270
+ protected void copyTexture(int texTarget, int texName,
1271
+ int texWidth, int texHeight,
1272
+ int x, int y, int w, int h, boolean scale) {
1273
+ if (tempFbo == null) {
1274
+ tempFbo = new FrameBuffer(pg, glWidth, glHeight);
1275
+ }
1396
1276
 
1397
- if (params.wrapV == CLAMP) {
1398
- glWrapT = PGL.CLAMP_TO_EDGE;
1399
- } else if (params.wrapV == REPEAT) {
1400
- glWrapT = PGL.REPEAT;
1401
- } else {
1402
- throw new RuntimeException("Unknown wrapping mode");
1403
- }
1277
+ // This texture is the color (destination) buffer of the FBO.
1278
+ tempFbo.setColorBuffer(this);
1279
+ tempFbo.disableDepthTest();
1404
1280
 
1405
- usingMipmaps = glMinFilter == PGL.LINEAR_MIPMAP_NEAREST
1406
- || glMinFilter == PGL.LINEAR_MIPMAP_LINEAR;
1407
-
1408
- usingRepeat = glWrapS == PGL.REPEAT || glWrapT == PGL.REPEAT;
1409
-
1410
- invertedX = false;
1411
- invertedY = false;
1412
- }
1413
-
1414
- protected void fillEdges(int x, int y, int w, int h) {
1415
- if ((width < glWidth || height < glHeight) && (x + w == width || y + h == height)) {
1416
- if (x + w == width) {
1417
- int ew = glWidth - width;
1418
- edgePixels = new int[h * ew];
1419
- for (int i = 0; i < h; i++) {
1420
- int c = rgbaPixels[i * w + (w - 1)];
1421
- Arrays.fill(edgePixels, i * ew, (i + 1) * ew, c);
1422
- }
1423
- edgeBuffer = PGL.updateIntBuffer(edgeBuffer, edgePixels, true);
1424
- pgl.texSubImage2D(glTarget, 0, width, y, ew, h, PGL.RGBA,
1425
- PGL.UNSIGNED_BYTE, edgeBuffer);
1426
- }
1427
-
1428
- if (y + h == height) {
1429
- int eh = glHeight - height;
1430
- edgePixels = new int[eh * w];
1431
- for (int i = 0; i < eh; i++) {
1432
- System.arraycopy(rgbaPixels, (h - 1) * w, edgePixels, i * w, w);
1433
- }
1434
- edgeBuffer = PGL.updateIntBuffer(edgeBuffer, edgePixels, true);
1435
- pgl.texSubImage2D(glTarget, 0, x, height, w, eh, PGL.RGBA,
1436
- PGL.UNSIGNED_BYTE, edgeBuffer);
1437
- }
1438
-
1439
- if (x + w == width && y + h == height) {
1440
- int ew = glWidth - width;
1441
- int eh = glHeight - height;
1442
- int c = rgbaPixels[w * h - 1];
1443
- edgePixels = new int[eh * ew];
1444
- Arrays.fill(edgePixels, 0, eh * ew, c);
1445
- edgeBuffer = PGL.updateIntBuffer(edgeBuffer, edgePixels, true);
1446
- pgl.texSubImage2D(glTarget, 0, width, height, ew, eh, PGL.RGBA,
1447
- PGL.UNSIGNED_BYTE, edgeBuffer);
1448
- }
1449
- }
1450
- }
1281
+ // FBO copy:
1282
+ pg.pushFramebuffer();
1283
+ pg.setFramebuffer(tempFbo);
1284
+ // Replaces anything that this texture might contain in the area being
1285
+ // replaced by the new one.
1286
+ pg.pushStyle();
1287
+ pg.blendMode(REPLACE);
1288
+ if (scale) {
1289
+ // Rendering tex into "this", and scaling the source rectangle
1290
+ // to cover the entire destination region.
1291
+ pgl.drawTexture(texTarget, texName, texWidth, texHeight,
1292
+ 0, 0, tempFbo.width, tempFbo.height,
1293
+ x, y, w, h, 0, 0, width, height);
1451
1294
 
1452
- ///////////////////////////////////////////////////////////////////////////
1453
- // Parameters object
1295
+ } else {
1296
+ // Rendering tex into "this" but without scaling so the contents
1297
+ // of the source texture fall in the corresponding texels of the
1298
+ // destination.
1299
+ pgl.drawTexture(texTarget, texName, texWidth, texHeight,
1300
+ 0, 0, tempFbo.width, tempFbo.height,
1301
+ x, y, w, h, x, y, w, h);
1302
+ }
1303
+ pgl.flush(); // Needed to make sure that the change in this texture is
1304
+ // available immediately.
1305
+ pg.popStyle();
1306
+ pg.popFramebuffer();
1307
+ updateTexels(x, y, w, h);
1308
+ }
1309
+
1310
+
1311
+ protected void copyObject(Texture src) {
1312
+ // The OpenGL texture of this object is replaced with the one from the
1313
+ // source object, so we delete the former to avoid resource wasting.
1314
+ dispose();
1315
+
1316
+ width = src.width;
1317
+ height = src.height;
1318
+
1319
+ glName = src.glName;
1320
+ glTarget = src.glTarget;
1321
+ glFormat = src.glFormat;
1322
+ glMinFilter = src.glMinFilter;
1323
+ glMagFilter = src.glMagFilter;
1324
+
1325
+ glWidth= src.glWidth;
1326
+ glHeight = src.glHeight;
1327
+
1328
+ usingMipmaps = src.usingMipmaps;
1329
+ usingRepeat = src.usingRepeat;
1330
+ maxTexcoordU = src.maxTexcoordU;
1331
+ maxTexcoordV = src.maxTexcoordV;
1332
+
1333
+ invertedX = src.invertedX;
1334
+ invertedY = src.invertedY;
1335
+ }
1336
+
1337
+
1338
+ // Releases the memory used by pixelBuffer either if the buffer hasn't been
1339
+ // used many times yet, or if the JVM is running low in free memory.
1340
+ protected void releasePixelBuffer() {
1341
+ double freeMB = Runtime.getRuntime().freeMemory() / 1E6;
1342
+ if (pixBufUpdateCount < MAX_UPDATES || freeMB < MIN_MEMORY) {
1343
+ pixelBuffer = null;
1344
+ }
1345
+ }
1346
+
1347
+
1348
+ // Releases the memory used by rgbaPixels either if the array hasn't been
1349
+ // used many times yet, or if the JVM is running low in free memory.
1350
+ protected void releaseRGBAPixels() {
1351
+ double freeMB = Runtime.getRuntime().freeMemory() / 1E6;
1352
+ if (rgbaPixUpdateCount < MAX_UPDATES || freeMB < MIN_MEMORY) {
1353
+ rgbaPixels = null;
1354
+ }
1355
+ }
1356
+
1357
+
1358
+ ///////////////////////////////////////////////////////////
1359
+
1360
+ // Parameter handling
1361
+
1362
+
1363
+ public Parameters getParameters() {
1364
+ Parameters res = new Parameters();
1365
+
1366
+ if (glTarget == PGL.TEXTURE_2D) {
1367
+ res.target = TEX2D;
1368
+ }
1369
+
1370
+ if (glFormat == PGL.RGB) {
1371
+ res.format = RGB;
1372
+ } else if (glFormat == PGL.RGBA) {
1373
+ res.format = ARGB;
1374
+ } else if (glFormat == PGL.ALPHA) {
1375
+ res.format = ALPHA;
1376
+ }
1377
+
1378
+ if (glMagFilter == PGL.NEAREST && glMinFilter == PGL.NEAREST) {
1379
+ res.sampling = POINT;
1380
+ res.mipmaps = false;
1381
+ } else if (glMagFilter == PGL.NEAREST && glMinFilter == PGL.LINEAR) {
1382
+ res.sampling = LINEAR;
1383
+ res.mipmaps = false;
1384
+ } else if (glMagFilter == PGL.NEAREST &&
1385
+ glMinFilter == PGL.LINEAR_MIPMAP_NEAREST) {
1386
+ res.sampling = LINEAR;
1387
+ res.mipmaps = true;
1388
+ } else if (glMagFilter == PGL.LINEAR && glMinFilter == PGL.LINEAR) {
1389
+ res.sampling = BILINEAR;
1390
+ res.mipmaps = false;
1391
+ } else if (glMagFilter == PGL.LINEAR &&
1392
+ glMinFilter == PGL.LINEAR_MIPMAP_NEAREST) {
1393
+ res.sampling = BILINEAR;
1394
+ res.mipmaps = true;
1395
+ } else if (glMagFilter == PGL.LINEAR &&
1396
+ glMinFilter == PGL.LINEAR_MIPMAP_LINEAR) {
1397
+ res.sampling = TRILINEAR;
1398
+ res.mipmaps = true;
1399
+ }
1400
+
1401
+ if (glWrapS == PGL.CLAMP_TO_EDGE) {
1402
+ res.wrapU = CLAMP;
1403
+ } else if (glWrapS == PGL.REPEAT) {
1404
+ res.wrapU = REPEAT;
1405
+ }
1406
+
1407
+ if (glWrapT == PGL.CLAMP_TO_EDGE) {
1408
+ res.wrapV = CLAMP;
1409
+ } else if (glWrapT == PGL.REPEAT) {
1410
+ res.wrapV = REPEAT;
1411
+ }
1412
+
1413
+ return res;
1414
+ }
1415
+
1416
+
1417
+ /**
1418
+ * Sets texture target and internal format according to the target and
1419
+ * type specified.
1420
+ * @param params GLTextureParameters
1421
+ */
1422
+ protected void setParameters(Parameters params) {
1423
+ if (params.target == TEX2D) {
1424
+ glTarget = PGL.TEXTURE_2D;
1425
+ } else {
1426
+ throw new RuntimeException("Unknown texture target");
1427
+ }
1428
+
1429
+ switch (params.format) {
1430
+ case RGB:
1431
+ glFormat = PGL.RGB;
1432
+ break;
1433
+ case ARGB:
1434
+ glFormat = PGL.RGBA;
1435
+ break;
1436
+ case ALPHA:
1437
+ glFormat = PGL.ALPHA;
1438
+ break;
1439
+ default:
1440
+ throw new RuntimeException("Unknown texture format");
1441
+ }
1442
+
1443
+ boolean mipmaps = params.mipmaps && PGL.MIPMAPS_ENABLED;
1444
+ if (mipmaps && !PGraphicsOpenGL.autoMipmapGenSupported) {
1445
+ PGraphics.showWarning("Mipmaps were requested but automatic mipmap " +
1446
+ "generation is not supported and manual " +
1447
+ "generation still not implemented, so mipmaps " +
1448
+ "will be disabled.");
1449
+ mipmaps = false;
1450
+ }
1451
+
1452
+ switch (params.sampling) {
1453
+ case POINT:
1454
+ glMagFilter = PGL.NEAREST;
1455
+ glMinFilter = PGL.NEAREST;
1456
+ break;
1457
+ case LINEAR:
1458
+ glMagFilter = PGL.NEAREST;
1459
+ glMinFilter = mipmaps ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR;
1460
+ break;
1461
+ case BILINEAR:
1462
+ glMagFilter = PGL.LINEAR;
1463
+ glMinFilter = mipmaps ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR;
1464
+ break;
1465
+ case TRILINEAR:
1466
+ glMagFilter = PGL.LINEAR;
1467
+ glMinFilter = mipmaps ? PGL.LINEAR_MIPMAP_LINEAR : PGL.LINEAR;
1468
+ break;
1469
+ default:
1470
+ throw new RuntimeException("Unknown texture filtering mode");
1471
+ }
1472
+
1473
+ switch (params.wrapU) {
1474
+ case CLAMP:
1475
+ glWrapS = PGL.CLAMP_TO_EDGE;
1476
+ break;
1477
+ case REPEAT:
1478
+ glWrapS = PGL.REPEAT;
1479
+ break;
1480
+ default:
1481
+ throw new RuntimeException("Unknown wrapping mode");
1482
+ }
1483
+
1484
+ switch (params.wrapV) {
1485
+ case CLAMP:
1486
+ glWrapT = PGL.CLAMP_TO_EDGE;
1487
+ break;
1488
+ case REPEAT:
1489
+ glWrapT = PGL.REPEAT;
1490
+ break;
1491
+ default:
1492
+ throw new RuntimeException("Unknown wrapping mode");
1493
+ }
1494
+
1495
+ usingMipmaps = glMinFilter == PGL.LINEAR_MIPMAP_NEAREST ||
1496
+ glMinFilter == PGL.LINEAR_MIPMAP_LINEAR;
1497
+
1498
+ usingRepeat = glWrapS == PGL.REPEAT || glWrapT == PGL.REPEAT;
1499
+
1500
+ invertedX = false;
1501
+ invertedY = false;
1502
+ }
1503
+
1504
+
1505
+ protected void fillEdges(int x, int y, int w, int h) {
1506
+ if ((width < glWidth || height < glHeight) && (x + w == width || y + h == height)) {
1507
+ if (x + w == width) {
1508
+ int ew = glWidth - width;
1509
+ edgePixels = new int[h * ew];
1510
+ for (int i = 0; i < h; i++) {
1511
+ int c = rgbaPixels[i * w + (w - 1)];
1512
+ Arrays.fill(edgePixels, i * ew, (i + 1) * ew, c);
1513
+ }
1514
+ edgeBuffer = PGL.updateIntBuffer(edgeBuffer, edgePixels, true);
1515
+ pgl.texSubImage2D(glTarget, 0, width, y, ew, h, PGL.RGBA,
1516
+ PGL.UNSIGNED_BYTE, edgeBuffer);
1517
+ }
1518
+
1519
+ if (y + h == height) {
1520
+ int eh = glHeight - height;
1521
+ edgePixels = new int[eh * w];
1522
+ for (int i = 0; i < eh; i++) {
1523
+ System.arraycopy(rgbaPixels, (h - 1) * w, edgePixels, i * w, w);
1524
+ }
1525
+ edgeBuffer = PGL.updateIntBuffer(edgeBuffer, edgePixels, true);
1526
+ pgl.texSubImage2D(glTarget, 0, x, height, w, eh, PGL.RGBA,
1527
+ PGL.UNSIGNED_BYTE, edgeBuffer);
1528
+ }
1529
+
1530
+ if (x + w == width && y + h == height) {
1531
+ int ew = glWidth - width;
1532
+ int eh = glHeight - height;
1533
+ int c = rgbaPixels[w * h - 1];
1534
+ edgePixels = new int[eh * ew];
1535
+ Arrays.fill(edgePixels, 0, eh * ew, c);
1536
+ edgeBuffer = PGL.updateIntBuffer(edgeBuffer, edgePixels, true);
1537
+ pgl.texSubImage2D(glTarget, 0, width, height, ew, eh, PGL.RGBA,
1538
+ PGL.UNSIGNED_BYTE, edgeBuffer);
1539
+ }
1540
+ }
1541
+ }
1542
+
1543
+ ///////////////////////////////////////////////////////////////////////////
1544
+
1545
+ // Parameters object
1546
+
1547
+
1548
+ /**
1549
+ * This class stores the parameters for a texture: target, internal format,
1550
+ * minimization filter and magnification filter.
1551
+ */
1552
+ static public class Parameters {
1454
1553
  /**
1455
- * This class stores the parameters for a texture: target, internal format,
1456
- * minimization filter and magnification filter.
1554
+ * Texture target.
1457
1555
  */
1458
- static public class Parameters {
1459
-
1460
- /**
1461
- * Texture target.
1462
- */
1463
- public int target;
1464
-
1465
- /**
1466
- * Texture internal format.
1467
- */
1468
- public int format;
1469
-
1470
- /**
1471
- * Texture filtering (POINT, LINEAR, BILINEAR or TRILINEAR).
1472
- */
1473
- public int sampling;
1474
-
1475
- /**
1476
- * Use mipmaps or not.
1477
- */
1478
- public boolean mipmaps;
1479
-
1480
- /**
1481
- * Wrapping mode along U.
1482
- */
1483
- public int wrapU;
1484
-
1485
- /**
1486
- * Wrapping mode along V.
1487
- */
1488
- public int wrapV;
1489
-
1490
- /**
1491
- * Sets all the parameters to default values.
1492
- */
1493
- public Parameters() {
1494
- this.target = TEX2D;
1495
- this.format = ARGB;
1496
- this.sampling = BILINEAR;
1497
- this.mipmaps = true;
1498
- this.wrapU = CLAMP;
1499
- this.wrapV = CLAMP;
1500
- }
1501
-
1502
- public Parameters(int format) {
1503
- this.target = TEX2D;
1504
- this.format = format;
1505
- this.sampling = BILINEAR;
1506
- this.mipmaps = true;
1507
- this.wrapU = CLAMP;
1508
- this.wrapV = CLAMP;
1509
- }
1510
-
1511
- public Parameters(int format, int sampling) {
1512
- this.target = TEX2D;
1513
- this.format = format;
1514
- this.sampling = sampling;
1515
- this.mipmaps = true;
1516
- this.wrapU = CLAMP;
1517
- this.wrapV = CLAMP;
1518
- }
1519
-
1520
- public Parameters(int format, int sampling, boolean mipmaps) {
1521
- this.target = TEX2D;
1522
- this.format = format;
1523
- this.mipmaps = mipmaps;
1524
- if (sampling == TRILINEAR && !mipmaps) {
1525
- this.sampling = BILINEAR;
1526
- } else {
1527
- this.sampling = sampling;
1528
- }
1529
- this.wrapU = CLAMP;
1530
- this.wrapV = CLAMP;
1531
- }
1532
-
1533
- public Parameters(int format, int sampling, boolean mipmaps, int wrap) {
1534
- this.target = TEX2D;
1535
- this.format = format;
1536
- this.mipmaps = mipmaps;
1537
- if (sampling == TRILINEAR && !mipmaps) {
1538
- this.sampling = BILINEAR;
1539
- } else {
1540
- this.sampling = sampling;
1541
- }
1542
- this.wrapU = wrap;
1543
- this.wrapV = wrap;
1544
- }
1545
-
1546
- public Parameters(Parameters src) {
1547
- set(src);
1548
- }
1556
+ public int target;
1549
1557
 
1550
- public void set(int format) {
1551
- this.format = format;
1552
- }
1558
+ /**
1559
+ * Texture internal format.
1560
+ */
1561
+ public int format;
1553
1562
 
1554
- public void set(int format, int sampling) {
1555
- this.format = format;
1556
- this.sampling = sampling;
1557
- }
1563
+ /**
1564
+ * Texture filtering (POINT, LINEAR, BILINEAR or TRILINEAR).
1565
+ */
1566
+ public int sampling;
1558
1567
 
1559
- public void set(int format, int sampling, boolean mipmaps) {
1560
- this.format = format;
1561
- this.sampling = sampling;
1562
- this.mipmaps = mipmaps;
1563
- }
1568
+ /**
1569
+ * Use mipmaps or not.
1570
+ */
1571
+ public boolean mipmaps;
1564
1572
 
1565
- public void set(Parameters src) {
1566
- this.target = src.target;
1567
- this.format = src.format;
1568
- this.sampling = src.sampling;
1569
- this.mipmaps = src.mipmaps;
1570
- this.wrapU = src.wrapU;
1571
- this.wrapV = src.wrapV;
1572
- }
1573
- }
1573
+ /**
1574
+ * Wrapping mode along U.
1575
+ */
1576
+ public int wrapU;
1574
1577
 
1575
1578
  /**
1576
- * This class stores a buffer copied from the buffer source.
1577
- *
1579
+ * Wrapping mode along V.
1578
1580
  */
1579
- protected class BufferData {
1580
-
1581
- int w, h;
1582
- // Native buffer object.
1583
- Object natBuf;
1584
- // Buffer viewed as int.
1585
- IntBuffer rgbBuf;
1586
-
1587
- BufferData(Object nat, IntBuffer rgb, int w, int h) {
1588
- natBuf = nat;
1589
- rgbBuf = rgb;
1590
- this.w = w;
1591
- this.h = h;
1592
- }
1581
+ public int wrapV;
1593
1582
 
1594
- void dispose() {
1595
- try {
1596
- // Disposing the native buffer.
1597
- disposeBufferMethod.invoke(bufferSource, new Object[]{natBuf});
1598
- natBuf = null;
1599
- rgbBuf = null;
1600
- } catch (Exception e) {
1601
- e.printStackTrace();
1602
- }
1603
- }
1604
- }
1605
- }
1583
+ /**
1584
+ * Sets all the parameters to default values.
1585
+ */
1586
+ public Parameters() {
1587
+ this.target = TEX2D;
1588
+ this.format = ARGB;
1589
+ this.sampling = BILINEAR;
1590
+ this.mipmaps = true;
1591
+ this.wrapU = CLAMP;
1592
+ this.wrapV = CLAMP;
1593
+ }
1594
+
1595
+ public Parameters(int format) {
1596
+ this.target = TEX2D;
1597
+ this.format = format;
1598
+ this.sampling = BILINEAR;
1599
+ this.mipmaps = true;
1600
+ this.wrapU = CLAMP;
1601
+ this.wrapV = CLAMP;
1602
+ }
1603
+
1604
+ public Parameters(int format, int sampling) {
1605
+ this.target = TEX2D;
1606
+ this.format = format;
1607
+ this.sampling = sampling;
1608
+ this.mipmaps = true;
1609
+ this.wrapU = CLAMP;
1610
+ this.wrapV = CLAMP;
1611
+ }
1612
+
1613
+ public Parameters(int format, int sampling, boolean mipmaps) {
1614
+ this.target = TEX2D;
1615
+ this.format = format;
1616
+ this.mipmaps = mipmaps;
1617
+ if (sampling == TRILINEAR && !mipmaps) {
1618
+ this.sampling = BILINEAR;
1619
+ } else {
1620
+ this.sampling = sampling;
1621
+ }
1622
+ this.wrapU = CLAMP;
1623
+ this.wrapV = CLAMP;
1624
+ }
1625
+
1626
+ public Parameters(int format, int sampling, boolean mipmaps, int wrap) {
1627
+ this.target = TEX2D;
1628
+ this.format = format;
1629
+ this.mipmaps = mipmaps;
1630
+ if (sampling == TRILINEAR && !mipmaps) {
1631
+ this.sampling = BILINEAR;
1632
+ } else {
1633
+ this.sampling = sampling;
1634
+ }
1635
+ this.wrapU = wrap;
1636
+ this.wrapV = wrap;
1637
+ }
1638
+
1639
+ public Parameters(Parameters src) {
1640
+ set(src);
1641
+ }
1642
+
1643
+ public void set(int format) {
1644
+ this.format = format;
1645
+ }
1646
+
1647
+ public void set(int format, int sampling) {
1648
+ this.format = format;
1649
+ this.sampling = sampling;
1650
+ }
1651
+
1652
+ public void set(int format, int sampling, boolean mipmaps) {
1653
+ this.format = format;
1654
+ this.sampling = sampling;
1655
+ this.mipmaps = mipmaps;
1656
+ }
1657
+
1658
+ public void set(Parameters src) {
1659
+ this.target = src.target;
1660
+ this.format = src.format;
1661
+ this.sampling = src.sampling;
1662
+ this.mipmaps = src.mipmaps;
1663
+ this.wrapU = src.wrapU;
1664
+ this.wrapV = src.wrapV;
1665
+ }
1666
+ }
1667
+
1668
+ /**
1669
+ * This class stores a buffer copied from the buffer source.
1670
+ *
1671
+ */
1672
+ protected class BufferData {
1673
+ int w, h;
1674
+ // Native buffer object.
1675
+ Object natBuf;
1676
+ // Buffer viewed as int.
1677
+ IntBuffer rgbBuf;
1678
+
1679
+ BufferData(Object nat, IntBuffer rgb, int w, int h) {
1680
+ natBuf = nat;
1681
+ rgbBuf = rgb;
1682
+ this.w = w;
1683
+ this.h = h;
1684
+ }
1685
+
1686
+ void dispose() {
1687
+ try {
1688
+ // Disposing the native buffer.
1689
+ disposeBufferMethod.invoke(bufferSource, natBuf);
1690
+ natBuf = null;
1691
+ rgbBuf = null;
1692
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
1693
+ }
1694
+ }
1695
+ }
1696
+ }