1
+ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
+
3
+ /*
4
+ Part of the Processing project - http://processing.org
5
+
6
+ Copyright (c) 2019 The Processing Foundation
7
+
8
+ This library is free software; you can redistribute it and/or
9
+ modify it under the terms of the GNU Lesser General Public
10
+ License as published by the Free Software Foundation, version 2.1.
11
+
12
+ This library is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ Lesser General Public License for more details.
16
+
17
+ You should have received a copy of the GNU Lesser General
18
+ Public License along with this library; if not, write to the
19
+ Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20
+ Boston, MA 02111-1307 USA
21
+ */
22
+
1
23
package processing .opengl ;
2
24
3
25
import static processing .core .PApplet .println ;
13
35
import processing .core .PShape ;
14
36
import processing .core .PShapeSVG ;
15
37
16
- // Super fast OpenGL 2D renderer by Miles Fogle:
17
- // https://github.com/hazmatsuitor
18
-
19
- //for testing purposes, I found it easier to create a separate class and avoid
20
- //touching existing code for now, rather than directly editing PGraphics2D/PGraphicsOpenGL
21
- //if this code becomes the new P2D implementation, then it will be properly migrated/integrated
22
-
23
- //NOTE: this implementation doesn't use some of Processing's OpenGL wrappers
24
- //(e.g. PShader, Texture) because I found it more convenient to handle them manually
25
- //it could probably be made to use those classes with a bit of elbow grease and a spot of guidance
26
- //but it may not be worth it - I doubt it would reduce complexity much, if at all
27
- //(if there are reasons we need to use those classes, let me know)
38
+ /**
39
+ * Super fast OpenGL 2D renderer originally contributed by Miles Fogle:
40
+ * https://github.com/hazmatsuitor
41
+ *
42
+ * It speeds-up rendering of 2D geometry by essentially two key optimizations: packing all the
43
+ * vertex data in a single VBO, and using a custom stroke tessellator (see StrokeRenderer class
44
+ * at the end). There are a number of other, less critical optimizations, for example using a single
45
+ * shader for textured and non-textured geometry and a depth algorithm that allows stacking a large
46
+ * number of 2D shapes without z-fighting (so occlusion is based on drawing order).
47
+ *
48
+ * Some notes from Miles:
49
+ *
50
+ * for testing purposes, I found it easier to create a separate class and avoid
51
+ * touching existing code for now, rather than directly editing PGraphics2D/PGraphicsOpenGL
52
+ * if this code becomes the new P2D implementation, then it will be properly migrated/integrated
53
+
54
+ * NOTE: this implementation doesn't use some of Processing's OpenGL wrappers
55
+ * (e.g. PShader, Texture) because I found it more convenient to handle them manually
56
+ * it could probably be made to use those classes with a bit of elbow grease and a spot of guidance
57
+ * but it may not be worth it - I doubt it would reduce complexity much, if at all
58
+ * (if there are reasons we need to use those classes, let me know)
59
+ *
60
+ */
28
61
29
62
//TODO: track debug performance stats
30
63
public final class PGraphics2DX extends PGraphicsOpenGL {
@@ -361,8 +394,6 @@ public void texture(PImage image) {
361
394
return ;
362
395
}
363
396
364
- init ();
365
-
366
397
Texture t = currentPG .getTexture (image );
367
398
texWidth = t .width ;
368
399
texHeight = t .height ;
@@ -1290,14 +1321,13 @@ protected void end2D() {
1290
1321
public void filter (PShader shader ) {
1291
1322
// The filter method needs to use the geometry-generation in the base class.
1292
1323
// We could re-implement it here, but this is easier.
1293
- // if (!useParentImpl) {
1294
- // useOldP2D();
1295
- // super.filter(shader);
1296
- // useNewP2D();
1297
- // } else {
1298
- // super.filter(shader);
1299
- // }
1300
- super .filter (shader );
1324
+ if (!useParentImpl ) {
1325
+ useOldP2D ();
1326
+ super .filter (shader );
1327
+ useNewP2D ();
1328
+ } else {
1329
+ super .filter (shader );
1330
+ }
1301
1331
}
1302
1332
1303
1333
@@ -1501,24 +1531,6 @@ public void lightSpecular(float v1, float v2, float v3) {
1501
1531
// PRIVATE IMPLEMENTATION
1502
1532
1503
1533
1504
- //superclass does lazy initialization, so we need to as well
1505
- private void init () {
1506
- if (initialized ) return ;
1507
- initialized = true ;
1508
-
1509
- String [] vertSource = pgl .loadVertexShader (defP2DShaderVertURL );
1510
- String [] fragSource = pgl .loadFragmentShader (defP2DShaderFragURL );
1511
- twoShader = new PShader (parent , vertSource , fragSource );
1512
- loadShaderLocs (twoShader );
1513
- defTwoShader = twoShader ;
1514
-
1515
- //generate vbo
1516
- IntBuffer vboBuff = IntBuffer .allocate (1 );
1517
- pgl .genBuffers (1 , vboBuff );
1518
- vbo = vboBuff .get (0 );
1519
- }
1520
-
1521
-
1522
1534
//maxVerts can be tweaked for memory/performance trade-off
1523
1535
//in my testing, performance seems to plateau after around 6000 (= 2000*3)
1524
1536
//memory usage should be around ~165kb for 6000 verts
@@ -1631,9 +1643,14 @@ private void flushBuffer() {
1631
1643
return ;
1632
1644
}
1633
1645
1634
- init ();
1646
+ if (vbo == 0 ) {
1647
+ // Generate vbo
1648
+ IntBuffer vboBuff = IntBuffer .allocate (1 );
1649
+ pgl .genBuffers (1 , vboBuff );
1650
+ vbo = vboBuff .get (0 );
1651
+ }
1635
1652
1636
- //upload vertex data
1653
+ // Upload vertex data
1637
1654
pgl .bindBuffer (PGL .ARRAY_BUFFER , vbo );
1638
1655
pgl .bufferData (PGL .ARRAY_BUFFER , usedVerts * vertSize ,
1639
1656
FloatBuffer .wrap (vertexData ), PGL .DYNAMIC_DRAW );
@@ -1666,6 +1683,9 @@ private boolean checkShaderLocs(PShader shader) {
1666
1683
transformLoc = shader .getUniformLoc ("transformMatrix" );
1667
1684
}
1668
1685
int texScaleLoc = shader .getUniformLoc ("texScale" );
1686
+ if (texScaleLoc == -1 ) {
1687
+ texScaleLoc = shader .getUniformLoc ("texOffset" );
1688
+ }
1669
1689
return positionLoc != -1 && colorLoc != -1 && texCoordLoc != -1 &&
1670
1690
texFactorLoc != -1 && transformLoc != -1 && texScaleLoc != -1 ;
1671
1691
}
@@ -1684,12 +1704,21 @@ private void loadShaderLocs(PShader shader) {
1684
1704
transformLoc = shader .getUniformLoc ("transformMatrix" );
1685
1705
}
1686
1706
texScaleLoc = shader .getUniformLoc ("texScale" );
1707
+ if (texScaleLoc == -1 ) {
1708
+ texScaleLoc = shader .getUniformLoc ("texOffset" );
1709
+ }
1687
1710
}
1688
1711
1689
1712
1690
1713
private PShader getShader () {
1691
1714
PShader shader ;
1692
1715
if (twoShader == null ) {
1716
+ if (defTwoShader == null ) {
1717
+ String [] vertSource = pgl .loadVertexShader (defP2DShaderVertURL );
1718
+ String [] fragSource = pgl .loadFragmentShader (defP2DShaderFragURL );
1719
+ defTwoShader = new PShader (parent , vertSource , fragSource );
1720
+ loadShaderLocs (defTwoShader );
1721
+ }
1693
1722
shader = defTwoShader ;
1694
1723
} else {
1695
1724
shader = twoShader ;
0 commit comments