propane 3.6.0-java → 3.10.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (161) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/extensions.xml +1 -1
  3. data/.travis.yml +1 -1
  4. data/CHANGELOG.md +5 -1
  5. data/README.md +6 -13
  6. data/Rakefile +7 -6
  7. data/lib/java/japplemenubar/JAppleMenuBar.java +88 -0
  8. data/lib/java/japplemenubar/libjAppleMenuBar.jnilib +0 -0
  9. data/lib/java/monkstone/ColorUtil.java +127 -0
  10. data/lib/java/monkstone/MathToolModule.java +287 -0
  11. data/lib/java/monkstone/PropaneLibrary.java +46 -0
  12. data/lib/java/monkstone/core/LibraryProxy.java +136 -0
  13. data/lib/java/monkstone/fastmath/DegLutTables.java +111 -0
  14. data/lib/java/monkstone/fastmath/Deglut.java +71 -0
  15. data/lib/java/monkstone/fastmath/package-info.java +6 -0
  16. data/lib/java/monkstone/filechooser/Chooser.java +39 -0
  17. data/lib/java/monkstone/noise/FastTerrain.java +874 -0
  18. data/lib/java/monkstone/noise/Noise.java +90 -0
  19. data/lib/java/monkstone/noise/NoiseGenerator.java +75 -0
  20. data/lib/java/monkstone/noise/NoiseMode.java +28 -0
  21. data/lib/java/monkstone/noise/OpenSimplex2F.java +881 -0
  22. data/lib/java/monkstone/noise/OpenSimplex2S.java +1106 -0
  23. data/lib/java/monkstone/noise/SmoothTerrain.java +1099 -0
  24. data/lib/java/monkstone/slider/CustomHorizontalSlider.java +164 -0
  25. data/lib/java/monkstone/slider/CustomVerticalSlider.java +178 -0
  26. data/lib/java/monkstone/slider/SimpleHorizontalSlider.java +145 -0
  27. data/lib/java/monkstone/slider/SimpleSlider.java +166 -0
  28. data/lib/java/monkstone/slider/SimpleVerticalSlider.java +157 -0
  29. data/lib/java/monkstone/slider/Slider.java +61 -0
  30. data/lib/java/monkstone/slider/SliderBar.java +245 -0
  31. data/lib/java/monkstone/slider/SliderGroup.java +56 -0
  32. data/lib/java/monkstone/slider/WheelHandler.java +35 -0
  33. data/lib/java/monkstone/vecmath/GfxRender.java +86 -0
  34. data/lib/java/monkstone/vecmath/JRender.java +56 -0
  35. data/lib/java/monkstone/vecmath/ShapeRender.java +87 -0
  36. data/lib/java/monkstone/vecmath/package-info.java +20 -0
  37. data/lib/java/monkstone/vecmath/vec2/Vec2.java +802 -0
  38. data/lib/java/monkstone/vecmath/vec2/package-info.java +6 -0
  39. data/lib/java/monkstone/vecmath/vec3/Vec3.java +727 -0
  40. data/lib/java/monkstone/vecmath/vec3/package-info.java +6 -0
  41. data/lib/java/monkstone/videoevent/CaptureEvent.java +27 -0
  42. data/lib/java/monkstone/videoevent/MovieEvent.java +32 -0
  43. data/lib/java/monkstone/videoevent/package-info.java +20 -0
  44. data/lib/java/processing/awt/PGraphicsJava2D.java +3040 -0
  45. data/lib/java/processing/awt/PImageAWT.java +377 -0
  46. data/lib/java/processing/awt/PShapeJava2D.java +387 -0
  47. data/lib/java/processing/awt/PSurfaceAWT.java +1581 -0
  48. data/lib/java/processing/awt/ShimAWT.java +581 -0
  49. data/lib/java/processing/core/PApplet.java +15156 -0
  50. data/lib/java/processing/core/PConstants.java +523 -0
  51. data/lib/java/processing/core/PFont.java +1126 -0
  52. data/lib/java/processing/core/PGraphics.java +8600 -0
  53. data/lib/java/processing/core/PImage.java +3377 -0
  54. data/lib/java/processing/core/PMatrix.java +208 -0
  55. data/lib/java/processing/core/PMatrix2D.java +562 -0
  56. data/lib/java/processing/core/PMatrix3D.java +890 -0
  57. data/lib/java/processing/core/PShape.java +3561 -0
  58. data/lib/java/processing/core/PShapeOBJ.java +483 -0
  59. data/lib/java/processing/core/PShapeSVG.java +2016 -0
  60. data/lib/java/processing/core/PStyle.java +63 -0
  61. data/lib/java/processing/core/PSurface.java +198 -0
  62. data/lib/java/processing/core/PSurfaceNone.java +431 -0
  63. data/lib/java/processing/core/PVector.java +1066 -0
  64. data/lib/java/processing/core/ThinkDifferent.java +115 -0
  65. data/lib/java/processing/data/DoubleDict.java +850 -0
  66. data/lib/java/processing/data/DoubleList.java +928 -0
  67. data/lib/java/processing/data/FloatDict.java +847 -0
  68. data/lib/java/processing/data/FloatList.java +936 -0
  69. data/lib/java/processing/data/IntDict.java +807 -0
  70. data/lib/java/processing/data/IntList.java +936 -0
  71. data/lib/java/processing/data/JSONArray.java +1260 -0
  72. data/lib/java/processing/data/JSONObject.java +2282 -0
  73. data/lib/java/processing/data/JSONTokener.java +435 -0
  74. data/lib/java/processing/data/LongDict.java +802 -0
  75. data/lib/java/processing/data/LongList.java +937 -0
  76. data/lib/java/processing/data/Sort.java +46 -0
  77. data/lib/java/processing/data/StringDict.java +613 -0
  78. data/lib/java/processing/data/StringList.java +800 -0
  79. data/lib/java/processing/data/Table.java +4936 -0
  80. data/lib/java/processing/data/TableRow.java +198 -0
  81. data/lib/java/processing/data/XML.java +1156 -0
  82. data/lib/java/processing/dxf/RawDXF.java +404 -0
  83. data/lib/java/processing/event/Event.java +125 -0
  84. data/lib/java/processing/event/KeyEvent.java +70 -0
  85. data/lib/java/processing/event/MouseEvent.java +114 -0
  86. data/lib/java/processing/event/TouchEvent.java +57 -0
  87. data/lib/java/processing/javafx/PGraphicsFX2D.java +32 -0
  88. data/lib/java/processing/javafx/PSurfaceFX.java +173 -0
  89. data/lib/java/processing/net/Client.java +744 -0
  90. data/lib/java/processing/net/Server.java +388 -0
  91. data/lib/java/processing/opengl/FontTexture.java +378 -0
  92. data/lib/java/processing/opengl/FrameBuffer.java +513 -0
  93. data/lib/java/processing/opengl/LinePath.java +627 -0
  94. data/lib/java/processing/opengl/LineStroker.java +681 -0
  95. data/lib/java/processing/opengl/PGL.java +3483 -0
  96. data/lib/java/processing/opengl/PGraphics2D.java +615 -0
  97. data/lib/java/processing/opengl/PGraphics3D.java +281 -0
  98. data/lib/java/processing/opengl/PGraphicsOpenGL.java +13753 -0
  99. data/lib/java/processing/opengl/PJOGL.java +2008 -0
  100. data/lib/java/processing/opengl/PShader.java +1484 -0
  101. data/lib/java/processing/opengl/PShapeOpenGL.java +5269 -0
  102. data/lib/java/processing/opengl/PSurfaceJOGL.java +1385 -0
  103. data/lib/java/processing/opengl/Texture.java +1696 -0
  104. data/lib/java/processing/opengl/VertexBuffer.java +88 -0
  105. data/lib/java/processing/opengl/cursors/arrow.png +0 -0
  106. data/lib/java/processing/opengl/cursors/cross.png +0 -0
  107. data/lib/java/processing/opengl/cursors/hand.png +0 -0
  108. data/lib/java/processing/opengl/cursors/license.txt +27 -0
  109. data/lib/java/processing/opengl/cursors/move.png +0 -0
  110. data/lib/java/processing/opengl/cursors/text.png +0 -0
  111. data/lib/java/processing/opengl/cursors/wait.png +0 -0
  112. data/lib/java/processing/opengl/shaders/ColorFrag.glsl +32 -0
  113. data/lib/java/processing/opengl/shaders/ColorVert.glsl +34 -0
  114. data/lib/java/processing/opengl/shaders/LightFrag.glsl +33 -0
  115. data/lib/java/processing/opengl/shaders/LightVert.glsl +151 -0
  116. data/lib/java/processing/opengl/shaders/LineFrag.glsl +32 -0
  117. data/lib/java/processing/opengl/shaders/LineVert.glsl +100 -0
  118. data/lib/java/processing/opengl/shaders/MaskFrag.glsl +40 -0
  119. data/lib/java/processing/opengl/shaders/PointFrag.glsl +32 -0
  120. data/lib/java/processing/opengl/shaders/PointVert.glsl +56 -0
  121. data/lib/java/processing/opengl/shaders/TexFrag.glsl +37 -0
  122. data/lib/java/processing/opengl/shaders/TexLightFrag.glsl +37 -0
  123. data/lib/java/processing/opengl/shaders/TexLightVert.glsl +157 -0
  124. data/lib/java/processing/opengl/shaders/TexVert.glsl +38 -0
  125. data/lib/java/processing/pdf/PGraphicsPDF.java +581 -0
  126. data/lib/java/processing/svg/PGraphicsSVG.java +378 -0
  127. data/lib/propane/app.rb +9 -10
  128. data/lib/propane/runner.rb +10 -12
  129. data/lib/propane/version.rb +1 -1
  130. data/library/pdf/pdf.rb +7 -0
  131. data/library/svg/svg.rb +7 -0
  132. data/mvnw +3 -3
  133. data/mvnw.cmd +2 -2
  134. data/pom.rb +30 -3
  135. data/pom.xml +54 -3
  136. data/propane.gemspec +7 -3
  137. data/src/main/java/monkstone/FastNoiseModuleJava.java +127 -0
  138. data/src/main/java/monkstone/MathToolModule.java +30 -30
  139. data/src/main/java/monkstone/PropaneLibrary.java +2 -0
  140. data/src/main/java/monkstone/SmoothNoiseModuleJava.java +127 -0
  141. data/src/main/java/monkstone/fastmath/DegLutTables.java +111 -0
  142. data/src/main/java/monkstone/fastmath/Deglut.java +6 -56
  143. data/src/main/java/monkstone/filechooser/Chooser.java +1 -1
  144. data/src/main/java/monkstone/noise/OpenSimplex2F.java +813 -0
  145. data/src/main/java/monkstone/noise/OpenSimplex2S.java +1138 -0
  146. data/src/main/java/monkstone/slider/WheelHandler.java +1 -1
  147. data/src/main/java/monkstone/vecmath/JRender.java +6 -6
  148. data/src/main/java/monkstone/vecmath/vec2/Vec2.java +20 -19
  149. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +12 -12
  150. data/src/main/java/processing/awt/PGraphicsJava2D.java +11 -3
  151. data/src/main/java/processing/core/PApplet.java +13242 -13374
  152. data/src/main/java/processing/core/PConstants.java +155 -163
  153. data/src/main/java/processing/core/PGraphics.java +118 -111
  154. data/src/main/java/processing/opengl/PJOGL.java +6 -5
  155. data/src/main/java/processing/pdf/PGraphicsPDF.java +581 -0
  156. data/src/main/java/processing/svg/PGraphicsSVG.java +378 -0
  157. data/test/deglut_spec_test.rb +2 -2
  158. data/vendors/Rakefile +1 -1
  159. metadata +146 -17
  160. data/library/simplex_noise/simplex_noise.rb +0 -5
  161. data/src/main/java/monkstone/noise/SimplexNoise.java +0 -436
