PageSourceSearch

https://henrikrydgard.com/static/webgl/electricflower/electricflower_files/framebuffers.js

js henrikrydgard.com collected 2026-10-02 05:53:03 UTC 9,065 bytes, 264 lines download raw bytes

1/*
2 * Copyright 2009, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 *     * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *     * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 *     * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32
33/**
34 * @fileoverview This file contains objects to manage
35 *               framebuffers.
36 */
37
38tdl.provide('tdl.framebuffers');
39
40tdl.require('tdl.textures');
41
42/**
43 * A module for textures.
44 * @namespace
45 */
46tdl.framebuffers = tdl.framebuffers || {};
47
48tdl.framebuffers.createFramebuffer = function(width, height, opt_depth) {
49  return new tdl.framebuffers.Framebuffer(width, height, opt_depth);
50};
51
52tdl.framebuffers.createCubeFramebuffer = function(size, opt_depth) {
53  return new tdl.framebuffers.CubeFramebuffer(size, opt_depth);
54};
55
56tdl.framebuffers.BackBuffer = function(canvas) {
57  this.depth = true;
58  this.buffer = null;
59};
60
61tdl.framebuffers.BackBuffer.prototype.bind = function() {
62    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
63    gl.viewport(0, 0, this.width, this.height);
64};
65
66if (Object.prototype.__defineSetter__) {
67tdl.framebuffers.BackBuffer.prototype.__defineGetter__(
68    'width',
69    function () {
70      return gl.drawingBufferWidth || gl.canvas.width;
71    }
72);
73
74tdl.framebuffers.BackBuffer.prototype.__defineGetter__(
75    'height',
76    function () {
77      return gl.drawingBufferHeight || gl.canvas.height;
78    }
79);
80}
81
82// Use this where you need to pass in a framebuffer, but you really
83// mean the backbuffer, so that binding it works as expected.
84tdl.framebuffers.getBackBuffer = function(canvas) {
85  return new tdl.framebuffers.BackBuffer(canvas)
86};
87
88tdl.framebuffers.Framebuffer = function(width, height, opt_depth) {
89  this.width = width;
90  this.height = height;
91  this.depth = opt_depth;
92  this.recoverFromLostContext();
93};
94
95tdl.framebuffers.Framebuffer.prototype.bind = function() {
96  gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
97  gl.viewport(0, 0, this.width, this.height);
98};
99
100tdl.framebuffers.Framebuffer.unbind = function() {
101  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
102  gl.viewport(
103      0, 0,
104      gl.drawingBufferWidth || gl.canvas.width,
105      gl.drawingBufferHeight || gl.canvas.height);
106};
107
108tdl.framebuffers.Framebuffer.prototype.unbind = function() {
109  tdl.framebuffers.Framebuffer.unbind();
110};
111
112tdl.framebuffers.Framebuffer.prototype.recoverFromLostContext = function() {
113  var tex = new tdl.textures.SolidTexture([0,0,0,0]);
114  this.initializeTexture(tex);
115  var db = null;
116  if (this.depth) {
117    db = gl.createRenderbuffer();
118    gl.bindRenderbuffer(gl.RENDERBUFFER, db);
119    gl.renderbufferStorage(
120        gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.width, this.height);
121    gl.bindRenderbuffer(gl.RENDERBUFFER, null);
122  }
123
124  var fb = gl.createFramebuffer();
125  gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
126  gl.framebufferTexture2D(
127      gl.FRAMEBUFFER,
128      gl.COLOR_ATTACHMENT0,
129      gl.TEXTURE_2D,
130      tex.texture,
131      0);
132  if (this.depth) {
133    gl.framebufferRenderbuffer(
134        gl.FRAMEBUFFER,
135        gl.DEPTH_ATTACHMENT,
136        gl.RENDERBUFFER,
137        db);
138  }
139  var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
140  if (status != gl.FRAMEBUFFER_COMPLETE && !gl.isContextLost()) {
141    throw("gl.checkFramebufferStatus() returned " +
142          tdl.webgl.glEnumToString(status));
143  }
144  this.framebuffer = fb;
145  this.texture = tex;
146  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
147};
148
149tdl.framebuffers.Framebuffer.prototype.initializeTexture = function(tex) {
150  gl.bindTexture(gl.TEXTURE_2D, tex.texture);
151  tex.setParameter(gl.TEXTURE_MIN_FILTER, gl.LINEAR);
152  tex.setParameter(gl.TEXTURE_MAG_FILTER, gl.LINEAR);
153  tex.setParameter(gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
154  tex.setParameter(gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
155  gl.texImage2D(gl.TEXTURE_2D,
156                0,                 // level
157                gl.RGBA,           // internalFormat
158                this.width,        // width
159                this.height,       // height
160                0,                 // border
161                gl.RGBA,           // format
162                gl.UNSIGNED_BYTE,  // type
163                null);             // data
164};
165
166tdl.framebuffers.CubeFramebuffer = function(size, opt_depth) {
167  this.size = size;
168  this.depth = opt_depth;
169  this.recoverFromLostContext();
170};
171
172tdl.framebuffers.CubeFramebuffer.prototype.bind = function(face) {
173  gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffers[face]);
174  gl.viewport(0, 0, this.size, this.size);
175};
176
177tdl.framebuffers.CubeFramebuffer.unbind = function() {
178  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
179  gl.viewport(
180      0, 0,
181      gl.drawingBufferWidth || gl.canvas.width,
182      gl.drawingBufferHeight || gl.canvas.height);
183};
184
185tdl.framebuffers.CubeFramebuffer.prototype.unbind = function() {
186  tdl.framebuffers.CubeFramebuffer.unbind();
187};
188
189tdl.framebuffers.CubeFramebuffer.prototype.recoverFromLostContext = function() {
190  var tex = new tdl.textures.CubeMap(this.size);
191  gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex.texture);
192  tex.setParameter(gl.TEXTURE_MIN_FILTER, gl.LINEAR);
193  tex.setParameter(gl.TEXTURE_MAG_FILTER, gl.LINEAR);
194  tex.setParameter(gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
195  tex.setParameter(gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
196  for (var ff = 0; ff < 6; ++ff) {
197    gl.texImage2D(tdl.textures.CubeMap.faceTargets[ff],
198                  0,                 // level
199                  gl.RGBA,           // internalFormat
200                  this.size,         // width
201                  this.size,         // height
202                  0,                 // border
203                  gl.RGBA,           // format
204                  gl.UNSIGNED_BYTE,  // type
205                  null);             // data
206  }
207  if (this.depth) {
208    var db = gl.createRenderbuffer();
209    gl.bindRenderbuffer(gl.RENDERBUFFER, db);
210    gl.renderbufferStorage(
211        gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.size, this.size);
212  }
213  this.framebuffers = [];
214  for (var ff = 0; ff < 6; ++ff) {
215    var fb = gl.createFramebuffer();
216    gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
217    gl.framebufferTexture2D(
218        gl.FRAMEBUFFER,
219        gl.COLOR_ATTACHMENT0,
220        tdl.textures.CubeMap.faceTargets[ff],
221        tex.texture,
222        0);
223    if (this.depth) {
224      gl.framebufferRenderbuffer(
225          gl.FRAMEBUFFER,
226          gl.DEPTH_ATTACHMENT,
227          gl.RENDERBUFFER,
228          db);
229    }
230    var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
231    if (status != gl.FRAMEBUFFER_COMPLETE) {
232      throw("gl.checkFramebufferStatus() returned " + WebGLDebugUtils.glEnumToString(status));
233    }
234    this.framebuffers.push(fb);
235  }
236  gl.bindRenderbuffer(gl.RENDERBUFFER, null);
237  this.texture = tex;
238};
239
240tdl.framebuffers.Float32Framebuffer = function(width, height, opt_depth) {
241  if (!gl.getExtension("OES_texture_float")) {
242    throw("Requires OES_texture_float extension");
243  }
244  tdl.framebuffers.Framebuffer.call(this, width, height, opt_depth);
245};
246
247tdl.base.inherit(tdl.framebuffers.Float32Framebuffer, tdl.framebuffers.Framebuffer);
248
249tdl.framebuffers.Float32Framebuffer.prototype.initializeTexture = function(tex) {
250  gl.bindTexture(gl.TEXTURE_2D, tex.texture);
251  tex.setParameter(gl.TEXTURE_MIN_FILTER, gl.NEAREST);
252  tex.setParameter(gl.TEXTURE_MAG_FILTER, gl.NEAREST);
253  tex.setParameter(gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
254  tex.setParameter(gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
255  gl.texImage2D(gl.TEXTURE_2D,
256                0,                 // level
257                gl.RGBA,           // internalFormat
258                this.width,        // width
259                this.height,       // height
260                0,                 // border
261                gl.RGBA,           // format
262                gl.FLOAT,          // type
263                null);             // data
264};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.