Skip to content

Commit 53b92e7

Browse files
committed
Add support for float textures + an example
1 parent 347c052 commit 53b92e7

File tree

7 files changed

+140
-17
lines changed

7 files changed

+140
-17
lines changed

.prettierrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"useTabs": false,
3+
"tabWidth": 2,
4+
"semi": false,
5+
"singleQuote": true,
6+
"trailingComma": "all",
7+
"printWidth": 80,
8+
"arrowParens": "always"
9+
}

examples/feedback/index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html><html lang="en"><head>
2+
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>
3+
<script src="../../p5.Framebuffer.js" type="text/javascript"></script>
4+
<link rel="stylesheet" type="text/css" href="style.css">
5+
<meta charset="utf-8">
6+
7+
</head>
8+
<body>
9+
<script src="sketch.js"></script>
10+
11+
12+
</body></html>

examples/feedback/sketch.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
let fboPrev, fboNext
2+
let canvas
3+
4+
function setup() {
5+
canvas = createCanvas(400, 400, WEBGL)
6+
// There's a bug in Firefox where you can only make floating point textures
7+
// if they're RGBA, and it breaks if it's just RGB
8+
setAttributes({ alpha: true })
9+
10+
// Try changing `float` to `unsigned_byte` to see it leave a trail
11+
options = { colorFormat: 'float' }
12+
fboPrev = createFramebuffer(options)
13+
fboNext = createFramebuffer(options)
14+
imageMode(CENTER)
15+
rectMode(CENTER)
16+
noStroke()
17+
}
18+
19+
function draw() {
20+
// Swap prev and next so that we can use the previous frame as a texture
21+
// when drawing the current frame
22+
[fboPrev, fboNext] = [fboNext, fboPrev]
23+
24+
// Draw to the Framebuffer
25+
fboNext.draw(() => {
26+
clear()
27+
28+
background(255)
29+
30+
// Disable depth testing so that the image of the previous
31+
// frame doesn't cut off the sube
32+
_renderer.GL.disable(_renderer.GL.DEPTH_TEST)
33+
push()
34+
scale(1.003)
35+
texture(fboPrev.color)
36+
plane(width, -height)
37+
pop()
38+
39+
push()
40+
// Fade to white slowly. This will leave a permanent trail if you don't
41+
// use floating point textures.
42+
fill(255, 1)
43+
rect(0, 0, width, height)
44+
pop()
45+
_renderer.GL.enable(_renderer.GL.DEPTH_TEST)
46+
47+
push()
48+
normalMaterial()
49+
translate(100*sin(frameCount * 0.014), 100*sin(frameCount * 0.02), 0)
50+
rotateX(frameCount * 0.01)
51+
rotateY(frameCount * 0.01)
52+
box(50)
53+
pop()
54+
})
55+
56+
clear()
57+
push()
58+
texture(fboNext.color)
59+
plane(width, -height)
60+
pop()
61+
}

examples/feedback/style.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
html, body {
2+
margin: 0;
3+
padding: 0;
4+
}
5+
canvas {
6+
display: block;
7+
}

