Javascript 调整画布和webGL纹理的大小
我想调整我的窗口大小,让画布和其中的所有东西随着窗口的扩展/收缩而拉伸填充 这有点棘手,因为在我的webgl代码中,我在帧缓冲区和片段着色器的菊花链之间创建了一个反馈循环。在一个顶点着色器中发生了一个小的变换以保持反馈循环。如果我在resize事件中调用以下命令,它会进行我不希望的额外转换,并使反馈循环失去控制。但是,它会拉伸纹理以适合窗口Javascript 调整画布和webGL纹理的大小,javascript,canvas,resize,webgl,feedback-loop,Javascript,Canvas,Resize,Webgl,Feedback Loop,我想调整我的窗口大小,让画布和其中的所有东西随着窗口的扩展/收缩而拉伸填充 这有点棘手,因为在我的webgl代码中,我在帧缓冲区和片段着色器的菊花链之间创建了一个反馈循环。在一个顶点着色器中发生了一个小的变换以保持反馈循环。如果我在resize事件中调用以下命令,它会进行我不希望的额外转换,并使反馈循环失去控制。但是,它会拉伸纹理以适合窗口 gl.viewport(0,0,canvas.clientWidth, canvas.clientHeight); 我还尝试过使用事件侦听器调整画布的大小
gl.viewport(0,0,canvas.clientWidth, canvas.clientHeight);
我还尝试过使用事件侦听器调整画布的大小,但纹理不会随之调整大小。相反,它们只是锁在我窗口的左下角。检查canvas元素表明画布确实改变了大小,但纹理没有改变
window.addEventListener( 'resize', resizeCanvas );
function resizeCanvas(){
var width = canvas.clientWidth;
var height = canvas.clientHeight;
if(canvas.width != width ||
canvas.height != height){
canvas.width = width;
canvas.height = height;
//gl.viewport(0,0,width, height);
}
}
我想这样做,而不必重新分配我的fbo。出于某种原因,我以为我可以拉伸画布和其中的一切,但我似乎无法让它工作
转到包含完整webgl代码的页面。为了简单起见,这篇文章没有任何反馈循环,但是如果有帮助的话,我可以发布一篇。提前感谢您的帮助 我不确定我是否理解这个问题,但浏览一下您的代码,如果您的帧缓冲区附件(在本例中为纹理)的大小与画布的大小不同,则每次更改当前帧缓冲区时,都需要调用
gl.viewport
换句话说,在伪代码中
function(render) {
resizeCanvas();
gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebuffer);
gl.viewport(0, 0, widthOfSomeFramebuffer, heightOfSomeFramebuffer);
drawStuffToFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, someOtherFramebuffer);
gl.viewport(0, 0, widthOfSomeOtherFramebuffer, heightOtherOfSomeFramebuffer);
drawStuffToOtherFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
drawStuffToCanvas();
requestAnimationFrame(render);
}
render();
在大多数情况下,在绘制到画布时,应始终将视口设置为画布的大小(width
和height
而不是clientWidth
和clientHeight
)。使用clientWidth
和clientHeight
调整投影的大小和/或计算投影的纵横比,无论投影是2d还是3d。事实上,对gl.viewport
使用clientWidth
和clientHeight
可能是错误的
您可以将gl.viewport
视为定义要绘制到的区域。将其设置为gl.viewport(0,0,gl.canvas.width,gl.canvas.height)
基本上是说您希望在整个画布上绘制
但这并不是全部事实gl.viewport
基本上设置如何将着色器中使用的空间clipspace(-1+1)转换回当前绘图曲面(画布或帧缓冲区)上的像素空间。因此,将视口设置为gl.viewport(x,y,width,height)
表示-1到+1 in x在当前图形表面上从像素x到x+w-1,而-1到+1 in y在当前图形表面上从像素y到y+height-1
由于在大多数情况下,您希望在整个绘图曲面上绘制,因此需要将gl.viewport
设置为要绘制的曲面的大小
希望这能清楚地解释为什么使用clientWidth
和clientHeight
对于gl.viewport
是错误的,因为clientWidth
和clientHeight
与画布的实际大小(其中的像素)没有关系。它们只与这些像素拉伸或收缩的大小有关。换句话说
<canvas width="10" height="20" style="width: 30px; height: 40px"></canvas>
...
console.log("canvas.width : " + canvas.width);
console.log("canvas.height : " + canvas.height);
console.log("canvas.clientWidth : " + canvas.clientWidth);
console.log("canvas.clientHeight: " + canvas.clientHeight);
这意味着画布中只有10x20个实际像素,但在页面上它们被拉伸到30x40。将视口设置为gl.viewport(0,0,canvas.clientWidth,canvas.clientHeight)
表示您希望绘制到30像素宽、40像素高的区域,但实际上只有10像素宽、20像素低
就处理resize而言,如果您一直在渲染(看起来您在代码中),那么在渲染循环开始时调用resize是最简单也是最好的方法 我不确定我是否理解这个问题,但浏览一下您的代码,如果您的帧缓冲区附件(在本例中为纹理)的大小与画布的大小不同,则每次更改当前帧缓冲区时,都需要调用
gl.viewport
换句话说,在伪代码中
function(render) {
resizeCanvas();
gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebuffer);
gl.viewport(0, 0, widthOfSomeFramebuffer, heightOfSomeFramebuffer);
drawStuffToFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, someOtherFramebuffer);
gl.viewport(0, 0, widthOfSomeOtherFramebuffer, heightOtherOfSomeFramebuffer);
drawStuffToOtherFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
drawStuffToCanvas();
requestAnimationFrame(render);
}
render();
在大多数情况下,在绘制到画布时,应始终将视口设置为画布的大小(width
和height
而不是clientWidth
和clientHeight
)。使用clientWidth
和clientHeight
调整投影的大小和/或计算投影的纵横比,无论投影是2d还是3d。事实上,对gl.viewport
使用clientWidth
和clientHeight
可能是错误的
您可以将gl.viewport
视为定义要绘制到的区域。将其设置为gl.viewport(0,0,gl.canvas.width,gl.canvas.height)
基本上是说您希望在整个画布上绘制
但这并不是全部事实gl.viewport
基本上设置如何将着色器中使用的空间clipspace(-1+1)转换回当前绘图曲面(画布或帧缓冲区)上的像素空间。因此,将视口设置为gl.viewport(x,y,width,height)
表示-1到+1 in x在当前图形表面上从像素x到x+w-1,而-1到+1 in y在当前图形表面上从像素y到y+height-1
由于在大多数情况下,您希望在整个绘图曲面上绘制,因此需要将gl.viewport
设置为要绘制的曲面的大小
希望这能清楚地解释为什么使用clientWidth
和clientHeight
对于gl.viewport
是错误的,因为clientWidth
和clientHeight
与画布的实际大小(其中的像素)没有关系。它们只与这些像素拉伸或收缩的大小有关。换句话说
<canvas width="10" height="20" style="width: 30px; height: 40px"></canvas>
...
console.log("canvas.width : " + canvas.width);
console.log("canvas.height : " + canvas.height);
console.log("canvas.clientWidth : " + canvas.clientWidth);
console.log("canvas.clientHeight: " + canvas.clientHeight);
这意味着只有10x20个实际像素i