picrate 0.0.2-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +47 -0
  3. data/.mvn/extensions.xml +9 -0
  4. data/.mvn/wrapper/maven-wrapper.properties +1 -0
  5. data/.travis.yml +10 -0
  6. data/CHANGELOG.md +4 -0
  7. data/LICENSE.md +165 -0
  8. data/README.md +51 -0
  9. data/Rakefile +59 -0
  10. data/bin/picrate +8 -0
  11. data/docs/.gitignore +6 -0
  12. data/docs/_config.yml +30 -0
  13. data/docs/_includes/footer.html +38 -0
  14. data/docs/_includes/head.html +16 -0
  15. data/docs/_includes/header.html +27 -0
  16. data/docs/_includes/icon-github.html +1 -0
  17. data/docs/_includes/icon-github.svg +1 -0
  18. data/docs/_includes/icon-twitter.html +1 -0
  19. data/docs/_includes/icon-twitter.svg +1 -0
  20. data/docs/_includes/navigation.html +24 -0
  21. data/docs/_layouts/default.html +20 -0
  22. data/docs/_layouts/page.html +14 -0
  23. data/docs/_layouts/post.html +15 -0
  24. data/docs/_posts/2018-05-06-getting_started.md +8 -0
  25. data/docs/_posts/2018-05-06-install_jruby.md +35 -0
  26. data/docs/_sass/_base.scss +206 -0
  27. data/docs/_sass/_layout.scss +242 -0
  28. data/docs/_sass/_syntax-highlighting.scss +71 -0
  29. data/docs/about.md +10 -0
  30. data/docs/css/main.scss +38 -0
  31. data/docs/favicon.ico +0 -0
  32. data/docs/feed.xml +30 -0
  33. data/docs/index.html +38 -0
  34. data/lib/picrate.rb +10 -0
  35. data/lib/picrate/app.rb +187 -0
  36. data/lib/picrate/creators/sketch_class.rb +57 -0
  37. data/lib/picrate/creators/sketch_factory.rb +12 -0
  38. data/lib/picrate/creators/sketch_writer.rb +21 -0
  39. data/lib/picrate/helper_methods.rb +214 -0
  40. data/lib/picrate/helpers/numeric.rb +9 -0
  41. data/lib/picrate/library.rb +69 -0
  42. data/lib/picrate/library_loader.rb +53 -0
  43. data/lib/picrate/native_folder.rb +35 -0
  44. data/lib/picrate/native_loader.rb +27 -0
  45. data/lib/picrate/runner.rb +81 -0
  46. data/lib/picrate/version.rb +4 -0
  47. data/library/boids/boids.rb +209 -0
  48. data/library/chooser/chooser.rb +19 -0
  49. data/library/control_panel/control_panel.rb +182 -0
  50. data/library/library_proxy/README.md +99 -0
  51. data/library/library_proxy/library_proxy.rb +14 -0
  52. data/library/slider/slider.rb +42 -0
  53. data/library/vector_utils/vector_utils.rb +69 -0
  54. data/library/video_event/video_event.rb +3 -0
  55. data/license.txt +508 -0
  56. data/picrate.gemspec +35 -0
  57. data/pom.rb +122 -0
  58. data/pom.xml +214 -0
  59. data/src/main/java/japplemenubar/JAppleMenuBar.java +88 -0
  60. data/src/main/java/japplemenubar/libjAppleMenuBar.jnilib +0 -0
  61. data/src/main/java/monkstone/ColorUtil.java +115 -0
  62. data/src/main/java/monkstone/MathToolModule.java +236 -0
  63. data/src/main/java/monkstone/PicrateLibrary.java +47 -0
  64. data/src/main/java/monkstone/core/LibraryProxy.java +127 -0
  65. data/src/main/java/monkstone/fastmath/Deglut.java +122 -0
  66. data/src/main/java/monkstone/fastmath/package-info.java +6 -0
  67. data/src/main/java/monkstone/filechooser/Chooser.java +48 -0
  68. data/src/main/java/monkstone/noise/SimplexNoise.java +465 -0
  69. data/src/main/java/monkstone/slider/CustomHorizontalSlider.java +168 -0
  70. data/src/main/java/monkstone/slider/CustomVerticalSlider.java +182 -0
  71. data/src/main/java/monkstone/slider/SimpleHorizontalSlider.java +149 -0
  72. data/src/main/java/monkstone/slider/SimpleSlider.java +196 -0
  73. data/src/main/java/monkstone/slider/SimpleVerticalSlider.java +163 -0
  74. data/src/main/java/monkstone/slider/Slider.java +67 -0
  75. data/src/main/java/monkstone/slider/SliderBar.java +277 -0
  76. data/src/main/java/monkstone/slider/SliderGroup.java +78 -0
  77. data/src/main/java/monkstone/slider/WheelHandler.java +35 -0
  78. data/src/main/java/monkstone/vecmath/AppRender.java +87 -0
  79. data/src/main/java/monkstone/vecmath/JRender.java +56 -0
  80. data/src/main/java/monkstone/vecmath/ShapeRender.java +87 -0
  81. data/src/main/java/monkstone/vecmath/package-info.java +20 -0
  82. data/src/main/java/monkstone/vecmath/vec2/Vec2.java +757 -0
  83. data/src/main/java/monkstone/vecmath/vec2/package-info.java +6 -0
  84. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +727 -0
  85. data/src/main/java/monkstone/vecmath/vec3/package-info.java +6 -0
  86. data/src/main/java/monkstone/videoevent/VideoInterface.java +42 -0
  87. data/src/main/java/monkstone/videoevent/package-info.java +20 -0
  88. data/src/main/java/processing/awt/PGraphicsJava2D.java +3098 -0
  89. data/src/main/java/processing/awt/PShapeJava2D.java +401 -0
  90. data/src/main/java/processing/awt/PSurfaceAWT.java +1660 -0
  91. data/src/main/java/processing/core/PApplet.java +17647 -0
  92. data/src/main/java/processing/core/PConstants.java +1033 -0
  93. data/src/main/java/processing/core/PFont.java +1250 -0
  94. data/src/main/java/processing/core/PGraphics.java +9614 -0
  95. data/src/main/java/processing/core/PImage.java +3608 -0
  96. data/src/main/java/processing/core/PMatrix.java +347 -0
  97. data/src/main/java/processing/core/PMatrix2D.java +694 -0
  98. data/src/main/java/processing/core/PMatrix3D.java +1153 -0
  99. data/src/main/java/processing/core/PShape.java +4332 -0
  100. data/src/main/java/processing/core/PShapeOBJ.java +544 -0
  101. data/src/main/java/processing/core/PShapeSVG.java +1987 -0
  102. data/src/main/java/processing/core/PStyle.java +208 -0
  103. data/src/main/java/processing/core/PSurface.java +242 -0
  104. data/src/main/java/processing/core/PSurfaceNone.java +479 -0
  105. data/src/main/java/processing/core/PVector.java +1140 -0
  106. data/src/main/java/processing/data/FloatDict.java +829 -0
  107. data/src/main/java/processing/data/FloatList.java +912 -0
  108. data/src/main/java/processing/data/IntDict.java +796 -0
  109. data/src/main/java/processing/data/IntList.java +913 -0
  110. data/src/main/java/processing/data/JSONArray.java +1260 -0
  111. data/src/main/java/processing/data/JSONObject.java +2282 -0
  112. data/src/main/java/processing/data/JSONTokener.java +435 -0
  113. data/src/main/java/processing/data/Sort.java +46 -0
  114. data/src/main/java/processing/data/StringDict.java +601 -0
  115. data/src/main/java/processing/data/StringList.java +775 -0
  116. data/src/main/java/processing/data/Table.java +4923 -0
  117. data/src/main/java/processing/data/TableRow.java +198 -0
  118. data/src/main/java/processing/data/XML.java +1149 -0
  119. data/src/main/java/processing/event/Event.java +108 -0
  120. data/src/main/java/processing/event/KeyEvent.java +70 -0
  121. data/src/main/java/processing/event/MouseEvent.java +149 -0
  122. data/src/main/java/processing/event/TouchEvent.java +57 -0
  123. data/src/main/java/processing/javafx/PGraphicsFX2D.java +354 -0
  124. data/src/main/java/processing/opengl/FontTexture.java +379 -0
  125. data/src/main/java/processing/opengl/FrameBuffer.java +503 -0
  126. data/src/main/java/processing/opengl/LinePath.java +623 -0
  127. data/src/main/java/processing/opengl/LineStroker.java +685 -0
  128. data/src/main/java/processing/opengl/PGL.java +3366 -0
  129. data/src/main/java/processing/opengl/PGraphics2D.java +615 -0
  130. data/src/main/java/processing/opengl/PGraphics3D.java +281 -0
  131. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +13634 -0
  132. data/src/main/java/processing/opengl/PJOGL.java +1966 -0
  133. data/src/main/java/processing/opengl/PShader.java +1478 -0
  134. data/src/main/java/processing/opengl/PShapeOpenGL.java +5234 -0
  135. data/src/main/java/processing/opengl/PSurfaceJOGL.java +1315 -0
  136. data/src/main/java/processing/opengl/Texture.java +1670 -0
  137. data/src/main/java/processing/opengl/VertexBuffer.java +88 -0
  138. data/src/main/java/processing/opengl/cursors/arrow.png +0 -0
  139. data/src/main/java/processing/opengl/cursors/cross.png +0 -0
  140. data/src/main/java/processing/opengl/cursors/hand.png +0 -0
  141. data/src/main/java/processing/opengl/cursors/license.txt +27 -0
  142. data/src/main/java/processing/opengl/cursors/move.png +0 -0
  143. data/src/main/java/processing/opengl/cursors/text.png +0 -0
  144. data/src/main/java/processing/opengl/cursors/wait.png +0 -0
  145. data/src/main/java/processing/opengl/shaders/ColorFrag.glsl +32 -0
  146. data/src/main/java/processing/opengl/shaders/ColorVert.glsl +34 -0
  147. data/src/main/java/processing/opengl/shaders/LightFrag.glsl +33 -0
  148. data/src/main/java/processing/opengl/shaders/LightVert-vc4.glsl +154 -0
  149. data/src/main/java/processing/opengl/shaders/LightVert.glsl +151 -0
  150. data/src/main/java/processing/opengl/shaders/LineFrag.glsl +32 -0
  151. data/src/main/java/processing/opengl/shaders/LineVert.glsl +100 -0
  152. data/src/main/java/processing/opengl/shaders/MaskFrag.glsl +40 -0
  153. data/src/main/java/processing/opengl/shaders/PointFrag.glsl +32 -0
  154. data/src/main/java/processing/opengl/shaders/PointVert.glsl +56 -0
  155. data/src/main/java/processing/opengl/shaders/TexFrag.glsl +37 -0
  156. data/src/main/java/processing/opengl/shaders/TexLightFrag.glsl +37 -0
  157. data/src/main/java/processing/opengl/shaders/TexLightVert-vc4.glsl +160 -0
  158. data/src/main/java/processing/opengl/shaders/TexLightVert.glsl +157 -0
  159. data/src/main/java/processing/opengl/shaders/TexVert.glsl +38 -0
  160. data/src/main/resources/icon/icon-1024.png +0 -0
  161. data/src/main/resources/icon/icon-128.png +0 -0
  162. data/src/main/resources/icon/icon-16.png +0 -0
  163. data/src/main/resources/icon/icon-256.png +0 -0
  164. data/src/main/resources/icon/icon-32.png +0 -0
  165. data/src/main/resources/icon/icon-48.png +0 -0
  166. data/src/main/resources/icon/icon-512.png +0 -0
  167. data/src/main/resources/icon/icon-64.png +0 -0
  168. data/src/main/resources/license.txt +508 -0
  169. data/test/create_test.rb +68 -0
  170. data/test/deglut_spec_test.rb +24 -0
  171. data/test/helper_methods_test.rb +58 -0
  172. data/test/math_tool_test.rb +75 -0
  173. data/test/respond_to_test.rb +215 -0
  174. data/test/sketches/key_event.rb +37 -0
  175. data/test/sketches/library/my_library/my_library.rb +32 -0
  176. data/test/test_helper.rb +3 -0
  177. data/test/vecmath_spec_test.rb +522 -0
  178. data/vendors/Rakefile +127 -0
  179. metadata +289 -0