p5.Framebuffer.js

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
const _createFramebuffer = function() {
2-
const fb = new Framebuffer(this)
1+
const _createFramebuffer = function (options) {
2+
const fb = new Framebuffer(this, options)
33

44
// Extend the old resize handler to also update the size of the framebuffer
55
const oldResize = this._renderer.resize
@@ -14,7 +14,7 @@ p5.prototype.createFramebuffer = _createFramebuffer
1414
p5.Graphics.prototype.createFramebuffer = _createFramebuffer
1515

1616
const parentGetTexture = p5.RendererGL.prototype.getTexture
17-
p5.RendererGL.prototype.getTexture = function(imgOrTexture) {
17+
p5.RendererGL.prototype.getTexture = function (imgOrTexture) {
1818
if (imgOrTexture instanceof p5.Texture) {
1919
return imgOrTexture
2020
} else {
@@ -31,12 +31,7 @@ p5.RendererGL.prototype.getTexture = function(imgOrTexture) {
3131
// that looks like a p5 texture but that never tries to update
3232
// data in order to use framebuffer textures inside p5.
3333
class RawTextureWrapper extends p5.Texture {
34-
constructor(
35-
renderer,
36-
obj,
37-
w,
38-
h,
39-
) {
34+
constructor(renderer, obj, w, h) {
4035
super(renderer, obj)
4136
this.width = w
4237
this.height = h
@@ -64,15 +59,33 @@ class RawTextureWrapper extends p5.Texture {
6459
}
6560

6661
class Framebuffer {
67-
constructor(canvas) {
62+
constructor(canvas, options = {}) {
6863
this._renderer = canvas._renderer
69-
7064
const gl = this._renderer.GL
71-
const ext = gl.getExtension('WEBGL_depth_texture')
72-
if (!ext) {
65+
if (!gl.getExtension('WEBGL_depth_texture')) {
7366
throw new Error('Unable to create depth textures in this environment')
7467
}
7568

69+
this.colorFormat = this.glColorFormat(options.colorFormat)
70+
this.depthFormat = this.glDepthFormat(options.depthFormat)
71+
if (
72+
(options.colorFormat === 'float' || options.depthFormat === 'float') &&
73+
(!gl.getExtension('OES_texture_float') ||
74+
!gl.getExtension('OES_texture_float_linear') ||
75+
!gl.getExtension('WEBGL_color_buffer_float'))
76+
) {
77+
// Reset to default
78+
if (options.colorFormat === 'float') {
79+
this.colorFormat = this.glColorFormat()
80+
}
81+
if (options.depthFormat === 'float') {
82+
this.depthFormat = this.glDepthFormat()
83+
}
84+
console.warn(
85+
'Warning: Unable to create floating point textures in this environment. Falling back to integers',
86+
)
87+
}
88+
7689
const framebuffer = gl.createFramebuffer()
7790
if (!framebuffer) {
7891
throw new Error('Unable to create a framebuffer')
@@ -81,6 +94,21 @@ class Framebuffer {
8194
this.recreateTextures()
8295
}
8396

97+
glColorFormat(format) {
98+
const gl = this._renderer.GL
99+
if (format === 'float') {
100+
return gl.FLOAT
101+
}
102+
return gl.UNSIGNED_BYTE
103+
}
104+
glDepthFormat(format) {
105+
const gl = this._renderer.GL
106+
if (format === 'float') {
107+
return gl.FLOAT
108+
}
109+
return gl.UNSIGNED_SHORT
110+
}
111+
84112
handleResize() {
85113
const oldColor = this.colorTexture
86114
const oldDepth = this.depthTexture
@@ -117,7 +145,7 @@ class Framebuffer {
117145
height * density,
118146
0,
119147
hasAlpha ? gl.RGBA : gl.RGB,
120-
gl.UNSIGNED_BYTE,
148+
this.colorFormat,
121149
null,
122150
)
123151

@@ -140,7 +168,7 @@ class Framebuffer {
140168
height * density,
141169
0,
142170
gl.DEPTH_COMPONENT,
143-
gl.UNSIGNED_SHORT,
171+
this.depthFormat,
144172
null,
145173
)
146174

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@davepagurek/p5.framebuffer",
3-
"version": "0.0.2",
3+
"version": "0.0.3",
44
"main": "p5.Framebuffer.js",
55
"author": "Dave Pagurek <[email protected]>",
66
"license": "MIT",
@@ -14,7 +14,8 @@
1414
"homepage": "https://github.com/davepagurek/p5.Framebuffer",
1515
"dependencies": {},
1616
"devDependencies": {
17-
"minify": "^9.0.0"
17+
"minify": "^9.0.0",
18+
"prettier": "^2.7.1"
1819
},
1920
"scripts": {
2021
"build:core": "minify p5.Framebuffer.js > p5.Framebuffer.core.min.js",

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,11 @@ path-exists@^5.0.0:
206206
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7"
207207
integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==
208208

209+
prettier@^2.7.1:
210+
version "2.7.1"
211+
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64"
212+
integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==
213+
209214
readjson@^2.2.0, readjson@^2.2.2:
210215
version "2.2.2"
211216
resolved "https://registry.yarnpkg.com/readjson/-/readjson-2.2.2.tgz#ed940ebdd72b88b383e02db7117402f980158959"

0 commit comments

Comments
 (0)