Skip to content

Commit

Permalink
Add support for float textures + an example
Browse files Browse the repository at this point in the history
  • Loading branch information
davepagurek committed Jul 10, 2022
1 parent 347c052 commit 53b92e7
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 17 deletions.
9 changes: 9 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"useTabs": false,
"tabWidth": 2,
"semi": false,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 80,
"arrowParens": "always"
}
12 changes: 12 additions & 0 deletions examples/feedback/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html><html lang="en"><head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>
<script src="../../p5.Framebuffer.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8">

</head>
<body>
<script src="sketch.js"></script>


</body></html>
61 changes: 61 additions & 0 deletions examples/feedback/sketch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
let fboPrev, fboNext
let canvas

function setup() {
canvas = createCanvas(400, 400, WEBGL)
// There's a bug in Firefox where you can only make floating point textures
// if they're RGBA, and it breaks if it's just RGB
setAttributes({ alpha: true })

// Try changing `float` to `unsigned_byte` to see it leave a trail
options = { colorFormat: 'float' }
fboPrev = createFramebuffer(options)
fboNext = createFramebuffer(options)
imageMode(CENTER)
rectMode(CENTER)
noStroke()
}

function draw() {
// Swap prev and next so that we can use the previous frame as a texture
// when drawing the current frame
[fboPrev, fboNext] = [fboNext, fboPrev]

// Draw to the Framebuffer
fboNext.draw(() => {
clear()

background(255)

// Disable depth testing so that the image of the previous
// frame doesn't cut off the sube
_renderer.GL.disable(_renderer.GL.DEPTH_TEST)
push()
scale(1.003)
texture(fboPrev.color)
plane(width, -height)
pop()

push()
// Fade to white slowly. This will leave a permanent trail if you don't
// use floating point textures.
fill(255, 1)
rect(0, 0, width, height)
pop()
_renderer.GL.enable(_renderer.GL.DEPTH_TEST)

push()
normalMaterial()
translate(100*sin(frameCount * 0.014), 100*sin(frameCount * 0.02), 0)
rotateX(frameCount * 0.01)
rotateY(frameCount * 0.01)
box(50)
pop()
})

clear()
push()
texture(fboNext.color)
plane(width, -height)
pop()
}
7 changes: 7 additions & 0 deletions examples/feedback/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
html, body {
margin: 0;
padding: 0;
}
canvas {
display: block;
}
58 changes: 43 additions & 15 deletions p5.Framebuffer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const _createFramebuffer = function() {
const fb = new Framebuffer(this)
const _createFramebuffer = function (options) {
const fb = new Framebuffer(this, options)

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

const parentGetTexture = p5.RendererGL.prototype.getTexture
p5.RendererGL.prototype.getTexture = function(imgOrTexture) {
p5.RendererGL.prototype.getTexture = function (imgOrTexture) {
if (imgOrTexture instanceof p5.Texture) {
return imgOrTexture
} else {
Expand All @@ -31,12 +31,7 @@ p5.RendererGL.prototype.getTexture = function(imgOrTexture) {
// that looks like a p5 texture but that never tries to update
// data in order to use framebuffer textures inside p5.
class RawTextureWrapper extends p5.Texture {
constructor(
renderer,
obj,
w,
h,
) {
constructor(renderer, obj, w, h) {
super(renderer, obj)
this.width = w
this.height = h
Expand Down Expand Up @@ -64,15 +59,33 @@ class RawTextureWrapper extends p5.Texture {
}

class Framebuffer {
constructor(canvas) {
constructor(canvas, options = {}) {
this._renderer = canvas._renderer

const gl = this._renderer.GL
const ext = gl.getExtension('WEBGL_depth_texture')
if (!ext) {
if (!gl.getExtension('WEBGL_depth_texture')) {
throw new Error('Unable to create depth textures in this environment')
}

this.colorFormat = this.glColorFormat(options.colorFormat)
this.depthFormat = this.glDepthFormat(options.depthFormat)
if (
(options.colorFormat === 'float' || options.depthFormat === 'float') &&
(!gl.getExtension('OES_texture_float') ||
!gl.getExtension('OES_texture_float_linear') ||
!gl.getExtension('WEBGL_color_buffer_float'))
) {
// Reset to default
if (options.colorFormat === 'float') {
this.colorFormat = this.glColorFormat()
}
if (options.depthFormat === 'float') {
this.depthFormat = this.glDepthFormat()
}
console.warn(
'Warning: Unable to create floating point textures in this environment. Falling back to integers',
)
}

const framebuffer = gl.createFramebuffer()
if (!framebuffer) {
throw new Error('Unable to create a framebuffer')
Expand All @@ -81,6 +94,21 @@ class Framebuffer {
this.recreateTextures()
}

glColorFormat(format) {
const gl = this._renderer.GL
if (format === 'float') {
return gl.FLOAT
}
return gl.UNSIGNED_BYTE
}
glDepthFormat(format) {
const gl = this._renderer.GL
if (format === 'float') {
return gl.FLOAT
}
return gl.UNSIGNED_SHORT
}

handleResize() {
const oldColor = this.colorTexture
const oldDepth = this.depthTexture
Expand Down Expand Up @@ -117,7 +145,7 @@ class Framebuffer {
height * density,
0,
hasAlpha ? gl.RGBA : gl.RGB,
gl.UNSIGNED_BYTE,
this.colorFormat,
null,
)

Expand All @@ -140,7 +168,7 @@ class Framebuffer {
height * density,
0,
gl.DEPTH_COMPONENT,
gl.UNSIGNED_SHORT,
this.depthFormat,
null,
)

Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@davepagurek/p5.framebuffer",
"version": "0.0.2",
"version": "0.0.3",
"main": "p5.Framebuffer.js",
"author": "Dave Pagurek <[email protected]>",
"license": "MIT",
Expand All @@ -14,7 +14,8 @@
"homepage": "https://github.com/davepagurek/p5.Framebuffer",
"dependencies": {},
"devDependencies": {
"minify": "^9.0.0"
"minify": "^9.0.0",
"prettier": "^2.7.1"
},
"scripts": {
"build:core": "minify p5.Framebuffer.js > p5.Framebuffer.core.min.js",
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,11 @@ path-exists@^5.0.0:
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7"
integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==

prettier@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64"
integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==

readjson@^2.2.0, readjson@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/readjson/-/readjson-2.2.2.tgz#ed940ebdd72b88b383e02db7117402f980158959"
Expand Down

0 comments on commit 53b92e7

Please sign in to comment.