propane 3.4.0-java → 3.4.1-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/extensions.xml +1 -2
  3. data/.travis.yml +2 -2
  4. data/CHANGELOG.md +2 -0
  5. data/README.md +12 -7
  6. data/Rakefile +2 -2
  7. data/lib/propane.rb +2 -2
  8. data/lib/propane/app.rb +18 -9
  9. data/lib/propane/helper_methods.rb +1 -1
  10. data/lib/propane/runner.rb +1 -1
  11. data/lib/propane/version.rb +1 -1
  12. data/library/color_group/color_group.rb +26 -0
  13. data/library/dxf/dxf.rb +4 -0
  14. data/library/net/net.rb +5 -0
  15. data/library/video_event/video_event.rb +2 -1
  16. data/pom.rb +3 -3
  17. data/pom.xml +3 -3
  18. data/propane.gemspec +1 -1
  19. data/src/main/java/japplemenubar/JAppleMenuBar.java +3 -3
  20. data/src/main/java/monkstone/ColorUtil.java +14 -0
  21. data/src/main/java/monkstone/MathToolModule.java +243 -194
  22. data/src/main/java/monkstone/filechooser/Chooser.java +1 -0
  23. data/src/main/java/monkstone/slider/WheelHandler.java +6 -5
  24. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +3 -2
  25. data/src/main/java/monkstone/videoevent/CaptureEvent.java +27 -0
  26. data/src/main/java/monkstone/videoevent/{VideoInterface.java → MovieEvent.java} +10 -26
  27. data/src/main/java/processing/awt/PSurfaceAWT.java +1 -1
  28. data/src/main/java/processing/core/PApplet.java +1236 -599
  29. data/src/main/java/processing/core/PGraphics.java +59 -59
  30. data/src/main/java/processing/core/PImage.java +528 -129
  31. data/src/main/java/processing/core/PShape.java +10 -10
  32. data/src/main/java/processing/core/PVector.java +2 -2
  33. data/src/main/java/processing/core/ThinkDifferent.java +5 -7
  34. data/src/main/java/processing/dxf/RawDXF.java +404 -0
  35. data/src/main/java/processing/net/Client.java +744 -0
  36. data/src/main/java/processing/net/Server.java +388 -0
  37. data/src/main/java/processing/opengl/FontTexture.java +19 -20
  38. data/src/main/java/processing/opengl/FrameBuffer.java +27 -17
  39. data/src/main/java/processing/opengl/LinePath.java +512 -508
  40. data/src/main/java/processing/opengl/PGL.java +3106 -3066
  41. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +4 -4
  42. data/src/main/java/processing/opengl/PShader.java +1442 -1341
  43. data/vendors/Rakefile +3 -27
  44. metadata +12 -25
  45. data/src/main/java/processing/core/util/image/ImageLoadFacade.java +0 -161
  46. data/src/main/java/processing/core/util/image/ImageSaveFacade.java +0 -169
  47. data/src/main/java/processing/core/util/image/constants/TifConstants.java +0 -45
  48. data/src/main/java/processing/core/util/image/load/AwtImageLoadStrategy.java +0 -80
  49. data/src/main/java/processing/core/util/image/load/Base64StringImageLoadStrategy.java +0 -73
  50. data/src/main/java/processing/core/util/image/load/FallbackImageLoadStrategy.java +0 -70
  51. data/src/main/java/processing/core/util/image/load/ImageIoImageLoadStrategy.java +0 -132
  52. data/src/main/java/processing/core/util/image/load/ImageLoadStrategy.java +0 -48
  53. data/src/main/java/processing/core/util/image/load/ImageLoadUtil.java +0 -45
  54. data/src/main/java/processing/core/util/image/load/TgaImageLoadStrategy.java +0 -255
  55. data/src/main/java/processing/core/util/image/load/TiffImageLoadStrategy.java +0 -98
  56. data/src/main/java/processing/core/util/image/save/ImageSaveStrategy.java +0 -49
  57. data/src/main/java/processing/core/util/image/save/ImageSaveUtil.java +0 -48
  58. data/src/main/java/processing/core/util/image/save/ImageWriterImageSaveStrategy.java +0 -179
  59. data/src/main/java/processing/core/util/image/save/SaveImageException.java +0 -41
  60. data/src/main/java/processing/core/util/image/save/TgaImageSaveStrategy.java +0 -198
  61. data/src/main/java/processing/core/util/image/save/TiffImageSaveStrategy.java +0 -91
  62. data/src/main/java/processing/core/util/image/save/TiffNakedFilenameImageSaveStrategy.java +0 -57
  63. data/src/main/java/processing/core/util/io/InputFactory.java +0 -285
  64. data/src/main/java/processing/core/util/io/PathUtil.java +0 -109
