propane 3.4.2-java → 3.8.0-java

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