picrate 0.0.2-java

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