propane 3.1.0.pre-java → 3.2.0-java

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