Files
Kepler/engine/framebuffer.js

296 lines
6.9 KiB
JavaScript
Raw Normal View History

2025-11-17 17:18:43 +01:00
class framebuffer{
constructor( ){
this.width = 1024;
this.height = 1024;
this._className = "_framebuffer";
this.glFramebuffer;
this.framebuffers = [];
this.renderbuffers = [];
this.face = false;
this.renderType = '2d';
this.samplers = []; // render to samplers
//GL_DEPTH_ATTACHMENT
this.multiSample = false;
this.msaaFramebuffer;
this.msaaColorRenderBuffer;
this.msaaDepthRenderBuffer;
this.MSAA_level = 4;
}
setViewport( viewport ){
this.viewport = viewport;
this.gl = viewport.gl;
this.target = this.gl.TEXTURE_2D;
this.type = this.gl.FLOAT;
this.attachment = this.gl.COLOR_ATTACHMENT0;
}
addSampler( sampler, face ) {
sampler.setViewport( this.viewport );
this.samplers.push( sampler );
if( face ){
this.face = face;
}
}
addCubeSampler( sampler ) {
sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_POSITIVE_X);
sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_NEGATIVE_X);
sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_POSITIVE_Y);
sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y);
sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_POSITIVE_Z);
sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z);
this.samplers.push( sampler );
}
getSampler( ) {
return this.samplers[0];
}
/**
* Create framebuffer
* @param {(int)} width
* @param {(int)} height
* @param {(object)} properties
**/
create() { //type, depth
//var WEBGL_draw_buffers = kepler.extensions.WEBGL_draw_buffers;
var attachments = [];
this.glFramebuffer = this.gl.createFramebuffer();
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.glFramebuffer);
this.renderbuffer = this.gl.createRenderbuffer();
this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, this.renderbuffer);
this.gl.renderbufferStorage(this.gl.RENDERBUFFER, this.gl.DEPTH_COMPONENT32F, this.width, this.height);
this.gl.framebufferRenderbuffer(this.gl.FRAMEBUFFER, this.gl.DEPTH_ATTACHMENT, this.gl.RENDERBUFFER, this.renderbuffer);
//}
for(var c = 0; c<this.samplers.length; c++) {
var sampler = this.samplers[c];
sampler.isFramebuffer = true;
sampler.internalFormat = this.gl.RGBA32F;
if(this.target == this.gl.TEXTURE_2D) {
sampler.setTarget( this.viewport );
var textures = sampler.getTextures();
} else {
//var textures = [ sampler.getTexture( this.face ) ];
var textures = sampler.getTextures( );
}
for(var b = 0; b<textures.length; b++) {
var textureObject = textures[b];
//var WEBGL_draw_buffers = kepler.extensions.WEBGL_draw_buffers;
if( this.samplers.length == 1 ) {
var attachment = this.attachment;
} else {
switch( c ) {
case 0:
var attachment = this.gl.COLOR_ATTACHMENT0
break;
case 1:
var attachment = this.gl.COLOR_ATTACHMENT1;
break;
case 2:
var attachment = this.gl.COLOR_ATTACHMENT2;
break;
case 3:
var attachment = this.gl.COLOR_ATTACHMENT3;
break;
}
}
attachments.push( attachment );
this.gl.bindTexture( sampler.target, textureObject.glTexture );
if( this.multiSample ) {
this.gl.texParameteri( this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
} else {
switch( sampler.filter ) {
case this.gl.NEAREST:
this.gl.texParameteri(sampler.target, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
this.gl.texParameteri(sampler.target, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
this.gl.texParameteri(sampler.target, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(sampler.target, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
break;
case this.gl.LINEAR:
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
break;
default:
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri( sampler.target, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
}
}
if( this.multiSample ) {
var levels = 1;
this.gl.texStorage2D( this.gl.TEXTURE_2D, levels, this.gl.RGBA32F, this.width, this.height);
this.gl.framebufferTexture2D( this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, textureObject.glTexture, 0);
} else {
this.gl.texImage2D( textureObject.face, 0, sampler.internalFormat, this.width, this.height, 0, sampler.format, sampler.type, null);
this.gl.framebufferTexture2D( this.gl.FRAMEBUFFER, attachment, textureObject.face, textureObject.glTexture, 0);
}
//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);
//const internalFormat = this.gl.RGBA32F;
//this.gl.framebufferTexture2D(this.gl.READ_FRAMEBUFFER, attachment, texture.face, texture.glTexture, 0);
textureObject.attachment = attachment;
//textureObject.dataType = 'framebuffer'; // weird bug when ob
textureObject.width = this.width;
textureObject.height = this.height;
textureObject.data = textureObject.glTexture;
this.gl.bindTexture(this.gl.TEXTURE_2D, null);
}
}
//}
//this.gl.framebufferRenderbuffer(this.gl.FRAMEBUFFER, this.gl.DEPTH_ATTACHMENT, this.gl.RENDERBUFFER, this.renderbuffer);
//this.gl.renderbufferStorageMultisample();
//console.log(this, textureObject);
if(this.samplers.length > 1) {
//kepler.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(attachments);
this.gl.drawBuffers(attachments);
}
if (this.gl.checkFramebufferStatus(this.gl.FRAMEBUFFER) != this.gl.FRAMEBUFFER_COMPLETE) {
alert("this combination of attachments does not work");
}
//this.gl.bindFramebuffer(this.gl.TEXTURE_2D, null);
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
//this.gl.bindFramebuffer(this.gl.RENDERBUFFER, null);
}
}
export {framebuffer as default};