@@ -0,0 +1,3483 @@
1
+ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
+
3
+ /*
4
+ Part of the Processing project - http://processing.org
5
+
6
+ Copyright (c) 2012-15 The Processing Foundation
7
+ Copyright (c) 2004-12 Ben Fry and Casey Reas
8
+ Copyright (c) 2001-04 Massachusetts Institute of Technology
9
+
10
+ This library is free software; you can redistribute it and/or
11
+ modify it under the terms of the GNU Lesser General Public
12
+ License as published by the Free Software Foundation, version 2.1.
13
+
14
+ This library is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
+ Lesser General Public License for more details.
18
+
19
+ You should have received a copy of the GNU Lesser General
20
+ Public License along with this library; if not, write to the
21
+ Free Software Foundation, Inc., 59 Temple Place, Suite 330,
22
+ Boston, MA 02111-1307 USA
23
+ */
24
+
25
+ package processing.opengl;
26
+
27
+ import java.io.IOException;
28
+ import java.net.URL;
29
+ import java.nio.Buffer;
30
+ import java.nio.ByteBuffer;
31
+ import java.nio.ByteOrder;
32
+ import java.nio.FloatBuffer;
33
+ import java.nio.IntBuffer;
34
+ import java.nio.ShortBuffer;
35
+ import java.util.Arrays;
36
+ import java.util.regex.Pattern;
37
+
38
+ import processing.core.PApplet;
39
+ import processing.core.PConstants;
40
+ import processing.core.PGraphics;
41
+ import processing.core.PImage;
42
+
43
+
44
+ /**
45
+ * Processing-OpenGL abstraction layer. Needs to be implemented by subclasses
46
+ * using specific OpenGL-Java bindings.
47
+ *
48
+ * It includes a full GLES 2.0 interface.
49
+ *
50
+ */
51
+ public abstract class PGL {
52
+ // ........................................................
53
+
54
+ // Basic fields
55
+
56
+ /** The PGraphics and PApplet objects using this interface */
57
+ protected PGraphicsOpenGL graphics;
58
+ protected PApplet sketch;
59
+ protected RenderCallback renderCallback;
60
+
61
+ /** OpenGL thread */
62
+ protected Thread glThread;
63
+
64
+ /** ID of the GL context associated to the surface **/
65
+ protected int glContext;
66
+
67
+ /** true if this is the GL interface for a primary surface PGraphics */
68
+ public boolean primaryPGL;
69
+
70
+ // ........................................................
71
+
72
+ // Parameters
73
+
74
+ public static int REQUESTED_DEPTH_BITS = 24;
75
+ public static int REQUESTED_STENCIL_BITS = 8;
76
+ public static int REQUESTED_ALPHA_BITS = 8;
77
+
78
+ /** Switches between the use of regular and direct buffers. */
79
+ protected static boolean USE_DIRECT_BUFFERS = true;
80
+ protected static int MIN_DIRECT_BUFFER_SIZE = 1;
81
+
82
+ /** Enables/disables mipmap use. */
83
+ protected static boolean MIPMAPS_ENABLED = true;
84
+
85
+ /** Initial sizes for arrays of input and tessellated data. */
86
+ protected static int DEFAULT_IN_VERTICES = 64;
87
+ protected static int DEFAULT_IN_EDGES = 128;
88
+ protected static int DEFAULT_IN_TEXTURES = 64;
89
+ protected static int DEFAULT_TESS_VERTICES = 64;
90
+ protected static int DEFAULT_TESS_INDICES = 128;
91
+
92
+ /** Maximum lights by default is 8, the minimum defined by OpenGL. */
93
+ protected static int MAX_LIGHTS = 8;
94
+
95
+ /** Maximum index value of a tessellated vertex. GLES restricts the vertex
96
+ * indices to be of type unsigned short. Since Java only supports signed
97
+ * shorts as primitive type we have 2^15 = 32768 as the maximum number of
98
+ * vertices that can be referred to within a single VBO.
99
+ */
100
+ protected static final int MAX_VERTEX_INDEX = 32767;
101
+ protected static final int MAX_VERTEX_INDEX1 = MAX_VERTEX_INDEX + 1;
102
+
103
+ /** Count of tessellated fill, line or point vertices that will
104
+ * trigger a flush in the immediate mode. It doesn't necessarily
105
+ * be equal to MAX_VERTEX_INDEX1, since the number of vertices can
106
+ * be effectively much large since the renderer uses offsets to
107
+ * refer to vertices beyond the MAX_VERTEX_INDEX limit.
108
+ */
109
+ protected static int FLUSH_VERTEX_COUNT = MAX_VERTEX_INDEX1;
110
+
111
+ /** Minimum/maximum dimensions of a texture used to hold font data. */
112
+ protected static int MIN_FONT_TEX_SIZE = 256;
113
+ protected static int MAX_FONT_TEX_SIZE = 1024;
114
+
115
+ /** Minimum stroke weight needed to apply the full path stroking
116
+ * algorithm that properly generates caps and joins.
117
+ */
118
+ protected static float MIN_CAPS_JOINS_WEIGHT = 2f;
119
+
120
+ /** Maximum length of linear paths to be stroked with the
121
+ * full algorithm that generates accurate caps and joins.
122
+ */
123
+ protected static int MAX_CAPS_JOINS_LENGTH = 5000;
124
+
125
+ /** Minimum array size to use arrayCopy method(). */
126
+ protected static int MIN_ARRAYCOPY_SIZE = 2;
127
+
128
+ /** Factor used to displace the stroke vertices towards the camera in
129
+ * order to make sure the lines are always on top of the fill geometry */
130
+ protected static float STROKE_DISPLACEMENT = 0.999f;
131
+
132
+ // ........................................................
133
+
134
+ // Variables to handle single-buffered situations (i.e.: Android)
135
+
136
+ protected IntBuffer firstFrame;
137
+ protected static boolean SINGLE_BUFFERED = false;
138
+
139
+ // ........................................................
140
+
141
+ // FBO layer
142
+
143
+ protected boolean fboLayerEnabled = false;
144
+ protected boolean fboLayerCreated = false;
145
+ protected boolean fboLayerEnabledReq = false;
146
+ protected boolean fboLayerDisableReq = false;
147
+ protected boolean fbolayerResetReq = false;
148
+ public int reqNumSamples;
149
+ protected int numSamples;
150
+
151
+ protected IntBuffer glColorFbo;
152
+ protected IntBuffer glColorTex;
153
+ protected IntBuffer glDepthStencil;
154
+ protected IntBuffer glDepth;
155
+ protected IntBuffer glStencil;
156
+
157
+ protected IntBuffer glMultiFbo;
158
+ protected IntBuffer glMultiColor;
159
+ protected IntBuffer glMultiDepthStencil;
160
+ protected IntBuffer glMultiDepth;
161
+ protected IntBuffer glMultiStencil;
162
+
163
+ protected int fboWidth, fboHeight;
164
+ protected int backTex, frontTex;
165
+
166
+ /** Flags used to handle the creation of a separate front texture */
167
+ protected boolean usingFrontTex = false;
168
+ protected boolean needSepFrontTex = false;
169
+
170
+ /**
171
+ * Defines if FBO Layer is allowed in the given environment.
172
+ * Using FBO can cause a fatal error during runtime for
173
+ * Intel HD Graphics 3000 chipsets (commonly used on older MacBooks)
174
+ * <a href="https://github.com/processing/processing/issues/4104">#4104</a>.
175
+ * Changed to private because needs to be accessed via isFboAllowed().
176
+ * <a href="https://github.com/processing/processing4/pull/76">#76</a> and
177
+ * <a href="https://github.com/processing/processing4/issues/50">#50</a>
178
+ */
179
+ private Boolean fboAllowed = true;
180
+
181
+ // ........................................................
182
+
183
+ // Texture rendering
184
+
185
+ protected boolean loadedTex2DShader = false;
186
+ protected int tex2DShaderProgram;
187
+ protected int tex2DVertShader;
188
+ protected int tex2DFragShader;
189
+ protected int tex2DShaderContext;
190
+ protected int tex2DVertLoc;
191
+ protected int tex2DTCoordLoc;
192
+ protected int tex2DSamplerLoc;
193
+ protected int tex2DGeoVBO;
194
+
195
+ protected boolean loadedTexRectShader = false;
196
+ protected int texRectShaderProgram;
197
+ protected int texRectVertShader;
198
+ protected int texRectFragShader;
199
+ protected int texRectShaderContext;
200
+ protected int texRectVertLoc;
201
+ protected int texRectTCoordLoc;
202
+ protected int texRectSamplerLoc;
203
+ protected int texRectGeoVBO;
204
+
205
+ protected float[] texCoords = {
206
+ // X, Y, U, V
207
+ -1.0f, -1.0f, 0.0f, 0.0f,
208
+ +1.0f, -1.0f, 1.0f, 0.0f,
209
+ -1.0f, +1.0f, 0.0f, 1.0f,
210
+ +1.0f, +1.0f, 1.0f, 1.0f
211
+ };
212
+ protected FloatBuffer texData;
213
+
214
+ protected static final String SHADER_PREPROCESSOR_DIRECTIVE =
215
+ "#ifdef GL_ES\n" +
216
+ "precision mediump float;\n" +
217
+ "precision mediump int;\n" +
218
+ "#endif\n";
219
+
220
+ protected static String[] texVertShaderSource = {
221
+ "attribute vec2 position;",
222
+ "attribute vec2 texCoord;",
223
+ "varying vec2 vertTexCoord;",
224
+ "void main() {",
225
+ " gl_Position = vec4(position, 0, 1);",
226
+ " vertTexCoord = texCoord;",
227
+ "}"
228
+ };
229
+
230
+ protected static String[] tex2DFragShaderSource = {
231
+ SHADER_PREPROCESSOR_DIRECTIVE,
232
+ "uniform sampler2D texMap;",
233
+ "varying vec2 vertTexCoord;",
234
+ "void main() {",
235
+ " gl_FragColor = texture2D(texMap, vertTexCoord.st);",
236
+ "}"
237
+ };
238
+
239
+ protected static String[] texRectFragShaderSource = {
240
+ SHADER_PREPROCESSOR_DIRECTIVE,
241
+ "uniform sampler2DRect texMap;",
242
+ "varying vec2 vertTexCoord;",
243
+ "void main() {",
244
+ " gl_FragColor = texture2DRect(texMap, vertTexCoord.st);",
245
+ "}"
246
+ };
247
+
248
+ /** Which texturing targets are enabled */
249
+ protected boolean[] texturingTargets = { false, false };
250
+
251
+ /** Used to keep track of which textures are bound to each target */
252
+ protected int maxTexUnits;
253
+ protected int activeTexUnit = 0;
254
+ protected int[][] boundTextures;
255
+
256
+ // ........................................................
257
+
258
+ // Framerate handling
259
+
260
+ protected float targetFps = 60;
261
+ protected float currentFps = 60;
262
+ protected boolean setFps = false;
263
+
264
+ // ........................................................
265
+
266
+ // Utility buffers
267
+
268
+ protected ByteBuffer byteBuffer;
269
+ protected IntBuffer intBuffer;
270
+ protected IntBuffer viewBuffer;
271
+
272
+ protected IntBuffer colorBuffer;
273
+ protected FloatBuffer depthBuffer;
274
+ protected ByteBuffer stencilBuffer;
275
+
276
+ //........................................................
277
+
278
+ // Rendering information
279
+
280
+ /** Used to register amount of geometry rendered in each frame. */
281
+ protected int geomCount = 0;
282
+ protected int pgeomCount;
283
+
284
+ /** Used to register calls to background. */
285
+ protected boolean clearColor = false;
286
+ protected boolean pclearColor;
287
+
288
+ protected boolean clearDepth = false;
289
+ protected boolean pclearDepth;
290
+
291
+ protected boolean clearStencil = false;
292
+ protected boolean pclearStencil;
293
+
294
+
295
+ // ........................................................
296
+
297
+ // Error messages
298
+
299
+ public static final String WIKI =
300
+ " Read http://wiki.processing.org/w/OpenGL_Issues for help.";
301
+
302
+ public static final String FRAMEBUFFER_ERROR =
303
+ "Framebuffer error (%1$s), rendering will probably not work as expected" + WIKI;
304
+
305
+ public static final String MISSING_FBO_ERROR =
306
+ "Framebuffer objects are not supported by this hardware (or driver)" + WIKI;
307
+
308
+ public static final String MISSING_GLSL_ERROR =
309
+ "GLSL shaders are not supported by this hardware (or driver)" + WIKI;
310
+
311
+ public static final String MISSING_GLFUNC_ERROR =
312
+ "GL function %1$s is not available on this hardware (or driver)" + WIKI;
313
+
314
+ public static final String UNSUPPORTED_GLPROF_ERROR =
315
+ "Unsupported OpenGL profile.";
316
+
317
+ public static final String TEXUNIT_ERROR =
318
+ "Number of texture units not supported by this hardware (or driver)" + WIKI;
319
+
320
+ public static final String NONPRIMARY_ERROR =
321
+ "The renderer is trying to call a PGL function that can only be called on a primary PGL. " +
322
+ "This is most likely due to a bug in the renderer's code, please report it with an " +
323
+ "issue on Processing's github page https://github.com/processing/processing/issues?state=open " +
324
+ "if using any of the built-in OpenGL renderers. If you are using a contributed " +
325
+ "library, contact the library's developers.";
326
+
327
+ protected static final String DEPTH_READING_NOT_ENABLED_ERROR =
328
+ "Reading depth and stencil values from this multisampled buffer is not enabled. " +
329
+ "You can enable it by calling hint(ENABLE_DEPTH_READING) once. " +
330
+ "If your sketch becomes too slow, disable multisampling with noSmooth() instead.";
331
+
332
+ // ........................................................
333
+
334
+ // Constants
335
+
336
+ /** Size of different types in bytes */
337
+ protected static final int SIZEOF_SHORT = Short.SIZE / 8;
338
+ protected static int SIZEOF_INT = Integer.SIZE / 8;
339
+ protected static int SIZEOF_FLOAT = Float.SIZE / 8;
340
+ protected static int SIZEOF_BYTE = Byte.SIZE / 8;
341
+ protected static int SIZEOF_INDEX = SIZEOF_SHORT;
342
+ protected static int INDEX_TYPE = 0x1403; // GL_UNSIGNED_SHORT
343
+
344
+ /** Machine Epsilon for float precision. */
345
+ protected static float FLOAT_EPS = Float.MIN_VALUE;
346
+ // Calculation of the Machine Epsilon for float precision. From:
347
+ // http://en.wikipedia.org/wiki/Machine_epsilon#Approximation_using_Java
348
+ static {
349
+ float eps = 1.0f;
350
+
351
+ do {
352
+ eps /= 2.0f;
353
+ } while ((float)(1.0 + (eps / 2.0)) != 1.0);
354
+
355
+ FLOAT_EPS = eps;
356
+ }
357
+
358
+ /**
359
+ * Set to true if the host system is big endian (PowerPC, MIPS, SPARC), false
360
+ * if little endian (x86 Intel for Mac or PC).
361
+ */
362
+ protected static boolean BIG_ENDIAN =
363
+ ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
364
+
365
+ // ........................................................
366
+
367
+ // Present mode
368
+
369
+ // ........................................................
370
+
371
+ // Present mode
372
+
373
+ protected boolean presentMode = false;
374
+ protected boolean showStopButton = true;
375
+ public float presentX;
376
+ public float presentY;
377
+ protected IntBuffer closeButtonTex;
378
+ protected int stopButtonColor;
379
+ protected int stopButtonWidth = 28;
380
+ protected int stopButtonHeight = 12;
381
+ protected int stopButtonX = 21; // The position of the close button is relative to the
382
+ protected int closeButtonY = 21; // lower left corner
383
+ protected static int[] closeButtonPix = {
384
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
385
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
386
+ 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1, -1, 0, 0, 0, -1,
387
+ -1, -1, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0,
388
+ 0, 0, 0, -1, -1, 0, -1, -1, 0, 0, -1, -1, 0, -1, -1, 0, 0, -1, 0, 0, 0, 0, 0,
389
+ 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1,
390
+ -1, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1,
391
+ 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1,
392
+ 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, -1, 0, -1,
393
+ -1, 0, 0, -1, -1, 0, -1, -1, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 0, -1, -1, -1,
394
+ 0, 0, 0, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
395
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
396
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0,
397
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0};
398
+
399
+
400
+ ///////////////////////////////////////////////////////////////
401
+
402
+ // Initialization, finalization
403
+
404
+
405
+ public PGL() {
406
+ this.renderCallback = () -> {};
407
+ }
408
+
409
+
410
+ public PGL(PGraphicsOpenGL pg) {
411
+ this.graphics = pg;
412
+ this.renderCallback = () -> {};
413
+ initGraphics();
414
+ }
415
+
416
+
417
+ public PGL(PGraphicsOpenGL pg, RenderCallback newCallback) {
418
+ this.graphics = pg;
419
+ this.renderCallback = newCallback;
420
+ initGraphics();
421
+ }
422
+
423
+
424
+ private void initGraphics() {
425
+ if (glColorTex == null) {
426
+ glColorFbo = allocateIntBuffer(1);
427
+ glColorTex = allocateIntBuffer(2);
428
+ glDepthStencil = allocateIntBuffer(1);
429
+ glDepth = allocateIntBuffer(1);
430
+ glStencil = allocateIntBuffer(1);
431
+
432
+ glMultiFbo = allocateIntBuffer(1);
433
+ glMultiColor = allocateIntBuffer(1);
434
+ glMultiDepthStencil = allocateIntBuffer(1);
435
+ glMultiDepth = allocateIntBuffer(1);
436
+ glMultiStencil = allocateIntBuffer(1);
437
+ }
438
+
439
+ byteBuffer = allocateByteBuffer(1);
440
+ intBuffer = allocateIntBuffer(1);
441
+ viewBuffer = allocateIntBuffer(4);
442
+ }
443
+
444
+
445
+ public void dispose() {
446
+ destroyFBOLayer();
447
+ }
448
+
449
+
450
+ public void setPrimary(boolean primary) {
451
+ primaryPGL = primary;
452
+ }
453
+
454
+
455
+ static public int smoothToSamples(int smooth) {
456
+ switch (smooth) {
457
+ case 0:
458
+ // smooth(0) is noSmooth(), which is 1x sampling
459
+ return 1;
460
+ case 1:
461
+ // smooth(1) means "default smoothing", which is 2x for OpenGL
462
+ return 2;
463
+ default:
464
+ // smooth(N) can be used for 4x, 8x, etc
465
+ return smooth;
466
+ }
467
+ }
468
+
469
+
470
+ abstract public Object getNative();
471
+
472
+
473
+ abstract protected void setFrameRate(float fps);
474
+
475
+
476
+ abstract protected void initSurface(int antialias);
477
+
478
+
479
+ abstract protected void reinitSurface();
480
+
481
+
482
+ abstract protected void registerListeners();
483
+
484
+
485
+ abstract protected PImage screenshot();
486
+
487
+
488
+ protected int getReadFramebuffer() {
489
+ return fboLayerEnabled ? glColorFbo.get(0) : 0;
490
+ }
491
+
492
+
493
+ protected int getDrawFramebuffer() {
494
+ if (fboLayerEnabled) return 1 < numSamples ? glMultiFbo.get(0) :
495
+ glColorFbo.get(0);
496
+ else return 0;
497
+ }
498
+
499
+
500
+ protected int getDefaultDrawBuffer() {
501
+ return fboLayerEnabled ? COLOR_ATTACHMENT0 : BACK;
502
+ }
503
+
504
+
505
+ protected int getDefaultReadBuffer() {
506
+ return fboLayerEnabled ? COLOR_ATTACHMENT0 : FRONT;
507
+ }
508
+
509
+
510
+ protected boolean isFBOBacked() {
511
+ return fboLayerEnabled;
512
+ }
513
+
514
+
515
+ @Deprecated
516
+ public void requestFBOLayer() {
517
+ enableFBOLayer();
518
+ }
519
+
520
+
521
+ public void enableFBOLayer() {
522
+ fboLayerEnabledReq = true;
523
+ }
524
+
525
+
526
+ public void disableFBOLayer() {
527
+ fboLayerDisableReq = true;
528
+ }
529
+
530
+
531
+ public void resetFBOLayer() {
532
+ fbolayerResetReq = true;
533
+ }
534
+
535
+
536
+ protected boolean isMultisampled() {
537
+ return 1 < numSamples;
538
+ }
539
+
540
+
541
+ abstract protected int getDepthBits();
542
+
543
+
544
+ abstract protected int getStencilBits();
545
+
546
+
547
+ protected boolean getDepthTest() {
548
+ intBuffer.rewind();
549
+ getBooleanv(DEPTH_TEST, intBuffer);
550
+ return intBuffer.get(0) == 0 ? false : true;
551
+ }
552
+
553
+
554
+ protected boolean getDepthWriteMask() {
555
+ intBuffer.rewind();
556
+ getBooleanv(DEPTH_WRITEMASK, intBuffer);
557
+ return intBuffer.get(0) == 0 ? false : true;
558
+ }
559
+
560
+
561
+ protected Texture wrapBackTexture(Texture texture) {
562
+ if (texture == null) {
563
+ texture = new Texture(graphics);
564
+ texture.init(graphics.width, graphics.height,
565
+ glColorTex.get(backTex), TEXTURE_2D, RGBA,
566
+ fboWidth, fboHeight, NEAREST, NEAREST,
567
+ CLAMP_TO_EDGE, CLAMP_TO_EDGE);
568
+ texture.invertedY(true);
569
+ texture.colorBuffer(true);
570
+ graphics.setCache(graphics, texture);
571
+ } else {
572
+ texture.glName = glColorTex.get(backTex);
573
+ }
574
+ return texture;
575
+ }
576
+
577
+
578
+ protected Texture wrapFrontTexture(Texture texture) {
579
+ if (texture == null) {
580
+ texture = new Texture(graphics);
581
+ texture.init(graphics.width, graphics.height,
582
+ glColorTex.get(frontTex), TEXTURE_2D, RGBA,
583
+ fboWidth, fboHeight, NEAREST, NEAREST,
584
+ CLAMP_TO_EDGE, CLAMP_TO_EDGE);
585
+ texture.invertedY(true);
586
+ texture.colorBuffer(true);
587
+ } else {
588
+ texture.glName = glColorTex.get(frontTex);
589
+ }
590
+ return texture;
591
+ }
592
+
593
+
594
+ protected void bindFrontTexture() {
595
+ usingFrontTex = true;
596
+ if (!texturingIsEnabled(TEXTURE_2D)) {
597
+ enableTexturing(TEXTURE_2D);
598
+ }
599
+ bindTexture(TEXTURE_2D, glColorTex.get(frontTex));
600
+ }
601
+
602
+
603
+ protected void unbindFrontTexture() {
604
+ if (textureIsBound(TEXTURE_2D, glColorTex.get(frontTex))) {
605
+ // We don't want to unbind another texture
606
+ // that might be bound instead of this one.
607
+ if (!texturingIsEnabled(TEXTURE_2D)) {
608
+ enableTexturing(TEXTURE_2D);
609
+ bindTexture(TEXTURE_2D, 0);
610
+ disableTexturing(TEXTURE_2D);
611
+ } else {
612
+ bindTexture(TEXTURE_2D, 0);
613
+ }
614
+ }
615
+ }
616
+
617
+
618
+ protected void syncBackTexture() {
619
+ if (usingFrontTex) needSepFrontTex = true;
620
+ if (1 < numSamples) {
621
+ bindFramebufferImpl(READ_FRAMEBUFFER, glMultiFbo.get(0));
622
+ bindFramebufferImpl(DRAW_FRAMEBUFFER, glColorFbo.get(0));
623
+ int mask = COLOR_BUFFER_BIT;
624
+ if (graphics.getHint(PConstants.ENABLE_BUFFER_READING)) {
625
+ mask |= DEPTH_BUFFER_BIT | STENCIL_BUFFER_BIT;
626
+ }
627
+ blitFramebuffer(0, 0, fboWidth, fboHeight,
628
+ 0, 0, fboWidth, fboHeight,
629
+ mask, NEAREST);
630
+ }
631
+ }
632
+
633
+
634
+ abstract protected float getPixelScale();
635
+
636
+ ///////////////////////////////////////////////////////////
637
+
638
+ // Present mode
639
+
640
+
641
+ public void initPresentMode(float x, float y, int stopColor) {
642
+ presentMode = true;
643
+ showStopButton = stopColor != 0;
644
+ stopButtonColor = stopColor;
645
+ presentX = x;
646
+ presentY = y;
647
+ enableFBOLayer();
648
+ }
649
+
650
+
651
+ public boolean presentMode() {
652
+ return presentMode;
653
+ }
654
+
655
+
656
+ public float presentX() {
657
+ return presentX;
658
+ }
659
+
660
+
661
+ public float presentY() {
662
+ return presentY;
663
+ }
664
+
665
+
666
+ public boolean insideStopButton(float x, float y) {
667
+ if (!showStopButton) return false;
668
+ return stopButtonX < x && x < stopButtonX + stopButtonWidth &&
669
+ -(closeButtonY + stopButtonHeight) < y && y < -closeButtonY;
670
+ }
671
+
672
+
673
+ ///////////////////////////////////////////////////////////
674
+
675
+ // Frame rendering
676
+
677
+
678
+ protected void clearDepthStencil() {
679
+ if (!pclearDepth && !pclearStencil) {
680
+ depthMask(true);
681
+ clearDepth(1);
682
+ clearStencil(0);
683
+ clear(DEPTH_BUFFER_BIT | STENCIL_BUFFER_BIT);
684
+ } else if (!pclearDepth) {
685
+ depthMask(true);
686
+ clearDepth(1);
687
+ clear(DEPTH_BUFFER_BIT);
688
+ } else if (!pclearStencil) {
689
+ clearStencil(0);
690
+ clear(STENCIL_BUFFER_BIT);
691
+ }
692
+ }
693
+
694
+
695
+ protected void clearBackground(float r, float g, float b, float a,
696
+ boolean depth, boolean stencil) {
697
+ clearColor(r, g, b, a);
698
+ if (depth && stencil) {
699
+ clearDepth(1);
700
+ clearStencil(0);
701
+ clear(DEPTH_BUFFER_BIT | STENCIL_BUFFER_BIT | COLOR_BUFFER_BIT);
702
+ if (0 < sketch.frameCount) {
703
+ clearDepth = true;
704
+ clearStencil = true;
705
+ }
706
+ } else if (depth) {
707
+ clearDepth(1);
708
+ clear(DEPTH_BUFFER_BIT | COLOR_BUFFER_BIT);
709
+ if (0 < sketch.frameCount) {
710
+ clearDepth = true;
711
+ }
712
+ } else if (stencil) {
713
+ clearStencil(0);
714
+ clear(STENCIL_BUFFER_BIT | COLOR_BUFFER_BIT);
715
+ if (0 < sketch.frameCount) {
716
+ clearStencil = true;
717
+ }
718
+ } else {
719
+ clear(PGL.COLOR_BUFFER_BIT);
720
+ }
721
+ if (0 < sketch.frameCount) {
722
+ clearColor = true;
723
+ }
724
+ }
725
+
726
+
727
+ protected void beginRender() {
728
+ if (sketch == null) {
729
+ sketch = graphics.parent;
730
+ }
731
+
732
+ pgeomCount = geomCount;
733
+ geomCount = 0;
734
+
735
+ pclearColor = clearColor;
736
+ clearColor = false;
737
+
738
+ pclearDepth = clearDepth;
739
+ clearDepth = false;
740
+
741
+ pclearStencil = clearStencil;
742
+ clearStencil = false;
743
+
744
+ if (SINGLE_BUFFERED && sketch.frameCount == 1) {
745
+ restoreFirstFrame();
746
+ }
747
+
748
+ if (fboLayerEnabledReq) {
749
+ fboLayerEnabled = true;
750
+ fboLayerEnabledReq = false;
751
+ }
752
+
753
+ if (fboLayerEnabled) {
754
+ if (fbolayerResetReq) {
755
+ destroyFBOLayer();
756
+ fbolayerResetReq = false;
757
+ }
758
+ if (!fboLayerCreated) {
759
+ createFBOLayer();
760
+ }
761
+
762
+ // Draw to the back texture
763
+ bindFramebufferImpl(FRAMEBUFFER, glColorFbo.get(0));
764
+ framebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0,
765
+ TEXTURE_2D, glColorTex.get(backTex), 0);
766
+
767
+ if (1 < numSamples) {
768
+ bindFramebufferImpl(FRAMEBUFFER, glMultiFbo.get(0));
769
+ }
770
+
771
+ if (sketch.frameCount == 0) {
772
+ // No need to draw back color buffer because we are in the first frame.
773
+ int argb = graphics.backgroundColor;
774
+ float ba = ((argb >> 24) & 0xff) / 255.0f;
775
+ float br = ((argb >> 16) & 0xff) / 255.0f;
776
+ float bg = ((argb >> 8) & 0xff) / 255.0f;
777
+ float bb = ((argb) & 0xff) / 255.0f;
778
+ clearColor(br, bg, bb, ba);
779
+ clear(COLOR_BUFFER_BIT);
780
+ } else if (!pclearColor || !sketch.isLooping()) {
781
+ // Render previous back texture (now is the front) as background,
782
+ // because no background() is being used ("incremental drawing")
783
+ int x = 0;
784
+ int y = 0;
785
+ if (presentMode) {
786
+ x = (int)presentX;
787
+ y = (int)presentY;
788
+ }
789
+ float scale = getPixelScale();
790
+ drawTexture(TEXTURE_2D, glColorTex.get(frontTex), fboWidth, fboHeight,
791
+ x, y, graphics.width, graphics.height,
792
+ 0, 0, (int)(scale * graphics.width), (int)(scale * graphics.height),
793
+ 0, 0, graphics.width, graphics.height);
794
+ }
795
+ }
796
+ }
797
+
798
+
799
+ protected void endRender(int windowColor) {
800
+ if (fboLayerEnabled) {
801
+ syncBackTexture();
802
+
803
+ // Draw the contents of the back texture to the screen framebuffer.
804
+ bindFramebufferImpl(FRAMEBUFFER, 0);
805
+
806
+ if (presentMode) {
807
+ float wa = ((windowColor >> 24) & 0xff) / 255.0f;
808
+ float wr = ((windowColor >> 16) & 0xff) / 255.0f;
809
+ float wg = ((windowColor >> 8) & 0xff) / 255.0f;
810
+ float wb = (windowColor & 0xff) / 255.0f;
811
+ clearDepth(1);
812
+ clearColor(wr, wg, wb, wa);
813
+ clear(COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT);
814
+
815
+ if (showStopButton) {
816
+ if (closeButtonTex == null) {
817
+ closeButtonTex = allocateIntBuffer(1);
818
+ genTextures(1, closeButtonTex);
819
+ bindTexture(TEXTURE_2D, closeButtonTex.get(0));
820
+ texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, NEAREST);
821
+ texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, NEAREST);
822
+ texParameteri(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE);
823
+ texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE);
824
+ texImage2D(TEXTURE_2D, 0, RGBA, stopButtonWidth, stopButtonHeight, 0, RGBA, UNSIGNED_BYTE, null);
825
+
826
+ int[] color = new int[closeButtonPix.length];
827
+ PApplet.arrayCopy(closeButtonPix, color);
828
+
829
+
830
+ // Multiply the texture by the button color
831
+ float ba = ((stopButtonColor >> 24) & 0xFF) / 255f;
832
+ float br = ((stopButtonColor >> 16) & 0xFF) / 255f;
833
+ float bg = ((stopButtonColor >> 8) & 0xFF) / 255f;
834
+ float bb = ((stopButtonColor) & 0xFF) / 255f;
835
+ for (int i = 0; i < color.length; i++) {
836
+ int c = closeButtonPix[i];
837
+ int a = (int)(ba * ((c >> 24) & 0xFF));
838
+ int r = (int)(br * ((c >> 16) & 0xFF));
839
+ int g = (int)(bg * ((c >> 8) & 0xFF));
840
+ int b = (int)(bb * ((c) & 0xFF));
841
+ color[i] = javaToNativeARGB((a << 24) | (r << 16) | (g << 8) | b);
842
+ }
843
+ IntBuffer buf = allocateIntBuffer(color);
844
+ copyToTexture(TEXTURE_2D, RGBA, closeButtonTex.get(0), 0, 0, stopButtonWidth, stopButtonHeight, buf);
845
+ bindTexture(TEXTURE_2D, 0);
846
+ }
847
+ drawTexture(TEXTURE_2D, closeButtonTex.get(0), stopButtonWidth, stopButtonHeight,
848
+ 0, 0, stopButtonX + stopButtonWidth, closeButtonY + stopButtonHeight,
849
+ 0, stopButtonHeight, stopButtonWidth, 0,
850
+ stopButtonX, closeButtonY, stopButtonX + stopButtonWidth, closeButtonY + stopButtonHeight);
851
+ }
852
+ } else {
853
+ clearDepth(1);
854
+ clearColor(0, 0, 0, 0);
855
+ clear(COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT);
856
+ }
857
+
858
+ // Render current back texture to screen, without blending.
859
+ disable(BLEND);
860
+ int x = 0;
861
+ int y = 0;
862
+ if (presentMode) {
863
+ x = (int)presentX;
864
+ y = (int)presentY;
865
+ }
866
+ float scale = getPixelScale();
867
+ drawTexture(TEXTURE_2D, glColorTex.get(backTex),
868
+ fboWidth, fboHeight,
869
+ x, y, graphics.width, graphics.height,
870
+ 0, 0, (int)(scale * graphics.width), (int)(scale * graphics.height),
871
+ 0, 0, graphics.width, graphics.height);
872
+
873
+ // Swapping front and back textures.
874
+ int temp = frontTex;
875
+ frontTex = backTex;
876
+ backTex = temp;
877
+
878
+ if (fboLayerDisableReq) {
879
+ fboLayerEnabled = false;
880
+ fboLayerDisableReq = false;
881
+ }
882
+ } else {
883
+ if (SINGLE_BUFFERED && sketch.frameCount == 0) {
884
+ saveFirstFrame();
885
+ }
886
+
887
+ if (isFboAllowed()) {
888
+ if (!clearColor && 0 < sketch.frameCount || !sketch.isLooping()) {
889
+ enableFBOLayer();
890
+ if (SINGLE_BUFFERED) {
891
+ createFBOLayer();
892
+ }
893
+ }
894
+ }
895
+ }
896
+
897
+ renderCallback.onRender();
898
+ }
899
+
900
+
901
+ protected abstract void getGL(PGL pgl);
902
+
903
+
904
+ protected abstract boolean canDraw();
905
+
906
+
907
+ protected abstract void requestFocus();
908
+
909
+
910
+ protected abstract void requestDraw();
911
+
912
+
913
+ protected abstract void swapBuffers();
914
+
915
+
916
+ public boolean threadIsCurrent() {
917
+ return Thread.currentThread() == glThread;
918
+ }
919
+
920
+
921
+ public void setThread(Thread thread) {
922
+ glThread = thread;
923
+ }
924
+
925
+
926
+ protected void beginGL() { }
927
+
928
+
929
+ protected void endGL() { }
930
+
931
+
932
+ private void createFBOLayer() {
933
+ float scale = getPixelScale();
934
+
935
+ if (hasNpotTexSupport()) {
936
+ fboWidth = (int)(scale * graphics.width);
937
+ fboHeight = (int)(scale * graphics.height);
938
+ } else {
939
+ fboWidth = nextPowerOfTwo((int)(scale * graphics.width));
940
+ fboHeight = nextPowerOfTwo((int)(scale * graphics.height));
941
+ }
942
+
943
+ if (hasFboMultisampleSupport()) {
944
+ int maxs = maxSamples();
945
+ numSamples = PApplet.min(reqNumSamples, maxs);
946
+ } else {
947
+ numSamples = 1;
948
+ }
949
+ boolean multisample = 1 < numSamples;
950
+
951
+ boolean packed = hasPackedDepthStencilSupport();
952
+ int depthBits = PApplet.min(REQUESTED_DEPTH_BITS, getDepthBits());
953
+ int stencilBits = PApplet.min(REQUESTED_STENCIL_BITS, getStencilBits());
954
+
955
+ genTextures(2, glColorTex);
956
+ for (int i = 0; i < 2; i++) {
957
+ bindTexture(TEXTURE_2D, glColorTex.get(i));
958
+ texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, NEAREST);
959
+ texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, NEAREST);
960
+ texParameteri(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE);
961
+ texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE);
962
+ texImage2D(TEXTURE_2D, 0, RGBA, fboWidth, fboHeight, 0,
963
+ RGBA, UNSIGNED_BYTE, null);
964
+ initTexture(TEXTURE_2D, RGBA, fboWidth, fboHeight, graphics.backgroundColor);
965
+ }
966
+ bindTexture(TEXTURE_2D, 0);
967
+
968
+ backTex = 0;
969
+ frontTex = 1;
970
+
971
+ genFramebuffers(1, glColorFbo);
972
+ bindFramebufferImpl(FRAMEBUFFER, glColorFbo.get(0));
973
+ framebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0, TEXTURE_2D,
974
+ glColorTex.get(backTex), 0);
975
+
976
+ if (!multisample || graphics.getHint(PConstants.ENABLE_BUFFER_READING)) {
977
+ // If not multisampled, this is the only depth and stencil buffer.
978
+ // If multisampled and depth reading enabled, these are going to
979
+ // hold downsampled depth and stencil buffers.
980
+ createDepthAndStencilBuffer(false, depthBits, stencilBits, packed);
981
+ }
982
+
983
+ if (multisample) {
984
+ // Creating multisampled FBO
985
+ genFramebuffers(1, glMultiFbo);
986
+ bindFramebufferImpl(FRAMEBUFFER, glMultiFbo.get(0));
987
+
988
+ // color render buffer...
989
+ genRenderbuffers(1, glMultiColor);
990
+ bindRenderbuffer(RENDERBUFFER, glMultiColor.get(0));
991
+ renderbufferStorageMultisample(RENDERBUFFER, numSamples,
992
+ RGBA8, fboWidth, fboHeight);
993
+ framebufferRenderbuffer(FRAMEBUFFER, COLOR_ATTACHMENT0,
994
+ RENDERBUFFER, glMultiColor.get(0));
995
+
996
+ // Creating multisampled depth and stencil buffers
997
+ createDepthAndStencilBuffer(true, depthBits, stencilBits, packed);
998
+ }
999
+
1000
+ int status = validateFramebuffer();
1001
+
1002
+ if (status == FRAMEBUFFER_INCOMPLETE_MULTISAMPLE && 1 < numSamples) {
1003
+ System.err.println("Continuing with multisampling disabled");
1004
+ reqNumSamples = 1;
1005
+ destroyFBOLayer();
1006
+ // try again
1007
+ createFBOLayer();
1008
+ return;
1009
+ }
1010
+
1011
+ // Clear all buffers.
1012
+ clearDepth(1);
1013
+ clearStencil(0);
1014
+ int argb = graphics.backgroundColor;
1015
+ float ba = ((argb >> 24) & 0xff) / 255.0f;
1016
+ float br = ((argb >> 16) & 0xff) / 255.0f;
1017
+ float bg = ((argb >> 8) & 0xff) / 255.0f;
1018
+ float bb = ((argb) & 0xff) / 255.0f;
1019
+ clearColor(br, bg, bb, ba);
1020
+ clear(DEPTH_BUFFER_BIT | STENCIL_BUFFER_BIT | COLOR_BUFFER_BIT);
1021
+
1022
+ bindFramebufferImpl(FRAMEBUFFER, 0);
1023
+ initFBOLayer();
1024
+
1025
+ fboLayerCreated = true;
1026
+ }
1027
+
1028
+ protected abstract void initFBOLayer();
1029
+
1030
+
1031
+ protected void saveFirstFrame() {
1032
+ firstFrame = allocateDirectIntBuffer(graphics.width * graphics.height);
1033
+ if (hasReadBuffer()) readBuffer(BACK);
1034
+ readPixelsImpl(0, 0, graphics.width, graphics.height, RGBA, UNSIGNED_BYTE, firstFrame);
1035
+ }
1036
+
1037
+
1038
+ protected void restoreFirstFrame() {
1039
+ if (firstFrame == null) return;
1040
+
1041
+ IntBuffer tex = allocateIntBuffer(1);
1042
+ genTextures(1, tex);
1043
+
1044
+ int w, h;
1045
+ float scale = getPixelScale();
1046
+ if (hasNpotTexSupport()) {
1047
+ w = (int)(scale * graphics.width);
1048
+ h = (int)(scale * graphics.height);
1049
+ } else {
1050
+ w = nextPowerOfTwo((int)(scale * graphics.width));
1051
+ h = nextPowerOfTwo((int)(scale * graphics.height));
1052
+ }
1053
+
1054
+ bindTexture(TEXTURE_2D, tex.get(0));
1055
+ texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, NEAREST);
1056
+ texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, NEAREST);
1057
+ texParameteri(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE);
1058
+ texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE);
1059
+ texImage2D(TEXTURE_2D, 0, RGBA, w, h, 0, RGBA, UNSIGNED_BYTE, null);
1060
+ texSubImage2D(TEXTURE_2D, 0, 0, 0, graphics.width, graphics.height, RGBA, UNSIGNED_BYTE, firstFrame);
1061
+
1062
+ drawTexture(TEXTURE_2D, tex.get(0), w, h,
1063
+ 0, 0, graphics.width, graphics.height,
1064
+ 0, 0, (int)(scale * graphics.width), (int)(scale * graphics.height),
1065
+ 0, 0, graphics.width, graphics.height);
1066
+
1067
+ deleteTextures(1, tex);
1068
+ firstFrame.clear();
1069
+ firstFrame = null;
1070
+ }
1071
+
1072
+ protected void destroyFBOLayer() {
1073
+ if (threadIsCurrent() && fboLayerCreated) {
1074
+ deleteFramebuffers(1, glColorFbo);
1075
+ deleteTextures(2, glColorTex);
1076
+ deleteRenderbuffers(1, glDepthStencil);
1077
+ deleteRenderbuffers(1, glDepth);
1078
+ deleteRenderbuffers(1, glStencil);
1079
+
1080
+ deleteFramebuffers(1, glMultiFbo);
1081
+ deleteRenderbuffers(1, glMultiColor);
1082
+ deleteRenderbuffers(1, glMultiDepthStencil);
1083
+ deleteRenderbuffers(1, glMultiDepth);
1084
+ deleteRenderbuffers(1, glMultiStencil);
1085
+ }
1086
+ fboLayerCreated = false;
1087
+ }
1088
+
1089
+
1090
+ private void createDepthAndStencilBuffer(boolean multisample, int depthBits,
1091
+ int stencilBits, boolean packed) {
1092
+ // Creating depth and stencil buffers
1093
+ if (packed && depthBits == 24 && stencilBits == 8) {
1094
+ // packed depth+stencil buffer
1095
+ IntBuffer depthStencilBuf =
1096
+ multisample ? glMultiDepthStencil : glDepthStencil;
1097
+ genRenderbuffers(1, depthStencilBuf);
1098
+ bindRenderbuffer(RENDERBUFFER, depthStencilBuf.get(0));
1099
+ if (multisample) {
1100
+ renderbufferStorageMultisample(RENDERBUFFER, numSamples,
1101
+ DEPTH24_STENCIL8, fboWidth, fboHeight);
1102
+ } else {
1103
+ renderbufferStorage(RENDERBUFFER, DEPTH24_STENCIL8,
1104
+ fboWidth, fboHeight);
1105
+ }
1106
+ framebufferRenderbuffer(FRAMEBUFFER, DEPTH_ATTACHMENT, RENDERBUFFER,
1107
+ depthStencilBuf.get(0));
1108
+ framebufferRenderbuffer(FRAMEBUFFER, STENCIL_ATTACHMENT, RENDERBUFFER,
1109
+ depthStencilBuf.get(0));
1110
+ } else {
1111
+ // separate depth and stencil buffers
1112
+ if (0 < depthBits) {
1113
+ int depthComponent = DEPTH_COMPONENT16;
1114
+ switch (depthBits) {
1115
+ case 32:
1116
+ depthComponent = DEPTH_COMPONENT32;
1117
+ break;
1118
+ case 24:
1119
+ depthComponent = DEPTH_COMPONENT24;
1120
+ break;
1121
+ case 16:
1122
+ depthComponent = DEPTH_COMPONENT16;
1123
+ break;
1124
+ default:
1125
+ break;
1126
+ }
1127
+
1128
+ IntBuffer depthBuf = multisample ? glMultiDepth : glDepth;
1129
+ genRenderbuffers(1, depthBuf);
1130
+ bindRenderbuffer(RENDERBUFFER, depthBuf.get(0));
1131
+ if (multisample) {
1132
+ renderbufferStorageMultisample(RENDERBUFFER, numSamples,
1133
+ depthComponent, fboWidth, fboHeight);
1134
+ } else {
1135
+ renderbufferStorage(RENDERBUFFER, depthComponent,
1136
+ fboWidth, fboHeight);
1137
+ }
1138
+ framebufferRenderbuffer(FRAMEBUFFER, DEPTH_ATTACHMENT,
1139
+ RENDERBUFFER, depthBuf.get(0));
1140
+ }
1141
+
1142
+ if (0 < stencilBits) {
1143
+ int stencilIndex = STENCIL_INDEX1;
1144
+ switch (stencilBits) {
1145
+ case 8:
1146
+ stencilIndex = STENCIL_INDEX8;
1147
+ break;
1148
+ case 4:
1149
+ stencilIndex = STENCIL_INDEX4;
1150
+ break;
1151
+ case 1:
1152
+ stencilIndex = STENCIL_INDEX1;
1153
+ break;
1154
+ default:
1155
+ break;
1156
+ }
1157
+
1158
+ IntBuffer stencilBuf = multisample ? glMultiStencil : glStencil;
1159
+ genRenderbuffers(1, stencilBuf);
1160
+ bindRenderbuffer(RENDERBUFFER, stencilBuf.get(0));
1161
+ if (multisample) {
1162
+ renderbufferStorageMultisample(RENDERBUFFER, numSamples,
1163
+ stencilIndex, fboWidth, fboHeight);
1164
+ } else {
1165
+ renderbufferStorage(RENDERBUFFER, stencilIndex,
1166
+ fboWidth, fboHeight);
1167
+ }
1168
+ framebufferRenderbuffer(FRAMEBUFFER, STENCIL_ATTACHMENT,
1169
+ RENDERBUFFER, stencilBuf.get(0));
1170
+ }
1171
+ }
1172
+ }
1173
+
1174
+
1175
+ ///////////////////////////////////////////////////////////
1176
+
1177
+ // Context interface
1178
+
1179
+
1180
+ protected int createEmptyContext() {
1181
+ return -1;
1182
+ }
1183
+
1184
+
1185
+ protected int getCurrentContext() {
1186
+ return glContext;
1187
+ }
1188
+
1189
+
1190
+ ///////////////////////////////////////////////////////////
1191
+
1192
+ // Utility functions
1193
+
1194
+
1195
+ protected boolean contextIsCurrent(int other) {
1196
+ return other == -1 || other == glContext;
1197
+ }
1198
+
1199
+
1200
+ protected void enableTexturing(int target) {
1201
+ if (target == TEXTURE_2D) {
1202
+ texturingTargets[0] = true;
1203
+ } else if (target == TEXTURE_RECTANGLE) {
1204
+ texturingTargets[1] = true;
1205
+ }
1206
+ }
1207
+
1208
+
1209
+ protected void disableTexturing(int target) {
1210
+ if (target == TEXTURE_2D) {
1211
+ texturingTargets[0] = false;
1212
+ } else if (target == TEXTURE_RECTANGLE) {
1213
+ texturingTargets[1] = false;
1214
+ }
1215
+ }
1216
+
1217
+
1218
+ protected boolean texturingIsEnabled(int target) {
1219
+ if (target == TEXTURE_2D) {
1220
+ return texturingTargets[0];
1221
+ } else if (target == TEXTURE_RECTANGLE) {
1222
+ return texturingTargets[1];
1223
+ } else {
1224
+ return false;
1225
+ }
1226
+ }
1227
+
1228
+
1229
+ protected boolean textureIsBound(int target, int id) {
1230
+ if (boundTextures == null) return false;
1231
+
1232
+ if (target == TEXTURE_2D) {
1233
+ return boundTextures[activeTexUnit][0] == id;
1234
+ } else if (target == TEXTURE_RECTANGLE) {
1235
+ return boundTextures[activeTexUnit][1] == id;
1236
+ } else {
1237
+ return false;
1238
+ }
1239
+ }
1240
+
1241
+
1242
+ protected void initTexture(int target, int format, int width, int height) {
1243
+ initTexture(target, format, width, height, 0);
1244
+ }
1245
+
1246
+
1247
+ protected void initTexture(int target, int format, int width, int height,
1248
+ int initColor) {
1249
+ int[] glcolor = new int[16 * 16];
1250
+ Arrays.fill(glcolor, javaToNativeARGB(initColor));
1251
+ IntBuffer texels = allocateDirectIntBuffer(16 * 16);
1252
+ texels.put(glcolor);
1253
+ texels.rewind();
1254
+ for (int y = 0; y < height; y += 16) {
1255
+ int h = PApplet.min(16, height - y);
1256
+ for (int x = 0; x < width; x += 16) {
1257
+ int w = PApplet.min(16, width - x);
1258
+ texSubImage2D(target, 0, x, y, w, h, format, UNSIGNED_BYTE, texels);
1259
+ }
1260
+ }
1261
+ }
1262
+
1263
+
1264
+ protected void copyToTexture(int target, int format, int id, int x, int y,
1265
+ int w, int h, int[] buffer) {
1266
+ copyToTexture(target, format, id, x, y, w, h, IntBuffer.wrap(buffer));
1267
+
1268
+ }
1269
+
1270
+ protected void copyToTexture(int target, int format, int id, int x, int y,
1271
+ int w, int h, IntBuffer buffer) {
1272
+ activeTexture(TEXTURE0);
1273
+ boolean enabledTex = false;
1274
+ if (!texturingIsEnabled(target)) {
1275
+ enableTexturing(target);
1276
+ enabledTex = true;
1277
+ }
1278
+ bindTexture(target, id);
1279
+ texSubImage2D(target, 0, x, y, w, h, format, UNSIGNED_BYTE, buffer);
1280
+ bindTexture(target, 0);
1281
+ if (enabledTex) {
1282
+ disableTexturing(target);
1283
+ }
1284
+ }
1285
+
1286
+
1287
+ /**
1288
+ * Not an approved function, this will change or be removed in the future.
1289
+ */
1290
+ public void drawTexture(int target, int id, int width, int height,
1291
+ int X0, int Y0, int X1, int Y1) {
1292
+ // If a texture is drawing on a viewport of the same size as its resolution,
1293
+ // the pixel factor is 1:1, so we override the surface's pixel factor.
1294
+ drawTexture(target, id, width, height,
1295
+ 0, 0, width, height, 1,
1296
+ X0, Y0, X1, Y1,
1297
+ X0, Y0, X1, Y1);
1298
+ }
1299
+
1300
+
1301
+ /**
1302
+ * Not an approved function, this will change or be removed in the future.
1303
+ */
1304
+ public void drawTexture(int target, int id,int texW, int texH,
1305
+ int viewX, int viewY, int viewW, int viewH,
1306
+ int texX0, int texY0, int texX1, int texY1,
1307
+ int scrX0, int scrY0, int scrX1, int scrY1) {
1308
+ int viewF = (int)getPixelScale();
1309
+ drawTexture(target, id, texW, texH,
1310
+ viewX, viewY, viewW, viewH, viewF,
1311
+ texX0, texY0, texX1, texY1,
1312
+ scrX0, scrY0, scrX1, scrY1);
1313
+ }
1314
+
1315
+
1316
+ public void drawTexture(int target, int id,int texW, int texH,
1317
+ int viewX, int viewY, int viewW, int viewH, int viewF,
1318
+ int texX0, int texY0, int texX1, int texY1,
1319
+ int scrX0, int scrY0, int scrX1, int scrY1) {
1320
+ if (target == TEXTURE_2D) {
1321
+ drawTexture2D(id, texW, texH,
1322
+ viewX, viewY, viewW, viewH, viewF,
1323
+ texX0, texY0, texX1, texY1,
1324
+ scrX0, scrY0, scrX1, scrY1);
1325
+ } else if (target == TEXTURE_RECTANGLE) {
1326
+ drawTextureRect(id, texW, texH,
1327
+ viewX, viewY, viewW, viewH, viewF,
1328
+ texX0, texY0, texX1, texY1,
1329
+ scrX0, scrY0, scrX1, scrY1);
1330
+ }
1331
+ }
1332
+
1333
+
1334
+ protected PGL initTex2DShader() {
1335
+ PGL ppgl = primaryPGL ? this : graphics.getPrimaryPGL();
1336
+
1337
+ if (!ppgl.loadedTex2DShader || ppgl.tex2DShaderContext != ppgl.glContext) {
1338
+ String[] preprocVertSrc = preprocessVertexSource(texVertShaderSource, getGLSLVersion(), getGLSLVersionSuffix());
1339
+ String vertSource = PApplet.join(preprocVertSrc, "\n");
1340
+ String[] preprocFragSrc = preprocessFragmentSource(tex2DFragShaderSource, getGLSLVersion(), getGLSLVersionSuffix());
1341
+ String fragSource = PApplet.join(preprocFragSrc, "\n");
1342
+ ppgl.tex2DVertShader = createShader(VERTEX_SHADER, vertSource);
1343
+ ppgl.tex2DFragShader = createShader(FRAGMENT_SHADER, fragSource);
1344
+ if (0 < ppgl.tex2DVertShader && 0 < ppgl.tex2DFragShader) {
1345
+ ppgl.tex2DShaderProgram = createProgram(ppgl.tex2DVertShader, ppgl.tex2DFragShader);
1346
+ }
1347
+ if (0 < ppgl.tex2DShaderProgram) {
1348
+ ppgl.tex2DVertLoc = getAttribLocation(ppgl.tex2DShaderProgram, "position");
1349
+ ppgl.tex2DTCoordLoc = getAttribLocation(ppgl.tex2DShaderProgram, "texCoord");
1350
+ ppgl.tex2DSamplerLoc = getUniformLocation(ppgl.tex2DShaderProgram, "texMap");
1351
+ }
1352
+ ppgl.loadedTex2DShader = true;
1353
+ ppgl.tex2DShaderContext = ppgl.glContext;
1354
+
1355
+ genBuffers(1, intBuffer);
1356
+ ppgl.tex2DGeoVBO = intBuffer.get(0);
1357
+ bindBuffer(ARRAY_BUFFER, ppgl.tex2DGeoVBO);
1358
+ bufferData(ARRAY_BUFFER, 16 * SIZEOF_FLOAT, null, STATIC_DRAW);
1359
+ }
1360
+
1361
+ if (texData == null) {
1362
+ texData = allocateDirectFloatBuffer(texCoords.length);
1363
+ }
1364
+
1365
+ return ppgl;
1366
+ }
1367
+
1368
+
1369
+ protected void drawTexture2D(int id, int texW, int texH,
1370
+ int viewX, int viewY, int viewW, int viewH, int viewF,
1371
+ int texX0, int texY0, int texX1, int texY1,
1372
+ int scrX0, int scrY0, int scrX1, int scrY1) {
1373
+ PGL ppgl = initTex2DShader();
1374
+
1375
+ if (0 < ppgl.tex2DShaderProgram) {
1376
+ // The texture overwrites anything drawn earlier.
1377
+ boolean depthTest = getDepthTest();
1378
+ disable(DEPTH_TEST);
1379
+
1380
+ // When drawing the texture we don't write to the
1381
+ // depth mask, so the texture remains in the background
1382
+ // and can be occluded by anything drawn later, even if
1383
+ // if it is behind it.
1384
+ boolean depthMask = getDepthWriteMask();
1385
+ depthMask(false);
1386
+
1387
+ // Making sure that the viewport matches the provided screen dimensions
1388
+ viewBuffer.rewind();
1389
+ getIntegerv(VIEWPORT, viewBuffer);
1390
+ viewportImpl(viewF * viewX, viewF * viewY, viewF * viewW, viewF * viewH);
1391
+
1392
+ useProgram(ppgl.tex2DShaderProgram);
1393
+
1394
+ enableVertexAttribArray(ppgl.tex2DVertLoc);
1395
+ enableVertexAttribArray(ppgl.tex2DTCoordLoc);
1396
+
1397
+ // Vertex coordinates of the textured quad are specified
1398
+ // in normalized screen space (-1, 1):
1399
+ // Corner 1
1400
+ texCoords[ 0] = 2 * (float)scrX0 / viewW - 1;
1401
+ texCoords[ 1] = 2 * (float)scrY0 / viewH - 1;
1402
+ texCoords[ 2] = (float)texX0 / texW;
1403
+ texCoords[ 3] = (float)texY0 / texH;
1404
+ // Corner 2
1405
+ texCoords[ 4] = 2 * (float)scrX1 / viewW - 1;
1406
+ texCoords[ 5] = 2 * (float)scrY0 / viewH - 1;
1407
+ texCoords[ 6] = (float)texX1 / texW;
1408
+ texCoords[ 7] = (float)texY0 / texH;
1409
+ // Corner 3
1410
+ texCoords[ 8] = 2 * (float)scrX0 / viewW - 1;
1411
+ texCoords[ 9] = 2 * (float)scrY1 / viewH - 1;
1412
+ texCoords[10] = (float)texX0 / texW;
1413
+ texCoords[11] = (float)texY1 / texH;
1414
+ // Corner 4
1415
+ texCoords[12] = 2 * (float)scrX1 / viewW - 1;
1416
+ texCoords[13] = 2 * (float)scrY1 / viewH - 1;
1417
+ texCoords[14] = (float)texX1 / texW;
1418
+ texCoords[15] = (float)texY1 / texH;
1419
+
1420
+ texData.rewind();
1421
+ texData.put(texCoords);
1422
+
1423
+ activeTexture(TEXTURE0);
1424
+ boolean enabledTex = false;
1425
+ if (!texturingIsEnabled(TEXTURE_2D)) {
1426
+ enableTexturing(TEXTURE_2D);
1427
+ enabledTex = true;
1428
+ }
1429
+ bindTexture(TEXTURE_2D, id);
1430
+ uniform1i(ppgl.tex2DSamplerLoc, 0);
1431
+
1432
+ texData.position(0);
1433
+ bindBuffer(ARRAY_BUFFER, ppgl.tex2DGeoVBO);
1434
+ bufferData(ARRAY_BUFFER, 16 * SIZEOF_FLOAT, texData, STATIC_DRAW);
1435
+
1436
+ vertexAttribPointer(ppgl.tex2DVertLoc, 2, FLOAT, false, 4 * SIZEOF_FLOAT, 0);
1437
+ vertexAttribPointer(ppgl.tex2DTCoordLoc, 2, FLOAT, false, 4 * SIZEOF_FLOAT, 2 * SIZEOF_FLOAT);
1438
+
1439
+ drawArrays(TRIANGLE_STRIP, 0, 4);
1440
+
1441
+ bindBuffer(ARRAY_BUFFER, 0); // Making sure that no VBO is bound at this point.
1442
+
1443
+ bindTexture(TEXTURE_2D, 0);
1444
+ if (enabledTex) {
1445
+ disableTexturing(TEXTURE_2D);
1446
+ }
1447
+
1448
+ disableVertexAttribArray(ppgl.tex2DVertLoc);
1449
+ disableVertexAttribArray(ppgl.tex2DTCoordLoc);
1450
+
1451
+ useProgram(0);
1452
+
1453
+ if (depthTest) {
1454
+ enable(DEPTH_TEST);
1455
+ } else {
1456
+ disable(DEPTH_TEST);
1457
+ }
1458
+ depthMask(depthMask);
1459
+
1460
+ viewportImpl(viewBuffer.get(0), viewBuffer.get(1),
1461
+ viewBuffer.get(2), viewBuffer.get(3));
1462
+ }
1463
+ }
1464
+
1465
+
1466
+ protected PGL initTexRectShader() {
1467
+ PGL ppgl = primaryPGL ? this : graphics.getPrimaryPGL();
1468
+
1469
+ if (!ppgl.loadedTexRectShader || ppgl.texRectShaderContext != ppgl.glContext) {
1470
+ String[] preprocVertSrc = preprocessVertexSource(texVertShaderSource, getGLSLVersion(), getGLSLVersionSuffix());
1471
+ String vertSource = PApplet.join(preprocVertSrc, "\n");
1472
+ String[] preprocFragSrc = preprocessFragmentSource(texRectFragShaderSource, getGLSLVersion(), getGLSLVersionSuffix());
1473
+ String fragSource = PApplet.join(preprocFragSrc, "\n");
1474
+ ppgl.texRectVertShader = createShader(VERTEX_SHADER, vertSource);
1475
+ ppgl.texRectFragShader = createShader(FRAGMENT_SHADER, fragSource);
1476
+ if (0 < ppgl.texRectVertShader && 0 < ppgl.texRectFragShader) {
1477
+ ppgl.texRectShaderProgram = createProgram(ppgl.texRectVertShader,
1478
+ ppgl.texRectFragShader);
1479
+ }
1480
+ if (0 < ppgl.texRectShaderProgram) {
1481
+ ppgl.texRectVertLoc = getAttribLocation(ppgl.texRectShaderProgram, "position");
1482
+ ppgl.texRectTCoordLoc = getAttribLocation(ppgl.texRectShaderProgram, "texCoord");
1483
+ ppgl.texRectSamplerLoc = getUniformLocation(ppgl.texRectShaderProgram, "texMap");
1484
+ }
1485
+ ppgl.loadedTexRectShader = true;
1486
+ ppgl.texRectShaderContext = ppgl.glContext;
1487
+
1488
+ genBuffers(1, intBuffer);
1489
+ ppgl.texRectGeoVBO = intBuffer.get(0);
1490
+ bindBuffer(ARRAY_BUFFER, ppgl.texRectGeoVBO);
1491
+ bufferData(ARRAY_BUFFER, 16 * SIZEOF_FLOAT, null, STATIC_DRAW);
1492
+ }
1493
+
1494
+ return ppgl;
1495
+ }
1496
+
1497
+
1498
+ protected void drawTextureRect(int id, int texW, int texH,
1499
+ int viewX, int viewY, int viewW, int viewH, int viewF,
1500
+ int texX0, int texY0, int texX1, int texY1,
1501
+ int scrX0, int scrY0, int scrX1, int scrY1) {
1502
+ PGL ppgl = initTexRectShader();
1503
+
1504
+ if (texData == null) {
1505
+ texData = allocateDirectFloatBuffer(texCoords.length);
1506
+ }
1507
+
1508
+ if (0 < ppgl.texRectShaderProgram) {
1509
+ // The texture overwrites anything drawn earlier.
1510
+ boolean depthTest = getDepthTest();
1511
+ disable(DEPTH_TEST);
1512
+
1513
+ // When drawing the texture we don't write to the
1514
+ // depth mask, so the texture remains in the background
1515
+ // and can be occluded by anything drawn later, even if
1516
+ // if it is behind it.
1517
+ boolean depthMask = getDepthWriteMask();
1518
+ depthMask(false);
1519
+
1520
+ // Making sure that the viewport matches the provided screen dimensions
1521
+ viewBuffer.rewind();
1522
+ getIntegerv(VIEWPORT, viewBuffer);
1523
+ viewportImpl(viewF * viewX, viewF * viewY, viewF * viewW, viewF * viewH);
1524
+
1525
+ useProgram(ppgl.texRectShaderProgram);
1526
+
1527
+ enableVertexAttribArray(ppgl.texRectVertLoc);
1528
+ enableVertexAttribArray(ppgl.texRectTCoordLoc);
1529
+
1530
+ // Vertex coordinates of the textured quad are specified
1531
+ // in normalized screen space (-1, 1):
1532
+ // Corner 1
1533
+ texCoords[ 0] = 2 * (float)scrX0 / viewW - 1;
1534
+ texCoords[ 1] = 2 * (float)scrY0 / viewH - 1;
1535
+ texCoords[ 2] = texX0;
1536
+ texCoords[ 3] = texY0;
1537
+ // Corner 2
1538
+ texCoords[ 4] = 2 * (float)scrX1 / viewW - 1;
1539
+ texCoords[ 5] = 2 * (float)scrY0 / viewH - 1;
1540
+ texCoords[ 6] = texX1;
1541
+ texCoords[ 7] = texY0;
1542
+ // Corner 3
1543
+ texCoords[ 8] = 2 * (float)scrX0 / viewW - 1;
1544
+ texCoords[ 9] = 2 * (float)scrY1 / viewH - 1;
1545
+ texCoords[10] = texX0;
1546
+ texCoords[11] = texY1;
1547
+ // Corner 4
1548
+ texCoords[12] = 2 * (float)scrX1 / viewW - 1;
1549
+ texCoords[13] = 2 * (float)scrY1 / viewH - 1;
1550
+ texCoords[14] = texX1;
1551
+ texCoords[15] = texY1;
1552
+
1553
+ texData.rewind();
1554
+ texData.put(texCoords);
1555
+
1556
+ activeTexture(TEXTURE0);
1557
+ boolean enabledTex = false;
1558
+ if (!texturingIsEnabled(TEXTURE_RECTANGLE)) {
1559
+ enableTexturing(TEXTURE_RECTANGLE);
1560
+ enabledTex = true;
1561
+ }
1562
+ bindTexture(TEXTURE_RECTANGLE, id);
1563
+ uniform1i(ppgl.texRectSamplerLoc, 0);
1564
+
1565
+ texData.position(0);
1566
+ bindBuffer(ARRAY_BUFFER, ppgl.texRectGeoVBO);
1567
+ bufferData(ARRAY_BUFFER, 16 * SIZEOF_FLOAT, texData, STATIC_DRAW);
1568
+
1569
+ vertexAttribPointer(ppgl.texRectVertLoc, 2, FLOAT, false, 4 * SIZEOF_FLOAT, 0);
1570
+ vertexAttribPointer(ppgl.texRectTCoordLoc, 2, FLOAT, false, 4 * SIZEOF_FLOAT, 2 * SIZEOF_FLOAT);
1571
+
1572
+ drawArrays(TRIANGLE_STRIP, 0, 4);
1573
+
1574
+ bindBuffer(ARRAY_BUFFER, 0); // Making sure that no VBO is bound at this point.
1575
+
1576
+ bindTexture(TEXTURE_RECTANGLE, 0);
1577
+ if (enabledTex) {
1578
+ disableTexturing(TEXTURE_RECTANGLE);
1579
+ }
1580
+
1581
+ disableVertexAttribArray(ppgl.texRectVertLoc);
1582
+ disableVertexAttribArray(ppgl.texRectTCoordLoc);
1583
+
1584
+ useProgram(0);
1585
+
1586
+ if (depthTest) {
1587
+ enable(DEPTH_TEST);
1588
+ } else {
1589
+ disable(DEPTH_TEST);
1590
+ }
1591
+ depthMask(depthMask);
1592
+
1593
+ viewportImpl(viewBuffer.get(0), viewBuffer.get(1),
1594
+ viewBuffer.get(2), viewBuffer.get(3));
1595
+ }
1596
+ }
1597
+
1598
+
1599
+ protected int getColorValue(int scrX, int scrY) {
1600
+ if (colorBuffer == null) {
1601
+ colorBuffer = IntBuffer.allocate(1);
1602
+ }
1603
+ colorBuffer.rewind();
1604
+ readPixels(scrX, graphics.height - scrY - 1, 1, 1, RGBA, UNSIGNED_BYTE,
1605
+ colorBuffer);
1606
+ return colorBuffer.get();
1607
+ }
1608
+
1609
+
1610
+ protected float getDepthValue(int scrX, int scrY) {
1611
+ if (depthBuffer == null) {
1612
+ depthBuffer = FloatBuffer.allocate(1);
1613
+ }
1614
+ depthBuffer.rewind();
1615
+ readPixels(scrX, graphics.height - scrY - 1, 1, 1, DEPTH_COMPONENT, FLOAT,
1616
+ depthBuffer);
1617
+ return depthBuffer.get(0);
1618
+ }
1619
+
1620
+
1621
+ protected byte getStencilValue(int scrX, int scrY) {
1622
+ if (stencilBuffer == null) {
1623
+ stencilBuffer = ByteBuffer.allocate(1);
1624
+ }
1625
+ stencilBuffer.rewind();
1626
+ readPixels(scrX, graphics.height - scrY - 1, 1, 1, STENCIL_INDEX,
1627
+ UNSIGNED_BYTE, stencilBuffer);
1628
+ return stencilBuffer.get(0);
1629
+ }
1630
+
1631
+
1632
+ protected static boolean isPowerOfTwo(int val) {
1633
+ return (val & (val - 1)) == 0;
1634
+ }
1635
+
1636
+
1637
+ // bit shifting this might be more efficient
1638
+ protected static int nextPowerOfTwo(int val) {
1639
+ int ret = 1;
1640
+ while (ret < val) ret <<= 1;
1641
+ return ret;
1642
+ }
1643
+
1644
+
1645
+ /**
1646
+ * Converts input native OpenGL value (RGBA on big endian, ABGR on little
1647
+ * endian) to Java ARGB.
1648
+ * @param color
1649
+ * @return
1650
+ */
1651
+ protected static int nativeToJavaARGB(int color) {
1652
+ if (BIG_ENDIAN) { // RGBA to ARGB
1653
+ return (color >>> 8) | (color << 24);
1654
+ } else { // ABGR to ARGB
1655
+ int rb = color & 0x00FF00FF;
1656
+ return (color & 0xFF00FF00) | (rb << 16) | (rb >> 16);
1657
+ }
1658
+ }
1659
+
1660
+
1661
+ /**
1662
+ * Converts input array of native OpenGL values (RGBA on big endian, ABGR on
1663
+ * little endian) representing an image of width x height resolution to Java
1664
+ * ARGB. It also rearranges the elements in the array so that the image is
1665
+ * flipped vertically.
1666
+ */
1667
+ protected static void nativeToJavaARGB(int[] pixels, int width, int height) {
1668
+ int index = 0;
1669
+ int yindex = (height - 1) * width;
1670
+ for (int y = 0; y < height / 2; y++) {
1671
+ for (int x = 0; x < width; x++) {
1672
+ int pixy = pixels[yindex];
1673
+ int pixi = pixels[index];
1674
+ if (BIG_ENDIAN) { // RGBA to ARGB
1675
+ pixels[index] = (pixy >>> 8) | (pixy << 24);
1676
+ pixels[yindex] = (pixi >>> 8) | (pixi << 24);
1677
+ } else { // ABGR to ARGB
1678
+ int rbi = pixi & 0x00FF00FF;
1679
+ int rby = pixy & 0x00FF00FF;
1680
+ pixels[index] = (pixy & 0xFF00FF00) | (rby << 16) | (rby >> 16);
1681
+ pixels[yindex] = (pixi & 0xFF00FF00) | (rbi << 16) | (rbi >> 16);
1682
+ }
1683
+ index++;
1684
+ yindex++;
1685
+ }
1686
+ yindex -= width * 2;
1687
+ }
1688
+
1689
+ if ((height % 2) == 1) { // Converts center row
1690
+ index = (height / 2) * width;
1691
+ for (int x = 0; x < width; x++) {
1692
+ int pixi = pixels[index];
1693
+ if (BIG_ENDIAN) { // RGBA to ARGB
1694
+ pixels[index] = (pixi >>> 8) | (pixi << 24);
1695
+ } else { // ABGR to ARGB
1696
+ int rbi = pixi & 0x00FF00FF;
1697
+ pixels[index] = (pixi & 0xFF00FF00) | (rbi << 16) | (rbi >> 16);
1698
+ }
1699
+ index++;
1700
+ }
1701
+ }
1702
+ }
1703
+
1704
+
1705
+ /**
1706
+ * Converts input native OpenGL value (RGBA on big endian, ABGR on little
1707
+ * endian) to Java RGB, so that the alpha component of the result is set
1708
+ * to opaque (255).
1709
+ */
1710
+ protected static int nativeToJavaRGB(int color) {
1711
+ if (BIG_ENDIAN) { // RGBA to ARGB
1712
+ return (color >>> 8) | 0xFF000000;
1713
+ } else { // ABGR to ARGB
1714
+ int rb = color & 0x00FF00FF;
1715
+ return 0xFF000000 | (rb << 16) |
1716
+ (color & 0x0000FF00) | (rb >> 16);
1717
+ }
1718
+ }
1719
+
1720
+
1721
+ /**
1722
+ * Converts input array of native OpenGL values (RGBA on big endian, ABGR on
1723
+ * little endian) representing an image of width x height resolution to Java
1724
+ * RGB, so that the alpha component of all pixels is set to opaque (255). It
1725
+ * also rearranges the elements in the array so that the image is flipped
1726
+ * vertically.
1727
+ */
1728
+ protected static void nativeToJavaRGB(int[] pixels, int width, int height) {
1729
+ int index = 0;
1730
+ int yindex = (height - 1) * width;
1731
+ for (int y = 0; y < height / 2; y++) {
1732
+ for (int x = 0; x < width; x++) {
1733
+ int pixy = pixels[yindex];
1734
+ int pixi = pixels[index];
1735
+ if (BIG_ENDIAN) { // RGBA to ARGB
1736
+ pixels[index] = (pixy >>> 8) | 0xFF000000;
1737
+ pixels[yindex] = (pixi >>> 8) | 0xFF000000;
1738
+ } else { // ABGR to ARGB
1739
+ int rbi = pixi & 0x00FF00FF;
1740
+ int rby = pixy & 0x00FF00FF;
1741
+ pixels[index] = 0xFF000000 | (rby << 16) |
1742
+ (pixy & 0x0000FF00) | (rby >> 16);
1743
+ pixels[yindex] = 0xFF000000 | (rbi << 16) |
1744
+ (pixi & 0x0000FF00) | (rbi >> 16);
1745
+ }
1746
+ index++;
1747
+ yindex++;
1748
+ }
1749
+ yindex -= width * 2;
1750
+ }
1751
+
1752
+ if ((height % 2) == 1) { // Converts center row
1753
+ index = (height / 2) * width;
1754
+ for (int x = 0; x < width; x++) {
1755
+ int pixi = pixels[index];
1756
+ if (BIG_ENDIAN) { // RGBA to ARGB
1757
+ pixels[index] = (pixi >>> 8) | 0xFF000000;
1758
+ } else { // ABGR to ARGB
1759
+ int rbi = pixi & 0x00FF00FF;
1760
+ pixels[index] = 0xFF000000 | (rbi << 16) |
1761
+ (pixi & 0x000FF00) | (rbi >> 16);
1762
+ }
1763
+ index++;
1764
+ }
1765
+ }
1766
+ }
1767
+
1768
+
1769
+ /**
1770
+ * Converts input Java ARGB value to native OpenGL format (RGBA on big endian,
1771
+ * BGRA on little endian).
1772
+ */
1773
+ protected static int javaToNativeARGB(int color) {
1774
+ if (BIG_ENDIAN) { // ARGB to RGBA
1775
+ return (color >>> 24) | (color << 8);
1776
+ } else { // ARGB to ABGR
1777
+ int rb = color & 0x00FF00FF;
1778
+ return (color & 0xFF00FF00) | (rb << 16) | (rb >> 16);
1779
+ }
1780
+ }
1781
+
1782
+
1783
+ /**
1784
+ * Converts input array of Java ARGB values representing an image of width x
1785
+ * height resolution to native OpenGL format (RGBA on big endian, BGRA on
1786
+ * little endian). It also rearranges the elements in the array so that the
1787
+ * image is flipped vertically.
1788
+ */
1789
+ protected static void javaToNativeARGB(int[] pixels, int width, int height) {
1790
+ int index = 0;
1791
+ int yindex = (height - 1) * width;
1792
+ for (int y = 0; y < height / 2; y++) {
1793
+ for (int x = 0; x < width; x++) {
1794
+ int pixy = pixels[yindex];
1795
+ int pixi = pixels[index];
1796
+ if (BIG_ENDIAN) { // ARGB to RGBA
1797
+ pixels[index] = (pixy >>> 24) | (pixy << 8);
1798
+ pixels[yindex] = (pixi >>> 24) | (pixi << 8);
1799
+ } else { // ARGB to ABGR
1800
+ int rbi = pixi & 0x00FF00FF;
1801
+ int rby = pixy & 0x00FF00FF;
1802
+ pixels[index] = (pixy & 0xFF00FF00) | (rby << 16) | (rby >> 16);
1803
+ pixels[yindex] = (pixi & 0xFF00FF00) | (rbi << 16) | (rbi >> 16);
1804
+ }
1805
+ index++;
1806
+ yindex++;
1807
+ }
1808
+ yindex -= width * 2;
1809
+ }
1810
+
1811
+ if ((height % 2) == 1) { // Converts center row
1812
+ index = (height / 2) * width;
1813
+ for (int x = 0; x < width; x++) {
1814
+ int pixi = pixels[index];
1815
+ if (BIG_ENDIAN) { // ARGB to RGBA
1816
+ pixels[index] = (pixi >>> 24) | (pixi << 8);
1817
+ } else { // ARGB to ABGR
1818
+ int rbi = pixi & 0x00FF00FF;
1819
+ pixels[index] = (pixi & 0xFF00FF00) | (rbi << 16) | (rbi >> 16);
1820
+ }
1821
+ index++;
1822
+ }
1823
+ }
1824
+ }
1825
+
1826
+ /**
1827
+ * Converts input Java ARGB value to native OpenGL format (RGBA on big endian,
1828
+ * BGRA on little endian), setting alpha component to opaque (255).
1829
+ * @param color
1830
+ * @return
1831
+ */
1832
+ protected static int javaToNativeRGB(int color) {
1833
+ if (BIG_ENDIAN) { // ARGB to RGB
1834
+ return 0xFF | (color << 8);
1835
+ } else { // ARGB to BGR
1836
+ int rb = color & 0x00FF00FF;
1837
+ return 0xFF000000 | (rb << 16) | (color & 0x0000FF00) | (rb >> 16);
1838
+ }
1839
+ }
1840
+
1841
+
1842
+ /**
1843
+ * Converts input array of Java ARGB values representing an image of width x
1844
+ * height resolution to native OpenGL format (RGBA on big endian, BGRA on
1845
+ * little endian), while setting alpha component of all pixels to opaque
1846
+ * (255). It also rearranges the elements in the array so that the image is
1847
+ * flipped vertically.
1848
+ */
1849
+ protected static void javaToNativeRGB(int[] pixels, int width, int height) {
1850
+ int index = 0;
1851
+ int yindex = (height - 1) * width;
1852
+ for (int y = 0; y < height / 2; y++) {
1853
+ for (int x = 0; x < width; x++) {
1854
+ int pixy = pixels[yindex];
1855
+ int pixi = pixels[index];
1856
+ if (BIG_ENDIAN) { // ARGB to RGB
1857
+ pixels[index] = 0xFF | (pixy << 8);
1858
+ pixels[yindex] = 0xFF | (pixi << 8);
1859
+ } else { // ARGB to BGR
1860
+ int rbi = pixi & 0x00FF00FF;
1861
+ int rby = pixy & 0x00FF00FF;
1862
+ pixels[index] = 0xFF000000 | (rby << 16) |
1863
+ (pixy & 0x0000FF00) | (rby >> 16);
1864
+ pixels[yindex] = 0xFF000000 | (rbi << 16) |
1865
+ (pixi & 0x0000FF00) | (rbi >> 16);
1866
+ }
1867
+ index++;
1868
+ yindex++;
1869
+ }
1870
+ yindex -= width * 2;
1871
+ }
1872
+
1873
+ if ((height % 2) == 1) { // Converts center row
1874
+ index = (height / 2) * width;
1875
+ for (int x = 0; x < width; x++) {
1876
+ int pixi = pixels[index];
1877
+ if (BIG_ENDIAN) { // ARGB to RGB
1878
+ pixels[index] = 0xFF | (pixi << 8);
1879
+ } else { // ARGB to BGR
1880
+ int rbi = pixi & 0x00FF00FF;
1881
+ pixels[index] = 0xFF000000 | (rbi << 16) |
1882
+ (pixi & 0x0000FF00) | (rbi >> 16);
1883
+ }
1884
+ index++;
1885
+ }
1886
+ }
1887
+ }
1888
+
1889
+
1890
+ protected static int qualityToSamples(int quality) {
1891
+ if (quality <= 1) {
1892
+ return 1;
1893
+ } else {
1894
+ // Number of samples is always an even number:
1895
+ int n = 2 * (quality / 2);
1896
+ return n;
1897
+ }
1898
+ }
1899
+
1900
+
1901
+ abstract protected int getGLSLVersion();
1902
+ abstract protected String getGLSLVersionSuffix();
1903
+
1904
+
1905
+ protected String[] loadVertexShader(String filename) {
1906
+ return sketch.loadStrings(filename);
1907
+ }
1908
+
1909
+
1910
+ protected String[] loadFragmentShader(String filename) {
1911
+ return sketch.loadStrings(filename);
1912
+ }
1913
+
1914
+
1915
+ protected String[] loadFragmentShader(URL url) {
1916
+ try {
1917
+ return PApplet.loadStrings(url.openStream());
1918
+ } catch (IOException e) {
1919
+ PGraphics.showException("Cannot load fragment shader " + url.getFile());
1920
+ }
1921
+ return null;
1922
+ }
1923
+
1924
+
1925
+ protected String[] loadVertexShader(URL url) {
1926
+ try {
1927
+ return PApplet.loadStrings(url.openStream());
1928
+ } catch (IOException e) {
1929
+ PGraphics.showException("Cannot load vertex shader " + url.getFile());
1930
+ }
1931
+ return null;
1932
+ }
1933
+
1934
+
1935
+ protected String[] loadVertexShader(String filename, int version, String versionSuffix) {
1936
+ return loadVertexShader(filename);
1937
+ }
1938
+
1939
+
1940
+ protected String[] loadFragmentShader(String filename, int version, String versionSuffix) {
1941
+ return loadFragmentShader(filename);
1942
+ }
1943
+
1944
+
1945
+ protected String[] loadFragmentShader(URL url, int version, String versionSuffix) {
1946
+ return loadFragmentShader(url);
1947
+ }
1948
+
1949
+
1950
+ protected String[] loadVertexShader(URL url, int version, String versionSuffix) {
1951
+ return loadVertexShader(url);
1952
+ }
1953
+
1954
+
1955
+ protected static String[] preprocessFragmentSource(String[] fragSrc0,
1956
+ int version,
1957
+ String versionSuffix) {
1958
+ if (containsVersionDirective(fragSrc0)) {
1959
+ // The user knows what she or he is doing
1960
+ return fragSrc0;
1961
+ }
1962
+
1963
+ String[] fragSrc;
1964
+
1965
+ if (version < 130) {
1966
+ Pattern[] search = { };
1967
+ String[] replace = { };
1968
+ int offset = 1;
1969
+
1970
+ fragSrc = preprocessShaderSource(fragSrc0, search, replace, offset);
1971
+ fragSrc[0] = "#version " + version + versionSuffix;
1972
+ } else {
1973
+ // We need to replace 'texture' uniform by 'texMap' uniform and
1974
+ // 'textureXXX()' functions by 'texture()' functions. Order of these
1975
+ // replacements is important to prevent collisions between these two.
1976
+ Pattern[] search = new Pattern[] {
1977
+ Pattern.compile(String.format(GLSL_ID_REGEX, "varying|attribute")),
1978
+ Pattern.compile(String.format(GLSL_ID_REGEX, "texture")),
1979
+ Pattern.compile(String.format(GLSL_FN_REGEX, "texture2DRect|texture2D|texture3D|textureCube")),
1980
+ Pattern.compile(String.format(GLSL_ID_REGEX, "gl_FragColor"))
1981
+ };
1982
+ String[] replace = new String[] {
1983
+ "in", "texMap", "texture", "_fragColor"
1984
+ };
1985
+ int offset = 2;
1986
+
1987
+ fragSrc = preprocessShaderSource(fragSrc0, search, replace, offset);
1988
+ fragSrc[0] = "#version " + version + versionSuffix;
1989
+ if (" es".equals(versionSuffix)) {
1990
+ fragSrc[1] = "out mediump vec4 _fragColor;";
1991
+ } else {
1992
+ fragSrc[1] = "out vec4 _fragColor;";
1993
+ }
1994
+ }
1995
+
1996
+ return fragSrc;
1997
+ }
1998
+
1999
+ protected static String[] preprocessVertexSource(String[] vertSrc0,
2000
+ int version,
2001
+ String versionSuffix) {
2002
+ if (containsVersionDirective(vertSrc0)) {
2003
+ // The user knows what she or he is doing
2004
+ return vertSrc0;
2005
+ }
2006
+
2007
+ String[] vertSrc;
2008
+
2009
+ if (version < 130) {
2010
+ Pattern[] search = { };
2011
+ String[] replace = { };
2012
+ int offset = 1;
2013
+
2014
+ vertSrc = preprocessShaderSource(vertSrc0, search, replace, offset);
2015
+ vertSrc[0] = "#version " + version + versionSuffix;
2016
+ } else {
2017
+ // We need to replace 'texture' uniform by 'texMap' uniform and
2018
+ // 'textureXXX()' functions by 'texture()' functions. Order of these
2019
+ // replacements is important to prevent collisions between these two.
2020
+ Pattern[] search = new Pattern[] {
2021
+ Pattern.compile(String.format(GLSL_ID_REGEX, "varying")),
2022
+ Pattern.compile(String.format(GLSL_ID_REGEX, "attribute")),
2023
+ Pattern.compile(String.format(GLSL_ID_REGEX, "texture")),
2024
+ Pattern.compile(String.format(GLSL_FN_REGEX, "texture2DRect|texture2D|texture3D|textureCube"))
2025
+ };
2026
+ String[] replace = new String[] {
2027
+ "out", "in", "texMap", "texture",
2028
+ };
2029
+ int offset = 1;
2030
+
2031
+ vertSrc = preprocessShaderSource(vertSrc0, search, replace, offset);
2032
+ vertSrc[0] = "#version " + version + versionSuffix;
2033
+ }
2034
+
2035
+ return vertSrc;
2036
+ }
2037
+
2038
+
2039
+ protected static final String GLSL_ID_REGEX = "(?<![0-9A-Z_a-z])(%s)(?![0-9A-Z_a-z]|\\s*\\()";
2040
+ protected static final String GLSL_FN_REGEX = "(?<![0-9A-Z_a-z])(%s)(?=\\s*\\()";
2041
+
2042
+
2043
+ protected static String[] preprocessShaderSource(String[] src0,
2044
+ Pattern[] search,
2045
+ String[] replace,
2046
+ int offset) {
2047
+ String[] src = new String[src0.length+offset];
2048
+ for (int i = 0; i < src0.length; i++) {
2049
+ String line = src0[i];
2050
+ int versionIndex = line.indexOf("#version");
2051
+ if (versionIndex >= 0) {
2052
+ line = line.substring(0, versionIndex);
2053
+ }
2054
+ for (int j = 0; j < search.length; j++) {
2055
+ line = search[j].matcher(line).replaceAll(replace[j]);
2056
+ }
2057
+ src[i+offset] = line;
2058
+ }
2059
+ return src;
2060
+ }
2061
+
2062
+ protected static boolean containsVersionDirective(String[] shSrc) {
2063
+ for (String line : shSrc) {
2064
+ int versionIndex = line.indexOf("#version");
2065
+ if (versionIndex >= 0) {
2066
+ int commentIndex = line.indexOf("//");
2067
+ if (commentIndex < 0 || versionIndex < commentIndex) {
2068
+ return true;
2069
+ }
2070
+ }
2071
+ }
2072
+ return false;
2073
+ }
2074
+
2075
+ protected int createShader(int shaderType, String source) {
2076
+ int shader = createShader(shaderType);
2077
+ if (shader != 0) {
2078
+ shaderSource(shader, source);
2079
+ compileShader(shader);
2080
+ if (!compiled(shader)) {
2081
+ System.err.println("Could not compile shader " + shaderType + ":");
2082
+ System.err.println(getShaderInfoLog(shader));
2083
+ deleteShader(shader);
2084
+ shader = 0;
2085
+ }
2086
+ }
2087
+ return shader;
2088
+ }
2089
+
2090
+
2091
+ protected int createProgram(int vertexShader, int fragmentShader) {
2092
+ int program = createProgram();
2093
+ if (program != 0) {
2094
+ attachShader(program, vertexShader);
2095
+ attachShader(program, fragmentShader);
2096
+ linkProgram(program);
2097
+ if (!linked(program)) {
2098
+ System.err.println("Could not link program: ");
2099
+ System.err.println(getProgramInfoLog(program));
2100
+ deleteProgram(program);
2101
+ program = 0;
2102
+ }
2103
+ }
2104
+ return program;
2105
+ }
2106
+
2107
+
2108
+ protected boolean compiled(int shader) {
2109
+ intBuffer.rewind();
2110
+ getShaderiv(shader, COMPILE_STATUS, intBuffer);
2111
+ return intBuffer.get(0) != 0;
2112
+ }
2113
+
2114
+
2115
+ protected boolean linked(int program) {
2116
+ intBuffer.rewind();
2117
+ getProgramiv(program, LINK_STATUS, intBuffer);
2118
+ return intBuffer.get(0) != 0;
2119
+ }
2120
+
2121
+
2122
+ protected int validateFramebuffer() {
2123
+ int status = checkFramebufferStatus(FRAMEBUFFER);
2124
+ if (status == FRAMEBUFFER_COMPLETE) {
2125
+ return 0;
2126
+ } else if (status == FRAMEBUFFER_UNDEFINED) {
2127
+ System.err.println(String.format(FRAMEBUFFER_ERROR,
2128
+ "framebuffer undefined"));
2129
+ } else if (status == FRAMEBUFFER_INCOMPLETE_ATTACHMENT) {
2130
+ System.err.println(String.format(FRAMEBUFFER_ERROR,
2131
+ "incomplete attachment"));
2132
+ } else if (status == FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) {
2133
+ System.err.println(String.format(FRAMEBUFFER_ERROR,
2134
+ "incomplete missing attachment"));
2135
+ } else if (status == FRAMEBUFFER_INCOMPLETE_DIMENSIONS) {
2136
+ System.err.println(String.format(FRAMEBUFFER_ERROR,
2137
+ "incomplete dimensions"));
2138
+ } else if (status == FRAMEBUFFER_INCOMPLETE_FORMATS) {
2139
+ System.err.println(String.format(FRAMEBUFFER_ERROR,
2140
+ "incomplete formats"));
2141
+ } else if (status == FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER) {
2142
+ System.err.println(String.format(FRAMEBUFFER_ERROR,
2143
+ "incomplete draw buffer"));
2144
+ } else if (status == FRAMEBUFFER_INCOMPLETE_READ_BUFFER) {
2145
+ System.err.println(String.format(FRAMEBUFFER_ERROR,
2146
+ "incomplete read buffer"));
2147
+ } else if (status == FRAMEBUFFER_UNSUPPORTED) {
2148
+ System.err.println(String.format(FRAMEBUFFER_ERROR,
2149
+ "framebuffer unsupported"));
2150
+ } else if (status == FRAMEBUFFER_INCOMPLETE_MULTISAMPLE) {
2151
+ System.err.println(String.format(FRAMEBUFFER_ERROR,
2152
+ "incomplete multisample buffer"));
2153
+ } else if (status == FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS) {
2154
+ System.err.println(String.format(FRAMEBUFFER_ERROR,
2155
+ "incomplete layer targets"));
2156
+ } else {
2157
+ System.err.println(String.format(FRAMEBUFFER_ERROR,
2158
+ "unknown error " + status));
2159
+ }
2160
+ return status;
2161
+ }
2162
+
2163
+ protected boolean isES() {
2164
+ return getString(VERSION).trim().toLowerCase().contains("opengl es");
2165
+ }
2166
+
2167
+ protected int[] getGLVersion() {
2168
+ String version = getString(VERSION).trim().toLowerCase();
2169
+
2170
+ String ES = "opengl es";
2171
+ int esPosition = version.indexOf(ES);
2172
+ if (esPosition >= 0) {
2173
+ version = version.substring(esPosition + ES.length()).trim();
2174
+ }
2175
+
2176
+ int[] res = {0, 0, 0};
2177
+ String[] parts = version.split(" ");
2178
+ for (String part : parts) {
2179
+ if (0 < part.indexOf(".")) {
2180
+ String[] nums = part.split("\\.");
2181
+ try {
2182
+ res[0] = Integer.parseInt(nums[0]);
2183
+ } catch (NumberFormatException e) { }
2184
+ if (1 < nums.length) {
2185
+ try {
2186
+ res[1] = Integer.parseInt(nums[1]);
2187
+ } catch (NumberFormatException e) { }
2188
+ }
2189
+ if (2 < nums.length) {
2190
+ try {
2191
+ res[2] = Integer.parseInt(nums[2]);
2192
+ } catch (NumberFormatException e) { }
2193
+ }
2194
+ break;
2195
+ }
2196
+ }
2197
+ return res;
2198
+ }
2199
+
2200
+
2201
+ protected boolean hasFBOs() {
2202
+ // FBOs might still be available through extensions.
2203
+ int major = getGLVersion()[0];
2204
+ if (major < 2) {
2205
+ String ext = getString(EXTENSIONS);
2206
+ return ext.contains("_framebuffer_object") &&
2207
+ ext.contains("_vertex_shader") &&
2208
+ ext.contains("_shader_objects") &&
2209
+ ext.contains("_shading_language");
2210
+ } else {
2211
+ return true;
2212
+ }
2213
+ }
2214
+
2215
+
2216
+ protected boolean hasShaders() {
2217
+ // GLSL might still be available through extensions. For instance,
2218
+ // GLContext.hasGLSL() gives false for older intel integrated chipsets on
2219
+ // OSX, where OpenGL is 1.4 but shaders are available.
2220
+ int major = getGLVersion()[0];
2221
+ if (major < 2) {
2222
+ String ext = getString(EXTENSIONS);
2223
+ return ext.contains("_fragment_shader") &&
2224
+ ext.contains("_vertex_shader") &&
2225
+ ext.contains("_shader_objects") &&
2226
+ ext.contains("_shading_language");
2227
+ } else {
2228
+ return true;
2229
+ }
2230
+ }
2231
+
2232
+
2233
+ protected boolean hasNpotTexSupport() {
2234
+ int major = getGLVersion()[0];
2235
+ if (major < 3) {
2236
+ String ext = getString(EXTENSIONS);
2237
+ if (isES()) {
2238
+ return -1 < ext.indexOf("_texture_npot");
2239
+ } else {
2240
+ return -1 < ext.indexOf("_texture_non_power_of_two");
2241
+ }
2242
+ } else {
2243
+ return true;
2244
+ }
2245
+ }
2246
+
2247
+
2248
+ protected boolean hasAutoMipmapGenSupport() {
2249
+ int major = getGLVersion()[0];
2250
+ if (isES() && major >= 2) {
2251
+ return true;
2252
+ } else if (!isES() && major >= 3) {
2253
+ return true;
2254
+ } else {
2255
+ String ext = getString(EXTENSIONS);
2256
+ return -1 < ext.indexOf("_generate_mipmap");
2257
+ }
2258
+ }
2259
+
2260
+
2261
+ protected boolean hasFboMultisampleSupport() {
2262
+ int major = getGLVersion()[0];
2263
+ if (major < 3) {
2264
+ String ext = getString(EXTENSIONS);
2265
+ return -1 < ext.indexOf("_framebuffer_multisample");
2266
+ } else {
2267
+ return true;
2268
+ }
2269
+ }
2270
+
2271
+
2272
+ protected boolean hasPackedDepthStencilSupport() {
2273
+ int major = getGLVersion()[0];
2274
+ if (major < 3) {
2275
+ String ext = getString(EXTENSIONS);
2276
+ return -1 < ext.indexOf("_packed_depth_stencil");
2277
+ } else {
2278
+ return true;
2279
+ }
2280
+ }
2281
+
2282
+
2283
+ protected boolean hasAnisoSamplingSupport() {
2284
+ int major = getGLVersion()[0];
2285
+ if (isES() || major < 3) {
2286
+ String ext = getString(EXTENSIONS);
2287
+ return -1 < ext.indexOf("_texture_filter_anisotropic");
2288
+ } else {
2289
+ return true;
2290
+ }
2291
+ }
2292
+
2293
+
2294
+ protected boolean hasSynchronization() {
2295
+ int[] version = getGLVersion();
2296
+ if (isES()) {
2297
+ return version[0] >= 3;
2298
+ }
2299
+ return (version[0] > 3) || (version[0] == 3 && version[1] >= 2);
2300
+ }
2301
+
2302
+
2303
+ protected boolean hasPBOs() {
2304
+ int[] version = getGLVersion();
2305
+ if (isES()) {
2306
+ return version[0] >= 3;
2307
+ }
2308
+ return (version[0] > 2) || (version[0] == 2 && version[1] >= 1);
2309
+ }
2310
+
2311
+
2312
+ protected boolean hasReadBuffer() {
2313
+ int[] version = getGLVersion();
2314
+ if (isES()) {
2315
+ return version[0] >= 3;
2316
+ }
2317
+ return version[0] >= 2;
2318
+ }
2319
+
2320
+
2321
+ protected boolean hasDrawBuffer() {
2322
+ int[] version = getGLVersion();
2323
+ if (isES()) {
2324
+ return version[0] >= 3;
2325
+ }
2326
+ return version[0] >= 2;
2327
+ }
2328
+
2329
+
2330
+ protected int maxSamples() {
2331
+ intBuffer.rewind();
2332
+ getIntegerv(MAX_SAMPLES, intBuffer);
2333
+ return intBuffer.get(0);
2334
+ }
2335
+
2336
+
2337
+ protected int getMaxTexUnits() {
2338
+ intBuffer.rewind();
2339
+ getIntegerv(MAX_TEXTURE_IMAGE_UNITS, intBuffer);
2340
+ return intBuffer.get(0);
2341
+ }
2342
+
2343
+
2344
+ public boolean isFboAllowed() {
2345
+ if (fboAllowed == null) {
2346
+ if (PApplet.platform == PConstants.MACOS) {
2347
+ try {
2348
+ String hardware = getString(PGL.RENDERER);
2349
+ if (hardware != null && hardware.contains("Intel HD Graphics 3000")) {
2350
+ fboAllowed = false;
2351
+ return false;
2352
+ }
2353
+ } catch (RuntimeException e) {
2354
+ System.err.println("Could not read renderer name. FBOs disabled. Reason: " + e);
2355
+ // disable for now, but will try again on next isFboAllowed() call
2356
+ return false;
2357
+ }
2358
+ }
2359
+ // all other scenarios allow for FBOs
2360
+ fboAllowed = true;
2361
+ }
2362
+ return fboAllowed;
2363
+ }
2364
+
2365
+
2366
+ protected static ByteBuffer allocateDirectByteBuffer(int size) {
2367
+ int bytes = PApplet.max(MIN_DIRECT_BUFFER_SIZE, size) * SIZEOF_BYTE;
2368
+ return ByteBuffer.allocateDirect(bytes).order(ByteOrder.nativeOrder());
2369
+ }
2370
+
2371
+
2372
+ protected static ByteBuffer allocateByteBuffer(int size) {
2373
+ if (USE_DIRECT_BUFFERS) {
2374
+ return allocateDirectByteBuffer(size);
2375
+ } else {
2376
+ return ByteBuffer.allocate(size);
2377
+ }
2378
+ }
2379
+
2380
+
2381
+ protected static ByteBuffer allocateByteBuffer(byte[] arr) {
2382
+ if (USE_DIRECT_BUFFERS) {
2383
+ ByteBuffer buf = allocateDirectByteBuffer(arr.length);
2384
+ buf.put(arr);
2385
+ buf.position(0);
2386
+ return buf;
2387
+ } else {
2388
+ return ByteBuffer.wrap(arr);
2389
+ }
2390
+ }
2391
+
2392
+
2393
+ protected static ByteBuffer updateByteBuffer(ByteBuffer buf, byte[] arr,
2394
+ boolean wrap) {
2395
+ if (USE_DIRECT_BUFFERS) {
2396
+ if (buf == null || buf.capacity() < arr.length) {
2397
+ buf = allocateDirectByteBuffer(arr.length);
2398
+ }
2399
+ buf.position(0);
2400
+ buf.put(arr);
2401
+ buf.rewind();
2402
+ } else {
2403
+ if (wrap) {
2404
+ buf = ByteBuffer.wrap(arr);
2405
+ } else {
2406
+ if (buf == null || buf.capacity() < arr.length) {
2407
+ buf = ByteBuffer.allocate(arr.length);
2408
+ }
2409
+ buf.position(0);
2410
+ buf.put(arr);
2411
+ buf.rewind();
2412
+ }
2413
+ }
2414
+ return buf;
2415
+ }
2416
+
2417
+
2418
+ protected static void updateByteBuffer(ByteBuffer buf, byte[] arr,
2419
+ int offset, int size) {
2420
+ if (USE_DIRECT_BUFFERS || (buf.hasArray() && buf.array() != arr)) {
2421
+ buf.position(offset);
2422
+ buf.put(arr, offset, size);
2423
+ buf.rewind();
2424
+ }
2425
+ }
2426
+
2427
+
2428
+ protected static void getByteArray(ByteBuffer buf, byte[] arr) {
2429
+ if (!buf.hasArray() || buf.array() != arr) {
2430
+ buf.position(0);
2431
+ buf.get(arr);
2432
+ buf.rewind();
2433
+ }
2434
+ }
2435
+
2436
+
2437
+ protected static void putByteArray(ByteBuffer buf, byte[] arr) {
2438
+ if (!buf.hasArray() || buf.array() != arr) {
2439
+ buf.position(0);
2440
+ buf.put(arr);
2441
+ buf.rewind();
2442
+ }
2443
+ }
2444
+
2445
+
2446
+ protected static void fillByteBuffer(ByteBuffer buf, int i0, int i1,
2447
+ byte val) {
2448
+ int n = i1 - i0;
2449
+ byte[] temp = new byte[n];
2450
+ Arrays.fill(temp, 0, n, val);
2451
+ buf.position(i0);
2452
+ buf.put(temp, 0, n);
2453
+ buf.rewind();
2454
+ }
2455
+
2456
+
2457
+ protected static ShortBuffer allocateDirectShortBuffer(int size) {
2458
+ int bytes = PApplet.max(MIN_DIRECT_BUFFER_SIZE, size) * SIZEOF_SHORT;
2459
+ return ByteBuffer.allocateDirect(bytes).order(ByteOrder.nativeOrder()).
2460
+ asShortBuffer();
2461
+ }
2462
+
2463
+
2464
+ protected static ShortBuffer allocateShortBuffer(int size) {
2465
+ if (USE_DIRECT_BUFFERS) {
2466
+ return allocateDirectShortBuffer(size);
2467
+ } else {
2468
+ return ShortBuffer.allocate(size);
2469
+ }
2470
+ }
2471
+
2472
+
2473
+ protected static ShortBuffer allocateShortBuffer(short[] arr) {
2474
+ if (USE_DIRECT_BUFFERS) {
2475
+ ShortBuffer buf = allocateDirectShortBuffer(arr.length);
2476
+ buf.put(arr);
2477
+ buf.position(0);
2478
+ return buf;
2479
+ } else {
2480
+ return ShortBuffer.wrap(arr);
2481
+ }
2482
+ }
2483
+
2484
+
2485
+ protected static ShortBuffer updateShortBuffer(ShortBuffer buf, short[] arr,
2486
+ boolean wrap) {
2487
+ if (USE_DIRECT_BUFFERS) {
2488
+ if (buf == null || buf.capacity() < arr.length) {
2489
+ buf = allocateDirectShortBuffer(arr.length);
2490
+ }
2491
+ buf.position(0);
2492
+ buf.put(arr);
2493
+ buf.rewind();
2494
+ } else {
2495
+ if (wrap) {
2496
+ buf = ShortBuffer.wrap(arr);
2497
+ } else {
2498
+ if (buf == null || buf.capacity() < arr.length) {
2499
+ buf = ShortBuffer.allocate(arr.length);
2500
+ }
2501
+ buf.position(0);
2502
+ buf.put(arr);
2503
+ buf.rewind();
2504
+ }
2505
+ }
2506
+ return buf;
2507
+ }
2508
+
2509
+
2510
+ protected static void updateShortBuffer(ShortBuffer buf, short[] arr,
2511
+ int offset, int size) {
2512
+ if (USE_DIRECT_BUFFERS || (buf.hasArray() && buf.array() != arr)) {
2513
+ buf.position(offset);
2514
+ buf.put(arr, offset, size);
2515
+ buf.rewind();
2516
+ }
2517
+ }
2518
+
2519
+
2520
+ protected static void getShortArray(ShortBuffer buf, short[] arr) {
2521
+ if (!buf.hasArray() || buf.array() != arr) {
2522
+ buf.position(0);
2523
+ buf.get(arr);
2524
+ buf.rewind();
2525
+ }
2526
+ }
2527
+
2528
+
2529
+ protected static void putShortArray(ShortBuffer buf, short[] arr) {
2530
+ if (!buf.hasArray() || buf.array() != arr) {
2531
+ buf.position(0);
2532
+ buf.put(arr);
2533
+ buf.rewind();
2534
+ }
2535
+ }
2536
+
2537
+
2538
+ protected static void fillShortBuffer(ShortBuffer buf, int i0, int i1,
2539
+ short val) {
2540
+ int n = i1 - i0;
2541
+ short[] temp = new short[n];
2542
+ Arrays.fill(temp, 0, n, val);
2543
+ buf.position(i0);
2544
+ buf.put(temp, 0, n);
2545
+ buf.rewind();
2546
+ }
2547
+
2548
+
2549
+ protected static IntBuffer allocateDirectIntBuffer(int size) {
2550
+ int bytes = PApplet.max(MIN_DIRECT_BUFFER_SIZE, size) * SIZEOF_INT;
2551
+ return ByteBuffer.allocateDirect(bytes).order(ByteOrder.nativeOrder()).
2552
+ asIntBuffer();
2553
+ }
2554
+
2555
+
2556
+ protected static IntBuffer allocateIntBuffer(int size) {
2557
+ if (USE_DIRECT_BUFFERS) {
2558
+ return allocateDirectIntBuffer(size);
2559
+ } else {
2560
+ return IntBuffer.allocate(size);
2561
+ }
2562
+ }
2563
+
2564
+
2565
+ protected static IntBuffer allocateIntBuffer(int[] arr) {
2566
+ if (USE_DIRECT_BUFFERS) {
2567
+ IntBuffer buf = allocateDirectIntBuffer(arr.length);
2568
+ buf.put(arr);
2569
+ buf.position(0);
2570
+ return buf;
2571
+ } else {
2572
+ return IntBuffer.wrap(arr);
2573
+ }
2574
+ }
2575
+
2576
+
2577
+ protected static IntBuffer updateIntBuffer(IntBuffer buf, int[] arr,
2578
+ boolean wrap) {
2579
+ if (USE_DIRECT_BUFFERS) {
2580
+ if (buf == null || buf.capacity() < arr.length) {
2581
+ buf = allocateDirectIntBuffer(arr.length);
2582
+ }
2583
+ buf.position(0);
2584
+ buf.put(arr);
2585
+ buf.rewind();
2586
+ } else {
2587
+ if (wrap) {
2588
+ buf = IntBuffer.wrap(arr);
2589
+ } else {
2590
+ if (buf == null || buf.capacity() < arr.length) {
2591
+ buf = IntBuffer.allocate(arr.length);
2592
+ }
2593
+ buf.position(0);
2594
+ buf.put(arr);
2595
+ buf.rewind();
2596
+ }
2597
+ }
2598
+ return buf;
2599
+ }
2600
+
2601
+
2602
+ protected static void updateIntBuffer(IntBuffer buf, int[] arr,
2603
+ int offset, int size) {
2604
+ if (USE_DIRECT_BUFFERS || (buf.hasArray() && buf.array() != arr)) {
2605
+ buf.position(offset);
2606
+ buf.put(arr, offset, size);
2607
+ buf.rewind();
2608
+ }
2609
+ }
2610
+
2611
+
2612
+ protected static void getIntArray(IntBuffer buf, int[] arr) {
2613
+ if (!buf.hasArray() || buf.array() != arr) {
2614
+ buf.position(0);
2615
+ buf.get(arr);
2616
+ buf.rewind();
2617
+ }
2618
+ }
2619
+
2620
+
2621
+ protected static void putIntArray(IntBuffer buf, int[] arr) {
2622
+ if (!buf.hasArray() || buf.array() != arr) {
2623
+ buf.position(0);
2624
+ buf.put(arr);
2625
+ buf.rewind();
2626
+ }
2627
+ }
2628
+
2629
+
2630
+ protected static void fillIntBuffer(IntBuffer buf, int i0, int i1, int val) {
2631
+ int n = i1 - i0;
2632
+ int[] temp = new int[n];
2633
+ Arrays.fill(temp, 0, n, val);
2634
+ buf.position(i0);
2635
+ buf.put(temp, 0, n);
2636
+ buf.rewind();
2637
+ }
2638
+
2639
+
2640
+ protected static FloatBuffer allocateDirectFloatBuffer(int size) {
2641
+ int bytes = PApplet.max(MIN_DIRECT_BUFFER_SIZE, size) * SIZEOF_FLOAT;
2642
+ return ByteBuffer.allocateDirect(bytes).order(ByteOrder.nativeOrder()).
2643
+ asFloatBuffer();
2644
+ }
2645
+
2646
+
2647
+ protected static FloatBuffer allocateFloatBuffer(int size) {
2648
+ if (USE_DIRECT_BUFFERS) {
2649
+ return allocateDirectFloatBuffer(size);
2650
+ } else {
2651
+ return FloatBuffer.allocate(size);
2652
+ }
2653
+ }
2654
+
2655
+
2656
+ protected static FloatBuffer allocateFloatBuffer(float[] arr) {
2657
+ if (USE_DIRECT_BUFFERS) {
2658
+ FloatBuffer buf = allocateDirectFloatBuffer(arr.length);
2659
+ buf.put(arr);
2660
+ buf.position(0);
2661
+ return buf;
2662
+ } else {
2663
+ return FloatBuffer.wrap(arr);
2664
+ }
2665
+ }
2666
+
2667
+
2668
+ protected static FloatBuffer updateFloatBuffer(FloatBuffer buf, float[] arr,
2669
+ boolean wrap) {
2670
+ if (USE_DIRECT_BUFFERS) {
2671
+ if (buf == null || buf.capacity() < arr.length) {
2672
+ buf = allocateDirectFloatBuffer(arr.length);
2673
+ }
2674
+ buf.position(0);
2675
+ buf.put(arr);
2676
+ buf.rewind();
2677
+ } else {
2678
+ if (wrap) {
2679
+ buf = FloatBuffer.wrap(arr);
2680
+ } else {
2681
+ if (buf == null || buf.capacity() < arr.length) {
2682
+ buf = FloatBuffer.allocate(arr.length);
2683
+ }
2684
+ buf.position(0);
2685
+ buf.put(arr);
2686
+ buf.rewind();
2687
+ }
2688
+ }
2689
+ return buf;
2690
+ }
2691
+
2692
+
2693
+ protected static void updateFloatBuffer(FloatBuffer buf, float[] arr,
2694
+ int offset, int size) {
2695
+ if (USE_DIRECT_BUFFERS || (buf.hasArray() && buf.array() != arr)) {
2696
+ buf.position(offset);
2697
+ buf.put(arr, offset, size);
2698
+ buf.rewind();
2699
+ }
2700
+ }
2701
+
2702
+
2703
+ protected static void getFloatArray(FloatBuffer buf, float[] arr) {
2704
+ if (!buf.hasArray() || buf.array() != arr) {
2705
+ buf.position(0);
2706
+ buf.get(arr);
2707
+ buf.rewind();
2708
+ }
2709
+ }
2710
+
2711
+
2712
+ protected static void putFloatArray(FloatBuffer buf, float[] arr) {
2713
+ if (!buf.hasArray() || buf.array() != arr) {
2714
+ buf.position(0);
2715
+ buf.put(arr);
2716
+ buf.rewind();
2717
+ }
2718
+ }
2719
+
2720
+
2721
+ protected static void fillFloatBuffer(FloatBuffer buf, int i0, int i1,
2722
+ float val) {
2723
+ int n = i1 - i0;
2724
+ float[] temp = new float[n];
2725
+ Arrays.fill(temp, 0, n, val);
2726
+ buf.position(i0);
2727
+ buf.put(temp, 0, n);
2728
+ buf.rewind();
2729
+ }
2730
+
2731
+
2732
+ // TODO: the next three functions shouldn't be here...
2733
+ // Uses 'Object' so that the API can be used w/ Android Typeface objects
2734
+
2735
+ abstract protected int getFontAscent(Object font);
2736
+
2737
+
2738
+ abstract protected int getFontDescent(Object font);
2739
+
2740
+
2741
+ abstract protected int getTextWidth(Object font, char[] buffer, int start, int stop);
2742
+
2743
+
2744
+ abstract protected Object getDerivedFont(Object font, float size);
2745
+
2746
+ ///////////////////////////////////////////////////////////
2747
+
2748
+ protected interface RenderCallback {
2749
+
2750
+ void onRender();
2751
+
2752
+ }
2753
+
2754
+ ///////////////////////////////////////////////////////////
2755
+
2756
+ // Tessellator interface
2757
+
2758
+
2759
+ protected abstract Tessellator createTessellator(TessellatorCallback callback);
2760
+
2761
+
2762
+ protected interface Tessellator {
2763
+ public void setCallback(int flag);
2764
+ public void setWindingRule(int rule);
2765
+ public void setProperty(int property, int value);
2766
+
2767
+ public void beginPolygon();
2768
+ public void beginPolygon(Object data);
2769
+ public void endPolygon();
2770
+ public void beginContour();
2771
+ public void endContour();
2772
+ public void addVertex(double[] v);
2773
+ public void addVertex(double[] v, int n, Object data);
2774
+ }
2775
+
2776
+
2777
+ protected interface TessellatorCallback {
2778
+ public void begin(int type);
2779
+ public void end();
2780
+ public void vertex(Object data);
2781
+ public void combine(double[] coords, Object[] data,
2782
+ float[] weight, Object[] outData);
2783
+ public void error(int errnum);
2784
+ }
2785
+
2786
+
2787
+ protected String tessError(int err) {
2788
+ return "";
2789
+ }
2790
+
2791
+
2792
+ ///////////////////////////////////////////////////////////
2793
+
2794
+ // FontOutline interface
2795
+
2796
+
2797
+ protected static boolean SHAPE_TEXT_SUPPORTED;
2798
+ protected static int SEG_MOVETO;
2799
+ protected static int SEG_LINETO;
2800
+ protected static int SEG_QUADTO;
2801
+ protected static int SEG_CUBICTO;
2802
+ protected static int SEG_CLOSE;
2803
+
2804
+
2805
+ protected abstract FontOutline createFontOutline(char ch, Object font);
2806
+
2807
+
2808
+ protected interface FontOutline {
2809
+ public boolean isDone();
2810
+ public int currentSegment(float coords[]);
2811
+ public void next();
2812
+ }
2813
+
2814
+
2815
+ //////////////////////////////////////////////////////////////////////////////
2816
+ //
2817
+ // OpenGL ES 2.0 API, with a few additional functions for multisampling and
2818
+ // and buffer mapping from OpenGL 2.1+.
2819
+ //
2820
+ // The functions are organized following the groups in the GLES 2.0 reference
2821
+ // card:
2822
+ // http://www.khronos.org/opengles/sdk/docs/reference_cards/OpenGL-ES-2_0-Reference-card.pdf
2823
+ //
2824
+ // The entire GLES 2.0 specification is available below:
2825
+ // http://www.khronos.org/opengles/2_X/
2826
+ //
2827
+ // Implementations of the PGL functions for specific OpenGL bindings (JOGL,
2828
+ // LWJGL) should simply call the corresponding GL function in the bindings.
2829
+ // readPixels(), activeTexture() and bindTexture() are special cases, please
2830
+ // read their comments.
2831
+ // Also, keep in mind the note about the PGL constants below.
2832
+ //
2833
+ //////////////////////////////////////////////////////////////////////////////
2834
+
2835
+ ///////////////////////////////////////////////////////////
2836
+
2837
+ // Constants
2838
+ // Very important note: set the GL constants in your PGL subclass by using an
2839
+ // static initialization block as follows:
2840
+ // static {
2841
+ // FALSE = SUPER_DUPER_JAVA_OPENGL_BINDINGS.GL_FALSE;
2842
+ // TRUE = SUPER_DUPER_JAVA_OPENGL_BINDINGS.GL_TRUE;
2843
+ // ...
2844
+ // }
2845
+ // and not by re-declaring the constants, because doing so will lead to
2846
+ // errors when the constants are accessed through PGL because they are not
2847
+ // overridden but hidden by the new declarations, and hence they keep their
2848
+ // initial values (all zeroes) when accessed through the superclass.
2849
+
2850
+ public static int FALSE;
2851
+ public static int TRUE;
2852
+
2853
+ public static int INT;
2854
+ public static int BYTE;
2855
+ public static int SHORT;
2856
+ public static int FLOAT;
2857
+ public static int BOOL;
2858
+ public static int UNSIGNED_INT;
2859
+ public static int UNSIGNED_BYTE;
2860
+ public static int UNSIGNED_SHORT;
2861
+
2862
+ public static int RGB;
2863
+ public static int RGBA;
2864
+ public static int ALPHA;
2865
+ public static int LUMINANCE;
2866
+ public static int LUMINANCE_ALPHA;
2867
+
2868
+ public static int UNSIGNED_SHORT_5_6_5;
2869
+ public static int UNSIGNED_SHORT_4_4_4_4;
2870
+ public static int UNSIGNED_SHORT_5_5_5_1;
2871
+
2872
+ public static int RGBA4;
2873
+ public static int RGB5_A1;
2874
+ public static int RGB565;
2875
+ public static int RGB8;
2876
+ public static int RGBA8;
2877
+ public static int ALPHA8;
2878
+
2879
+ public static int READ_ONLY;
2880
+ public static int WRITE_ONLY;
2881
+ public static int READ_WRITE;
2882
+
2883
+ public static int TESS_WINDING_NONZERO;
2884
+ public static int TESS_WINDING_ODD;
2885
+ public static int TESS_EDGE_FLAG;
2886
+
2887
+ public static int GENERATE_MIPMAP_HINT;
2888
+ public static int FASTEST;
2889
+ public static int NICEST;
2890
+ public static int DONT_CARE;
2891
+
2892
+ public static int VENDOR;
2893
+ public static int RENDERER;
2894
+ public static int VERSION;
2895
+ public static int EXTENSIONS;
2896
+ public static int SHADING_LANGUAGE_VERSION;
2897
+
2898
+ public static int MAX_SAMPLES;
2899
+ public static int SAMPLES;
2900
+
2901
+ public static int ALIASED_LINE_WIDTH_RANGE;
2902
+ public static int ALIASED_POINT_SIZE_RANGE;
2903
+
2904
+ public static int DEPTH_BITS;
2905
+ public static int STENCIL_BITS;
2906
+
2907
+ public static int CCW;
2908
+ public static int CW;
2909
+
2910
+ public static int VIEWPORT;
2911
+
2912
+ public static int ARRAY_BUFFER;
2913
+ public static int ELEMENT_ARRAY_BUFFER;
2914
+ public static int PIXEL_PACK_BUFFER;
2915
+
2916
+ public static int MAX_VERTEX_ATTRIBS;
2917
+
2918
+ public static int STATIC_DRAW;
2919
+ public static int DYNAMIC_DRAW;
2920
+ public static int STREAM_DRAW;
2921
+ public static int STREAM_READ;
2922
+
2923
+ public static int BUFFER_SIZE;
2924
+ public static int BUFFER_USAGE;
2925
+
2926
+ public static int POINTS;
2927
+ public static int LINE_STRIP;
2928
+ public static int LINE_LOOP;
2929
+ public static int LINES;
2930
+ public static int TRIANGLE_FAN;
2931
+ public static int TRIANGLE_STRIP;
2932
+ public static int TRIANGLES;
2933
+
2934
+ public static int CULL_FACE;
2935
+ public static int FRONT;
2936
+ public static int BACK;
2937
+ public static int FRONT_AND_BACK;
2938
+
2939
+ public static int POLYGON_OFFSET_FILL;
2940
+
2941
+ public static int UNPACK_ALIGNMENT;
2942
+ public static int PACK_ALIGNMENT;
2943
+
2944
+ public static int TEXTURE_2D;
2945
+ public static int TEXTURE_RECTANGLE;
2946
+
2947
+ public static int TEXTURE_BINDING_2D;
2948
+ public static int TEXTURE_BINDING_RECTANGLE;
2949
+
2950
+ public static int MAX_TEXTURE_SIZE;
2951
+ public static int TEXTURE_MAX_ANISOTROPY;
2952
+ public static int MAX_TEXTURE_MAX_ANISOTROPY;
2953
+
2954
+ public static int MAX_VERTEX_TEXTURE_IMAGE_UNITS;
2955
+ public static int MAX_TEXTURE_IMAGE_UNITS;
2956
+ public static int MAX_COMBINED_TEXTURE_IMAGE_UNITS;
2957
+
2958
+ public static int NUM_COMPRESSED_TEXTURE_FORMATS;
2959
+ public static int COMPRESSED_TEXTURE_FORMATS;
2960
+
2961
+ public static int NEAREST;
2962
+ public static int LINEAR;
2963
+ public static int LINEAR_MIPMAP_NEAREST;
2964
+ public static int LINEAR_MIPMAP_LINEAR;
2965
+
2966
+ public static int CLAMP_TO_EDGE;
2967
+ public static int REPEAT;
2968
+
2969
+ public static int TEXTURE0;
2970
+ public static int TEXTURE1;
2971
+ public static int TEXTURE2;
2972
+ public static int TEXTURE3;
2973
+ public static int TEXTURE_MIN_FILTER;
2974
+ public static int TEXTURE_MAG_FILTER;
2975
+ public static int TEXTURE_WRAP_S;
2976
+ public static int TEXTURE_WRAP_T;
2977
+ public static int TEXTURE_WRAP_R;
2978
+
2979
+ public static int TEXTURE_CUBE_MAP;
2980
+ public static int TEXTURE_CUBE_MAP_POSITIVE_X;
2981
+ public static int TEXTURE_CUBE_MAP_POSITIVE_Y;
2982
+ public static int TEXTURE_CUBE_MAP_POSITIVE_Z;
2983
+ public static int TEXTURE_CUBE_MAP_NEGATIVE_X;
2984
+ public static int TEXTURE_CUBE_MAP_NEGATIVE_Y;
2985
+ public static int TEXTURE_CUBE_MAP_NEGATIVE_Z;
2986
+
2987
+ public static int VERTEX_SHADER;
2988
+ public static int FRAGMENT_SHADER;
2989
+ public static int INFO_LOG_LENGTH;
2990
+ public static int SHADER_SOURCE_LENGTH;
2991
+ public static int COMPILE_STATUS;
2992
+ public static int LINK_STATUS;
2993
+ public static int VALIDATE_STATUS;
2994
+ public static int SHADER_TYPE;
2995
+ public static int DELETE_STATUS;
2996
+
2997
+ public static int FLOAT_VEC2;
2998
+ public static int FLOAT_VEC3;
2999
+ public static int FLOAT_VEC4;
3000
+ public static int FLOAT_MAT2;
3001
+ public static int FLOAT_MAT3;
3002
+ public static int FLOAT_MAT4;
3003
+ public static int INT_VEC2;
3004
+ public static int INT_VEC3;
3005
+ public static int INT_VEC4;
3006
+ public static int BOOL_VEC2;
3007
+ public static int BOOL_VEC3;
3008
+ public static int BOOL_VEC4;
3009
+ public static int SAMPLER_2D;
3010
+ public static int SAMPLER_CUBE;
3011
+
3012
+ public static int LOW_FLOAT;
3013
+ public static int MEDIUM_FLOAT;
3014
+ public static int HIGH_FLOAT;
3015
+ public static int LOW_INT;
3016
+ public static int MEDIUM_INT;
3017
+ public static int HIGH_INT;
3018
+
3019
+ public static int CURRENT_VERTEX_ATTRIB;
3020
+
3021
+ public static int VERTEX_ATTRIB_ARRAY_BUFFER_BINDING;
3022
+ public static int VERTEX_ATTRIB_ARRAY_ENABLED;
3023
+ public static int VERTEX_ATTRIB_ARRAY_SIZE;
3024
+ public static int VERTEX_ATTRIB_ARRAY_STRIDE;
3025
+ public static int VERTEX_ATTRIB_ARRAY_TYPE;
3026
+ public static int VERTEX_ATTRIB_ARRAY_NORMALIZED;
3027
+ public static int VERTEX_ATTRIB_ARRAY_POINTER;
3028
+
3029
+ public static int BLEND;
3030
+ public static int ONE;
3031
+ public static int ZERO;
3032
+ public static int SRC_ALPHA;
3033
+ public static int DST_ALPHA;
3034
+ public static int ONE_MINUS_SRC_ALPHA;
3035
+ public static int ONE_MINUS_DST_COLOR;
3036
+ public static int ONE_MINUS_SRC_COLOR;
3037
+ public static int DST_COLOR;
3038
+ public static int SRC_COLOR;
3039
+
3040
+ public static int SAMPLE_ALPHA_TO_COVERAGE;
3041
+ public static int SAMPLE_COVERAGE;
3042
+
3043
+ public static int KEEP;
3044
+ public static int REPLACE;
3045
+ public static int INCR;
3046
+ public static int DECR;
3047
+ public static int INVERT;
3048
+ public static int INCR_WRAP;
3049
+ public static int DECR_WRAP;
3050
+ public static int NEVER;
3051
+ public static int ALWAYS;
3052
+
3053
+ public static int EQUAL;
3054
+ public static int LESS;
3055
+ public static int LEQUAL;
3056
+ public static int GREATER;
3057
+ public static int GEQUAL;
3058
+ public static int NOTEQUAL;
3059
+
3060
+ public static int FUNC_ADD;
3061
+ public static int FUNC_MIN;
3062
+ public static int FUNC_MAX;
3063
+ public static int FUNC_REVERSE_SUBTRACT;
3064
+ public static int FUNC_SUBTRACT;
3065
+
3066
+ public static int DITHER;
3067
+
3068
+ public static int CONSTANT_COLOR;
3069
+ public static int CONSTANT_ALPHA;
3070
+ public static int ONE_MINUS_CONSTANT_COLOR;
3071
+ public static int ONE_MINUS_CONSTANT_ALPHA;
3072
+ public static int SRC_ALPHA_SATURATE;
3073
+
3074
+ public static int SCISSOR_TEST;
3075
+ public static int STENCIL_TEST;
3076
+ public static int DEPTH_TEST;
3077
+ public static int DEPTH_WRITEMASK;
3078
+
3079
+ public static int COLOR_BUFFER_BIT;
3080
+ public static int DEPTH_BUFFER_BIT;
3081
+ public static int STENCIL_BUFFER_BIT;
3082
+
3083
+ public static int FRAMEBUFFER;
3084
+ public static int COLOR_ATTACHMENT0;
3085
+ public static int COLOR_ATTACHMENT1;
3086
+ public static int COLOR_ATTACHMENT2;
3087
+ public static int COLOR_ATTACHMENT3;
3088
+ public static int RENDERBUFFER;
3089
+ public static int DEPTH_ATTACHMENT;
3090
+ public static int STENCIL_ATTACHMENT;
3091
+ public static int READ_FRAMEBUFFER;
3092
+ public static int DRAW_FRAMEBUFFER;
3093
+
3094
+ public static int DEPTH24_STENCIL8;
3095
+
3096
+ public static int DEPTH_COMPONENT;
3097
+ public static int DEPTH_COMPONENT16;
3098
+ public static int DEPTH_COMPONENT24;
3099
+ public static int DEPTH_COMPONENT32;
3100
+
3101
+ public static int STENCIL_INDEX;
3102
+ public static int STENCIL_INDEX1;
3103
+ public static int STENCIL_INDEX4;
3104
+ public static int STENCIL_INDEX8;
3105
+
3106
+ public static int DEPTH_STENCIL;
3107
+
3108
+ public static int FRAMEBUFFER_COMPLETE;
3109
+ public static int FRAMEBUFFER_UNDEFINED;
3110
+ public static int FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
3111
+ public static int FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
3112
+ public static int FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
3113
+ public static int FRAMEBUFFER_INCOMPLETE_FORMATS;
3114
+ public static int FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER;
3115
+ public static int FRAMEBUFFER_INCOMPLETE_READ_BUFFER;
3116
+ public static int FRAMEBUFFER_UNSUPPORTED;
3117
+ public static int FRAMEBUFFER_INCOMPLETE_MULTISAMPLE;
3118
+ public static int FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS;
3119
+
3120
+ public static int FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE;
3121
+ public static int FRAMEBUFFER_ATTACHMENT_OBJECT_NAME;
3122
+ public static int FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL;
3123
+ public static int FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE;
3124
+
3125
+ public static int RENDERBUFFER_WIDTH;
3126
+ public static int RENDERBUFFER_HEIGHT;
3127
+ public static int RENDERBUFFER_RED_SIZE;
3128
+ public static int RENDERBUFFER_GREEN_SIZE;
3129
+ public static int RENDERBUFFER_BLUE_SIZE;
3130
+ public static int RENDERBUFFER_ALPHA_SIZE;
3131
+ public static int RENDERBUFFER_DEPTH_SIZE;
3132
+ public static int RENDERBUFFER_STENCIL_SIZE;
3133
+ public static int RENDERBUFFER_INTERNAL_FORMAT;
3134
+
3135
+ public static int MULTISAMPLE;
3136
+ public static int LINE_SMOOTH;
3137
+ public static int POLYGON_SMOOTH;
3138
+
3139
+ public static int SYNC_GPU_COMMANDS_COMPLETE;
3140
+ public static int ALREADY_SIGNALED;
3141
+ public static int CONDITION_SATISFIED;
3142
+
3143
+ ///////////////////////////////////////////////////////////
3144
+
3145
+ // Special Functions
3146
+
3147
+ public abstract void flush();
3148
+ public abstract void finish();
3149
+ public abstract void hint(int target, int hint);
3150
+
3151
+ ///////////////////////////////////////////////////////////
3152
+
3153
+ // State and State Requests
3154
+
3155
+ public abstract void enable(int value);
3156
+ public abstract void disable(int value);
3157
+ public abstract void getBooleanv(int value, IntBuffer data);
3158
+ public abstract void getIntegerv(int value, IntBuffer data);
3159
+ public abstract void getFloatv(int value, FloatBuffer data);
3160
+ public abstract boolean isEnabled(int value);
3161
+
3162
+ /**
3163
+ * Get a configuration or status string from the underlying renderer.
3164
+ *
3165
+ * @param name The name or ID of the attribute to request.
3166
+ * @return The requested value as a string.
3167
+ * @throws GraphicsNotInitializedException Thrown if an attribute is requested that is not
3168
+ * available until graphics initialization before that initialization compeltes. For example,
3169
+ * if requesting a GL string before GL context is available.
3170
+ */
3171
+ public abstract String getString(int name) throws GraphicsNotInitializedException;
3172
+
3173
+ ///////////////////////////////////////////////////////////
3174
+
3175
+ // Error Handling
3176
+
3177
+ public abstract int getError();
3178
+ public abstract String errorString(int err);
3179
+
3180
+ //////////////////////////////////////////////////////////////////////////////
3181
+
3182
+ // Buffer Objects
3183
+
3184
+ public abstract void genBuffers(int n, IntBuffer buffers);
3185
+ public abstract void deleteBuffers(int n, IntBuffer buffers);
3186
+ public abstract void bindBuffer(int target, int buffer);
3187
+ public abstract void bufferData(int target, int size, Buffer data, int usage);
3188
+ public abstract void bufferSubData(int target, int offset, int size, Buffer data);
3189
+ public abstract void isBuffer(int buffer);
3190
+ public abstract void getBufferParameteriv(int target, int value, IntBuffer data);
3191
+ public abstract ByteBuffer mapBuffer(int target, int access);
3192
+ public abstract ByteBuffer mapBufferRange(int target, int offset, int length, int access);
3193
+ public abstract void unmapBuffer(int target);
3194
+
3195
+ //////////////////////////////////////////////////////////////////////////////
3196
+
3197
+ // Synchronization
3198
+
3199
+ public abstract long fenceSync(int condition, int flags);
3200
+ public abstract void deleteSync(long sync);
3201
+ public abstract int clientWaitSync(long sync, int flags, long timeout);
3202
+
3203
+ //////////////////////////////////////////////////////////////////////////////
3204
+
3205
+ // Viewport and Clipping
3206
+
3207
+ public abstract void depthRangef(float n, float f);
3208
+ public abstract void viewport(int x, int y, int w, int h);
3209
+ protected abstract void viewportImpl(int x, int y, int w, int h);
3210
+
3211
+ //////////////////////////////////////////////////////////////////////////////
3212
+
3213
+ // Reading Pixels
3214
+ // This is a special case: because the renderer might be using an FBO even on
3215
+ // the main surface, some extra handling might be needed before and after
3216
+ // reading the pixels. To make this transparent to the user, the actual call
3217
+ // to glReadPixels() should be done in readPixelsImpl().
3218
+
3219
+ public void readPixels(int x, int y, int width, int height, int format, int type, Buffer buffer){
3220
+ boolean multisampled = isMultisampled() || graphics.offscreenMultisample;
3221
+ boolean depthReadingEnabled = graphics.getHint(PConstants.ENABLE_BUFFER_READING);
3222
+ boolean depthRequested = format == STENCIL_INDEX || format == DEPTH_COMPONENT || format == DEPTH_STENCIL;
3223
+
3224
+ if (multisampled && depthRequested && !depthReadingEnabled) {
3225
+ PGraphics.showWarning(DEPTH_READING_NOT_ENABLED_ERROR);
3226
+ return;
3227
+ }
3228
+
3229
+ graphics.beginReadPixels();
3230
+ readPixelsImpl(x, y, width, height, format, type, buffer);
3231
+ graphics.endReadPixels();
3232
+ }
3233
+
3234
+ public void readPixels(int x, int y, int width, int height, int format, int type, long offset){
3235
+ boolean multisampled = isMultisampled() || graphics.offscreenMultisample;
3236
+ boolean depthReadingEnabled = graphics.getHint(PConstants.ENABLE_BUFFER_READING);
3237
+ boolean depthRequested = format == STENCIL_INDEX || format == DEPTH_COMPONENT || format == DEPTH_STENCIL;
3238
+
3239
+ if (multisampled && depthRequested && !depthReadingEnabled) {
3240
+ PGraphics.showWarning(DEPTH_READING_NOT_ENABLED_ERROR);
3241
+ return;
3242
+ }
3243
+
3244
+ graphics.beginReadPixels();
3245
+ readPixelsImpl(x, y, width, height, format, type, offset);
3246
+ graphics.endReadPixels();
3247
+ }
3248
+
3249
+ protected abstract void readPixelsImpl(int x, int y, int width, int height, int format, int type, Buffer buffer);
3250
+ protected abstract void readPixelsImpl(int x, int y, int width, int height, int format, int type, long offset);
3251
+
3252
+ //////////////////////////////////////////////////////////////////////////////
3253
+
3254
+ // Vertices
3255
+
3256
+ public abstract void vertexAttrib1f(int index, float value);
3257
+ public abstract void vertexAttrib2f(int index, float value0, float value1);
3258
+ public abstract void vertexAttrib3f(int index, float value0, float value1, float value2);
3259
+ public abstract void vertexAttrib4f(int index, float value0, float value1, float value2, float value3);
3260
+ public abstract void vertexAttrib1fv(int index, FloatBuffer values);
3261
+ public abstract void vertexAttrib2fv(int index, FloatBuffer values);
3262
+ public abstract void vertexAttrib3fv(int index, FloatBuffer values);
3263
+ public abstract void vertexAttrib4fv(int index, FloatBuffer values);
3264
+ public abstract void vertexAttribPointer(int index, int size, int type, boolean normalized, int stride, int offset);
3265
+ public abstract void enableVertexAttribArray(int index);
3266
+ public abstract void disableVertexAttribArray(int index);
3267
+
3268
+ public void drawArrays(int mode, int first, int count) {
3269
+ geomCount += count;
3270
+ drawArraysImpl(mode, first, count);
3271
+ }
3272
+
3273
+ public abstract void drawArraysImpl(int mode, int first, int count);
3274
+
3275
+ public void drawElements(int mode, int count, int type, int offset) {
3276
+ geomCount += count;
3277
+ drawElementsImpl(mode, count, type, offset);
3278
+ }
3279
+
3280
+ public abstract void drawElementsImpl(int mode, int count, int type, int offset);
3281
+
3282
+ //////////////////////////////////////////////////////////////////////////////
3283
+
3284
+ // Rasterization
3285
+
3286
+ public abstract void lineWidth(float width);
3287
+ public abstract void frontFace(int dir);
3288
+ public abstract void cullFace(int mode);
3289
+ public abstract void polygonOffset(float factor, float units);
3290
+
3291
+ //////////////////////////////////////////////////////////////////////////////
3292
+
3293
+ // Pixel Rectangles
3294
+
3295
+ public abstract void pixelStorei(int pname, int param);
3296
+
3297
+ ///////////////////////////////////////////////////////////
3298
+
3299
+ // Texturing
3300
+
3301
+ public abstract void texImage2D(int target, int level, int internalFormat, int width, int height, int border, int format, int type, Buffer data);
3302
+ public abstract void copyTexImage2D(int target, int level, int internalFormat, int x, int y, int width, int height, int border);
3303
+ public abstract void texSubImage2D(int target, int level, int xOffset, int yOffset, int width, int height, int format, int type, Buffer data);
3304
+ public abstract void copyTexSubImage2D(int target, int level, int xOffset, int yOffset, int x, int y, int width, int height);
3305
+ public abstract void compressedTexImage2D(int target, int level, int internalFormat, int width, int height, int border, int imageSize, Buffer data);
3306
+ public abstract void compressedTexSubImage2D(int target, int level, int xOffset, int yOffset, int width, int height, int format, int imageSize, Buffer data);
3307
+ public abstract void texParameteri(int target, int pname, int param);
3308
+ public abstract void texParameterf(int target, int pname, float param);
3309
+ public abstract void texParameteriv(int target, int pname, IntBuffer params);
3310
+ public abstract void texParameterfv(int target, int pname, FloatBuffer params);
3311
+ public abstract void generateMipmap(int target);
3312
+ public abstract void genTextures(int n, IntBuffer textures);
3313
+ public abstract void deleteTextures(int n, IntBuffer textures);
3314
+ public abstract void getTexParameteriv(int target, int pname, IntBuffer params);
3315
+ public abstract void getTexParameterfv(int target, int pname, FloatBuffer params);
3316
+ public abstract boolean isTexture(int texture);
3317
+
3318
+ // activeTexture() and bindTexture() have some extra logic to keep track of
3319
+ // the bound textures, so the actual GL call should go in activeTextureImpl()
3320
+ // and bindTextureImpl().
3321
+ public void activeTexture(int texture) {
3322
+ activeTexUnit = texture - TEXTURE0;
3323
+ activeTextureImpl(texture);
3324
+ }
3325
+
3326
+ protected abstract void activeTextureImpl(int texture);
3327
+
3328
+ public void bindTexture(int target, int texture) {
3329
+ bindTextureImpl(target, texture);
3330
+
3331
+ if (boundTextures == null) {
3332
+ maxTexUnits = getMaxTexUnits();
3333
+ boundTextures = new int[maxTexUnits][2];
3334
+ }
3335
+
3336
+ if (maxTexUnits <= activeTexUnit) {
3337
+ throw new RuntimeException(TEXUNIT_ERROR);
3338
+ }
3339
+
3340
+ if (target == TEXTURE_2D) {
3341
+ boundTextures[activeTexUnit][0] = texture;
3342
+ } else if (target == TEXTURE_RECTANGLE) {
3343
+ boundTextures[activeTexUnit][1] = texture;
3344
+ }
3345
+ }
3346
+ protected abstract void bindTextureImpl(int target, int texture);
3347
+
3348
+ ///////////////////////////////////////////////////////////
3349
+
3350
+ // Shaders and Programs
3351
+
3352
+ public abstract int createShader(int type);
3353
+ public abstract void shaderSource(int shader, String source);
3354
+ public abstract void compileShader(int shader);
3355
+ public abstract void releaseShaderCompiler();
3356
+ public abstract void deleteShader(int shader);
3357
+ public abstract void shaderBinary(int count, IntBuffer shaders, int binaryFormat, Buffer binary, int length);
3358
+ public abstract int createProgram();
3359
+ public abstract void attachShader(int program, int shader);
3360
+ public abstract void detachShader(int program, int shader);
3361
+ public abstract void linkProgram(int program);
3362
+ public abstract void useProgram(int program);
3363
+ public abstract void deleteProgram(int program);
3364
+ public abstract String getActiveAttrib(int program, int index, IntBuffer size, IntBuffer type);
3365
+ public abstract int getAttribLocation(int program, String name);
3366
+ public abstract void bindAttribLocation(int program, int index, String name);
3367
+ public abstract int getUniformLocation(int program, String name);
3368
+ public abstract String getActiveUniform(int program, int index, IntBuffer size, IntBuffer type);
3369
+ public abstract void uniform1i(int location, int value);
3370
+ public abstract void uniform2i(int location, int value0, int value1);
3371
+ public abstract void uniform3i(int location, int value0, int value1, int value2);
3372
+ public abstract void uniform4i(int location, int value0, int value1, int value2, int value3);
3373
+ public abstract void uniform1f(int location, float value);
3374
+ public abstract void uniform2f(int location, float value0, float value1);
3375
+ public abstract void uniform3f(int location, float value0, float value1, float value2);
3376
+ public abstract void uniform4f(int location, float value0, float value1, float value2, float value3);
3377
+ public abstract void uniform1iv(int location, int count, IntBuffer v);
3378
+ public abstract void uniform2iv(int location, int count, IntBuffer v);
3379
+ public abstract void uniform3iv(int location, int count, IntBuffer v);
3380
+ public abstract void uniform4iv(int location, int count, IntBuffer v);
3381
+ public abstract void uniform1fv(int location, int count, FloatBuffer v);
3382
+ public abstract void uniform2fv(int location, int count, FloatBuffer v);
3383
+ public abstract void uniform3fv(int location, int count, FloatBuffer v);
3384
+ public abstract void uniform4fv(int location, int count, FloatBuffer v);
3385
+ public abstract void uniformMatrix2fv(int location, int count, boolean transpose, FloatBuffer mat);
3386
+ public abstract void uniformMatrix3fv(int location, int count, boolean transpose, FloatBuffer mat);
3387
+ public abstract void uniformMatrix4fv(int location, int count, boolean transpose, FloatBuffer mat);
3388
+ public abstract void validateProgram(int program);
3389
+ public abstract boolean isShader(int shader);
3390
+ public abstract void getShaderiv(int shader, int pname, IntBuffer params);
3391
+ public abstract void getAttachedShaders(int program, int maxCount, IntBuffer count, IntBuffer shaders);
3392
+ public abstract String getShaderInfoLog(int shader);
3393
+ public abstract String getShaderSource(int shader);
3394
+ public abstract void getShaderPrecisionFormat(int shaderType, int precisionType, IntBuffer range, IntBuffer precision);
3395
+ public abstract void getVertexAttribfv(int index, int pname, FloatBuffer params);
3396
+ public abstract void getVertexAttribiv(int index, int pname, IntBuffer params);
3397
+ public abstract void getVertexAttribPointerv(int index, int pname, ByteBuffer data);
3398
+ public abstract void getUniformfv(int program, int location, FloatBuffer params);
3399
+ public abstract void getUniformiv(int program, int location, IntBuffer params);
3400
+ public abstract boolean isProgram(int program);
3401
+ public abstract void getProgramiv(int program, int pname, IntBuffer params);
3402
+ public abstract String getProgramInfoLog(int program);
3403
+
3404
+ ///////////////////////////////////////////////////////////
3405
+
3406
+ // Per-Fragment Operations
3407
+
3408
+ public abstract void scissor(int x, int y, int w, int h);
3409
+ public abstract void sampleCoverage(float value, boolean invert);
3410
+ public abstract void stencilFunc(int func, int ref, int mask);
3411
+ public abstract void stencilFuncSeparate(int face, int func, int ref, int mask);
3412
+ public abstract void stencilOp(int sfail, int dpfail, int dppass);
3413
+ public abstract void stencilOpSeparate(int face, int sfail, int dpfail, int dppass);
3414
+ public abstract void depthFunc(int func);
3415
+ public abstract void blendEquation(int mode);
3416
+ public abstract void blendEquationSeparate(int modeRGB, int modeAlpha);
3417
+ public abstract void blendFunc(int src, int dst);
3418
+ public abstract void blendFuncSeparate(int srcRGB, int dstRGB, int srcAlpha, int dstAlpha);
3419
+ public abstract void blendColor(float red, float green, float blue, float alpha);
3420
+
3421
+ ///////////////////////////////////////////////////////////
3422
+
3423
+ // Whole Framebuffer Operations
3424
+
3425
+ public abstract void colorMask(boolean r, boolean g, boolean b, boolean a);
3426
+ public abstract void depthMask(boolean mask);
3427
+ public abstract void stencilMask(int mask);
3428
+ public abstract void stencilMaskSeparate(int face, int mask);
3429
+ public abstract void clearColor(float r, float g, float b, float a);
3430
+ public abstract void clearDepth(float d);
3431
+ public abstract void clearStencil(int s);
3432
+ public abstract void clear(int buf);
3433
+
3434
+ ///////////////////////////////////////////////////////////
3435
+
3436
+ // Framebuffers Objects
3437
+
3438
+ public void bindFramebuffer(int target, int framebuffer) {
3439
+ graphics.beginBindFramebuffer(target, framebuffer);
3440
+ bindFramebufferImpl(target, framebuffer);
3441
+ graphics.endBindFramebuffer(target, framebuffer);
3442
+ }
3443
+ protected abstract void bindFramebufferImpl(int target, int framebuffer);
3444
+
3445
+ public abstract void deleteFramebuffers(int n, IntBuffer framebuffers);
3446
+ public abstract void genFramebuffers(int n, IntBuffer framebuffers);
3447
+ public abstract void bindRenderbuffer(int target, int renderbuffer);
3448
+ public abstract void deleteRenderbuffers(int n, IntBuffer renderbuffers);
3449
+ public abstract void genRenderbuffers(int n, IntBuffer renderbuffers);
3450
+ public abstract void renderbufferStorage(int target, int internalFormat, int width, int height);
3451
+ public abstract void framebufferRenderbuffer(int target, int attachment, int rendbuferfTarget, int renderbuffer);
3452
+ public abstract void framebufferTexture2D(int target, int attachment, int texTarget, int texture, int level);
3453
+ public abstract int checkFramebufferStatus(int target);
3454
+ public abstract boolean isFramebuffer(int framebuffer);
3455
+ public abstract void getFramebufferAttachmentParameteriv(int target, int attachment, int pname, IntBuffer params);
3456
+ public abstract boolean isRenderbuffer(int renderbuffer);
3457
+ public abstract void getRenderbufferParameteriv(int target, int pname, IntBuffer params);
3458
+ public abstract void blitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter);
3459
+ public abstract void renderbufferStorageMultisample(int target, int samples, int format, int width, int height);
3460
+ public abstract void readBuffer(int buf);
3461
+ public abstract void drawBuffer(int buf);
3462
+
3463
+ ///////////////////////////////////////////////////////////
3464
+
3465
+ // Exceptions
3466
+
3467
+ /**
3468
+ * Exception for when attempting an operation requiring the graphics renderer, context, etc
3469
+ * to have been initialized before that initialization.
3470
+ */
3471
+ public class GraphicsNotInitializedException extends RuntimeException {
3472
+
3473
+ /**
3474
+ * Create a new exception indicating that an action could not be fulfilled because the rendering
3475
+ * context or equivalent is not ready.
3476
+ *
3477
+ * @param msg Further details about the issue.
3478
+ */
3479
+ public GraphicsNotInitializedException(String msg) {
3480
+ super(msg);
3481
+ }
3482
+ }
3483
+ }