动态更新渲染目标的宽度和高度 [英] Updating width and height of render target on the fly

查看:3
本文介绍了动态更新渲染目标的宽度和高度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了一个纹理和一个渲染缓冲区来将现有的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);
    }
}

推荐答案

这样重置纹理/渲染缓冲区属性就足够了:

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

这篇关于动态更新渲染目标的宽度和高度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