我习惯使用GLUT的PostRedisplay和(App | UI)工具包的setNeedsDisplay方法来请求新的显示事件应用程序希望重绘场景时发布到事件队列。我还没有找到与HTML5的Canvas元素相对应的内容。例如,当我想重绘到画布时,我目前只是直接调用我的display()
函数:
function mouseMove(event) {
if (mouseDrag) {
// update camera position
display();
}
}
display()
函数渲染场景(可能很昂贵):
function display() {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// issue WebGL calls to redraw scene
gl.flush();
}
如果在上次渲染完成之前发生多个渲染请求,我习惯使用的大多数系统会将多个显示事件合并为一个事件。如果长display()
次调用超过渲染速度,我上面所做的事情可能会有问题。
无论如何,有效重绘画布元素的正确方法是什么?
You can see the demo app I am working on here(如果您启用了WebGL)。
更新:根据以下答案,我现在使用RequestAnimationFrame
并使用返回值作为标志来指示已经发出请求。渲染场景时,我清除了标志,因此可以进一步请求:
var requestId = 0; // id of current requestAnimationFrame request (0 = no request)
function mouseMove(event) {
if (mouseDrag) {
// update camera position
if (requestId)
requestId = requestAnimationFrame(display);
else
console.log("request already in queued"); // test
}
}
function display() {
requestId = 0;
// redraw scene
}
注意到我收到的日志消息确实合并了多个请求。这似乎是一个很好的方法。还有其他解决方案吗?
答案 0 :(得分:2)
您可以使用requestAnimationFrame(display)
设置回调(在这种情况下,display
),以便在下次重绘时调用。
在等待重新绘制时,您只能调用一次(在重新绘制时,它将执行回复您对requestAnimationFrame
进行的每次调用) 。如果您想要连续制作动画,还可以请求另一个动画帧。