Permalink
Browse files

Implemented framebufferRenderbuffer(), detach renderbuffer from frame…

…buffer upon disposal
1 parent 5ba17b2 commit 7f2f9dd8acaec76c0ae60ac6c5ef0773afd52978 @sinisterchipmunk committed Jun 25, 2011
@@ -13,6 +13,80 @@ describe("Framebuffer", function() {
});
});
+ describe("attaching a renderbuffer", function() {
+ var framebuffer, renderbuffer;
+
+ beforeEach(function() {
+ framebuffer = CONTEXT.createFramebuffer();
+ CONTEXT.bindFramebuffer(framebuffer);
+ renderbuffer = CONTEXT.createRenderbuffer();
+ CONTEXT.bindRenderbuffer(CONTEXT.RENDERBUFFER, renderbuffer);
+ CONTEXT.renderbufferStorage(CONTEXT.RENDERBUFFER, CONTEXT.RGBA4, 300, 300);
+ });
+
+ it("should generate INVALID_OPERATION while default framebuffer is bound", function() {
+ CONTEXT.bindFramebuffer(null);
+ CONTEXT.framebufferRenderbuffer(CONTEXT.FRAMEBUFFER, CONTEXT.COLOR_ATTACHMENT0, CONTEXT.RENDERBUFFER, renderbuffer);
+ expect(CONTEXT.getError()).toEqual(CONTEXT.INVALID_OPERATION);
+ });
+
+ it("should generate INVALID_OPERATION if renderbuffer is neither 0 nor a valid renderbuffer name", function() {
+ renderbuffer.dispose(); // makes it fail #isRenderbuffer()
+ CONTEXT.framebufferRenderbuffer(CONTEXT.FRAMEBUFFER, CONTEXT.COLOR_ATTACHMENT0, CONTEXT.RENDERBUFFER, renderbuffer);
+ expect(CONTEXT.getError()).toEqual(CONTEXT.INVALID_OPERATION);
+ });
+
+ it("should generate INVALID_ENUM when target != FRAMEBUFFER", function() {
+ CONTEXT.framebufferRenderbuffer(CONTEXT.TEXTURE_2D, CONTEXT.COLOR_ATTACHMENT0, CONTEXT.RENDERBUFFER, renderbuffer);
+ expect(CONTEXT.getError()).toEqual(CONTEXT.INVALID_ENUM);
+ });
+
+ it("should generate INVALID_ENUM when renderbuffertarget != RENDERBUFFER && renderbuffer != 0", function() {
+ CONTEXT.framebufferRenderbuffer(CONTEXT.FRAMEBUFFER, CONTEXT.COLOR_ATTACHMENT0, CONTEXT.GL_TEXTURE_2D, renderbuffer);
+ expect(CONTEXT.getError()).toEqual(CONTEXT.INVALID_ENUM);
+ });
+
+ it("should generate INVALID_ENUM when attachment is not acceptable", function() {
+ CONTEXT.framebufferRenderbuffer(CONTEXT.FRAMEBUFFER, CONTEXT.GL_TEXTURE_2D, CONTEXT.RENDERBUFFER, renderbuffer);
+ expect(CONTEXT.getError()).toEqual(CONTEXT.INVALID_ENUM);
+ });
+
+ describe("properly", function() {
+ describe("and then detaching it", function() {
+ beforeEach(function() {
+ CONTEXT.framebufferRenderbuffer(CONTEXT.FRAMEBUFFER, CONTEXT.COLOR_ATTACHMENT0, CONTEXT.RENDERBUFFER, renderbuffer);
+ CONTEXT.framebufferRenderbuffer(CONTEXT.FRAMEBUFFER, CONTEXT.COLOR_ATTACHMENT0, CONTEXT.RENDERBUFFER, null);
+ });
+
+ it("should reset to default values", function() {
+ expect(CONTEXT.getFramebufferAttachmentParameter(CONTEXT.FRAMEBUFFER, CONTEXT.COLOR_ATTACHMENT0, CONTEXT.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)).toEqual(CONTEXT.NONE);
+ });
+ });
+
+ var attachmentTypes = {COLOR_ATTACHMENT0:WEBGL_CONSTANTS.COLOR_ATTACHMENT0,
+ DEPTH_ATTACHMENT:WEBGL_CONSTANTS.DEPTH_ATTACHMENT,
+ STENCIL_ATTACHMENT:WEBGL_CONSTANTS.STENCIL_ATTACHMENT};
+ for (var typeName in attachmentTypes) {
+ describe("to "+typeName, function() {
+ var type = attachmentTypes[typeName];
+ beforeEach(function() {
+ CONTEXT.framebufferRenderbuffer(CONTEXT.FRAMEBUFFER, type, CONTEXT.RENDERBUFFER, renderbuffer);
+ });
+
+ it("should set name", function() {
+ var v = CONTEXT.getFramebufferAttachmentParameter(CONTEXT.FRAMEBUFFER, type, CONTEXT.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
+ expect(v).toBe(renderbuffer);
+ });
+
+ it("should set type to RENDERBUFFER", function() {
+ var v = CONTEXT.getFramebufferAttachmentParameter(CONTEXT.FRAMEBUFFER, type, CONTEXT.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
+ expect(v).toEqual(CONTEXT.RENDERBUFFER);
+ });
+ });
+ }
+ });
+ });
+
describe("querying a framebuffer", function() {
it("should not be a framebuffer until bound", function() {
var framebuffer = CONTEXT.createFramebuffer();
@@ -79,6 +153,20 @@ describe("Framebuffer", function() {
CONTEXT.getFramebufferAttachmentParameter(CONTEXT.FRAMEBUFFER, CONTEXT.COLOR_ATTACHMENT0, CONTEXT.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
expect(CONTEXT.getError()).toEqual(CONTEXT.INVALID_OPERATION);
});
+
+ it("should generate INVALID_ENUM if attached object is RENDERBUFFER and pname is not OBJECT_TYPE or OBJECT_NAME", function() {
+ var buf = CONTEXT.createRenderbuffer();
+ CONTEXT.bindRenderbuffer(CONTEXT.RENDERBUFFER, buf);
+ CONTEXT.renderbufferStorage(CONTEXT.RENDERBUFFER, CONTEXT.RGBA4, 300, 300);
+ CONTEXT.framebufferRenderbuffer(CONTEXT.FRAMEBUFFER, CONTEXT.DEPTH_ATTACHMENT, CONTEXT.RENDERBUFFER, buf);
+
+ expect(CONTEXT.getFramebufferAttachmentParameter(CONTEXT.FRAMEBUFFER, CONTEXT.DEPTH_ATTACHMENT, CONTEXT.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE)).toEqual(0);
+ expect(CONTEXT.getError()).toEqual(CONTEXT.INVALID_ENUM);
+ });
+
+ it("should generate INVALID_ENUM if attached object is TEXTURE and pname is not OBJECT_TYPE, OBJECT_NAME, TEXTURE_LEVEL, TEXTURE_CUBE_MAP_FACE", function() {
+ throw("pending texture attachment support");
+ });
});
describe("deleting a framebuffer", function() {
@@ -78,13 +78,25 @@ describe("Renderbuffer", function() {
expect(CONTEXT.getError()).toEqual(CONTEXT.NO_ERROR);
});
- it("that is attached to the currently bound framebuffer", function() {
+ describe("that is attached to the currently bound framebuffer", function() {
// if the deleted renderbuffer object is
// attached to the currently bound framebuffer object, it is
// automatically detached. However, attachments to any other framebuffer objects are the
// responsibility of the application.
- throw("pending attachment support");
+ beforeEach(function() {
+ var framebuffer = CONTEXT.createFramebuffer();
+ CONTEXT.bindFramebuffer(framebuffer);
+ CONTEXT.bindRenderbuffer(CONTEXT.RENDERBUFFER, buf);
+ CONTEXT.renderbufferStorage(CONTEXT.RENDERBUFFER, CONTEXT.RGBA4, 300, 300);
+ CONTEXT.framebufferRenderbuffer(CONTEXT.FRAMEBUFFER, CONTEXT.DEPTH_ATTACHMENT, CONTEXT.RENDERBUFFER, buf);
+ expect(CONTEXT.getError()).toEqual(CONTEXT.NO_ERROR); // sanity check
+ });
+
+ it("should be detached from framebuffer", function() {
+ CONTEXT.deleteRenderbuffer(buf);
+ expect(CONTEXT.getFramebufferAttachmentParameter(CONTEXT.FRAMEBUFFER, CONTEXT.DEPTH_ATTACHMENT, CONTEXT.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)).toEqual(CONTEXT.NONE);
+ });
});
describe("that is currently bound", function() {
@@ -91,6 +91,17 @@ var WebGLCompatibilityLayer = (function() {
return 0;
};
+ this.framebufferRenderbuffer = function(target, attachment, renderbuffertarget, renderbuffer) {
+ if (target != this.FRAMEBUFFER) generateError(this.INVALID_ENUM);
+ else if (renderbuffertarget != this.RENDERBUFFER && renderbuffer) generateError(this.INVALID_ENUM);
+ else if (state.bindings.framebuffer == defaultFramebuffer) generateError(this.INVALID_OPERATION);
+ else if (renderbuffer && !this.isRenderbuffer(renderbuffer)) generateError(this.INVALID_OPERATION);
+ else {
+ try { state.bindings.framebuffer.renderbuffer(attachment, renderbuffer); }
+ catch(e) { generateError(e); }
+ }
+ };
+
this.isFramebuffer = function(fb) {
return fb && (fb instanceof WebGLFramebuffer) && fb.isPrepared();
};
@@ -116,6 +127,8 @@ var WebGLCompatibilityLayer = (function() {
this.deleteRenderbuffer = function(buf) {
if (this.isRenderbuffer(buf)) {
buf.dispose();
+ if (state.bindings.framebuffer && state.bindings.framebuffer != defaultFramebuffer)
+ state.bindings.framebuffer.detachAll(buf);
if (buf === state.bindings.renderbuffer) state.bindings.renderbuffer = null;
}
};
@@ -1,9 +1,9 @@
var WebGLFramebuffer = function(c2d) {
this._prepared = false;
this._attachments = {};
- this._attachments[WEBGL_CONSTANTS.COLOR_ATTACHMENT0 ] = WEBGL_CONSTANTS.NONE;
- this._attachments[WEBGL_CONSTANTS.DEPTH_ATTACHMENT ] = WEBGL_CONSTANTS.NONE;
- this._attachments[WEBGL_CONSTANTS.STENCIL_ATTACHMENT] = WEBGL_CONSTANTS.NONE;
+ this._attachments[WEBGL_CONSTANTS.COLOR_ATTACHMENT0 ] = { type: WEBGL_CONSTANTS.NONE };
+ this._attachments[WEBGL_CONSTANTS.DEPTH_ATTACHMENT ] = { type: WEBGL_CONSTANTS.NONE };
+ this._attachments[WEBGL_CONSTANTS.STENCIL_ATTACHMENT] = { type: WEBGL_CONSTANTS.NONE };
};
(function() {
@@ -20,14 +20,48 @@ var WebGLFramebuffer = function(c2d) {
return this._prepared;
};
+ c.detachAll = function(buffer) {
+ if (this._attachments[WEBGL_CONSTANTS.COLOR_ATTACHMENT0].object == buffer) this.renderbuffer(WEBGL_CONSTANTS.COLOR_ATTACHMENT0, null);
+ if (this._attachments[WEBGL_CONSTANTS.DEPTH_ATTACHMENT].object == buffer) this.renderbuffer(WEBGL_CONSTANTS.DEPTH_ATTACHMENT, null);
+ if (this._attachments[WEBGL_CONSTANTS.STENCIL_ATTACHMENT].object == buffer) this.renderbuffer(WEBGL_CONSTANTS.STENCIL_ATTACHMENT, null);
+ };
+
+ c.renderbuffer = function(attachment, buffer) {
+ switch(attachment) {
+ case WEBGL_CONSTANTS.COLOR_ATTACHMENT0:
+ case WEBGL_CONSTANTS.DEPTH_ATTACHMENT:
+ case WEBGL_CONSTANTS.STENCIL_ATTACHMENT:
+ if (buffer) {
+ this._attachments[attachment].type = WEBGL_CONSTANTS.RENDERBUFFER;
+ this._attachments[attachment].object = buffer;
+ } else {
+ this._attachments[attachment].type = WEBGL_CONSTANTS.NONE;
+ this._attachments[attachment].object = null;
+ }
+ this._attachments[attachment].texture_level = 0;
+ this._attachments[attachment].cubemap_texture_face = WEBGL_CONSTANTS.TEXTURE_CUBE_MAP_POSITIVE_X;
+ break;
+ default:
+ throw WEBGL_CONSTANTS.INVALID_ENUM;
+ }
+ }
+
c.getAttachmentParameter = function(attachment, pname) {
switch(attachment) {
case WEBGL_CONSTANTS.COLOR_ATTACHMENT0:
case WEBGL_CONSTANTS.DEPTH_ATTACHMENT:
case WEBGL_CONSTANTS.STENCIL_ATTACHMENT:
- if (this._attachments[attachment] == WEBGL_CONSTANTS.NONE) {
- if (pname == WEBGL_CONSTANTS.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) return WEBGL_CONSTANTS.NONE;
- throw WEBGL_CONSTANTS.INVALID_ENUM;
+ var a = this._attachments[attachment];
+ switch(pname) {
+ case WEBGL_CONSTANTS.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ return a.type;
+ case WEBGL_CONSTANTS.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ if (a.type == WEBGL_CONSTANTS.NONE) throw WEBGL_CONSTANTS.INVALID_ENUM;
+ return a.object;
+ case WEBGL_CONSTANTS.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+ case WEBGL_CONSTANTS.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+ case WEBGL_CONSTANTS.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+ default: throw WEBGL_CONSTANTS.INVALID_ENUM;
}
break;
default:

0 comments on commit 7f2f9dd

Please sign in to comment.