2017-06-26 40 views
0

我創建了一個紋理和一個渲染緩衝區,將現有的3d場景渲染爲紋理,並將該紋理用作另一個webgl程序的輸入。動態更新渲染目標的寬度和高度

下面是處理渲染場景到紋理的類的僞代碼。

什麼是根據需要更新紋理寬度和高度的最佳方式(例如,如果瀏覽器調整大小)?我是否需要每次都創建一個新的紋理/渲染緩衝區?

我想知道是否可以用比我目前做的代碼少的代碼來做到這一點?

class Renderer { 
    constructor() { 
     // creates the texture and framebuffer for the first time 
     this.updateRTT(128, 128); 
    } 

    updateRTT(width, height) { 
     const gl = getContext(); 

     this.rttwidth = width; 
     this.rttheight = height; 
     console.log('update RTT', this.rttwidth, this.rttheight); 

     this.frameBuffer = gl.createFramebuffer(); 
     gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer); 

     this.texture = gl.createTexture(); 
     gl.bindTexture(gl.TEXTURE_2D, this.texture); 
     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 
     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 
     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 
     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 
     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.rttwidth, this.rttheight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 

     this.renderBuffer = gl.createRenderbuffer(); 
     gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderBuffer); 
     gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.rttwidth, this.rttheight); 
     gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0); 
     gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.renderBuffer); 

     gl.bindTexture(gl.TEXTURE_2D, null); 
     gl.bindRenderbuffer(gl.RENDERBUFFER, null); 
     gl.bindFramebuffer(gl.FRAMEBUFFER, null); 
    } 

    render_to_target(width, height) { 
     // is there a better way to just update the texture/framebuffer? 
     if (this.rttwidth !== width || this.rttheight !== height) { 
      // if the width or height is different from the previous one, update the texture and framebuffer 
      this.updateRTT(width, height); 
     } 

     gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer); 

     // draw my scene here 


     gl.activeTexture(gl.TEXTURE0); 
     gl.bindTexture(gl.TEXTURE_2D, this.texture); 
     gl.generateMipmap(gl.TEXTURE_2D); 

     // clear 
     gl.bindTexture(gl.TEXTURE_2D, null); 
     gl.bindRenderbuffer(gl.RENDERBUFFER, null); 
     gl.bindFramebuffer(gl.FRAMEBUFFER, null); 
    } 
} 

回答

2

它足以重置紋理/渲染屬性,像這樣:

resize(width, height) { 
    // resize color attachment 
    gl.bindTexture(gl.TEXTURE_2D, this.texture); 
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 
    gl.bindTexture(gl.TEXTURE_2D, null); 

    // resize depth attachment 
    gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderBuffer); 
    gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height); 
    gl.bindRenderbuffer(gl.RENDERBUFFER, null); 

    // update internal dimensions 
    this.rttwidth=width; 
    this.rttheight=height; 
}