@@ -3528,7 +3528,7 @@ public class PGraphicsOpenGL extends PGraphics {
3528
3528
  * Ported from the implementation of textCharShapeImpl() in 1.5.1
3529
3529
  *
3530
3530
  * <EM>No attempt has been made to optimize this code</EM>
3531
- * <p/>
3531
+ *
3532
3532
  * TODO: Implement a FontShape class where each glyph is tessellated and
3533
3533
  * stored inside a larger PShapeOpenGL object (which needs to be expanded as
3534
3534
  * new glyphs are added and exceed the initial capacity in a similar way as
@@ -3536,18 +3536,18 @@ public class PGraphicsOpenGL extends PGraphics {
3536
3536
  * rendered in shape mode, then the correct sequences of vertex indices are
3537
3537
  * computed (akin to the texcoords in the texture case) and used to draw
3538
3538
  * only those parts of the PShape object that are required for the text.
3539
- * <p/>
3539
+ *
3540
3540
  *
3541
3541
  * Some issues of the original implementation probably remain, so they are
3542
3542
  * reproduced below:
3543
- * <p/>
3543
+ *
3544
3544
  * Also a problem where some fonts seem to be a bit slight, as if the
3545
3545
  * control points aren't being mapped quite correctly. Probably doing
3546
3546
  * something dumb that the control points don't map to P5's control points.
3547
3547
  * Perhaps it's returning b-spline data from the TrueType font? Though it
3548
3548
  * seems like that would make a lot of garbage rather than just a little
3549
3549
  * flattening.
3550
- * <p/>
3550
+ *
3551
3551
  * There also seems to be a bug that is causing a line (but not a filled
3552
3552
  * triangle) back to the origin on some letters (i.e. a capital L when
3553
3553
  * tested with Akzidenz Grotesk Light). But this won't be visible with the
@@ -39,1437 +39,1538 @@ import java.util.HashMap;
39
39
  */
40
40
  public class PShader implements PConstants {
41
41
 
42
- static protected final int POINT = 0;
43
- static protected final int LINE = 1;
44
- static protected final int POLY = 2;
45
- static protected final int COLOR = 3;
46
- static protected final int LIGHT = 4;
47
- static protected final int TEXTURE = 5;
48
- static protected final int TEXLIGHT = 6;
49
-
50
- static protected String pointShaderAttrRegexp
51
- = "attribute *vec2 *offset";
52
- static protected String pointShaderInRegexp
53
- = "in *vec2 *offset;";
54
- static protected String lineShaderAttrRegexp
55
- = "attribute *vec4 *direction";
56
- static protected String lineShaderInRegexp
57
- = "in *vec4 *direction";
58
- static protected String pointShaderDefRegexp
59
- = "#define *PROCESSING_POINT_SHADER";
60
- static protected String lineShaderDefRegexp
61
- = "#define *PROCESSING_LINE_SHADER";
62
- static protected String colorShaderDefRegexp
63
- = "#define *PROCESSING_COLOR_SHADER";
64
- static protected String lightShaderDefRegexp
65
- = "#define *PROCESSING_LIGHT_SHADER";
66
- static protected String texShaderDefRegexp
67
- = "#define *PROCESSING_TEXTURE_SHADER";
68
- static protected String texlightShaderDefRegexp
69
- = "#define *PROCESSING_TEXLIGHT_SHADER";
70
- static protected String polyShaderDefRegexp
71
- = "#define *PROCESSING_POLYGON_SHADER";
72
- static protected String triShaderAttrRegexp
73
- = "#define *PROCESSING_TRIANGLES_SHADER";
74
- static protected String quadShaderAttrRegexp
75
- = "#define *PROCESSING_QUADS_SHADER";
76
-
77
- protected PApplet parent;
78
- // The main renderer associated to the parent PApplet.
79
- //protected PGraphicsOpenGL pgMain;
80
- // We need a reference to the renderer since a shader might
81
- // be called by different renderers within a single application
82
- // (the one corresponding to the main surface, or other offscreen
83
- // renderers).
84
- protected PGraphicsOpenGL primaryPG;
85
- protected PGraphicsOpenGL currentPG;
86
- protected PGL pgl;
87
- protected int context; // The context that created this shader.
88
-
89
- // The shader type: POINT, LINE, POLY, etc.
90
- protected int type;
91
-
92
- public int glProgram;
93
- public int glVertex;
94
- public int glFragment;
95
- private GLResourceShader glres;
96
-
97
- protected URL vertexURL;
98
- protected URL fragmentURL;
99
-
100
- protected String vertexFilename;
101
- protected String fragmentFilename;
102
-
103
- protected String[] vertexShaderSource;
104
- protected String[] fragmentShaderSource;
105
-
106
- protected boolean bound;
107
-
108
- protected HashMap<String, UniformValue> uniformValues = null;
109
-
110
- protected HashMap<Integer, Texture> textures;
111
- protected HashMap<Integer, Integer> texUnits;
112
-
113
- // Direct buffers to pass shader data to GL
114
- protected IntBuffer intBuffer;
115
- protected FloatBuffer floatBuffer;
116
-
117
- protected boolean loadedAttributes = false;
118
- protected boolean loadedUniforms = false;
119
-
120
- // Uniforms common to all shader types
121
- protected int transformMatLoc;
122
- protected int modelviewMatLoc;
123
- protected int projectionMatLoc;
124
- protected int ppixelsLoc;
125
- protected int ppixelsUnit;
126
- protected int viewportLoc;
127
- protected int resolutionLoc;
128
-
129
- // Uniforms only for lines and points
130
- protected int perspectiveLoc;
131
- protected int scaleLoc;
132
-
133
- // Lighting uniforms
134
- protected int lightCountLoc;
135
- protected int lightPositionLoc;
136
- protected int lightNormalLoc;
137
- protected int lightAmbientLoc;
138
- protected int lightDiffuseLoc;
139
- protected int lightSpecularLoc;
140
- protected int lightFalloffLoc;
141
- protected int lightSpotLoc;
142
-
143
- // Texturing uniforms
144
- protected Texture texture;
145
- protected int texUnit;
146
- protected int textureLoc;
147
- protected int texMatrixLoc;
148
- protected int texOffsetLoc;
149
- protected float[] tcmat;
150
-
151
- // Vertex attributes
152
- protected int vertexLoc;
153
- protected int colorLoc;
154
- protected int normalLoc;
155
- protected int texCoordLoc;
156
- protected int normalMatLoc;
157
- protected int directionLoc;
158
- protected int offsetLoc;
159
- protected int ambientLoc;
160
- protected int specularLoc;
161
- protected int emissiveLoc;
162
- protected int shininessLoc;
163
-
164
- public PShader() {
165
- parent = null;
166
- pgl = null;
167
- context = -1;
168
-
169
- this.vertexURL = null;
170
- this.fragmentURL = null;
171
- this.vertexFilename = null;
172
- this.fragmentFilename = null;
173
-
174
- glProgram = 0;
175
- glVertex = 0;
176
- glFragment = 0;
177
-
178
- intBuffer = PGL.allocateIntBuffer(1);
179
- floatBuffer = PGL.allocateFloatBuffer(1);
180
-
181
- bound = false;
182
-
183
- type = -1;
184
- }
185
-
186
- public PShader(PApplet parent) {
187
- this();
188
- this.parent = parent;
189
- primaryPG = (PGraphicsOpenGL) parent.g;
190
- pgl = primaryPG.pgl;
191
- context = pgl.createEmptyContext();
192
- }
193
-
194
- /**
195
- * Creates a shader program using the specified vertex and fragment shaders.
196
- *
197
- * @param parent the parent program
198
- * @param vertFilename name of the vertex shader
199
- * @param fragFilename name of the fragment shader
200
- */
201
- public PShader(PApplet parent, String vertFilename, String fragFilename) {
202
- this.parent = parent;
203
- primaryPG = (PGraphicsOpenGL) parent.g;
204
- pgl = primaryPG.pgl;
205
-
206
- this.vertexURL = null;
207
- this.fragmentURL = null;
208
- this.vertexFilename = vertFilename;
209
- this.fragmentFilename = fragFilename;
210
- fragmentShaderSource = pgl.loadFragmentShader(fragFilename);
211
- vertexShaderSource = pgl.loadVertexShader(vertFilename);
212
-
213
- glProgram = 0;
214
- glVertex = 0;
215
- glFragment = 0;
216
-
217
- intBuffer = PGL.allocateIntBuffer(1);
218
- floatBuffer = PGL.allocateFloatBuffer(1);
219
-
220
- int vertType = getShaderType(vertexShaderSource, -1);
221
- int fragType = getShaderType(fragmentShaderSource, -1);
222
- if (vertType == -1 && fragType == -1) {
223
- type = PShader.POLY;
224
- } else if (vertType == -1) {
225
- type = fragType;
226
- } else if (fragType == -1) {
227
- type = vertType;
228
- } else if (fragType == vertType) {
229
- type = vertType;
230
- } else {
231
- PGraphics.showWarning(PGraphicsOpenGL.INCONSISTENT_SHADER_TYPES);
232
- }
233
- }
234
-
235
- /**
236
- * @param vertURL network location of the vertex shader
237
- * @param fragURL network location of the fragment shader
238
- */
239
- public PShader(PApplet parent, URL vertURL, URL fragURL) {
240
- this.parent = parent;
241
- primaryPG = (PGraphicsOpenGL) parent.g;
242
- pgl = primaryPG.pgl;
243
-
244
- this.vertexURL = vertURL;
245
- this.fragmentURL = fragURL;
246
- this.vertexFilename = null;
247
- this.fragmentFilename = null;
248
- fragmentShaderSource = pgl.loadFragmentShader(fragURL);
249
- vertexShaderSource = pgl.loadVertexShader(vertURL);
250
-
251
- glProgram = 0;
252
- glVertex = 0;
253
- glFragment = 0;
254
-
255
- intBuffer = PGL.allocateIntBuffer(1);
256
- floatBuffer = PGL.allocateFloatBuffer(1);
257
-
258
- int vertType = getShaderType(vertexShaderSource, -1);
259
- int fragType = getShaderType(fragmentShaderSource, -1);
260
- if (vertType == -1 && fragType == -1) {
261
- type = PShader.POLY;
262
- } else if (vertType == -1) {
263
- type = fragType;
264
- } else if (fragType == -1) {
265
- type = vertType;
266
- } else if (fragType == vertType) {
267
- type = vertType;
268
- } else {
269
- PGraphics.showWarning(PGraphicsOpenGL.INCONSISTENT_SHADER_TYPES);
270
- }
271
- }
272
-
273
- public PShader(PApplet parent, String[] vertSource, String[] fragSource) {
274
- this.parent = parent;
275
- primaryPG = (PGraphicsOpenGL) parent.g;
276
- pgl = primaryPG.pgl;
277
-
278
- this.vertexURL = null;
279
- this.fragmentURL = null;
280
- this.vertexFilename = null;
281
- this.fragmentFilename = null;
282
- vertexShaderSource = vertSource;
283
- fragmentShaderSource = fragSource;
284
-
285
- glProgram = 0;
286
- glVertex = 0;
287
- glFragment = 0;
288
-
289
- intBuffer = PGL.allocateIntBuffer(1);
290
- floatBuffer = PGL.allocateFloatBuffer(1);
291
-
292
- int vertType = getShaderType(vertexShaderSource, -1);
293
- int fragType = getShaderType(fragmentShaderSource, -1);
294
- if (vertType == -1 && fragType == -1) {
295
- type = PShader.POLY;
296
- } else if (vertType == -1) {
297
- type = fragType;
298
- } else if (fragType == -1) {
299
- type = vertType;
300
- } else if (fragType == vertType) {
301
- type = vertType;
302
- } else {
303
- PGraphics.showWarning(PGraphicsOpenGL.INCONSISTENT_SHADER_TYPES);
304
- }
305
- }
306
-
307
- public void setVertexShader(String vertFilename) {
308
- this.vertexFilename = vertFilename;
309
- vertexShaderSource = pgl.loadVertexShader(vertFilename);
310
- }
311
-
312
- public void setVertexShader(URL vertURL) {
313
- this.vertexURL = vertURL;
314
- vertexShaderSource = pgl.loadVertexShader(vertURL);
315
- }
316
-
317
- public void setVertexShader(String[] vertSource) {
318
- vertexShaderSource = vertSource;
319
- }
320
-
321
- public void setFragmentShader(String fragFilename) {
322
- this.fragmentFilename = fragFilename;
323
- fragmentShaderSource = pgl.loadFragmentShader(fragFilename);
324
- }
325
-
326
- public void setFragmentShader(URL fragURL) {
327
- this.fragmentURL = fragURL;
328
- fragmentShaderSource = pgl.loadFragmentShader(fragURL);
329
- }
330
-
331
- public void setFragmentShader(String[] fragSource) {
332
- fragmentShaderSource = fragSource;
333
- }
334
-
335
- /**
336
- * Initializes (if needed) and binds the shader program.
337
- */
338
- public void bind() {
339
- init();
340
- if (!bound) {
341
- pgl.useProgram(glProgram);
342
- bound = true;
343
- consumeUniforms();
344
- bindTextures();
345
- }
346
-
347
- if (hasType()) {
348
- bindTyped();
349
- }
350
- }
351
-
352
- /**
353
- * Unbinds the shader program.
354
- */
355
- public void unbind() {
356
- if (hasType()) {
357
- unbindTyped();
358
- }
359
-
360
- if (bound) {
361
- unbindTextures();
362
- pgl.useProgram(0);
363
- bound = false;
364
- }
365
- }
366
-
367
- /**
368
- * Returns true if the shader is bound, false otherwise.
369
- */
370
- public boolean bound() {
371
- return bound;
372
- }
373
-
374
- /**
375
- * @webref rendering:shaders
376
- * @brief Sets a variable within the shader
377
- * @param name the name of the uniform variable to modify
378
- * @param x first component of the variable to modify
379
- */
380
- public void set(String name, int x) {
381
- setUniformImpl(name, UniformValue.INT1, new int[]{x});
382
- }
383
-
384
- /**
385
- * @param y second component of the variable to modify. The variable has to
386
- * be declared with an array/vector type in the shader (i.e.: int[2], vec2)
387
- */
388
- public void set(String name, int x, int y) {
389
- setUniformImpl(name, UniformValue.INT2, new int[]{x, y});
390
- }
391
-
392
- /**
393
- * @param z third component of the variable to modify. The variable has to
394
- * be declared with an array/vector type in the shader (i.e.: int[3], vec3)
395
- */
396
- public void set(String name, int x, int y, int z) {
397
- setUniformImpl(name, UniformValue.INT3, new int[]{x, y, z});
398
- }
399
-
400
- /**
401
- * @param w fourth component of the variable to modify. The variable has to
402
- * be declared with an array/vector type in the shader (i.e.: int[4], vec4)
403
- */
404
- public void set(String name, int x, int y, int z, int w) {
405
- setUniformImpl(name, UniformValue.INT4, new int[]{x, y, z, w});
406
- }
407
-
408
- public void set(String name, float x) {
409
- setUniformImpl(name, UniformValue.FLOAT1, new float[]{x});
410
- }
411
-
412
- public void set(String name, float x, float y) {
413
- setUniformImpl(name, UniformValue.FLOAT2, new float[]{x, y});
414
- }
415
-
416
- public void set(String name, float x, float y, float z) {
417
- setUniformImpl(name, UniformValue.FLOAT3, new float[]{x, y, z});
418
- }
419
-
420
- public void set(String name, float x, float y, float z, float w) {
421
- setUniformImpl(name, UniformValue.FLOAT4, new float[]{x, y, z, w});
422
- }
423
-
424
- /**
425
- * @param vec modifies all the components of an array/vector uniform
426
- * variable. PVector can only be used if the type of the variable is vec3.
427
- */
428
- public void set(String name, PVector vec) {
429
- setUniformImpl(name, UniformValue.FLOAT3,
430
- new float[]{vec.x, vec.y, vec.z});
431
- }
432
-
433
- public void set(String name, boolean x) {
434
- setUniformImpl(name, UniformValue.INT1, new int[]{(x) ? 1 : 0});
435
- }
436
-
437
- public void set(String name, boolean x, boolean y) {
438
- setUniformImpl(name, UniformValue.INT2,
439
- new int[]{(x) ? 1 : 0, (y) ? 1 : 0});
440
- }
441
-
442
- public void set(String name, boolean x, boolean y, boolean z) {
443
- setUniformImpl(name, UniformValue.INT3,
444
- new int[]{(x) ? 1 : 0, (y) ? 1 : 0, (z) ? 1 : 0});
445
- }
446
-
447
- public void set(String name, boolean x, boolean y, boolean z, boolean w) {
448
- setUniformImpl(name, UniformValue.INT4,
449
- new int[]{(x) ? 1 : 0, (y) ? 1 : 0, (z) ? 1 : 0, (w) ? 1 : 0});
450
- }
451
-
452
- public void set(String name, int[] vec) {
453
- set(name, vec, 1);
454
- }
455
-
456
- /**
457
- * @param ncoords number of coordinates per element, max 4
458
- */
459
- public void set(String name, int[] vec, int ncoords) {
460
- if (ncoords == 1) {
461
- setUniformImpl(name, UniformValue.INT1VEC, vec);
462
- } else if (ncoords == 2) {
463
- setUniformImpl(name, UniformValue.INT2VEC, vec);
464
- } else if (ncoords == 3) {
465
- setUniformImpl(name, UniformValue.INT3VEC, vec);
466
- } else if (ncoords == 4) {
467
- setUniformImpl(name, UniformValue.INT4VEC, vec);
468
- } else if (4 < ncoords) {
469
- PGraphics.showWarning("Only up to 4 coordinates per element are "
470
- + "supported.");
471
- } else {
472
- PGraphics.showWarning("Wrong number of coordinates: it is negative!");
473
- }
474
- }
475
-
476
- public void set(String name, float[] vec) {
477
- set(name, vec, 1);
478
- }
479
-
480
- public void set(String name, float[] vec, int ncoords) {
481
- if (ncoords == 1) {
482
- setUniformImpl(name, UniformValue.FLOAT1VEC, vec);
483
- } else if (ncoords == 2) {
484
- setUniformImpl(name, UniformValue.FLOAT2VEC, vec);
485
- } else if (ncoords == 3) {
486
- setUniformImpl(name, UniformValue.FLOAT3VEC, vec);
487
- } else if (ncoords == 4) {
488
- setUniformImpl(name, UniformValue.FLOAT4VEC, vec);
489
- } else if (4 < ncoords) {
490
- PGraphics.showWarning("Only up to 4 coordinates per element are "
491
- + "supported.");
42
+ static protected final int POINT = 0;
43
+ static protected final int LINE = 1;
44
+ static protected final int POLY = 2;
45
+ static protected final int COLOR = 3;
46
+ static protected final int LIGHT = 4;
47
+ static protected final int TEXTURE = 5;
48
+ static protected final int TEXLIGHT = 6;
49
+
50
+ static protected String pointShaderAttrRegexp
51
+ = "attribute *vec2 *offset";
52
+ static protected String pointShaderInRegexp
53
+ = "in *vec2 *offset;";
54
+ static protected String lineShaderAttrRegexp
55
+ = "attribute *vec4 *direction";
56
+ static protected String lineShaderInRegexp
57
+ = "in *vec4 *direction";
58
+ static protected String pointShaderDefRegexp
59
+ = "#define *PROCESSING_POINT_SHADER";
60
+ static protected String lineShaderDefRegexp
61
+ = "#define *PROCESSING_LINE_SHADER";
62
+ static protected String colorShaderDefRegexp
63
+ = "#define *PROCESSING_COLOR_SHADER";
64
+ static protected String lightShaderDefRegexp
65
+ = "#define *PROCESSING_LIGHT_SHADER";
66
+ static protected String texShaderDefRegexp
67
+ = "#define *PROCESSING_TEXTURE_SHADER";
68
+ static protected String texlightShaderDefRegexp
69
+ = "#define *PROCESSING_TEXLIGHT_SHADER";
70
+ static protected String polyShaderDefRegexp
71
+ = "#define *PROCESSING_POLYGON_SHADER";
72
+ static protected String triShaderAttrRegexp
73
+ = "#define *PROCESSING_TRIANGLES_SHADER";
74
+ static protected String quadShaderAttrRegexp
75
+ = "#define *PROCESSING_QUADS_SHADER";
76
+
77
+ protected PApplet parent;
78
+ // The main renderer associated to the parent PApplet.
79
+ //protected PGraphicsOpenGL pgMain;
80
+ // We need a reference to the renderer since a shader might
81
+ // be called by different renderers within a single application
82
+ // (the one corresponding to the main surface, or other offscreen
83
+ // renderers).
84
+ protected PGraphicsOpenGL primaryPG;
85
+ protected PGraphicsOpenGL currentPG;
86
+ protected PGL pgl;
87
+ protected int context; // The context that created this shader.
88
+
89
+ // The shader type: POINT, LINE, POLY, etc.
90
+ protected int type;
91
+
92
+ public int glProgram;
93
+ public int glVertex;
94
+ public int glFragment;
95
+ private GLResourceShader glres;
96
+
97
+ protected URL vertexURL;
98
+ protected URL fragmentURL;
99
+
100
+ protected String vertexFilename;
101
+ protected String fragmentFilename;
102
+
103
+ protected String[] vertexShaderSource;
104
+ protected String[] fragmentShaderSource;
105
+
106
+ protected boolean bound;
107
+
108
+ protected HashMap<String, UniformValue> uniformValues = null;
109
+
110
+ protected HashMap<Integer, Texture> textures;
111
+ protected HashMap<Integer, Integer> texUnits;
112
+
113
+ // Direct buffers to pass shader data to GL
114
+ protected IntBuffer intBuffer;
115
+ protected FloatBuffer floatBuffer;
116
+
117
+ protected boolean loadedAttributes = false;
118
+ protected boolean loadedUniforms = false;
119
+
120
+ // Uniforms common to all shader types
121
+ protected int transformMatLoc;
122
+ protected int modelviewMatLoc;
123
+ protected int projectionMatLoc;
124
+ protected int ppixelsLoc;
125
+ protected int ppixelsUnit;
126
+ protected int viewportLoc;
127
+ protected int resolutionLoc;
128
+
129
+ // Uniforms only for lines and points
130
+ protected int perspectiveLoc;
131
+ protected int scaleLoc;
132
+
133
+ // Lighting uniforms
134
+ protected int lightCountLoc;
135
+ protected int lightPositionLoc;
136
+ protected int lightNormalLoc;
137
+ protected int lightAmbientLoc;
138
+ protected int lightDiffuseLoc;
139
+ protected int lightSpecularLoc;
140
+ protected int lightFalloffLoc;
141
+ protected int lightSpotLoc;
142
+
143
+ // Texturing uniforms
144
+ protected Texture texture;
145
+ protected int texUnit;
146
+ protected int textureLoc;
147
+ protected int texMatrixLoc;
148
+ protected int texOffsetLoc;
149
+ protected float[] tcmat;
150
+
151
+ // Vertex attributes
152
+ protected int vertexLoc;
153
+ protected int colorLoc;
154
+ protected int normalLoc;
155
+ protected int texCoordLoc;
156
+ protected int normalMatLoc;
157
+ protected int directionLoc;
158
+ protected int offsetLoc;
159
+ protected int ambientLoc;
160
+ protected int specularLoc;
161
+ protected int emissiveLoc;
162
+ protected int shininessLoc;
163
+
164
+ public PShader() {
165
+ parent = null;
166
+ pgl = null;
167
+ context = -1;
168
+
169
+ this.vertexURL = null;
170
+ this.fragmentURL = null;
171
+ this.vertexFilename = null;
172
+ this.fragmentFilename = null;
173
+
174
+ glProgram = 0;
175
+ glVertex = 0;
176
+ glFragment = 0;
177
+
178
+ intBuffer = PGL.allocateIntBuffer(1);
179
+ floatBuffer = PGL.allocateFloatBuffer(1);
180
+
181
+ bound = false;
182
+
183
+ type = -1;
184
+ }
185
+
186
+ public PShader(PApplet parent) {
187
+ this();
188
+ this.parent = parent;
189
+ primaryPG = (PGraphicsOpenGL) parent.g;
190
+ pgl = primaryPG.pgl;
191
+ context = pgl.createEmptyContext();
192
+ }
193
+
194
+ /**
195
+ * Creates a shader program using the specified vertex and fragment shaders.
196
+ *
197
+ * @param parent the parent program
198
+ * @param vertFilename name of the vertex shader
199
+ * @param fragFilename name of the fragment shader
200
+ */
201
+ public PShader(PApplet parent, String vertFilename, String fragFilename) {
202
+ this.parent = parent;
203
+ primaryPG = (PGraphicsOpenGL) parent.g;
204
+ pgl = primaryPG.pgl;
205
+
206
+ this.vertexURL = null;
207
+ this.fragmentURL = null;
208
+ this.vertexFilename = vertFilename;
209
+ this.fragmentFilename = fragFilename;
210
+ fragmentShaderSource = pgl.loadFragmentShader(fragFilename);
211
+ vertexShaderSource = pgl.loadVertexShader(vertFilename);
212
+
213
+ glProgram = 0;
214
+ glVertex = 0;
215
+ glFragment = 0;
216
+
217
+ intBuffer = PGL.allocateIntBuffer(1);
218
+ floatBuffer = PGL.allocateFloatBuffer(1);
219
+
220
+ int vertType = getShaderType(vertexShaderSource, -1);
221
+ int fragType = getShaderType(fragmentShaderSource, -1);
222
+ if (vertType == -1 && fragType == -1) {
223
+ type = PShader.POLY;
224
+ } else if (vertType == -1) {
225
+ type = fragType;
226
+ } else if (fragType == -1) {
227
+ type = vertType;
228
+ } else if (fragType == vertType) {
229
+ type = vertType;
230
+ } else {
231
+ PGraphics.showWarning(PGraphicsOpenGL.INCONSISTENT_SHADER_TYPES);
232
+ }
233
+ }
234
+
235
+ /**
236
+ * @param parent
237
+ * @param vertURL network location of the vertex shader
238
+ * @param fragURL network location of the fragment shader
239
+ */
240
+ public PShader(PApplet parent, URL vertURL, URL fragURL) {
241
+ this.parent = parent;
242
+ primaryPG = (PGraphicsOpenGL) parent.g;
243
+ pgl = primaryPG.pgl;
244
+
245
+ this.vertexURL = vertURL;
246
+ this.fragmentURL = fragURL;
247
+ this.vertexFilename = null;
248
+ this.fragmentFilename = null;
249
+ fragmentShaderSource = pgl.loadFragmentShader(fragURL);
250
+ vertexShaderSource = pgl.loadVertexShader(vertURL);
251
+
252
+ glProgram = 0;
253
+ glVertex = 0;
254
+ glFragment = 0;
255
+
256
+ intBuffer = PGL.allocateIntBuffer(1);
257
+ floatBuffer = PGL.allocateFloatBuffer(1);
258
+
259
+ int vertType = getShaderType(vertexShaderSource, -1);
260
+ int fragType = getShaderType(fragmentShaderSource, -1);
261
+ if (vertType == -1 && fragType == -1) {
262
+ type = PShader.POLY;
263
+ } else if (vertType == -1) {
264
+ type = fragType;
265
+ } else if (fragType == -1) {
266
+ type = vertType;
267
+ } else if (fragType == vertType) {
268
+ type = vertType;
269
+ } else {
270
+ PGraphics.showWarning(PGraphicsOpenGL.INCONSISTENT_SHADER_TYPES);
271
+ }
272
+ }
273
+
274
+ public PShader(PApplet parent, String[] vertSource, String[] fragSource) {
275
+ this.parent = parent;
276
+ primaryPG = (PGraphicsOpenGL) parent.g;
277
+ pgl = primaryPG.pgl;
278
+
279
+ this.vertexURL = null;
280
+ this.fragmentURL = null;
281
+ this.vertexFilename = null;
282
+ this.fragmentFilename = null;
283
+ vertexShaderSource = vertSource;
284
+ fragmentShaderSource = fragSource;
285
+
286
+ glProgram = 0;
287
+ glVertex = 0;
288
+ glFragment = 0;
289
+
290
+ intBuffer = PGL.allocateIntBuffer(1);
291
+ floatBuffer = PGL.allocateFloatBuffer(1);
292
+
293
+ int vertType = getShaderType(vertexShaderSource, -1);
294
+ int fragType = getShaderType(fragmentShaderSource, -1);
295
+ if (vertType == -1 && fragType == -1) {
296
+ type = PShader.POLY;
297
+ } else if (vertType == -1) {
298
+ type = fragType;
299
+ } else if (fragType == -1) {
300
+ type = vertType;
301
+ } else if (fragType == vertType) {
302
+ type = vertType;
303
+ } else {
304
+ PGraphics.showWarning(PGraphicsOpenGL.INCONSISTENT_SHADER_TYPES);
305
+ }
306
+ }
307
+
308
+ public void setVertexShader(String vertFilename) {
309
+ this.vertexFilename = vertFilename;
310
+ vertexShaderSource = pgl.loadVertexShader(vertFilename);
311
+ }
312
+
313
+ public void setVertexShader(URL vertURL) {
314
+ this.vertexURL = vertURL;
315
+ vertexShaderSource = pgl.loadVertexShader(vertURL);
316
+ }
317
+
318
+ public void setVertexShader(String[] vertSource) {
319
+ vertexShaderSource = vertSource;
320
+ }
321
+
322
+ public void setFragmentShader(String fragFilename) {
323
+ this.fragmentFilename = fragFilename;
324
+ fragmentShaderSource = pgl.loadFragmentShader(fragFilename);
325
+ }
326
+
327
+ public void setFragmentShader(URL fragURL) {
328
+ this.fragmentURL = fragURL;
329
+ fragmentShaderSource = pgl.loadFragmentShader(fragURL);
330
+ }
331
+
332
+ public void setFragmentShader(String[] fragSource) {
333
+ fragmentShaderSource = fragSource;
334
+ }
335
+
336
+ /**
337
+ * Initializes (if needed) and binds the shader program.
338
+ */
339
+ public void bind() {
340
+ init();
341
+ if (!bound) {
342
+ pgl.useProgram(glProgram);
343
+ bound = true;
344
+ consumeUniforms();
345
+ bindTextures();
346
+ }
347
+
348
+ if (hasType()) {
349
+ bindTyped();
350
+ }
351
+ }
352
+
353
+ /**
354
+ * Unbinds the shader program.
355
+ */
356
+ public void unbind() {
357
+ if (hasType()) {
358
+ unbindTyped();
359
+ }
360
+
361
+ if (bound) {
362
+ unbindTextures();
363
+ pgl.useProgram(0);
364
+ bound = false;
365
+ }
366
+ }
367
+
368
+ /**
369
+ * Returns true if the shader is bound, false otherwise.
370
+ *
371
+ * @return
372
+ */
373
+ public boolean bound() {
374
+ return bound;
375
+ }
376
+
377
+ /**
378
+ * @webref rendering:shaders
379
+ * @brief Sets a variable within the shader
380
+ * @param name the name of the uniform variable to modify
381
+ * @param x first component of the variable to modify
382
+ */
383
+ public void set(String name, int x) {
384
+ setUniformImpl(name, UniformValue.INT1, new int[]{x});
385
+ }
386
+
387
+ /**
388
+ * @param name
389
+ * @param x
390
+ * @param y second component of the variable to modify. The variable has to be
391
+ * declared with an array/vector type in the shader (i.e.: int[2], vec2)
392
+ */
393
+ public void set(String name, int x, int y) {
394
+ setUniformImpl(name, UniformValue.INT2, new int[]{x, y});
395
+ }
396
+
397
+ /**
398
+ * @param name
399
+ * @param x
400
+ * @param y
401
+ * @param z third component of the variable to modify. The variable has to be
402
+ * declared with an array/vector type in the shader (i.e.: int[3], vec3)
403
+ */
404
+ public void set(String name, int x, int y, int z) {
405
+ setUniformImpl(name, UniformValue.INT3, new int[]{x, y, z});
406
+ }
407
+
408
+ /**
409
+ * @param name
410
+ * @param x
411
+ * @param y
412
+ * @param z
413
+ * @param w fourth component of the variable to modify. The variable has to be
414
+ * declared with an array/vector type in the shader (i.e.: int[4], vec4)
415
+ */
416
+ public void set(String name, int x, int y, int z, int w) {
417
+ setUniformImpl(name, UniformValue.INT4, new int[]{x, y, z, w});
418
+ }
419
+
420
+ public void set(String name, float x) {
421
+ setUniformImpl(name, UniformValue.FLOAT1, new float[]{x});
422
+ }
423
+
424
+ public void set(String name, float x, float y) {
425
+ setUniformImpl(name, UniformValue.FLOAT2, new float[]{x, y});
426
+ }
427
+
428
+ public void set(String name, float x, float y, float z) {
429
+ setUniformImpl(name, UniformValue.FLOAT3, new float[]{x, y, z});
430
+ }
431
+
432
+ public void set(String name, float x, float y, float z, float w) {
433
+ setUniformImpl(name, UniformValue.FLOAT4, new float[]{x, y, z, w});
434
+ }
435
+
436
+ /**
437
+ * @param name
438
+ * @param vec modifies all the components of an array/vector uniform variable.
439
+ * PVector can only be used if the type of the variable is vec3.
440
+ */
441
+ public void set(String name, PVector vec) {
442
+ setUniformImpl(name, UniformValue.FLOAT3,
443
+ new float[]{vec.x, vec.y, vec.z});
444
+ }
445
+
446
+ public void set(String name, boolean x) {
447
+ setUniformImpl(name, UniformValue.INT1, new int[]{(x) ? 1 : 0});
448
+ }
449
+
450
+ public void set(String name, boolean x, boolean y) {
451
+ setUniformImpl(name, UniformValue.INT2,
452
+ new int[]{(x) ? 1 : 0, (y) ? 1 : 0});
453
+ }
454
+
455
+ public void set(String name, boolean x, boolean y, boolean z) {
456
+ setUniformImpl(name, UniformValue.INT3,
457
+ new int[]{(x) ? 1 : 0, (y) ? 1 : 0, (z) ? 1 : 0});
458
+ }
459
+
460
+ public void set(String name, boolean x, boolean y, boolean z, boolean w) {
461
+ setUniformImpl(name, UniformValue.INT4,
462
+ new int[]{(x) ? 1 : 0, (y) ? 1 : 0, (z) ? 1 : 0, (w) ? 1 : 0});
463
+ }
464
+
465
+ public void set(String name, int[] vec) {
466
+ set(name, vec, 1);
467
+ }
468
+
469
+ /**
470
+ * @param name
471
+ * @param vec
472
+ * @param ncoords number of coordinates per element, max 4
473
+ */
474
+ public void set(String name, int[] vec, int ncoords) {
475
+ if (ncoords == 1) {
476
+ setUniformImpl(name, UniformValue.INT1VEC, vec);
477
+ } else if (ncoords == 2) {
478
+ setUniformImpl(name, UniformValue.INT2VEC, vec);
479
+ } else if (ncoords == 3) {
480
+ setUniformImpl(name, UniformValue.INT3VEC, vec);
481
+ } else if (ncoords == 4) {
482
+ setUniformImpl(name, UniformValue.INT4VEC, vec);
483
+ } else if (4 < ncoords) {
484
+ PGraphics.showWarning("Only up to 4 coordinates per element are "
485
+ + "supported.");
486
+ } else {
487
+ PGraphics.showWarning("Wrong number of coordinates: it is negative!");
488
+ }
489
+ }
490
+
491
+ public void set(String name, float[] vec) {
492
+ set(name, vec, 1);
493
+ }
494
+
495
+ public void set(String name, float[] vec, int ncoords) {
496
+ if (ncoords == 1) {
497
+ setUniformImpl(name, UniformValue.FLOAT1VEC, vec);
498
+ } else if (ncoords == 2) {
499
+ setUniformImpl(name, UniformValue.FLOAT2VEC, vec);
500
+ } else if (ncoords == 3) {
501
+ setUniformImpl(name, UniformValue.FLOAT3VEC, vec);
502
+ } else if (ncoords == 4) {
503
+ setUniformImpl(name, UniformValue.FLOAT4VEC, vec);
504
+ } else if (4 < ncoords) {
505
+ PGraphics.showWarning("Only up to 4 coordinates per element are "
506
+ + "supported.");
507
+ } else {
508
+ PGraphics.showWarning("Wrong number of coordinates: it is negative!");
509
+ }
510
+ }
511
+
512
+ public void set(String name, boolean[] vec) {
513
+ set(name, vec, 1);
514
+ }
515
+
516
+ public void set(String name, boolean[] boolvec, int ncoords) {
517
+ int[] vec = new int[boolvec.length];
518
+ for (int i = 0; i < boolvec.length; i++) {
519
+ vec[i] = (boolvec[i]) ? 1 : 0;
520
+ }
521
+ set(name, vec, ncoords);
522
+ }
523
+
524
+ /**
525
+ * @param name
526
+ * @param mat matrix of values
527
+ */
528
+ public void set(String name, PMatrix2D mat) {
529
+ float[] matv = {mat.m00, mat.m01,
530
+ mat.m10, mat.m11};
531
+ setUniformImpl(name, UniformValue.MAT2, matv);
532
+ }
533
+
534
+ public void set(String name, PMatrix3D mat) {
535
+ set(name, mat, false);
536
+ }
537
+
538
+ /**
539
+ * @param name
540
+ * @param mat
541
+ * @param use3x3 enforces the matrix is 3 x 3
542
+ */
543
+ public void set(String name, PMatrix3D mat, boolean use3x3) {
544
+ if (use3x3) {
545
+ float[] matv = {mat.m00, mat.m01, mat.m02,
546
+ mat.m10, mat.m11, mat.m12,
547
+ mat.m20, mat.m21, mat.m22};
548
+ setUniformImpl(name, UniformValue.MAT3, matv);
549
+ } else {
550
+ float[] matv = {mat.m00, mat.m01, mat.m02, mat.m03,
551
+ mat.m10, mat.m11, mat.m12, mat.m13,
552
+ mat.m20, mat.m21, mat.m22, mat.m23,
553
+ mat.m30, mat.m31, mat.m32, mat.m33};
554
+ setUniformImpl(name, UniformValue.MAT4, matv);
555
+ }
556
+ }
557
+
558
+ /**
559
+ * @param name
560
+ * @param tex sets the sampler uniform variable to read from this image
561
+ * texture
562
+ */
563
+ public void set(String name, PImage tex) {
564
+ setUniformImpl(name, UniformValue.SAMPLER2D, tex);
565
+ }
566
+
567
+ /**
568
+ * Extra initialization method that can be used by subclasses, called after
569
+ * compiling and attaching the vertex and fragment shaders, and before linking
570
+ * the shader program.
571
+ *
572
+ */
573
+ protected void setup() {
574
+ }
575
+
576
+ protected void draw(int idxId, int count, int offset) {
577
+ pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, idxId);
578
+ pgl.drawElements(PGL.TRIANGLES, count, PGL.INDEX_TYPE,
579
+ offset * PGL.SIZEOF_INDEX);
580
+ pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, 0);
581
+ }
582
+
583
+ /**
584
+ * Returns the ID location of the attribute parameter given its name.
585
+ *
586
+ * @param name String
587
+ * @return int
588
+ */
589
+ protected int getAttributeLoc(String name) {
590
+ init();
591
+ return pgl.getAttribLocation(glProgram, name);
592
+ }
593
+
594
+ /**
595
+ * Returns the ID location of the uniform parameter given its name.
596
+ *
597
+ * @param name String
598
+ * @return int
599
+ */
600
+ protected int getUniformLoc(String name) {
601
+ init();
602
+ return pgl.getUniformLocation(glProgram, name);
603
+ }
604
+
605
+ protected void setAttributeVBO(int loc, int vboId, int size, int type,
606
+ boolean normalized, int stride, int offset) {
607
+ if (-1 < loc) {
608
+ pgl.bindBuffer(PGL.ARRAY_BUFFER, vboId);
609
+ pgl.vertexAttribPointer(loc, size, type, normalized, stride, offset);
610
+ }
611
+ }
612
+
613
+ protected void setUniformValue(int loc, int x) {
614
+ if (-1 < loc) {
615
+ pgl.uniform1i(loc, x);
616
+ }
617
+ }
618
+
619
+ protected void setUniformValue(int loc, int x, int y) {
620
+ if (-1 < loc) {
621
+ pgl.uniform2i(loc, x, y);
622
+ }
623
+ }
624
+
625
+ protected void setUniformValue(int loc, int x, int y, int z) {
626
+ if (-1 < loc) {
627
+ pgl.uniform3i(loc, x, y, z);
628
+ }
629
+ }
630
+
631
+ protected void setUniformValue(int loc, int x, int y, int z, int w) {
632
+ if (-1 < loc) {
633
+ pgl.uniform4i(loc, x, y, z, w);
634
+ }
635
+ }
636
+
637
+ protected void setUniformValue(int loc, float x) {
638
+ if (-1 < loc) {
639
+ pgl.uniform1f(loc, x);
640
+ }
641
+ }
642
+
643
+ protected void setUniformValue(int loc, float x, float y) {
644
+ if (-1 < loc) {
645
+ pgl.uniform2f(loc, x, y);
646
+ }
647
+ }
648
+
649
+ protected void setUniformValue(int loc, float x, float y, float z) {
650
+ if (-1 < loc) {
651
+ pgl.uniform3f(loc, x, y, z);
652
+ }
653
+ }
654
+
655
+ protected void setUniformValue(int loc, float x, float y, float z, float w) {
656
+ if (-1 < loc) {
657
+ pgl.uniform4f(loc, x, y, z, w);
658
+ }
659
+ }
660
+
661
+ protected void setUniformVector(int loc, int[] vec, int ncoords,
662
+ int length) {
663
+ if (-1 < loc) {
664
+ updateIntBuffer(vec);
665
+ switch (ncoords) {
666
+ case 1:
667
+ pgl.uniform1iv(loc, length, intBuffer);
668
+ break;
669
+ case 2:
670
+ pgl.uniform2iv(loc, length, intBuffer);
671
+ break;
672
+ case 3:
673
+ pgl.uniform3iv(loc, length, intBuffer);
674
+ break;
675
+ case 4:
676
+ pgl.uniform3iv(loc, length, intBuffer);
677
+ break;
678
+ default:
679
+ break;
680
+ }
681
+ }
682
+ }
683
+
684
+ protected void setUniformVector(int loc, float[] vec, int ncoords,
685
+ int length) {
686
+ if (-1 < loc) {
687
+ updateFloatBuffer(vec);
688
+ switch (ncoords) {
689
+ case 1:
690
+ pgl.uniform1fv(loc, length, floatBuffer);
691
+ break;
692
+ case 2:
693
+ pgl.uniform2fv(loc, length, floatBuffer);
694
+ break;
695
+ case 3:
696
+ pgl.uniform3fv(loc, length, floatBuffer);
697
+ break;
698
+ case 4:
699
+ pgl.uniform4fv(loc, length, floatBuffer);
700
+ break;
701
+ default:
702
+ break;
703
+ }
704
+ }
705
+ }
706
+
707
+ protected void setUniformMatrix(int loc, float[] mat) {
708
+ if (-1 < loc) {
709
+ updateFloatBuffer(mat);
710
+ switch (mat.length) {
711
+ case 4:
712
+ pgl.uniformMatrix2fv(loc, 1, false, floatBuffer);
713
+ break;
714
+ case 9:
715
+ pgl.uniformMatrix3fv(loc, 1, false, floatBuffer);
716
+ break;
717
+ case 16:
718
+ pgl.uniformMatrix4fv(loc, 1, false, floatBuffer);
719
+ break;
720
+ default:
721
+ break;
722
+ }
723
+ }
724
+ }
725
+
726
+ protected void setUniformTex(int loc, Texture tex) {
727
+ if (texUnits != null) {
728
+ Integer unit = texUnits.get(loc);
729
+ if (unit != null) {
730
+ pgl.activeTexture(PGL.TEXTURE0 + unit);
731
+ tex.bind();
732
+ } else {
733
+ throw new RuntimeException("Cannot find unit for texture " + tex);
734
+ }
735
+ }
736
+ }
737
+
738
+ protected void setUniformImpl(String name, int type, Object value) {
739
+ if (uniformValues == null) {
740
+ uniformValues = new HashMap<>();
741
+ }
742
+ uniformValues.put(name, new UniformValue(type, value));
743
+ }
744
+
745
+ protected void consumeUniforms() {
746
+ if (uniformValues != null && 0 < uniformValues.size()) {
747
+ int unit = 0;
748
+ for (String name : uniformValues.keySet()) {
749
+ int loc = getUniformLoc(name);
750
+ if (loc == -1) {
751
+ PGraphics.showWarning("The shader doesn't have a uniform called \""
752
+ + name + "\" OR the uniform was removed during "
753
+ + "compilation because it was unused.");
754
+ continue;
755
+ }
756
+ UniformValue val = uniformValues.get(name);
757
+ switch (val.type) {
758
+ case UniformValue.INT1:
759
+ {
760
+ int[] v = ((int[]) val.value);
761
+ pgl.uniform1i(loc, v[0]);
762
+ break;
763
+ }
764
+ case UniformValue.INT2:
765
+ {
766
+ int[] v = ((int[]) val.value);
767
+ pgl.uniform2i(loc, v[0], v[1]);
768
+ break;
769
+ }
770
+ case UniformValue.INT3:
771
+ {
772
+ int[] v = ((int[]) val.value);
773
+ pgl.uniform3i(loc, v[0], v[1], v[2]);
774
+ break;
775
+ }
776
+ case UniformValue.INT4:
777
+ {
778
+ int[] v = ((int[]) val.value);
779
+ pgl.uniform4i(loc, v[0], v[1], v[2], v[3]);
780
+ break;
781
+ }
782
+ case UniformValue.FLOAT1:
783
+ {
784
+ float[] v = ((float[]) val.value);
785
+ pgl.uniform1f(loc, v[0]);
786
+ break;
787
+ }
788
+ case UniformValue.FLOAT2:
789
+ {
790
+ float[] v = ((float[]) val.value);
791
+ pgl.uniform2f(loc, v[0], v[1]);
792
+ break;
793
+ }
794
+ case UniformValue.FLOAT3:
795
+ {
796
+ float[] v = ((float[]) val.value);
797
+ pgl.uniform3f(loc, v[0], v[1], v[2]);
798
+ break;
799
+ }
800
+ case UniformValue.FLOAT4:
801
+ {
802
+ float[] v = ((float[]) val.value);
803
+ pgl.uniform4f(loc, v[0], v[1], v[2], v[3]);
804
+ break;
805
+ }
806
+ case UniformValue.INT1VEC:
807
+ {
808
+ int[] v = ((int[]) val.value);
809
+ updateIntBuffer(v);
810
+ pgl.uniform1iv(loc, v.length, intBuffer);
811
+ break;
812
+ }
813
+ case UniformValue.INT2VEC:
814
+ {
815
+ int[] v = ((int[]) val.value);
816
+ updateIntBuffer(v);
817
+ pgl.uniform2iv(loc, v.length / 2, intBuffer);
818
+ break;
819
+ }
820
+ case UniformValue.INT3VEC:
821
+ {
822
+ int[] v = ((int[]) val.value);
823
+ updateIntBuffer(v);
824
+ pgl.uniform3iv(loc, v.length / 3, intBuffer);
825
+ break;
826
+ }
827
+ case UniformValue.INT4VEC:
828
+ {
829
+ int[] v = ((int[]) val.value);
830
+ updateIntBuffer(v);
831
+ pgl.uniform4iv(loc, v.length / 4, intBuffer);
832
+ break;
833
+ }
834
+ case UniformValue.FLOAT1VEC:
835
+ {
836
+ float[] v = ((float[]) val.value);
837
+ updateFloatBuffer(v);
838
+ pgl.uniform1fv(loc, v.length, floatBuffer);
839
+ break;
840
+ }
841
+ case UniformValue.FLOAT2VEC:
842
+ {
843
+ float[] v = ((float[]) val.value);
844
+ updateFloatBuffer(v);
845
+ pgl.uniform2fv(loc, v.length / 2, floatBuffer);
846
+ break;
847
+ }
848
+ case UniformValue.FLOAT3VEC:
849
+ {
850
+ float[] v = ((float[]) val.value);
851
+ updateFloatBuffer(v);
852
+ pgl.uniform3fv(loc, v.length / 3, floatBuffer);
853
+ break;
854
+ }
855
+ case UniformValue.FLOAT4VEC:
856
+ {
857
+ float[] v = ((float[]) val.value);
858
+ updateFloatBuffer(v);
859
+ pgl.uniform4fv(loc, v.length / 4, floatBuffer);
860
+ break;
861
+ }
862
+ case UniformValue.MAT2:
863
+ {
864
+ float[] v = ((float[]) val.value);
865
+ updateFloatBuffer(v);
866
+ pgl.uniformMatrix2fv(loc, 1, false, floatBuffer);
867
+ break;
868
+ }
869
+ case UniformValue.MAT3:
870
+ {
871
+ float[] v = ((float[]) val.value);
872
+ updateFloatBuffer(v);
873
+ pgl.uniformMatrix3fv(loc, 1, false, floatBuffer);
874
+ break;
875
+ }
876
+ case UniformValue.MAT4:
877
+ {
878
+ float[] v = ((float[]) val.value);
879
+ updateFloatBuffer(v);
880
+ pgl.uniformMatrix4fv(loc, 1, false, floatBuffer);
881
+ break;
882
+ }
883
+ case UniformValue.SAMPLER2D:
884
+ PImage img = (PImage) val.value;
885
+ Texture tex = currentPG.getTexture(img);
886
+ if (textures == null) {
887
+ textures = new HashMap<>();
888
+ } textures.put(loc, tex);
889
+ if (texUnits == null) {
890
+ texUnits = new HashMap<>();
891
+ } if (texUnits.containsKey(loc)) {
892
+ unit = texUnits.get(loc);
893
+ pgl.uniform1i(loc, unit);
894
+ } else {
895
+ texUnits.put(loc, unit);
896
+ pgl.uniform1i(loc, unit);
897
+ } unit++;
898
+ break;
899
+ default:
900
+ break;
901
+ }
902
+ }
903
+ uniformValues.clear();
904
+ }
905
+ }
906
+
907
+ protected void updateIntBuffer(int[] vec) {
908
+ intBuffer = PGL.updateIntBuffer(intBuffer, vec, false);
909
+ }
910
+
911
+ protected void updateFloatBuffer(float[] vec) {
912
+ floatBuffer = PGL.updateFloatBuffer(floatBuffer, vec, false);
913
+ }
914
+
915
+ protected void bindTextures() {
916
+ if (textures != null && texUnits != null) {
917
+ textures.keySet().forEach((loc) -> {
918
+ Texture tex = textures.get(loc);
919
+ Integer unit = texUnits.get(loc);
920
+ if (unit != null) {
921
+ pgl.activeTexture(PGL.TEXTURE0 + unit);
922
+ tex.bind();
492
923
  } else {
493
- PGraphics.showWarning("Wrong number of coordinates: it is negative!");
924
+ throw new RuntimeException("Cannot find unit for texture " + tex);
494
925
  }
926
+ });
495
927
  }
928
+ }
496
929
 
497
- public void set(String name, boolean[] vec) {
498
- set(name, vec, 1);
499
- }
500
-
501
- public void set(String name, boolean[] boolvec, int ncoords) {
502
- int[] vec = new int[boolvec.length];
503
- for (int i = 0; i < boolvec.length; i++) {
504
- vec[i] = (boolvec[i]) ? 1 : 0;
505
- }
506
- set(name, vec, ncoords);
507
- }
508
-
509
- /**
510
- * @param mat matrix of values
511
- */
512
- public void set(String name, PMatrix2D mat) {
513
- float[] matv = {mat.m00, mat.m01,
514
- mat.m10, mat.m11};
515
- setUniformImpl(name, UniformValue.MAT2, matv);
516
- }
517
-
518
- public void set(String name, PMatrix3D mat) {
519
- set(name, mat, false);
520
- }
521
-
522
- /**
523
- * @param use3x3 enforces the matrix is 3 x 3
524
- */
525
- public void set(String name, PMatrix3D mat, boolean use3x3) {
526
- if (use3x3) {
527
- float[] matv = {mat.m00, mat.m01, mat.m02,
528
- mat.m10, mat.m11, mat.m12,
529
- mat.m20, mat.m21, mat.m22};
530
- setUniformImpl(name, UniformValue.MAT3, matv);
930
+ protected void unbindTextures() {
931
+ if (textures != null && texUnits != null) {
932
+ textures.keySet().forEach((loc) -> {
933
+ Texture tex = textures.get(loc);
934
+ Integer unit = texUnits.get(loc);
935
+ if (unit != null) {
936
+ pgl.activeTexture(PGL.TEXTURE0 + unit);
937
+ tex.unbind();
531
938
  } else {
532
- float[] matv = {mat.m00, mat.m01, mat.m02, mat.m03,
533
- mat.m10, mat.m11, mat.m12, mat.m13,
534
- mat.m20, mat.m21, mat.m22, mat.m23,
535
- mat.m30, mat.m31, mat.m32, mat.m33};
536
- setUniformImpl(name, UniformValue.MAT4, matv);
939
+ throw new RuntimeException("Cannot find unit for texture " + tex);
537
940
  }
941
+ });
942
+ pgl.activeTexture(PGL.TEXTURE0);
538
943
  }
944
+ }
539
945
 
540
- /**
541
- * @param tex sets the sampler uniform variable to read from this image
542
- * texture
543
- */
544
- public void set(String name, PImage tex) {
545
- setUniformImpl(name, UniformValue.SAMPLER2D, tex);
546
- }
547
-
548
- /**
549
- * Extra initialization method that can be used by subclasses, called after
550
- * compiling and attaching the vertex and fragment shaders, and before
551
- * linking the shader program.
552
- *
553
- */
554
- protected void setup() {
555
- }
556
-
557
- protected void draw(int idxId, int count, int offset) {
558
- pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, idxId);
559
- pgl.drawElements(PGL.TRIANGLES, count, PGL.INDEX_TYPE,
560
- offset * PGL.SIZEOF_INDEX);
561
- pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, 0);
562
- }
563
-
564
- /**
565
- * Returns the ID location of the attribute parameter given its name.
566
- *
567
- * @param name String
568
- * @return int
569
- */
570
- protected int getAttributeLoc(String name) {
571
- init();
572
- return pgl.getAttribLocation(glProgram, name);
573
- }
574
-
575
- /**
576
- * Returns the ID location of the uniform parameter given its name.
577
- *
578
- * @param name String
579
- * @return int
580
- */
581
- protected int getUniformLoc(String name) {
582
- init();
583
- return pgl.getUniformLocation(glProgram, name);
584
- }
585
-
586
- protected void setAttributeVBO(int loc, int vboId, int size, int type,
587
- boolean normalized, int stride, int offset) {
588
- if (-1 < loc) {
589
- pgl.bindBuffer(PGL.ARRAY_BUFFER, vboId);
590
- pgl.vertexAttribPointer(loc, size, type, normalized, stride, offset);
591
- }
592
- }
946
+ public void init() {
947
+ if (glProgram == 0 || contextIsOutdated()) {
948
+ create();
949
+ if (compile()) {
950
+ pgl.attachShader(glProgram, glVertex);
951
+ pgl.attachShader(glProgram, glFragment);
952
+
953
+ setup();
954
+
955
+ pgl.linkProgram(glProgram);
956
+
957
+ validate();
958
+ }
959
+ }
960
+ }
961
+
962
+ protected void create() {
963
+ context = pgl.getCurrentContext();
964
+ glres = new GLResourceShader(this);
965
+ }
966
+
967
+ protected boolean compile() {
968
+ boolean vertRes = true;
969
+ if (hasVertexShader()) {
970
+ vertRes = compileVertexShader();
971
+ } else {
972
+ PGraphics.showException("Doesn't have a vertex shader");
973
+ }
974
+
975
+ boolean fragRes = true;
976
+ if (hasFragmentShader()) {
977
+ fragRes = compileFragmentShader();
978
+ } else {
979
+ PGraphics.showException("Doesn't have a fragment shader");
980
+ }
981
+
982
+ return vertRes && fragRes;
983
+ }
984
+
985
+ protected void validate() {
986
+ pgl.getProgramiv(glProgram, PGL.LINK_STATUS, intBuffer);
987
+ boolean linked = intBuffer.get(0) != 0;
988
+ if (!linked) {
989
+ PGraphics.showException("Cannot link shader program:\n"
990
+ + pgl.getProgramInfoLog(glProgram));
991
+ }
992
+
993
+ pgl.validateProgram(glProgram);
994
+ pgl.getProgramiv(glProgram, PGL.VALIDATE_STATUS, intBuffer);
995
+ boolean validated = intBuffer.get(0) != 0;
996
+ if (!validated) {
997
+ PGraphics.showException("Cannot validate shader program:\n"
998
+ + pgl.getProgramInfoLog(glProgram));
999
+ }
1000
+ }
1001
+
1002
+ protected boolean contextIsOutdated() {
1003
+ boolean outdated = !pgl.contextIsCurrent(context);
1004
+ if (outdated) {
1005
+ dispose();
1006
+ }
1007
+ return outdated;
1008
+ }
1009
+
1010
+ protected boolean hasVertexShader() {
1011
+ return vertexShaderSource != null && 0 < vertexShaderSource.length;
1012
+ }
1013
+
1014
+ protected boolean hasFragmentShader() {
1015
+ return fragmentShaderSource != null && 0 < fragmentShaderSource.length;
1016
+ }
1017
+
1018
+ /**
1019
+ * @return
1020
+ */
1021
+ protected boolean compileVertexShader() {
1022
+ pgl.shaderSource(glVertex, PApplet.join(vertexShaderSource, "\n"));
1023
+ pgl.compileShader(glVertex);
1024
+
1025
+ pgl.getShaderiv(glVertex, PGL.COMPILE_STATUS, intBuffer);
1026
+ boolean compiled = intBuffer.get(0) != 0;
1027
+ if (!compiled) {
1028
+ PGraphics.showException("Cannot compile vertex shader:\n"
1029
+ + pgl.getShaderInfoLog(glVertex));
1030
+ return false;
1031
+ } else {
1032
+ return true;
1033
+ }
1034
+ }
1035
+
1036
+ /**
1037
+ * @return
1038
+ */
1039
+ protected boolean compileFragmentShader() {
1040
+ pgl.shaderSource(glFragment, PApplet.join(fragmentShaderSource, "\n"));
1041
+ pgl.compileShader(glFragment);
1042
+
1043
+ pgl.getShaderiv(glFragment, PGL.COMPILE_STATUS, intBuffer);
1044
+ boolean compiled = intBuffer.get(0) != 0;
1045
+ if (!compiled) {
1046
+ PGraphics.showException("Cannot compile fragment shader:\n"
1047
+ + pgl.getShaderInfoLog(glFragment));
1048
+ return false;
1049
+ } else {
1050
+ return true;
1051
+ }
1052
+ }
1053
+
1054
+ protected void dispose() {
1055
+ if (glres != null) {
1056
+ glres.dispose();
1057
+ glVertex = 0;
1058
+ glFragment = 0;
1059
+ glProgram = 0;
1060
+ glres = null;
1061
+ }
1062
+ }
1063
+
1064
+ static protected int getShaderType(String[] source, int defaultType) {
1065
+ for (String source1 : source) {
1066
+ String line = source1.trim();
1067
+ if (PApplet.match(line, colorShaderDefRegexp) != null) {
1068
+ return PShader.COLOR;
1069
+ } else if (PApplet.match(line, lightShaderDefRegexp) != null) {
1070
+ return PShader.LIGHT;
1071
+ } else if (PApplet.match(line, texShaderDefRegexp) != null) {
1072
+ return PShader.TEXTURE;
1073
+ } else if (PApplet.match(line, texlightShaderDefRegexp) != null) {
1074
+ return PShader.TEXLIGHT;
1075
+ } else if (PApplet.match(line, polyShaderDefRegexp) != null) {
1076
+ return PShader.POLY;
1077
+ } else if (PApplet.match(line, triShaderAttrRegexp) != null) {
1078
+ return PShader.POLY;
1079
+ } else if (PApplet.match(line, quadShaderAttrRegexp) != null) {
1080
+ return PShader.POLY;
1081
+ } else if (PApplet.match(line, pointShaderDefRegexp) != null) {
1082
+ return PShader.POINT;
1083
+ } else if (PApplet.match(line, lineShaderDefRegexp) != null) {
1084
+ return PShader.LINE;
1085
+ } else if (PApplet.match(line, pointShaderAttrRegexp) != null) {
1086
+ return PShader.POINT;
1087
+ } else if (PApplet.match(line, pointShaderInRegexp) != null) {
1088
+ return PShader.POINT;
1089
+ } else if (PApplet.match(line, lineShaderAttrRegexp) != null) {
1090
+ return PShader.LINE;
1091
+ } else if (PApplet.match(line, lineShaderInRegexp) != null) {
1092
+ return PShader.LINE;
1093
+ }
1094
+ }
1095
+ return defaultType;
1096
+ }
1097
+
1098
+ // ***************************************************************************
1099
+ //
1100
+ // Processing specific
1101
+ protected int getType() {
1102
+ return type;
1103
+ }
1104
+
1105
+ protected void setType(int type) {
1106
+ this.type = type;
1107
+ }
1108
+
1109
+ protected boolean hasType() {
1110
+ return POINT <= type && type <= TEXLIGHT;
1111
+ }
1112
+
1113
+ protected boolean isPointShader() {
1114
+ return type == POINT;
1115
+ }
1116
+
1117
+ protected boolean isLineShader() {
1118
+ return type == LINE;
1119
+ }
1120
+
1121
+ protected boolean isPolyShader() {
1122
+ return POLY <= type && type <= TEXLIGHT;
1123
+ }
1124
+
1125
+ protected boolean checkPolyType(int type) {
1126
+ if (getType() == PShader.POLY) {
1127
+ return true;
1128
+ }
1129
+
1130
+ if (getType() != type) {
1131
+ switch (type) {
1132
+ case TEXLIGHT:
1133
+ PGraphics.showWarning(PGraphicsOpenGL.NO_TEXLIGHT_SHADER_ERROR);
1134
+ break;
1135
+ case LIGHT:
1136
+ PGraphics.showWarning(PGraphicsOpenGL.NO_LIGHT_SHADER_ERROR);
1137
+ break;
1138
+ case TEXTURE:
1139
+ PGraphics.showWarning(PGraphicsOpenGL.NO_TEXTURE_SHADER_ERROR);
1140
+ break;
1141
+ case COLOR:
1142
+ PGraphics.showWarning(PGraphicsOpenGL.NO_COLOR_SHADER_ERROR);
1143
+ break;
1144
+ default:
1145
+ break;
1146
+ }
1147
+ return false;
1148
+ }
1149
+
1150
+ return true;
1151
+ }
1152
+
1153
+ protected int getLastTexUnit() {
1154
+ return texUnits == null ? -1 : texUnits.size() - 1;
1155
+ }
1156
+
1157
+ protected void setRenderer(PGraphicsOpenGL pg) {
1158
+ this.currentPG = pg;
1159
+ }
1160
+
1161
+ protected void loadAttributes() {
1162
+ if (loadedAttributes) {
1163
+ return;
1164
+ }
1165
+
1166
+ vertexLoc = getAttributeLoc("vertex");
1167
+ if (vertexLoc == -1) {
1168
+ vertexLoc = getAttributeLoc("position");
1169
+ }
1170
+
1171
+ colorLoc = getAttributeLoc("color");
1172
+ texCoordLoc = getAttributeLoc("texCoord");
1173
+ normalLoc = getAttributeLoc("normal");
593
1174
 
594
- protected void setUniformValue(int loc, int x) {
595
- if (-1 < loc) {
596
- pgl.uniform1i(loc, x);
597
- }
598
- }
1175
+ ambientLoc = getAttributeLoc("ambient");
1176
+ specularLoc = getAttributeLoc("specular");
1177
+ emissiveLoc = getAttributeLoc("emissive");
1178
+ shininessLoc = getAttributeLoc("shininess");
599
1179
 
600
- protected void setUniformValue(int loc, int x, int y) {
601
- if (-1 < loc) {
602
- pgl.uniform2i(loc, x, y);
603
- }
604
- }
1180
+ directionLoc = getAttributeLoc("direction");
605
1181
 
606
- protected void setUniformValue(int loc, int x, int y, int z) {
607
- if (-1 < loc) {
608
- pgl.uniform3i(loc, x, y, z);
609
- }
610
- }
1182
+ offsetLoc = getAttributeLoc("offset");
611
1183
 
612
- protected void setUniformValue(int loc, int x, int y, int z, int w) {
613
- if (-1 < loc) {
614
- pgl.uniform4i(loc, x, y, z, w);
615
- }
616
- }
617
-
618
- protected void setUniformValue(int loc, float x) {
619
- if (-1 < loc) {
620
- pgl.uniform1f(loc, x);
621
- }
622
- }
623
-
624
- protected void setUniformValue(int loc, float x, float y) {
625
- if (-1 < loc) {
626
- pgl.uniform2f(loc, x, y);
627
- }
628
- }
629
-
630
- protected void setUniformValue(int loc, float x, float y, float z) {
631
- if (-1 < loc) {
632
- pgl.uniform3f(loc, x, y, z);
633
- }
634
- }
635
-
636
- protected void setUniformValue(int loc, float x, float y, float z, float w) {
637
- if (-1 < loc) {
638
- pgl.uniform4f(loc, x, y, z, w);
639
- }
640
- }
641
-
642
- protected void setUniformVector(int loc, int[] vec, int ncoords,
643
- int length) {
644
- if (-1 < loc) {
645
- updateIntBuffer(vec);
646
- if (ncoords == 1) {
647
- pgl.uniform1iv(loc, length, intBuffer);
648
- } else if (ncoords == 2) {
649
- pgl.uniform2iv(loc, length, intBuffer);
650
- } else if (ncoords == 3) {
651
- pgl.uniform3iv(loc, length, intBuffer);
652
- } else if (ncoords == 4) {
653
- pgl.uniform3iv(loc, length, intBuffer);
654
- }
655
- }
656
- }
1184
+ directionLoc = getAttributeLoc("direction");
1185
+ offsetLoc = getAttributeLoc("offset");
657
1186
 
658
- protected void setUniformVector(int loc, float[] vec, int ncoords,
659
- int length) {
660
- if (-1 < loc) {
661
- updateFloatBuffer(vec);
662
- if (ncoords == 1) {
663
- pgl.uniform1fv(loc, length, floatBuffer);
664
- } else if (ncoords == 2) {
665
- pgl.uniform2fv(loc, length, floatBuffer);
666
- } else if (ncoords == 3) {
667
- pgl.uniform3fv(loc, length, floatBuffer);
668
- } else if (ncoords == 4) {
669
- pgl.uniform4fv(loc, length, floatBuffer);
670
- }
671
- }
672
- }
673
-
674
- protected void setUniformMatrix(int loc, float[] mat) {
675
- if (-1 < loc) {
676
- updateFloatBuffer(mat);
677
- if (mat.length == 4) {
678
- pgl.uniformMatrix2fv(loc, 1, false, floatBuffer);
679
- } else if (mat.length == 9) {
680
- pgl.uniformMatrix3fv(loc, 1, false, floatBuffer);
681
- } else if (mat.length == 16) {
682
- pgl.uniformMatrix4fv(loc, 1, false, floatBuffer);
683
- }
684
- }
685
- }
686
-
687
- protected void setUniformTex(int loc, Texture tex) {
688
- if (texUnits != null) {
689
- Integer unit = texUnits.get(loc);
690
- if (unit != null) {
691
- pgl.activeTexture(PGL.TEXTURE0 + unit);
692
- tex.bind();
693
- } else {
694
- throw new RuntimeException("Cannot find unit for texture " + tex);
695
- }
696
- }
697
- }
698
-
699
- protected void setUniformImpl(String name, int type, Object value) {
700
- if (uniformValues == null) {
701
- uniformValues = new HashMap<String, UniformValue>();
702
- }
703
- uniformValues.put(name, new UniformValue(type, value));
704
- }
705
-
706
- protected void consumeUniforms() {
707
- if (uniformValues != null && 0 < uniformValues.size()) {
708
- int unit = 0;
709
- for (String name : uniformValues.keySet()) {
710
- int loc = getUniformLoc(name);
711
- if (loc == -1) {
712
- PGraphics.showWarning("The shader doesn't have a uniform called \""
713
- + name + "\" OR the uniform was removed during "
714
- + "compilation because it was unused.");
715
- continue;
716
- }
717
- UniformValue val = uniformValues.get(name);
718
- if (val.type == UniformValue.INT1) {
719
- int[] v = ((int[]) val.value);
720
- pgl.uniform1i(loc, v[0]);
721
- } else if (val.type == UniformValue.INT2) {
722
- int[] v = ((int[]) val.value);
723
- pgl.uniform2i(loc, v[0], v[1]);
724
- } else if (val.type == UniformValue.INT3) {
725
- int[] v = ((int[]) val.value);
726
- pgl.uniform3i(loc, v[0], v[1], v[2]);
727
- } else if (val.type == UniformValue.INT4) {
728
- int[] v = ((int[]) val.value);
729
- pgl.uniform4i(loc, v[0], v[1], v[2], v[3]);
730
- } else if (val.type == UniformValue.FLOAT1) {
731
- float[] v = ((float[]) val.value);
732
- pgl.uniform1f(loc, v[0]);
733
- } else if (val.type == UniformValue.FLOAT2) {
734
- float[] v = ((float[]) val.value);
735
- pgl.uniform2f(loc, v[0], v[1]);
736
- } else if (val.type == UniformValue.FLOAT3) {
737
- float[] v = ((float[]) val.value);
738
- pgl.uniform3f(loc, v[0], v[1], v[2]);
739
- } else if (val.type == UniformValue.FLOAT4) {
740
- float[] v = ((float[]) val.value);
741
- pgl.uniform4f(loc, v[0], v[1], v[2], v[3]);
742
- } else if (val.type == UniformValue.INT1VEC) {
743
- int[] v = ((int[]) val.value);
744
- updateIntBuffer(v);
745
- pgl.uniform1iv(loc, v.length, intBuffer);
746
- } else if (val.type == UniformValue.INT2VEC) {
747
- int[] v = ((int[]) val.value);
748
- updateIntBuffer(v);
749
- pgl.uniform2iv(loc, v.length / 2, intBuffer);
750
- } else if (val.type == UniformValue.INT3VEC) {
751
- int[] v = ((int[]) val.value);
752
- updateIntBuffer(v);
753
- pgl.uniform3iv(loc, v.length / 3, intBuffer);
754
- } else if (val.type == UniformValue.INT4VEC) {
755
- int[] v = ((int[]) val.value);
756
- updateIntBuffer(v);
757
- pgl.uniform4iv(loc, v.length / 4, intBuffer);
758
- } else if (val.type == UniformValue.FLOAT1VEC) {
759
- float[] v = ((float[]) val.value);
760
- updateFloatBuffer(v);
761
- pgl.uniform1fv(loc, v.length, floatBuffer);
762
- } else if (val.type == UniformValue.FLOAT2VEC) {
763
- float[] v = ((float[]) val.value);
764
- updateFloatBuffer(v);
765
- pgl.uniform2fv(loc, v.length / 2, floatBuffer);
766
- } else if (val.type == UniformValue.FLOAT3VEC) {
767
- float[] v = ((float[]) val.value);
768
- updateFloatBuffer(v);
769
- pgl.uniform3fv(loc, v.length / 3, floatBuffer);
770
- } else if (val.type == UniformValue.FLOAT4VEC) {
771
- float[] v = ((float[]) val.value);
772
- updateFloatBuffer(v);
773
- pgl.uniform4fv(loc, v.length / 4, floatBuffer);
774
- } else if (val.type == UniformValue.MAT2) {
775
- float[] v = ((float[]) val.value);
776
- updateFloatBuffer(v);
777
- pgl.uniformMatrix2fv(loc, 1, false, floatBuffer);
778
- } else if (val.type == UniformValue.MAT3) {
779
- float[] v = ((float[]) val.value);
780
- updateFloatBuffer(v);
781
- pgl.uniformMatrix3fv(loc, 1, false, floatBuffer);
782
- } else if (val.type == UniformValue.MAT4) {
783
- float[] v = ((float[]) val.value);
784
- updateFloatBuffer(v);
785
- pgl.uniformMatrix4fv(loc, 1, false, floatBuffer);
786
- } else if (val.type == UniformValue.SAMPLER2D) {
787
- PImage img = (PImage) val.value;
788
- Texture tex = currentPG.getTexture(img);
789
-
790
- if (textures == null) {
791
- textures = new HashMap<Integer, Texture>();
792
- }
793
- textures.put(loc, tex);
794
-
795
- if (texUnits == null) {
796
- texUnits = new HashMap<Integer, Integer>();
797
- }
798
- if (texUnits.containsKey(loc)) {
799
- unit = texUnits.get(loc);
800
- pgl.uniform1i(loc, unit);
801
- } else {
802
- texUnits.put(loc, unit);
803
- pgl.uniform1i(loc, unit);
804
- }
805
- unit++;
806
- }
807
- }
808
- uniformValues.clear();
809
- }
810
- }
1187
+ loadedAttributes = true;
1188
+ }
811
1189
 
812
- protected void updateIntBuffer(int[] vec) {
813
- intBuffer = PGL.updateIntBuffer(intBuffer, vec, false);
1190
+ protected void loadUniforms() {
1191
+ if (loadedUniforms) {
1192
+ return;
814
1193
  }
815
-
816
- protected void updateFloatBuffer(float[] vec) {
817
- floatBuffer = PGL.updateFloatBuffer(floatBuffer, vec, false);
1194
+ transformMatLoc = getUniformLoc("transform");
1195
+ if (transformMatLoc == -1) {
1196
+ transformMatLoc = getUniformLoc("transformMatrix");
818
1197
  }
819
1198
 
820
- protected void bindTextures() {
821
- if (textures != null && texUnits != null) {
822
- for (int loc : textures.keySet()) {
823
- Texture tex = textures.get(loc);
824
- Integer unit = texUnits.get(loc);
825
- if (unit != null) {
826
- pgl.activeTexture(PGL.TEXTURE0 + unit);
827
- tex.bind();
828
- } else {
829
- throw new RuntimeException("Cannot find unit for texture " + tex);
830
- }
831
- }
832
- }
1199
+ modelviewMatLoc = getUniformLoc("modelview");
1200
+ if (modelviewMatLoc == -1) {
1201
+ modelviewMatLoc = getUniformLoc("modelviewMatrix");
833
1202
  }
834
1203
 
835
- protected void unbindTextures() {
836
- if (textures != null && texUnits != null) {
837
- for (int loc : textures.keySet()) {
838
- Texture tex = textures.get(loc);
839
- Integer unit = texUnits.get(loc);
840
- if (unit != null) {
841
- pgl.activeTexture(PGL.TEXTURE0 + unit);
842
- tex.unbind();
843
- } else {
844
- throw new RuntimeException("Cannot find unit for texture " + tex);
845
- }
846
- }
847
- pgl.activeTexture(PGL.TEXTURE0);
848
- }
1204
+ projectionMatLoc = getUniformLoc("projection");
1205
+ if (projectionMatLoc == -1) {
1206
+ projectionMatLoc = getUniformLoc("projectionMatrix");
849
1207
  }
850
1208
 
851
- public void init() {
852
- if (glProgram == 0 || contextIsOutdated()) {
853
- create();
854
- if (compile()) {
855
- pgl.attachShader(glProgram, glVertex);
856
- pgl.attachShader(glProgram, glFragment);
1209
+ viewportLoc = getUniformLoc("viewport");
1210
+ resolutionLoc = getUniformLoc("resolution");
1211
+ ppixelsLoc = getUniformLoc("ppixels");
857
1212
 
858
- setup();
1213
+ normalMatLoc = getUniformLoc("normalMatrix");
859
1214
 
860
- pgl.linkProgram(glProgram);
861
-
862
- validate();
863
- }
864
- }
865
- }
1215
+ lightCountLoc = getUniformLoc("lightCount");
1216
+ lightPositionLoc = getUniformLoc("lightPosition");
1217
+ lightNormalLoc = getUniformLoc("lightNormal");
1218
+ lightAmbientLoc = getUniformLoc("lightAmbient");
1219
+ lightDiffuseLoc = getUniformLoc("lightDiffuse");
1220
+ lightSpecularLoc = getUniformLoc("lightSpecular");
1221
+ lightFalloffLoc = getUniformLoc("lightFalloff");
1222
+ lightSpotLoc = getUniformLoc("lightSpot");
866
1223
 
867
- protected void create() {
868
- context = pgl.getCurrentContext();
869
- glres = new GLResourceShader(this);
1224
+ textureLoc = getUniformLoc("texture");
1225
+ if (textureLoc == -1) {
1226
+ textureLoc = getUniformLoc("texMap");
870
1227
  }
871
1228
 
872
- protected boolean compile() {
873
- boolean vertRes = true;
874
- if (hasVertexShader()) {
875
- vertRes = compileVertexShader();
876
- } else {
877
- PGraphics.showException("Doesn't have a vertex shader");
878
- }
1229
+ texMatrixLoc = getUniformLoc("texMatrix");
1230
+ texOffsetLoc = getUniformLoc("texOffset");
879
1231
 
880
- boolean fragRes = true;
881
- if (hasFragmentShader()) {
882
- fragRes = compileFragmentShader();
883
- } else {
884
- PGraphics.showException("Doesn't have a fragment shader");
885
- }
1232
+ perspectiveLoc = getUniformLoc("perspective");
1233
+ scaleLoc = getUniformLoc("scale");
1234
+ loadedUniforms = true;
1235
+ }
886
1236
 
887
- return vertRes && fragRes;
1237
+ protected void setCommonUniforms() {
1238
+ if (-1 < transformMatLoc) {
1239
+ currentPG.updateGLProjmodelview();
1240
+ setUniformMatrix(transformMatLoc, currentPG.glProjmodelview);
888
1241
  }
889
1242
 
890
- protected void validate() {
891
- pgl.getProgramiv(glProgram, PGL.LINK_STATUS, intBuffer);
892
- boolean linked = intBuffer.get(0) == 0 ? false : true;
893
- if (!linked) {
894
- PGraphics.showException("Cannot link shader program:\n"
895
- + pgl.getProgramInfoLog(glProgram));
896
- }
897
-
898
- pgl.validateProgram(glProgram);
899
- pgl.getProgramiv(glProgram, PGL.VALIDATE_STATUS, intBuffer);
900
- boolean validated = intBuffer.get(0) == 0 ? false : true;
901
- if (!validated) {
902
- PGraphics.showException("Cannot validate shader program:\n"
903
- + pgl.getProgramInfoLog(glProgram));
904
- }
1243
+ if (-1 < modelviewMatLoc) {
1244
+ currentPG.updateGLModelview();
1245
+ setUniformMatrix(modelviewMatLoc, currentPG.glModelview);
905
1246
  }
906
1247
 
907
- protected boolean contextIsOutdated() {
908
- boolean outdated = !pgl.contextIsCurrent(context);
909
- if (outdated) {
910
- dispose();
911
- }
912
- return outdated;
1248
+ if (-1 < projectionMatLoc) {
1249
+ currentPG.updateGLProjection();
1250
+ setUniformMatrix(projectionMatLoc, currentPG.glProjection);
913
1251
  }
914
1252
 
915
- protected boolean hasVertexShader() {
916
- return vertexShaderSource != null && 0 < vertexShaderSource.length;
1253
+ if (-1 < viewportLoc) {
1254
+ float x = currentPG.viewport.get(0);
1255
+ float y = currentPG.viewport.get(1);
1256
+ float w = currentPG.viewport.get(2);
1257
+ float h = currentPG.viewport.get(3);
1258
+ setUniformValue(viewportLoc, x, y, w, h);
917
1259
  }
918
1260
 
919
- protected boolean hasFragmentShader() {
920
- return fragmentShaderSource != null && 0 < fragmentShaderSource.length;
1261
+ if (-1 < resolutionLoc) {
1262
+ float w = currentPG.viewport.get(2);
1263
+ float h = currentPG.viewport.get(3);
1264
+ setUniformValue(resolutionLoc, w, h);
921
1265
  }
922
1266
 
923
- /**
924
- * @param shaderSource a string containing the shader's code
925
- */
926
- protected boolean compileVertexShader() {
927
- pgl.shaderSource(glVertex, PApplet.join(vertexShaderSource, "\n"));
928
- pgl.compileShader(glVertex);
929
-
930
- pgl.getShaderiv(glVertex, PGL.COMPILE_STATUS, intBuffer);
931
- boolean compiled = intBuffer.get(0) == 0 ? false : true;
932
- if (!compiled) {
933
- PGraphics.showException("Cannot compile vertex shader:\n"
934
- + pgl.getShaderInfoLog(glVertex));
935
- return false;
936
- } else {
937
- return true;
938
- }
1267
+ if (-1 < ppixelsLoc) {
1268
+ ppixelsUnit = getLastTexUnit() + 1;
1269
+ setUniformValue(ppixelsLoc, ppixelsUnit);
1270
+ pgl.activeTexture(PGL.TEXTURE0 + ppixelsUnit);
1271
+ currentPG.bindFrontTexture();
1272
+ } else {
1273
+ ppixelsUnit = -1;
939
1274
  }
1275
+ }
940
1276
 
941
- /**
942
- * @param shaderSource a string containing the shader's code
943
- */
944
- protected boolean compileFragmentShader() {
945
- pgl.shaderSource(glFragment, PApplet.join(fragmentShaderSource, "\n"));
946
- pgl.compileShader(glFragment);
947
-
948
- pgl.getShaderiv(glFragment, PGL.COMPILE_STATUS, intBuffer);
949
- boolean compiled = intBuffer.get(0) == 0 ? false : true;
950
- if (!compiled) {
951
- PGraphics.showException("Cannot compile fragment shader:\n"
952
- + pgl.getShaderInfoLog(glFragment));
953
- return false;
954
- } else {
955
- return true;
956
- }
1277
+ protected void bindTyped() {
1278
+ if (currentPG == null) {
1279
+ setRenderer(primaryPG.getCurrentPG());
1280
+ loadAttributes();
1281
+ loadUniforms();
957
1282
  }
1283
+ setCommonUniforms();
958
1284
 
959
- protected void dispose() {
960
- if (glres != null) {
961
- glres.dispose();
962
- glVertex = 0;
963
- glFragment = 0;
964
- glProgram = 0;
965
- glres = null;
966
- }
1285
+ if (-1 < vertexLoc) {
1286
+ pgl.enableVertexAttribArray(vertexLoc);
967
1287
  }
968
-
969
- static protected int getShaderType(String[] source, int defaultType) {
970
- for (int i = 0; i < source.length; i++) {
971
- String line = source[i].trim();
972
-
973
- if (PApplet.match(line, colorShaderDefRegexp) != null) {
974
- return PShader.COLOR;
975
- } else if (PApplet.match(line, lightShaderDefRegexp) != null) {
976
- return PShader.LIGHT;
977
- } else if (PApplet.match(line, texShaderDefRegexp) != null) {
978
- return PShader.TEXTURE;
979
- } else if (PApplet.match(line, texlightShaderDefRegexp) != null) {
980
- return PShader.TEXLIGHT;
981
- } else if (PApplet.match(line, polyShaderDefRegexp) != null) {
982
- return PShader.POLY;
983
- } else if (PApplet.match(line, triShaderAttrRegexp) != null) {
984
- return PShader.POLY;
985
- } else if (PApplet.match(line, quadShaderAttrRegexp) != null) {
986
- return PShader.POLY;
987
- } else if (PApplet.match(line, pointShaderDefRegexp) != null) {
988
- return PShader.POINT;
989
- } else if (PApplet.match(line, lineShaderDefRegexp) != null) {
990
- return PShader.LINE;
991
- } else if (PApplet.match(line, pointShaderAttrRegexp) != null) {
992
- return PShader.POINT;
993
- } else if (PApplet.match(line, pointShaderInRegexp) != null) {
994
- return PShader.POINT;
995
- } else if (PApplet.match(line, lineShaderAttrRegexp) != null) {
996
- return PShader.LINE;
997
- } else if (PApplet.match(line, lineShaderInRegexp) != null) {
998
- return PShader.LINE;
999
- }
1000
- }
1001
- return defaultType;
1288
+ if (-1 < colorLoc) {
1289
+ pgl.enableVertexAttribArray(colorLoc);
1002
1290
  }
1003
-
1004
- // ***************************************************************************
1005
- //
1006
- // Processing specific
1007
- protected int getType() {
1008
- return type;
1291
+ if (-1 < texCoordLoc) {
1292
+ pgl.enableVertexAttribArray(texCoordLoc);
1009
1293
  }
1010
-
1011
- protected void setType(int type) {
1012
- this.type = type;
1294
+ if (-1 < normalLoc) {
1295
+ pgl.enableVertexAttribArray(normalLoc);
1013
1296
  }
1014
1297
 
1015
- protected boolean hasType() {
1016
- return POINT <= type && type <= TEXLIGHT;
1298
+ if (-1 < normalMatLoc) {
1299
+ currentPG.updateGLNormal();
1300
+ setUniformMatrix(normalMatLoc, currentPG.glNormal);
1017
1301
  }
1018
1302
 
1019
- protected boolean isPointShader() {
1020
- return type == POINT;
1303
+ if (-1 < ambientLoc) {
1304
+ pgl.enableVertexAttribArray(ambientLoc);
1021
1305
  }
1022
-
1023
- protected boolean isLineShader() {
1024
- return type == LINE;
1306
+ if (-1 < specularLoc) {
1307
+ pgl.enableVertexAttribArray(specularLoc);
1025
1308
  }
1026
-
1027
- protected boolean isPolyShader() {
1028
- return POLY <= type && type <= TEXLIGHT;
1309
+ if (-1 < emissiveLoc) {
1310
+ pgl.enableVertexAttribArray(emissiveLoc);
1029
1311
  }
1030
-
1031
- protected boolean checkPolyType(int type) {
1032
- if (getType() == PShader.POLY) {
1033
- return true;
1034
- }
1035
-
1036
- if (getType() != type) {
1037
- if (type == TEXLIGHT) {
1038
- PGraphics.showWarning(PGraphicsOpenGL.NO_TEXLIGHT_SHADER_ERROR);
1039
- } else if (type == LIGHT) {
1040
- PGraphics.showWarning(PGraphicsOpenGL.NO_LIGHT_SHADER_ERROR);
1041
- } else if (type == TEXTURE) {
1042
- PGraphics.showWarning(PGraphicsOpenGL.NO_TEXTURE_SHADER_ERROR);
1043
- } else if (type == COLOR) {
1044
- PGraphics.showWarning(PGraphicsOpenGL.NO_COLOR_SHADER_ERROR);
1045
- }
1046
- return false;
1047
- }
1048
-
1049
- return true;
1312
+ if (-1 < shininessLoc) {
1313
+ pgl.enableVertexAttribArray(shininessLoc);
1050
1314
  }
1051
1315
 
1052
- protected int getLastTexUnit() {
1053
- return texUnits == null ? -1 : texUnits.size() - 1;
1316
+ int count = currentPG.lightCount;
1317
+ setUniformValue(lightCountLoc, count);
1318
+ if (0 < count) {
1319
+ setUniformVector(lightPositionLoc, currentPG.lightPosition, 4, count);
1320
+ setUniformVector(lightNormalLoc, currentPG.lightNormal, 3, count);
1321
+ setUniformVector(lightAmbientLoc, currentPG.lightAmbient, 3, count);
1322
+ setUniformVector(lightDiffuseLoc, currentPG.lightDiffuse, 3, count);
1323
+ setUniformVector(lightSpecularLoc, currentPG.lightSpecular, 3, count);
1324
+ setUniformVector(lightFalloffLoc, currentPG.lightFalloffCoefficients,
1325
+ 3, count);
1326
+ setUniformVector(lightSpotLoc, currentPG.lightSpotParameters, 2, count);
1054
1327
  }
1055
1328
 
1056
- protected void setRenderer(PGraphicsOpenGL pg) {
1057
- this.currentPG = pg;
1329
+ if (-1 < directionLoc) {
1330
+ pgl.enableVertexAttribArray(directionLoc);
1058
1331
  }
1059
1332
 
1060
- protected void loadAttributes() {
1061
- if (loadedAttributes) {
1062
- return;
1063
- }
1064
-
1065
- vertexLoc = getAttributeLoc("vertex");
1066
- if (vertexLoc == -1) {
1067
- vertexLoc = getAttributeLoc("position");
1068
- }
1069
-
1070
- colorLoc = getAttributeLoc("color");
1071
- texCoordLoc = getAttributeLoc("texCoord");
1072
- normalLoc = getAttributeLoc("normal");
1073
-
1074
- ambientLoc = getAttributeLoc("ambient");
1075
- specularLoc = getAttributeLoc("specular");
1076
- emissiveLoc = getAttributeLoc("emissive");
1077
- shininessLoc = getAttributeLoc("shininess");
1078
-
1079
- directionLoc = getAttributeLoc("direction");
1080
-
1081
- offsetLoc = getAttributeLoc("offset");
1082
-
1083
- directionLoc = getAttributeLoc("direction");
1084
- offsetLoc = getAttributeLoc("offset");
1085
-
1086
- loadedAttributes = true;
1333
+ if (-1 < offsetLoc) {
1334
+ pgl.enableVertexAttribArray(offsetLoc);
1087
1335
  }
1088
1336
 
1089
- protected void loadUniforms() {
1090
- if (loadedUniforms) {
1091
- return;
1092
- }
1093
- transformMatLoc = getUniformLoc("transform");
1094
- if (transformMatLoc == -1) {
1095
- transformMatLoc = getUniformLoc("transformMatrix");
1096
- }
1097
-
1098
- modelviewMatLoc = getUniformLoc("modelview");
1099
- if (modelviewMatLoc == -1) {
1100
- modelviewMatLoc = getUniformLoc("modelviewMatrix");
1101
- }
1102
-
1103
- projectionMatLoc = getUniformLoc("projection");
1104
- if (projectionMatLoc == -1) {
1105
- projectionMatLoc = getUniformLoc("projectionMatrix");
1106
- }
1107
-
1108
- viewportLoc = getUniformLoc("viewport");
1109
- resolutionLoc = getUniformLoc("resolution");
1110
- ppixelsLoc = getUniformLoc("ppixels");
1111
-
1112
- normalMatLoc = getUniformLoc("normalMatrix");
1113
-
1114
- lightCountLoc = getUniformLoc("lightCount");
1115
- lightPositionLoc = getUniformLoc("lightPosition");
1116
- lightNormalLoc = getUniformLoc("lightNormal");
1117
- lightAmbientLoc = getUniformLoc("lightAmbient");
1118
- lightDiffuseLoc = getUniformLoc("lightDiffuse");
1119
- lightSpecularLoc = getUniformLoc("lightSpecular");
1120
- lightFalloffLoc = getUniformLoc("lightFalloff");
1121
- lightSpotLoc = getUniformLoc("lightSpot");
1122
-
1123
- textureLoc = getUniformLoc("texture");
1124
- if (textureLoc == -1) {
1125
- textureLoc = getUniformLoc("texMap");
1126
- }
1127
-
1128
- texMatrixLoc = getUniformLoc("texMatrix");
1129
- texOffsetLoc = getUniformLoc("texOffset");
1130
-
1131
- perspectiveLoc = getUniformLoc("perspective");
1132
- scaleLoc = getUniformLoc("scale");
1133
- loadedUniforms = true;
1337
+ if (-1 < perspectiveLoc) {
1338
+ if (currentPG.getHint(ENABLE_STROKE_PERSPECTIVE)
1339
+ && currentPG.nonOrthoProjection()) {
1340
+ setUniformValue(perspectiveLoc, 1);
1341
+ } else {
1342
+ setUniformValue(perspectiveLoc, 0);
1343
+ }
1134
1344
  }
1135
1345
 
1136
- protected void setCommonUniforms() {
1137
- if (-1 < transformMatLoc) {
1138
- currentPG.updateGLProjmodelview();
1139
- setUniformMatrix(transformMatLoc, currentPG.glProjmodelview);
1140
- }
1141
-
1142
- if (-1 < modelviewMatLoc) {
1143
- currentPG.updateGLModelview();
1144
- setUniformMatrix(modelviewMatLoc, currentPG.glModelview);
1145
- }
1146
-
1147
- if (-1 < projectionMatLoc) {
1148
- currentPG.updateGLProjection();
1149
- setUniformMatrix(projectionMatLoc, currentPG.glProjection);
1150
- }
1151
-
1152
- if (-1 < viewportLoc) {
1153
- float x = currentPG.viewport.get(0);
1154
- float y = currentPG.viewport.get(1);
1155
- float w = currentPG.viewport.get(2);
1156
- float h = currentPG.viewport.get(3);
1157
- setUniformValue(viewportLoc, x, y, w, h);
1158
- }
1159
-
1160
- if (-1 < resolutionLoc) {
1161
- float w = currentPG.viewport.get(2);
1162
- float h = currentPG.viewport.get(3);
1163
- setUniformValue(resolutionLoc, w, h);
1164
- }
1165
-
1166
- if (-1 < ppixelsLoc) {
1167
- ppixelsUnit = getLastTexUnit() + 1;
1168
- setUniformValue(ppixelsLoc, ppixelsUnit);
1169
- pgl.activeTexture(PGL.TEXTURE0 + ppixelsUnit);
1170
- currentPG.bindFrontTexture();
1346
+ if (-1 < scaleLoc) {
1347
+ if (currentPG.getHint(DISABLE_OPTIMIZED_STROKE)) {
1348
+ setUniformValue(scaleLoc, 1.0f, 1.0f, 1.0f);
1349
+ } else {
1350
+ float f = PGL.STROKE_DISPLACEMENT;
1351
+ if (currentPG.orthoProjection()) {
1352
+ setUniformValue(scaleLoc, 1, 1, f);
1171
1353
  } else {
1172
- ppixelsUnit = -1;
1173
- }
1174
- }
1175
-
1176
- protected void bindTyped() {
1177
- if (currentPG == null) {
1178
- setRenderer(primaryPG.getCurrentPG());
1179
- loadAttributes();
1180
- loadUniforms();
1181
- }
1182
- setCommonUniforms();
1183
-
1184
- if (-1 < vertexLoc) {
1185
- pgl.enableVertexAttribArray(vertexLoc);
1186
- }
1187
- if (-1 < colorLoc) {
1188
- pgl.enableVertexAttribArray(colorLoc);
1189
- }
1190
- if (-1 < texCoordLoc) {
1191
- pgl.enableVertexAttribArray(texCoordLoc);
1192
- }
1193
- if (-1 < normalLoc) {
1194
- pgl.enableVertexAttribArray(normalLoc);
1195
- }
1196
-
1197
- if (-1 < normalMatLoc) {
1198
- currentPG.updateGLNormal();
1199
- setUniformMatrix(normalMatLoc, currentPG.glNormal);
1200
- }
1201
-
1202
- if (-1 < ambientLoc) {
1203
- pgl.enableVertexAttribArray(ambientLoc);
1204
- }
1205
- if (-1 < specularLoc) {
1206
- pgl.enableVertexAttribArray(specularLoc);
1207
- }
1208
- if (-1 < emissiveLoc) {
1209
- pgl.enableVertexAttribArray(emissiveLoc);
1210
- }
1211
- if (-1 < shininessLoc) {
1212
- pgl.enableVertexAttribArray(shininessLoc);
1213
- }
1214
-
1215
- int count = currentPG.lightCount;
1216
- setUniformValue(lightCountLoc, count);
1217
- if (0 < count) {
1218
- setUniformVector(lightPositionLoc, currentPG.lightPosition, 4, count);
1219
- setUniformVector(lightNormalLoc, currentPG.lightNormal, 3, count);
1220
- setUniformVector(lightAmbientLoc, currentPG.lightAmbient, 3, count);
1221
- setUniformVector(lightDiffuseLoc, currentPG.lightDiffuse, 3, count);
1222
- setUniformVector(lightSpecularLoc, currentPG.lightSpecular, 3, count);
1223
- setUniformVector(lightFalloffLoc, currentPG.lightFalloffCoefficients,
1224
- 3, count);
1225
- setUniformVector(lightSpotLoc, currentPG.lightSpotParameters, 2, count);
1226
- }
1227
-
1228
- if (-1 < directionLoc) {
1229
- pgl.enableVertexAttribArray(directionLoc);
1230
- }
1231
-
1232
- if (-1 < offsetLoc) {
1233
- pgl.enableVertexAttribArray(offsetLoc);
1234
- }
1235
-
1236
- if (-1 < perspectiveLoc) {
1237
- if (currentPG.getHint(ENABLE_STROKE_PERSPECTIVE)
1238
- && currentPG.nonOrthoProjection()) {
1239
- setUniformValue(perspectiveLoc, 1);
1240
- } else {
1241
- setUniformValue(perspectiveLoc, 0);
1242
- }
1243
- }
1244
-
1245
- if (-1 < scaleLoc) {
1246
- if (currentPG.getHint(DISABLE_OPTIMIZED_STROKE)) {
1247
- setUniformValue(scaleLoc, 1.0f, 1.0f, 1.0f);
1248
- } else {
1249
- float f = PGL.STROKE_DISPLACEMENT;
1250
- if (currentPG.orthoProjection()) {
1251
- setUniformValue(scaleLoc, 1, 1, f);
1252
- } else {
1253
- setUniformValue(scaleLoc, f, f, f);
1254
- }
1255
- }
1354
+ setUniformValue(scaleLoc, f, f, f);
1256
1355
  }
1356
+ }
1257
1357
  }
1358
+ }
1258
1359
 
1259
- protected void unbindTyped() {
1260
- if (-1 < offsetLoc) {
1261
- pgl.disableVertexAttribArray(offsetLoc);
1262
- }
1263
-
1264
- if (-1 < directionLoc) {
1265
- pgl.disableVertexAttribArray(directionLoc);
1266
- }
1267
-
1268
- if (-1 < textureLoc && texture != null) {
1269
- pgl.activeTexture(PGL.TEXTURE0 + texUnit);
1270
- texture.unbind();
1271
- pgl.activeTexture(PGL.TEXTURE0);
1272
- texture = null;
1273
- }
1274
-
1275
- if (-1 < ambientLoc) {
1276
- pgl.disableVertexAttribArray(ambientLoc);
1277
- }
1278
- if (-1 < specularLoc) {
1279
- pgl.disableVertexAttribArray(specularLoc);
1280
- }
1281
- if (-1 < emissiveLoc) {
1282
- pgl.disableVertexAttribArray(emissiveLoc);
1283
- }
1284
- if (-1 < shininessLoc) {
1285
- pgl.disableVertexAttribArray(shininessLoc);
1286
- }
1287
-
1288
- if (-1 < vertexLoc) {
1289
- pgl.disableVertexAttribArray(vertexLoc);
1290
- }
1291
- if (-1 < colorLoc) {
1292
- pgl.disableVertexAttribArray(colorLoc);
1293
- }
1294
- if (-1 < texCoordLoc) {
1295
- pgl.disableVertexAttribArray(texCoordLoc);
1296
- }
1297
- if (-1 < normalLoc) {
1298
- pgl.disableVertexAttribArray(normalLoc);
1299
- }
1300
-
1301
- if (-1 < ppixelsLoc) {
1302
- pgl.enableFBOLayer();
1303
- pgl.activeTexture(PGL.TEXTURE0 + ppixelsUnit);
1304
- currentPG.unbindFrontTexture();
1305
- pgl.activeTexture(PGL.TEXTURE0);
1306
- }
1307
-
1308
- pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
1360
+ protected void unbindTyped() {
1361
+ if (-1 < offsetLoc) {
1362
+ pgl.disableVertexAttribArray(offsetLoc);
1309
1363
  }
1310
1364
 
1311
- protected void setTexture(Texture tex) {
1312
- texture = tex;
1313
-
1314
- float scaleu = 1;
1315
- float scalev = 1;
1316
- float dispu = 0;
1317
- float dispv = 0;
1318
-
1319
- if (tex != null) {
1320
- if (tex.invertedX()) {
1321
- scaleu = -1;
1322
- dispu = 1;
1323
- }
1324
-
1325
- if (tex.invertedY()) {
1326
- scalev = -1;
1327
- dispv = 1;
1328
- }
1329
-
1330
- scaleu *= tex.maxTexcoordU();
1331
- dispu *= tex.maxTexcoordU();
1332
- scalev *= tex.maxTexcoordV();
1333
- dispv *= tex.maxTexcoordV();
1334
-
1335
- setUniformValue(texOffsetLoc, 1.0f / tex.width, 1.0f / tex.height);
1336
-
1337
- if (-1 < textureLoc) {
1338
- texUnit = -1 < ppixelsUnit ? ppixelsUnit + 1 : getLastTexUnit() + 1;
1339
- setUniformValue(textureLoc, texUnit);
1340
- pgl.activeTexture(PGL.TEXTURE0 + texUnit);
1341
- tex.bind();
1342
- }
1343
- }
1344
-
1345
- if (-1 < texMatrixLoc) {
1346
- if (tcmat == null) {
1347
- tcmat = new float[16];
1348
- }
1349
- tcmat[0] = scaleu;
1350
- tcmat[4] = 0;
1351
- tcmat[8] = 0;
1352
- tcmat[12] = dispu;
1353
- tcmat[1] = 0;
1354
- tcmat[5] = scalev;
1355
- tcmat[9] = 0;
1356
- tcmat[13] = dispv;
1357
- tcmat[2] = 0;
1358
- tcmat[6] = 0;
1359
- tcmat[10] = 0;
1360
- tcmat[14] = 0;
1361
- tcmat[3] = 0;
1362
- tcmat[7] = 0;
1363
- tcmat[11] = 0;
1364
- tcmat[15] = 0;
1365
- setUniformMatrix(texMatrixLoc, tcmat);
1366
- }
1365
+ if (-1 < directionLoc) {
1366
+ pgl.disableVertexAttribArray(directionLoc);
1367
1367
  }
1368
1368
 
1369
- protected boolean supportsTexturing() {
1370
- return -1 < textureLoc;
1369
+ if (-1 < textureLoc && texture != null) {
1370
+ pgl.activeTexture(PGL.TEXTURE0 + texUnit);
1371
+ texture.unbind();
1372
+ pgl.activeTexture(PGL.TEXTURE0);
1373
+ texture = null;
1371
1374
  }
1372
1375
 
1373
- protected boolean supportLighting() {
1374
- return -1 < lightCountLoc || -1 < lightPositionLoc || -1 < lightNormalLoc;
1376
+ if (-1 < ambientLoc) {
1377
+ pgl.disableVertexAttribArray(ambientLoc);
1375
1378
  }
1376
-
1377
- protected boolean accessTexCoords() {
1378
- return -1 < texCoordLoc;
1379
+ if (-1 < specularLoc) {
1380
+ pgl.disableVertexAttribArray(specularLoc);
1379
1381
  }
1380
-
1381
- protected boolean accessNormals() {
1382
- return -1 < normalLoc;
1382
+ if (-1 < emissiveLoc) {
1383
+ pgl.disableVertexAttribArray(emissiveLoc);
1383
1384
  }
1384
-
1385
- protected boolean accessLightAttribs() {
1386
- return -1 < ambientLoc || -1 < specularLoc || -1 < emissiveLoc
1387
- || -1 < shininessLoc;
1385
+ if (-1 < shininessLoc) {
1386
+ pgl.disableVertexAttribArray(shininessLoc);
1388
1387
  }
1389
1388
 
1390
- protected void setVertexAttribute(int vboId, int size, int type,
1391
- int stride, int offset) {
1392
- setAttributeVBO(vertexLoc, vboId, size, type, false, stride, offset);
1389
+ if (-1 < vertexLoc) {
1390
+ pgl.disableVertexAttribArray(vertexLoc);
1393
1391
  }
1394
-
1395
- protected void setColorAttribute(int vboId, int size, int type,
1396
- int stride, int offset) {
1397
- setAttributeVBO(colorLoc, vboId, size, type, true, stride, offset);
1392
+ if (-1 < colorLoc) {
1393
+ pgl.disableVertexAttribArray(colorLoc);
1398
1394
  }
1399
-
1400
- protected void setNormalAttribute(int vboId, int size, int type,
1401
- int stride, int offset) {
1402
- setAttributeVBO(normalLoc, vboId, size, type, false, stride, offset);
1395
+ if (-1 < texCoordLoc) {
1396
+ pgl.disableVertexAttribArray(texCoordLoc);
1403
1397
  }
1404
-
1405
- protected void setTexcoordAttribute(int vboId, int size, int type,
1406
- int stride, int offset) {
1407
- setAttributeVBO(texCoordLoc, vboId, size, type, false, stride, offset);
1408
- }
1409
-
1410
- protected void setAmbientAttribute(int vboId, int size, int type,
1411
- int stride, int offset) {
1412
- setAttributeVBO(ambientLoc, vboId, size, type, true, stride, offset);
1398
+ if (-1 < normalLoc) {
1399
+ pgl.disableVertexAttribArray(normalLoc);
1413
1400
  }
1414
1401
 
1415
- protected void setSpecularAttribute(int vboId, int size, int type,
1416
- int stride, int offset) {
1417
- setAttributeVBO(specularLoc, vboId, size, type, true, stride, offset);
1402
+ if (-1 < ppixelsLoc) {
1403
+ pgl.enableFBOLayer();
1404
+ pgl.activeTexture(PGL.TEXTURE0 + ppixelsUnit);
1405
+ currentPG.unbindFrontTexture();
1406
+ pgl.activeTexture(PGL.TEXTURE0);
1418
1407
  }
1419
1408
 
1420
- protected void setEmissiveAttribute(int vboId, int size, int type,
1421
- int stride, int offset) {
1422
- setAttributeVBO(emissiveLoc, vboId, size, type, true, stride, offset);
1423
- }
1409
+ pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
1410
+ }
1424
1411
 
1425
- protected void setShininessAttribute(int vboId, int size, int type,
1426
- int stride, int offset) {
1427
- setAttributeVBO(shininessLoc, vboId, size, type, false, stride, offset);
1428
- }
1412
+ protected void setTexture(Texture tex) {
1413
+ texture = tex;
1429
1414
 
1430
- protected void setLineAttribute(int vboId, int size, int type,
1431
- int stride, int offset) {
1432
- setAttributeVBO(directionLoc, vboId, size, type, false, stride, offset);
1433
- }
1415
+ float scaleu = 1;
1416
+ float scalev = 1;
1417
+ float dispu = 0;
1418
+ float dispv = 0;
1434
1419
 
1435
- protected void setPointAttribute(int vboId, int size, int type,
1436
- int stride, int offset) {
1437
- setAttributeVBO(offsetLoc, vboId, size, type, false, stride, offset);
1438
- }
1420
+ if (tex != null) {
1421
+ if (tex.invertedX()) {
1422
+ scaleu = -1;
1423
+ dispu = 1;
1424
+ }
1439
1425
 
1440
- // ***************************************************************************
1441
- //
1442
- // Class to store a user-specified value for a uniform parameter
1443
- // in the shader
1444
- protected static class UniformValue {
1426
+ if (tex.invertedY()) {
1427
+ scalev = -1;
1428
+ dispv = 1;
1429
+ }
1445
1430
 
1446
- static final int INT1 = 0;
1447
- static final int INT2 = 1;
1448
- static final int INT3 = 2;
1449
- static final int INT4 = 3;
1450
- static final int FLOAT1 = 4;
1451
- static final int FLOAT2 = 5;
1452
- static final int FLOAT3 = 6;
1453
- static final int FLOAT4 = 7;
1454
- static final int INT1VEC = 8;
1455
- static final int INT2VEC = 9;
1456
- static final int INT3VEC = 10;
1457
- static final int INT4VEC = 11;
1458
- static final int FLOAT1VEC = 12;
1459
- static final int FLOAT2VEC = 13;
1460
- static final int FLOAT3VEC = 14;
1461
- static final int FLOAT4VEC = 15;
1462
- static final int MAT2 = 16;
1463
- static final int MAT3 = 17;
1464
- static final int MAT4 = 18;
1465
- static final int SAMPLER2D = 19;
1431
+ scaleu *= tex.maxTexcoordU();
1432
+ dispu *= tex.maxTexcoordU();
1433
+ scalev *= tex.maxTexcoordV();
1434
+ dispv *= tex.maxTexcoordV();
1466
1435
 
1467
- int type;
1468
- Object value;
1436
+ setUniformValue(texOffsetLoc, 1.0f / tex.width, 1.0f / tex.height);
1469
1437
 
1470
- UniformValue(int type, Object value) {
1471
- this.type = type;
1472
- this.value = value;
1473
- }
1438
+ if (-1 < textureLoc) {
1439
+ texUnit = -1 < ppixelsUnit ? ppixelsUnit + 1 : getLastTexUnit() + 1;
1440
+ setUniformValue(textureLoc, texUnit);
1441
+ pgl.activeTexture(PGL.TEXTURE0 + texUnit);
1442
+ tex.bind();
1443
+ }
1474
1444
  }
1445
+
1446
+ if (-1 < texMatrixLoc) {
1447
+ if (tcmat == null) {
1448
+ tcmat = new float[16];
1449
+ }
1450
+ tcmat[0] = scaleu;
1451
+ tcmat[4] = 0;
1452
+ tcmat[8] = 0;
1453
+ tcmat[12] = dispu;
1454
+ tcmat[1] = 0;
1455
+ tcmat[5] = scalev;
1456
+ tcmat[9] = 0;
1457
+ tcmat[13] = dispv;
1458
+ tcmat[2] = 0;
1459
+ tcmat[6] = 0;
1460
+ tcmat[10] = 0;
1461
+ tcmat[14] = 0;
1462
+ tcmat[3] = 0;
1463
+ tcmat[7] = 0;
1464
+ tcmat[11] = 0;
1465
+ tcmat[15] = 0;
1466
+ setUniformMatrix(texMatrixLoc, tcmat);
1467
+ }
1468
+ }
1469
+
1470
+ protected boolean supportsTexturing() {
1471
+ return -1 < textureLoc;
1472
+ }
1473
+
1474
+ protected boolean supportLighting() {
1475
+ return -1 < lightCountLoc || -1 < lightPositionLoc || -1 < lightNormalLoc;
1476
+ }
1477
+
1478
+ protected boolean accessTexCoords() {
1479
+ return -1 < texCoordLoc;
1480
+ }
1481
+
1482
+ protected boolean accessNormals() {
1483
+ return -1 < normalLoc;
1484
+ }
1485
+
1486
+ protected boolean accessLightAttribs() {
1487
+ return -1 < ambientLoc || -1 < specularLoc || -1 < emissiveLoc
1488
+ || -1 < shininessLoc;
1489
+ }
1490
+
1491
+ protected void setVertexAttribute(int vboId, int size, int type,
1492
+ int stride, int offset) {
1493
+ setAttributeVBO(vertexLoc, vboId, size, type, false, stride, offset);
1494
+ }
1495
+
1496
+ protected void setColorAttribute(int vboId, int size, int type,
1497
+ int stride, int offset) {
1498
+ setAttributeVBO(colorLoc, vboId, size, type, true, stride, offset);
1499
+ }
1500
+
1501
+ protected void setNormalAttribute(int vboId, int size, int type,
1502
+ int stride, int offset) {
1503
+ setAttributeVBO(normalLoc, vboId, size, type, false, stride, offset);
1504
+ }
1505
+
1506
+ protected void setTexcoordAttribute(int vboId, int size, int type,
1507
+ int stride, int offset) {
1508
+ setAttributeVBO(texCoordLoc, vboId, size, type, false, stride, offset);
1509
+ }
1510
+
1511
+ protected void setAmbientAttribute(int vboId, int size, int type,
1512
+ int stride, int offset) {
1513
+ setAttributeVBO(ambientLoc, vboId, size, type, true, stride, offset);
1514
+ }
1515
+
1516
+ protected void setSpecularAttribute(int vboId, int size, int type,
1517
+ int stride, int offset) {
1518
+ setAttributeVBO(specularLoc, vboId, size, type, true, stride, offset);
1519
+ }
1520
+
1521
+ protected void setEmissiveAttribute(int vboId, int size, int type,
1522
+ int stride, int offset) {
1523
+ setAttributeVBO(emissiveLoc, vboId, size, type, true, stride, offset);
1524
+ }
1525
+
1526
+ protected void setShininessAttribute(int vboId, int size, int type,
1527
+ int stride, int offset) {
1528
+ setAttributeVBO(shininessLoc, vboId, size, type, false, stride, offset);
1529
+ }
1530
+
1531
+ protected void setLineAttribute(int vboId, int size, int type,
1532
+ int stride, int offset) {
1533
+ setAttributeVBO(directionLoc, vboId, size, type, false, stride, offset);
1534
+ }
1535
+
1536
+ protected void setPointAttribute(int vboId, int size, int type,
1537
+ int stride, int offset) {
1538
+ setAttributeVBO(offsetLoc, vboId, size, type, false, stride, offset);
1539
+ }
1540
+
1541
+ // ***************************************************************************
1542
+ //
1543
+ // Class to store a user-specified value for a uniform parameter
1544
+ // in the shader
1545
+ protected static class UniformValue {
1546
+
1547
+ static final int INT1 = 0;
1548
+ static final int INT2 = 1;
1549
+ static final int INT3 = 2;
1550
+ static final int INT4 = 3;
1551
+ static final int FLOAT1 = 4;
1552
+ static final int FLOAT2 = 5;
1553
+ static final int FLOAT3 = 6;
1554
+ static final int FLOAT4 = 7;
1555
+ static final int INT1VEC = 8;
1556
+ static final int INT2VEC = 9;
1557
+ static final int INT3VEC = 10;
1558
+ static final int INT4VEC = 11;
1559
+ static final int FLOAT1VEC = 12;
1560
+ static final int FLOAT2VEC = 13;
1561
+ static final int FLOAT3VEC = 14;
1562
+ static final int FLOAT4VEC = 15;
1563
+ static final int MAT2 = 16;
1564
+ static final int MAT3 = 17;
1565
+ static final int MAT4 = 18;
1566
+ static final int SAMPLER2D = 19;
1567
+
1568
+ int type;
1569
+ Object value;
1570
+
1571
+ UniformValue(int type, Object value) {
1572
+ this.type = type;
1573
+ this.value = value;
1574
+ }
1575
+ }
1475
1576
  }