@@ -0,0 +1,379 @@
1
+ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
+
3
+ /*
4
+ Part of the Processing project - http://processing.org
5
+
6
+ Copyright (c) 2012-15 The Processing Foundation
7
+ Copyright (c) 2004-12 Ben Fry and Casey Reas
8
+ Copyright (c) 2001-04 Massachusetts Institute of Technology
9
+
10
+ This library is free software; you can redistribute it and/or
11
+ modify it under the terms of the GNU Lesser General Public
12
+ License as published by the Free Software Foundation, version 2.1.
13
+
14
+ This library is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
+ Lesser General Public License for more details.
18
+
19
+ You should have received a copy of the GNU Lesser General
20
+ Public License along with this library; if not, write to the
21
+ Free Software Foundation, Inc., 59 Temple Place, Suite 330,
22
+ Boston, MA 02111-1307 USA
23
+ */
24
+
25
+ package processing.opengl;
26
+
27
+ import processing.core.PApplet;
28
+ import processing.core.PConstants;
29
+ import processing.core.PFont;
30
+ import processing.core.PGraphics;
31
+ import processing.core.PImage;
32
+
33
+ import java.util.HashMap;
34
+
35
+ /**
36
+ * All the infrastructure needed for optimized font rendering
37
+ * in OpenGL. Basically, this special class is needed because
38
+ * fonts in Processing are handled by a separate PImage for each
39
+ * glyph. For performance reasons, all these glyphs should be
40
+ * stored in a single OpenGL texture (otherwise, rendering a
41
+ * string of text would involve binding and un-binding several
42
+ * textures.
43
+ * PFontTexture manages the correspondence between individual
44
+ * glyphs and the large OpenGL texture containing them. Also,
45
+ * in the case that the font size is very large, one single
46
+ * OpenGL texture might not be enough to store all the glyphs,
47
+ * so PFontTexture also takes care of spreading a single font
48
+ * over several textures.
49
+ * @author Andres Colubri
50
+ */
51
+ class FontTexture implements PConstants {
52
+ protected PGL pgl;
53
+ protected boolean is3D;
54
+
55
+ protected int minSize;
56
+ protected int maxSize;
57
+ protected int offsetX;
58
+ protected int offsetY;
59
+ protected int lineHeight;
60
+ protected Texture[] textures = null;
61
+ protected PImage[] images = null;
62
+ protected int lastTex;
63
+ protected TextureInfo[] glyphTexinfos;
64
+ protected HashMap<PFont.Glyph, TextureInfo> texinfoMap;
65
+
66
+ public FontTexture(PGraphicsOpenGL pg, PFont font, boolean is3D) {
67
+ pgl = pg.pgl;
68
+ this.is3D = is3D;
69
+
70
+ initTexture(pg, font);
71
+ }
72
+
73
+
74
+ protected void allocate() {
75
+ // Nothing to do here: the font textures will allocate
76
+ // themselves.
77
+ }
78
+
79
+
80
+ protected void dispose() {
81
+ for (int i = 0; i < textures.length; i++) {
82
+ textures[i].dispose();
83
+ }
84
+ }
85
+
86
+
87
+ protected void initTexture(PGraphicsOpenGL pg, PFont font) {
88
+ lastTex = -1;
89
+
90
+ int spow = PGL.nextPowerOfTwo(font.getSize());
91
+ minSize = PApplet.min(PGraphicsOpenGL.maxTextureSize,
92
+ PApplet.max(PGL.MIN_FONT_TEX_SIZE, spow));
93
+ maxSize = PApplet.min(PGraphicsOpenGL.maxTextureSize,
94
+ PApplet.max(PGL.MAX_FONT_TEX_SIZE, 2 * spow));
95
+
96
+ if (maxSize < spow) {
97
+ PGraphics.showWarning("The font size is too large to be properly " +
98
+ "displayed with OpenGL");
99
+ }
100
+
101
+ addTexture(pg);
102
+
103
+ offsetX = 0;
104
+ offsetY = 0;
105
+ lineHeight = 0;
106
+
107
+ texinfoMap = new HashMap<PFont.Glyph, TextureInfo>();
108
+ glyphTexinfos = new TextureInfo[font.getGlyphCount()];
109
+ addAllGlyphsToTexture(pg, font);
110
+ }
111
+
112
+
113
+ public boolean addTexture(PGraphicsOpenGL pg) {
114
+ int w, h;
115
+ boolean resize;
116
+
117
+ w = maxSize;
118
+ if (-1 < lastTex && textures[lastTex].glHeight < maxSize) {
119
+ // The height of the current texture is less than the maximum, this
120
+ // means we can replace it with a larger texture.
121
+ h = PApplet.min(2 * textures[lastTex].glHeight, maxSize);
122
+ resize = true;
123
+ } else {
124
+ h = minSize;
125
+ resize = false;
126
+ }
127
+
128
+ Texture tex;
129
+ if (is3D) {
130
+ // Bilinear sampling ensures that the texture doesn't look pixelated
131
+ // either when it is magnified or minified...
132
+ tex = new Texture(pg, w, h,
133
+ new Texture.Parameters(ARGB, Texture.BILINEAR, false));
134
+ } else {
135
+ // ...however, the effect of bilinear sampling is to add some blurriness
136
+ // to the text in its original size. In 2D, we assume that text will be
137
+ // shown at its original size, so linear sampling is chosen instead (which
138
+ // only affects minimized text).
139
+ tex = new Texture(pg, w, h,
140
+ new Texture.Parameters(ARGB, Texture.LINEAR, false));
141
+ }
142
+
143
+ if (textures == null) {
144
+ textures = new Texture[1];
145
+ textures[0] = tex;
146
+ images = new PImage[1];
147
+ images[0] = pg.wrapTexture(tex);
148
+ lastTex = 0;
149
+ } else if (resize) {
150
+ // Replacing old smaller texture with larger one.
151
+ // But first we must copy the contents of the older
152
+ // texture into the new one.
153
+ Texture tex0 = textures[lastTex];
154
+ tex.put(tex0);
155
+ textures[lastTex] = tex;
156
+
157
+ pg.setCache(images[lastTex], tex);
158
+ images[lastTex].width = tex.width;
159
+ images[lastTex].height = tex.height;
160
+ } else {
161
+ // Adding new texture to the list.
162
+ lastTex = textures.length;
163
+ Texture[] tempTex = new Texture[lastTex + 1];
164
+ PApplet.arrayCopy(textures, tempTex, textures.length);
165
+ tempTex[lastTex] = tex;
166
+ textures = tempTex;
167
+
168
+ PImage[] tempImg = new PImage[textures.length];
169
+ PApplet.arrayCopy(images, tempImg, images.length);
170
+ tempImg[lastTex] = pg.wrapTexture(tex);
171
+ images = tempImg;
172
+ }
173
+
174
+ // Make sure that the current texture is bound.
175
+ tex.bind();
176
+
177
+ return resize;
178
+ }
179
+
180
+
181
+ public void begin() {
182
+ }
183
+
184
+
185
+ public void end() {
186
+ for (int i = 0; i < textures.length; i++) {
187
+ pgl.disableTexturing(textures[i].glTarget);
188
+ }
189
+ }
190
+
191
+
192
+ public PImage getTexture(TextureInfo info) {
193
+ return images[info.texIndex];
194
+ }
195
+
196
+
197
+ // Add all the current glyphs to opengl texture.
198
+ public void addAllGlyphsToTexture(PGraphicsOpenGL pg, PFont font) {
199
+ // loop over current glyphs.
200
+ for (int i = 0; i < font.getGlyphCount(); i++) {
201
+ addToTexture(pg, i, font.getGlyph(i));
202
+ }
203
+ }
204
+
205
+
206
+ public void updateGlyphsTexCoords() {
207
+ // loop over current glyphs.
208
+ for (int i = 0; i < glyphTexinfos.length; i++) {
209
+ TextureInfo tinfo = glyphTexinfos[i];
210
+ if (tinfo != null && tinfo.texIndex == lastTex) {
211
+ tinfo.updateUV();
212
+ }
213
+ }
214
+ }
215
+
216
+
217
+ public TextureInfo getTexInfo(PFont.Glyph glyph) {
218
+ TextureInfo info = texinfoMap.get(glyph);
219
+ return info;
220
+ }
221
+
222
+
223
+ public TextureInfo addToTexture(PGraphicsOpenGL pg, PFont.Glyph glyph) {
224
+ int n = glyphTexinfos.length;
225
+ if (n == 0) {
226
+ glyphTexinfos = new TextureInfo[1];
227
+ }
228
+ addToTexture(pg, n, glyph);
229
+ return glyphTexinfos[n];
230
+ }
231
+
232
+
233
+ public boolean contextIsOutdated() {
234
+ boolean outdated = false;
235
+ for (int i = 0; i < textures.length; i++) {
236
+ if (textures[i].contextIsOutdated()) {
237
+ outdated = true;
238
+ }
239
+ }
240
+ if (outdated) {
241
+ for (int i = 0; i < textures.length; i++) {
242
+ textures[i].dispose();
243
+ }
244
+ }
245
+ return outdated;
246
+ }
247
+
248
+ // public void draw() {
249
+ // Texture tex = textures[lastTex];
250
+ // pgl.drawTexture(tex.glTarget, tex.glName,
251
+ // tex.glWidth, tex.glHeight,
252
+ // 0, 0, tex.glWidth, tex.glHeight);
253
+ // }
254
+
255
+
256
+ // Adds this glyph to the opengl texture in PFont.
257
+ protected void addToTexture(PGraphicsOpenGL pg, int idx, PFont.Glyph glyph) {
258
+ // We add one pixel to avoid issues when sampling the font texture at
259
+ // fractional screen positions. I.e.: the pixel on the screen only contains
260
+ // half of the font rectangle, so it would sample half of the color from the
261
+ // glyph area in the texture, and the other half from the contiguous pixel.
262
+ // If the later contains a portion of the neighbor glyph and the former
263
+ // doesn't, this would result in a shaded pixel when the correct output is
264
+ // blank. This is a consequence of putting all the glyphs in a common
265
+ // texture with bilinear sampling.
266
+ int w = 1 + glyph.width + 1;
267
+ int h = 1 + glyph.height + 1;
268
+
269
+ // Converting the pixels array from the PImage into a valid RGBA array for
270
+ // OpenGL.
271
+ int[] rgba = new int[w * h];
272
+ int t = 0;
273
+ int p = 0;
274
+ if (PGL.BIG_ENDIAN) {
275
+ java.util.Arrays.fill(rgba, 0, w, 0xFFFFFF00); // Set the first row to blank pixels.
276
+ t = w;
277
+ for (int y = 0; y < glyph.height; y++) {
278
+ rgba[t++] = 0xFFFFFF00; // Set the leftmost pixel in this row as blank
279
+ for (int x = 0; x < glyph.width; x++) {
280
+ rgba[t++] = 0xFFFFFF00 | glyph.image.pixels[p++];
281
+ }
282
+ rgba[t++] = 0xFFFFFF00; // Set the rightmost pixel in this row as blank
283
+ }
284
+ java.util.Arrays.fill(rgba, (h - 1) * w, h * w, 0xFFFFFF00); // Set the last row to blank pixels.
285
+ } else {
286
+ java.util.Arrays.fill(rgba, 0, w, 0x00FFFFFF); // Set the first row to blank pixels.
287
+ t = w;
288
+ for (int y = 0; y < glyph.height; y++) {
289
+ rgba[t++] = 0x00FFFFFF; // Set the leftmost pixel in this row as blank
290
+ for (int x = 0; x < glyph.width; x++) {
291
+ rgba[t++] = (glyph.image.pixels[p++] << 24) | 0x00FFFFFF;
292
+ }
293
+ rgba[t++] = 0x00FFFFFF; // Set the rightmost pixel in this row as blank
294
+ }
295
+ java.util.Arrays.fill(rgba, (h - 1) * w, h * w, 0x00FFFFFF); // Set the last row to blank pixels.
296
+ }
297
+
298
+ // Is there room for this glyph in the current line?
299
+ if (offsetX + w > textures[lastTex].glWidth) {
300
+ // No room, go to the next line:
301
+ offsetX = 0;
302
+ offsetY += lineHeight;
303
+ }
304
+ lineHeight = Math.max(lineHeight, h);
305
+
306
+ boolean resized = false;
307
+ if (offsetY + lineHeight > textures[lastTex].glHeight) {
308
+ // We run out of space in the current texture, so we add a new texture:
309
+ resized = addTexture(pg);
310
+ if (resized) {
311
+ // Because the current texture has been resized, we need to
312
+ // update the UV coordinates of all the glyphs associated to it:
313
+ updateGlyphsTexCoords();
314
+ } else {
315
+ // A new texture has been created. Reseting texture coordinates
316
+ // and line.
317
+ offsetX = 0;
318
+ offsetY = 0;
319
+ lineHeight = 0;
320
+ }
321
+ }
322
+
323
+ TextureInfo tinfo = new TextureInfo(lastTex, offsetX, offsetY, w, h, rgba);
324
+ offsetX += w;
325
+
326
+ if (idx == glyphTexinfos.length) {
327
+ TextureInfo[] temp = new TextureInfo[glyphTexinfos.length + 1];
328
+ System.arraycopy(glyphTexinfos, 0, temp, 0, glyphTexinfos.length);
329
+ glyphTexinfos = temp;
330
+ }
331
+
332
+ glyphTexinfos[idx] = tinfo;
333
+ texinfoMap.put(glyph, tinfo);
334
+ }
335
+
336
+
337
+ class TextureInfo {
338
+ int texIndex;
339
+ int width;
340
+ int height;
341
+ int[] crop;
342
+ float u0, u1;
343
+ float v0, v1;
344
+ int[] pixels;
345
+
346
+ TextureInfo(int tidx, int cropX, int cropY, int cropW, int cropH,
347
+ int[] pix) {
348
+ texIndex = tidx;
349
+ crop = new int[4];
350
+ // The region of the texture corresponding to the glyph is surrounded by a
351
+ // 1-pixel wide border to avoid artifacts due to bilinear sampling. This
352
+ // is why the additions and subtractions to the crop values.
353
+ crop[0] = cropX + 1;
354
+ crop[1] = cropY + 1 + cropH - 2;
355
+ crop[2] = cropW - 2;
356
+ crop[3] = -cropH + 2;
357
+ pixels = pix;
358
+ updateUV();
359
+ updateTex();
360
+ }
361
+
362
+
363
+ void updateUV() {
364
+ width = textures[texIndex].glWidth;
365
+ height = textures[texIndex].glHeight;
366
+
367
+ u0 = (float)crop[0] / (float)width;
368
+ u1 = u0 + (float)crop[2] / (float)width;
369
+ v0 = (float)(crop[1] + crop[3]) / (float)height;
370
+ v1 = v0 - (float)crop[3] / (float)height;
371
+ }
372
+
373
+
374
+ void updateTex() {
375
+ textures[texIndex].setNative(pixels, crop[0] - 1, crop[1] + crop[3] - 1,
376
+ crop[2] + 2, -crop[3] + 2);
377
+ }
378
+ }
379
+ }
@@ -0,0 +1,503 @@
1
+ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
+
3
+ /*
4
+ Part of the Processing project - http://processing.org
5
+
6
+ Copyright (c) 2012-15 The Processing Foundation
7
+ Copyright (c) 2004-12 Ben Fry and Casey Reas
8
+ Copyright (c) 2001-04 Massachusetts Institute of Technology
9
+
10
+ This library is free software; you can redistribute it and/or
11
+ modify it under the terms of the GNU Lesser General Public
12
+ License as published by the Free Software Foundation, version 2.1.
13
+
14
+ This library is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
+ Lesser General Public License for more details.
18
+
19
+ You should have received a copy of the GNU Lesser General
20
+ Public License along with this library; if not, write to the
21
+ Free Software Foundation, Inc., 59 Temple Place, Suite 330,
22
+ Boston, MA 02111-1307 USA
23
+ */
24
+
25
+ package processing.opengl;
26
+
27
+ import processing.core.PApplet;
28
+ import processing.core.PConstants;
29
+ import processing.opengl.PGraphicsOpenGL.GLResourceFrameBuffer;
30
+
31
+ import java.nio.IntBuffer;
32
+
33
+ /**
34
+ * Encapsulates a Frame Buffer Object for offscreen rendering.
35
+ * When created with onscreen == true, it represents the normal
36
+ * framebuffer. Needed by the stack mechanism in OPENGL2 to return
37
+ * to onscreen rendering after a sequence of pushFramebuffer calls.
38
+ * It transparently handles the situations when the FBO extension is
39
+ * not available.
40
+ *
41
+ * By Andres Colubri.
42
+ */
43
+
44
+ public class FrameBuffer implements PConstants {
45
+ protected PGraphicsOpenGL pg;
46
+ protected PGL pgl;
47
+ protected int context; // The context that created this framebuffer.
48
+
49
+ public int glFbo;
50
+ public int glDepth;
51
+ public int glStencil;
52
+ public int glDepthStencil;
53
+ public int glMultisample;
54
+ public int width;
55
+ public int height;
56
+ private GLResourceFrameBuffer glres;
57
+
58
+ protected int depthBits;
59
+ protected int stencilBits;
60
+ protected boolean packedDepthStencil;
61
+
62
+ protected boolean multisample;
63
+ protected int nsamples;
64
+
65
+ protected int numColorBuffers;
66
+ protected Texture[] colorBufferTex;
67
+
68
+ protected boolean screenFb;
69
+ protected boolean noDepth;
70
+
71
+ protected IntBuffer pixelBuffer;
72
+
73
+
74
+ FrameBuffer(PGraphicsOpenGL pg) {
75
+ this.pg = pg;
76
+ pgl = pg.pgl;
77
+ context = pgl.createEmptyContext();
78
+ }
79
+
80
+
81
+ FrameBuffer(PGraphicsOpenGL pg, int w, int h, int samples, int colorBuffers,
82
+ int depthBits, int stencilBits, boolean packedDepthStencil,
83
+ boolean screen) {
84
+ this(pg);
85
+
86
+ glFbo = 0;
87
+ glDepth = 0;
88
+ glStencil = 0;
89
+ glDepthStencil = 0;
90
+ glMultisample = 0;
91
+
92
+ if (screen) {
93
+ // If this framebuffer is used to represent a on-screen buffer,
94
+ // then it doesn't make it sense for it to have multisampling,
95
+ // color, depth or stencil buffers.
96
+ depthBits = stencilBits = samples = colorBuffers = 0;
97
+ }
98
+
99
+ width = w;
100
+ height = h;
101
+
102
+ if (1 < samples) {
103
+ multisample = true;
104
+ nsamples = samples;
105
+ } else {
106
+ multisample = false;
107
+ nsamples = 1;
108
+ }
109
+
110
+ numColorBuffers = colorBuffers;
111
+ colorBufferTex = new Texture[numColorBuffers];
112
+ for (int i = 0; i < numColorBuffers; i++) {
113
+ colorBufferTex[i] = null;
114
+ }
115
+
116
+ if (depthBits < 1 && stencilBits < 1) {
117
+ this.depthBits = 0;
118
+ this.stencilBits = 0;
119
+ this.packedDepthStencil = false;
120
+ } else {
121
+ if (packedDepthStencil) {
122
+ // When combined depth/stencil format is required, the depth and stencil
123
+ // bits are overriden and the 24/8 combination for a 32 bits surface is
124
+ // used.
125
+ this.depthBits = 24;
126
+ this.stencilBits = 8;
127
+ this.packedDepthStencil = true;
128
+ } else {
129
+ this.depthBits = depthBits;
130
+ this.stencilBits = stencilBits;
131
+ this.packedDepthStencil = false;
132
+ }
133
+ }
134
+
135
+ screenFb = screen;
136
+
137
+ allocate();
138
+ noDepth = false;
139
+
140
+ pixelBuffer = null;
141
+ }
142
+
143
+
144
+ FrameBuffer(PGraphicsOpenGL pg, int w, int h) {
145
+ this(pg, w, h, 1, 1, 0, 0, false, false);
146
+ }
147
+
148
+
149
+ FrameBuffer(PGraphicsOpenGL pg, int w, int h, boolean screen) {
150
+ this(pg, w, h, 1, 1, 0, 0, false, screen);
151
+ }
152
+
153
+
154
+ public void clear() {
155
+ pg.pushFramebuffer();
156
+ pg.setFramebuffer(this);
157
+ pgl.clearDepth(1);
158
+ pgl.clearStencil(0);
159
+ pgl.clearColor(0, 0, 0, 0);
160
+ pgl.clear(PGL.DEPTH_BUFFER_BIT |
161
+ PGL.STENCIL_BUFFER_BIT |
162
+ PGL.COLOR_BUFFER_BIT);
163
+ pg.popFramebuffer();
164
+ }
165
+
166
+ public void copyColor(FrameBuffer dest) {
167
+ copy(dest, PGL.COLOR_BUFFER_BIT);
168
+ }
169
+
170
+ public void copyDepth(FrameBuffer dest) {
171
+ copy(dest, PGL.DEPTH_BUFFER_BIT);
172
+ }
173
+
174
+ public void copyStencil(FrameBuffer dest) {
175
+ copy(dest, PGL.STENCIL_BUFFER_BIT);
176
+ }
177
+
178
+ public void copy(FrameBuffer dest, int mask) {
179
+ pgl.bindFramebufferImpl(PGL.READ_FRAMEBUFFER, this.glFbo);
180
+ pgl.bindFramebufferImpl(PGL.DRAW_FRAMEBUFFER, dest.glFbo);
181
+ pgl.blitFramebuffer(0, 0, this.width, this.height,
182
+ 0, 0, dest.width, dest.height, mask, PGL.NEAREST);
183
+ pgl.bindFramebufferImpl(PGL.READ_FRAMEBUFFER, pg.getCurrentFB().glFbo);
184
+ pgl.bindFramebufferImpl(PGL.DRAW_FRAMEBUFFER, pg.getCurrentFB().glFbo);
185
+ }
186
+
187
+ public void bind() {
188
+ pgl.bindFramebufferImpl(PGL.FRAMEBUFFER, glFbo);
189
+ }
190
+
191
+ public void disableDepthTest() {
192
+ noDepth = true;
193
+ }
194
+
195
+ public void finish() {
196
+ if (noDepth) {
197
+ // No need to clear depth buffer because depth testing was disabled.
198
+ if (pg.getHint(ENABLE_DEPTH_TEST)) {
199
+ pgl.enable(PGL.DEPTH_TEST);
200
+ } else {
201
+ pgl.disable(PGL.DEPTH_TEST);
202
+ }
203
+ }
204
+ }
205
+
206
+ public void readPixels() {
207
+ if (pixelBuffer == null) createPixelBuffer();
208
+ pixelBuffer.rewind();
209
+ pgl.readPixels(0, 0, width, height, PGL.RGBA, PGL.UNSIGNED_BYTE,
210
+ pixelBuffer);
211
+ }
212
+
213
+ public void getPixels(int[] pixels) {
214
+ if (pixelBuffer != null) {
215
+ pixelBuffer.get(pixels, 0, pixels.length);
216
+ pixelBuffer.rewind();
217
+ }
218
+ }
219
+
220
+ public IntBuffer getPixelBuffer() {
221
+ return pixelBuffer;
222
+ }
223
+
224
+ public boolean hasDepthBuffer() {
225
+ return 0 < depthBits;
226
+ }
227
+
228
+ public boolean hasStencilBuffer() {
229
+ return 0 < stencilBits;
230
+ }
231
+
232
+ public void setFBO(int id) {
233
+ if (screenFb) {
234
+ glFbo = id;
235
+ }
236
+ }
237
+
238
+ ///////////////////////////////////////////////////////////
239
+
240
+ // Color buffer setters.
241
+
242
+
243
+ public void setColorBuffer(Texture tex) {
244
+ setColorBuffers(new Texture[] { tex }, 1);
245
+ }
246
+
247
+
248
+ public void setColorBuffers(Texture[] textures) {
249
+ setColorBuffers(textures, textures.length);
250
+ }
251
+
252
+
253
+ public void setColorBuffers(Texture[] textures, int n) {
254
+ if (screenFb) return;
255
+
256
+ if (numColorBuffers != PApplet.min(n, textures.length)) {
257
+ throw new RuntimeException("Wrong number of textures to set the color " +
258
+ "buffers.");
259
+ }
260
+
261
+ for (int i = 0; i < numColorBuffers; i++) {
262
+ colorBufferTex[i] = textures[i];
263
+ }
264
+
265
+ pg.pushFramebuffer();
266
+ pg.setFramebuffer(this);
267
+
268
+ // Making sure nothing is attached.
269
+ for (int i = 0; i < numColorBuffers; i++) {
270
+ pgl.framebufferTexture2D(PGL.FRAMEBUFFER, PGL.COLOR_ATTACHMENT0 + i,
271
+ PGL.TEXTURE_2D, 0, 0);
272
+ }
273
+
274
+ for (int i = 0; i < numColorBuffers; i++) {
275
+ pgl.framebufferTexture2D(PGL.FRAMEBUFFER, PGL.COLOR_ATTACHMENT0 + i,
276
+ colorBufferTex[i].glTarget,
277
+ colorBufferTex[i].glName, 0);
278
+ }
279
+
280
+ pgl.validateFramebuffer();
281
+
282
+ pg.popFramebuffer();
283
+ }
284
+
285
+
286
+ public void swapColorBuffers() {
287
+ for (int i = 0; i < numColorBuffers - 1; i++) {
288
+ int i1 = (i + 1);
289
+ Texture tmp = colorBufferTex[i];
290
+ colorBufferTex[i] = colorBufferTex[i1];
291
+ colorBufferTex[i1] = tmp;
292
+ }
293
+
294
+ pg.pushFramebuffer();
295
+ pg.setFramebuffer(this);
296
+ for (int i = 0; i < numColorBuffers; i++) {
297
+ pgl.framebufferTexture2D(PGL.FRAMEBUFFER, PGL.COLOR_ATTACHMENT0 + i,
298
+ colorBufferTex[i].glTarget,
299
+ colorBufferTex[i].glName, 0);
300
+ }
301
+ pgl.validateFramebuffer();
302
+
303
+ pg.popFramebuffer();
304
+ }
305
+
306
+
307
+ public int getDefaultReadBuffer() {
308
+ if (screenFb) {
309
+ return pgl.getDefaultReadBuffer();
310
+ } else {
311
+ return PGL.COLOR_ATTACHMENT0;
312
+ }
313
+ }
314
+
315
+
316
+ public int getDefaultDrawBuffer() {
317
+ if (screenFb) {
318
+ return pgl.getDefaultDrawBuffer();
319
+ } else {
320
+ return PGL.COLOR_ATTACHMENT0;
321
+ }
322
+ }
323
+
324
+
325
+ ///////////////////////////////////////////////////////////
326
+
327
+ // Allocate/release framebuffer.
328
+
329
+
330
+ protected void allocate() {
331
+ dispose(); // Just in the case this object is being re-allocated.
332
+
333
+ context = pgl.getCurrentContext();
334
+ glres = new GLResourceFrameBuffer(this); // create the FBO resources...
335
+
336
+ if (screenFb) {
337
+ glFbo = 0;
338
+ } else {
339
+ if (multisample) {
340
+ initColorBufferMultisample();
341
+ }
342
+
343
+ if (packedDepthStencil) {
344
+ initPackedDepthStencilBuffer();
345
+ } else {
346
+ if (0 < depthBits) {
347
+ initDepthBuffer();
348
+ }
349
+ if (0 < stencilBits) {
350
+ initStencilBuffer();
351
+ }
352
+ }
353
+ }
354
+ }
355
+
356
+
357
+ protected void dispose() {
358
+ if (screenFb) return;
359
+ if (glres != null) {
360
+ glres.dispose();
361
+ glFbo = 0;
362
+ glDepth = 0;
363
+ glStencil = 0;
364
+ glMultisample = 0;
365
+ glDepthStencil = 0;
366
+ glres = null;
367
+ }
368
+ }
369
+
370
+
371
+ protected boolean contextIsOutdated() {
372
+ if (screenFb) return false;
373
+
374
+ boolean outdated = !pgl.contextIsCurrent(context);
375
+ if (outdated) {
376
+ dispose();
377
+ for (int i = 0; i < numColorBuffers; i++) {
378
+ colorBufferTex[i] = null;
379
+ }
380
+ }
381
+ return outdated;
382
+ }
383
+
384
+
385
+ protected void initColorBufferMultisample() {
386
+ if (screenFb) return;
387
+
388
+ pg.pushFramebuffer();
389
+ pg.setFramebuffer(this);
390
+
391
+ pgl.bindRenderbuffer(PGL.RENDERBUFFER, glMultisample);
392
+ pgl.renderbufferStorageMultisample(PGL.RENDERBUFFER, nsamples,
393
+ PGL.RGBA8, width, height);
394
+ pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.COLOR_ATTACHMENT0,
395
+ PGL.RENDERBUFFER, glMultisample);
396
+
397
+ pg.popFramebuffer();
398
+ }
399
+
400
+
401
+ protected void initPackedDepthStencilBuffer() {
402
+ if (screenFb) return;
403
+
404
+ if (width == 0 || height == 0) {
405
+ throw new RuntimeException("PFramebuffer: size undefined.");
406
+ }
407
+
408
+ pg.pushFramebuffer();
409
+ pg.setFramebuffer(this);
410
+
411
+ pgl.bindRenderbuffer(PGL.RENDERBUFFER, glDepthStencil);
412
+
413
+ if (multisample) {
414
+ pgl.renderbufferStorageMultisample(PGL.RENDERBUFFER, nsamples,
415
+ PGL.DEPTH24_STENCIL8, width, height);
416
+ } else {
417
+ pgl.renderbufferStorage(PGL.RENDERBUFFER, PGL.DEPTH24_STENCIL8,
418
+ width, height);
419
+ }
420
+
421
+ pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.DEPTH_ATTACHMENT,
422
+ PGL.RENDERBUFFER, glDepthStencil);
423
+ pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.STENCIL_ATTACHMENT,
424
+ PGL.RENDERBUFFER, glDepthStencil);
425
+
426
+ pg.popFramebuffer();
427
+ }
428
+
429
+
430
+ protected void initDepthBuffer() {
431
+ if (screenFb) return;
432
+
433
+ if (width == 0 || height == 0) {
434
+ throw new RuntimeException("PFramebuffer: size undefined.");
435
+ }
436
+
437
+ pg.pushFramebuffer();
438
+ pg.setFramebuffer(this);
439
+
440
+ pgl.bindRenderbuffer(PGL.RENDERBUFFER, glDepth);
441
+
442
+ int glConst = PGL.DEPTH_COMPONENT16;
443
+ if (depthBits == 16) {
444
+ glConst = PGL.DEPTH_COMPONENT16;
445
+ } else if (depthBits == 24) {
446
+ glConst = PGL.DEPTH_COMPONENT24;
447
+ } else if (depthBits == 32) {
448
+ glConst = PGL.DEPTH_COMPONENT32;
449
+ }
450
+
451
+ if (multisample) {
452
+ pgl.renderbufferStorageMultisample(PGL.RENDERBUFFER, nsamples, glConst,
453
+ width, height);
454
+ } else {
455
+ pgl.renderbufferStorage(PGL.RENDERBUFFER, glConst, width, height);
456
+ }
457
+
458
+ pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.DEPTH_ATTACHMENT,
459
+ PGL.RENDERBUFFER, glDepth);
460
+
461
+ pg.popFramebuffer();
462
+ }
463
+
464
+
465
+ protected void initStencilBuffer() {
466
+ if (screenFb) return;
467
+
468
+ if (width == 0 || height == 0) {
469
+ throw new RuntimeException("PFramebuffer: size undefined.");
470
+ }
471
+
472
+ pg.pushFramebuffer();
473
+ pg.setFramebuffer(this);
474
+
475
+ pgl.bindRenderbuffer(PGL.RENDERBUFFER, glStencil);
476
+
477
+ int glConst = PGL.STENCIL_INDEX1;
478
+ if (stencilBits == 1) {
479
+ glConst = PGL.STENCIL_INDEX1;
480
+ } else if (stencilBits == 4) {
481
+ glConst = PGL.STENCIL_INDEX4;
482
+ } else if (stencilBits == 8) {
483
+ glConst = PGL.STENCIL_INDEX8;
484
+ }
485
+ if (multisample) {
486
+ pgl.renderbufferStorageMultisample(PGL.RENDERBUFFER, nsamples, glConst,
487
+ width, height);
488
+ } else {
489
+ pgl.renderbufferStorage(PGL.RENDERBUFFER, glConst, width, height);
490
+ }
491
+
492
+ pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.STENCIL_ATTACHMENT,
493
+ PGL.RENDERBUFFER, glStencil);
494
+
495
+ pg.popFramebuffer();
496
+ }
497
+
498
+
499
+ protected void createPixelBuffer() {
500
+ pixelBuffer = IntBuffer.allocate(width * height);
501
+ pixelBuffer.rewind();
502
+ }
503
+ }