2017-06-26 3 views
0

J'ai créé une texture et un rendu pour rendre une scène 3D existante à une texture et utiliser cette texture comme entrée pour un autre programme webgl. Ci-dessous le pseudo-code de la classe qui gère le rendu de la scène à une texture. Quelle est la meilleure façon de mettre à jour la largeur et la hauteur de la texture si nécessaire (si un redimensionnement du navigateur arrive par exemple)? Ai-je besoin de créer une nouvelle texture/tampon de rendu à chaque fois? Je me demande si je peux le faire avec moins de code que ce que je suis en train de faire?Mise à jour de la largeur et de la hauteur de la cible de rendu à la volée

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); 
    } 
} 

Répondre

2

Son assez pour réinitialiser la texture/renderbuffer attributs comme ceci:

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; 
}