【问题标题】:Reset WebGL viewport with canvas resize使用画布调整大小重置 WebGL 视口
【发布时间】:2014-10-16 03:00:04
【问题描述】:

在我的 WebGL 程序中,我正在根据某个事件更改画布的高度和宽度,并且我尝试在每次事件发生时使用 gl.viewport(0,0,canvas.width, canvas.height) 命令更新我的视口.

但是我的视口没有更新(或者看起来像这样),并且我绘制的对象离开了场景。我尝试添加一些偏移来放大/缩小我的视口,但即使视口增加,它也会在侧面放置一个黑屏,并且对象会移到屏幕后面。

任何人都可以建议我应该怎么做才能根据画布高度和宽度的变化来改变我的视口并显示所有的对象吗?我没有使用任何库。我在这里查看了有关此问题的其他一些帖子,但仍然无法找到解决方案。

谢谢, 阿德南

【问题讨论】:

  • 你是否也在更新你的投影矩阵?
  • 嗨,我没有使用投影矩阵。有必要吗?但是,每当对象位置发生变化时,我也会通过调用它来更新视口。

标签: webgl viewport


【解决方案1】:

您应该通过更改 canvas.style.widthcanvas.style.height 中的 style 大小来更改 WebGL 画布大小,等待 CSS 再次布局您的画布,然后更改画布 content canvas.widthcanvas.height 中的大小。最后,您应该重置您的 GL 投影矩阵和视口以使用 gl.drawingBufferWidthgl.drawingBufferHeight。这样,您的应用程序在布局调整大小的画布时处理 CSS 所做的任何事情,以及在分配绘图缓冲区以适应画布内容时所做的任何事情。例如:

<html>
<head>
    <title>Resize WebGL</title>
    <meta name="viewport" content="width=device-width, user-scalable=no">
</head>
<body>

<input type="button" id="resizeButton" value="resize"><br>
<canvas id="chart" style="width:100px; height:100px; border:1px solid #000;">
    <script>
        var canvas = document.getElementById('chart');
        var gl = null;

        function resetGL() {
            var devicePixelRatio = window.devicePixelRatio || 1;
            var w = Math.floor(canvas.clientWidth * devicePixelRatio);
            var h = Math.floor(canvas.clientHeight * devicePixelRatio);
            if (canvas.width != w || canvas.height != h) {
                console.log("resetGL: Setting canvas.width=" + w + " canvas.height=" + h);

                canvas.width = w;
                canvas.height = h;
            }
            if (!gl || gl.isContextLost()) {
                gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
                console.log("Allocated WebGL context: " + gl);
            }
        }

        function redraw() {
            requestAnimationFrame(function () {
                resetGL();
                gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
                gl.clearColor(1, 0.8, 1, 1);
                gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
                // Draw your stuff here
            });
        }

        var bToggle = false;
        function resize() {
            bToggle = !bToggle;
            var s = bToggle ? '50px' : '100px';
            console.log("");
            console.log("Button: Setting canvas.style.width=" + s + " canvas.style.height=" + s);
            canvas.style.width = s;
            canvas.style.height = s;
            redraw();
        }
        var button = document.getElementById('resizeButton');
        button.addEventListener("click", resize);
        redraw();
    </script>
</canvas>
</body>
</html>

PS:在 iOS 中,您可能需要强制 devicePixelRatio 为 1 以避免 iOS Safari 中出现明显的错误。详情请见here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-24
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    • 2013-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多