webgl - Must render buffer texture dimensions be power-of-two? -


does texture use webgl render buffer storage need have dimensions power-of-two?

background info

i'm chasing framebuffer_incomplete_attachment reported client on setup:

windows 7 enterprise 32-bit firefox version: 33 video card: intel q45/q43 express chipset driver version 8.13.10.2413

and far i'm @ loss why it's happening, guessing might npot textures.

here's render buffer implementation, not have power-of-two-texture yet:

scenejs._webgl.renderbuffer = function (cfg) {        /**       * true buffer allocated , ready go       * @type {boolean}       */      this.allocated = false;        this.canvas = cfg.canvas;      this.gl = cfg.canvas.gl;      this.buf = null;      this.bound = false;  };    /**   * called after webgl context restored.   */  scenejs._webgl.renderbuffer.prototype.webglrestored = function (_gl) {      this.gl = _gl;      this.buf = null;  };    /**   * binds buffer   */  scenejs._webgl.renderbuffer.prototype.bind = function () {      this._touch();      if (this.bound) {          return;      }      this.gl.bindframebuffer(this.gl.framebuffer, this.buf.framebuf);      this.bound = true;  };      scenejs._webgl.renderbuffer.prototype._touch = function () {        var width = this.canvas.canvas.width;      var height = this.canvas.canvas.height;        if (this.buf) { // have buffer          if (this.buf.width == width && this.buf.height == height) { // canvas size unchanged, buffer still              return;          } else { // buffer needs reallocation new canvas size              this.gl.deletetexture(this.buf.texture);              this.gl.deleteframebuffer(this.buf.framebuf);              this.gl.deleterenderbuffer(this.buf.renderbuf);          }      }        this.buf = {          framebuf: this.gl.createframebuffer(),          renderbuf: this.gl.createrenderbuffer(),          texture: this.gl.createtexture(),          width: width,          height: height      };        this.gl.bindframebuffer(this.gl.framebuffer, this.buf.framebuf);      this.gl.bindtexture(this.gl.texture_2d, this.buf.texture);      this.gl.texparameteri(this.gl.texture_2d, this.gl.texture_mag_filter, this.gl.nearest);      this.gl.texparameteri(this.gl.texture_2d, this.gl.texture_min_filter, this.gl.nearest);      this.gl.texparameteri(this.gl.texture_2d, this.gl.texture_wrap_s, this.gl.clamp_to_edge);      this.gl.texparameteri(this.gl.texture_2d, this.gl.texture_wrap_t, this.gl.clamp_to_edge);             try {          // way spec requires          this.gl.teximage2d(this.gl.texture_2d, 0, this.gl.rgba, width, height, 0, this.gl.rgba, this.gl.unsigned_byte, null);      } catch (exception) {          // workaround appears minefield bug.          var texturestorage = new webglunsignedbytearray(width * height * 3);          this.gl.teximage2d(this.gl.texture_2d, 0, this.gl.rgba, width, height, 0, this.gl.rgba, this.gl.unsigned_byte, texturestorage);      }        this.gl.bindrenderbuffer(this.gl.renderbuffer, this.buf.renderbuf);      this.gl.renderbufferstorage(this.gl.renderbuffer, this.gl.depth_component16, width, height);      this.gl.framebuffertexture2d(this.gl.framebuffer, this.gl.color_attachment0, this.gl.texture_2d, this.buf.texture, 0);      this.gl.framebufferrenderbuffer(this.gl.framebuffer, this.gl.depth_attachment, this.gl.renderbuffer, this.buf.renderbuf);      this.gl.bindtexture(this.gl.texture_2d, null);      this.gl.bindrenderbuffer(this.gl.renderbuffer, null);      this.gl.bindframebuffer(this.gl.framebuffer, null);      // verify framebuffer ok      this.gl.bindframebuffer(this.gl.framebuffer, this.buf.framebuf);        if (!this.gl.isframebuffer(this.buf.framebuf)) {          throw scenejs_error.fatalerror(scenejs.errors.error, "invalid framebuffer");      }        var status = this.gl.checkframebufferstatus(this.gl.framebuffer);        switch (status) {            case this.gl.framebuffer_complete:              break;            case this.gl.framebuffer_incomplete_attachment:              throw scenejs_error.fatalerror(scenejs.errors.error, "incomplete framebuffer: framebuffer_incomplete_attachment");            case this.gl.framebuffer_incomplete_missing_attachment:              throw scenejs_error.fatalerror(scenejs.errors.error, "incomplete framebuffer: framebuffer_incomplete_missing_attachment");            case this.gl.framebuffer_incomplete_dimensions:              throw scenejs_error.fatalerror(scenejs.errors.error, "incomplete framebuffer: framebuffer_incomplete_dimensions");            case this.gl.framebuffer_unsupported:              throw scenejs_error.fatalerror(scenejs.errors.error, "incomplete framebuffer: framebuffer_unsupported");            default:              throw scenejs_error.fatalerror(scenejs.errors.error, "incomplete framebuffer: " + status);      }        this.bound = false;  };    /**   * clears renderbuffer   */  scenejs._webgl.renderbuffer.prototype.clear = function () {      if (!this.bound) {          throw "render buffer not bound";      }      this.gl.clear(this.gl.color_buffer_bit | this.gl.depth_buffer_bit);      this.gl.disable(this.gl.blend);  };    /**   * reads buffer pixel @ given coordinates   */  scenejs._webgl.renderbuffer.prototype.read = function (pickx, picky) {      var x = pickx;      var y = this.canvas.canvas.height - picky;      var pix = new uint8array(4);      this.gl.readpixels(x, y, 1, 1, this.gl.rgba, this.gl.unsigned_byte, pix);      return pix;  };    /**   * unbinds renderbuffer   */  scenejs._webgl.renderbuffer.prototype.unbind = function () {      this.gl.bindframebuffer(this.gl.framebuffer, null);      this.bound = false;  };    /** returns texture   */  scenejs._webgl.renderbuffer.prototype.gettexture = function () {      var self = this;      return {          bind: function (unit) {              if (self.buf && self.buf.texture) {                  self.gl.activetexture(self.gl["texture" + unit]);                  self.gl.bindtexture(self.gl.texture_2d, self.buf.texture);                  return true;              }              return false;          },          unbind: function (unit) {              if (self.buf && self.buf.texture) {                  self.gl.activetexture(self.gl["texture" + unit]);                  self.gl.bindtexture(self.gl.texture_2d, null);              }          }      };  };    /** destroys buffer   */  scenejs._webgl.renderbuffer.prototype.destroy = function () {      if (this.buf) {          this.gl.deletetexture(this.buf.texture);          this.gl.deleteframebuffer(this.buf.framebuf);          this.gl.deleterenderbuffer(this.buf.renderbuf);          this.buf = null;          this.bound = false;      }  };

as far find (i don't use webgl), webgl spec delegates opengl es 2.0 spec on these fbo related calls. rgba 8 bits per component not format supported render target in es 2.0. many devices support (advertised oes_rgb8_rgba8 extension), not part of standard.

the texture using color_attachment0 rgba 8-bit components:

this.gl.teximage2d(this.gl.texture_2d, 0, this.gl.rgba, width, height, 0,                    this.gl.rgba, this.gl.unsigned_byte, texturestorage); 

try specifying rgb565, color renderable:

this.gl.teximage2d(this.gl.texture_2d, 0, this.gl.rgba, width, height, 0,                    this.gl.rgb, this.gl.unsigned_short_5_6_5, texturestorage); 

if need alpha component in texture, rgba4444 or rgb5_a1 portable options:

this.gl.teximage2d(this.gl.texture_2d, 0, this.gl.rgba, width, height, 0,                    this.gl.rgba, this.gl.unsigned_short_4_4_4_4, texturestorage); this.gl.teximage2d(this.gl.texture_2d, 0, this.gl.rgba, width, height, 0,                    this.gl.rgba, this.gl.unsigned_short_5_5_5_1, texturestorage); 

the spec looks contradictory me. under "differences between webgl , opengl es 2.0", says:

the following combinations of framebuffer object attachments, when of attachments framebuffer attachment complete, non-zero, , have same width , height, must result in framebuffer being framebuffer complete:
color_attachment0 = rgba/unsigned_byte texture

which @ first sight suggests rgba/unsigned_byte supported. that's under condition "when of attachments framebuffer attachment complete", , according es 2.0 spec, attachments format not attachment complete. , there no override in webgl spec on "attachment complete" means.


Comments

Popular posts from this blog

c++ - QTextObjectInterface with Qml TextEdit (QQuickTextEdit) -

javascript - angular ng-required radio button not toggling required off in firefox 33, OK in chrome -

xcode - Swift Playground - Files are not readable -