首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >提前更新场景,同时仍然呈现前一个框架

提前更新场景,同时仍然呈现前一个框架
EN

Stack Overflow用户
提问于 2012-07-12 23:47:02
回答 1查看 216关注 0票数 0

我目前正在工作的多线程安全渲染系统,我想知道你的想法,如何正确更新游戏世界的下一个步骤,而前一个场景正在渲染。目前,我正在使用Java的LWJGL Opengl绑定。下面是我的游戏循环的伪代码,因为它是当前设置的(这可能只是大多数人熟悉的基本循环):

代码语言:javascript
复制
//DrawingLayers are wrappers for in game entities and has an update 
//and render method

game-loop:
    addInputEventsToInputStack()

    removeCompletedDrawingLayers()

    foreach layer in DrawingLayerQueue :
        layer.update(deltaTime) //update position/color/size for entity
        layer.render() //performs OpenGL calls
        if(layer.isCompleted):
            addToCompletedDrawingLayersList()


    swapBuffers() //blocks until scene is fully rendered
goto game-loop

我的问题在于swapBuffers()方法会阻塞,直到场景被呈现,这意味着我不能在此过程中执行任何更新。我对如何绕过这件事的想法是:

拥有用于更新实体状态的所有DrawingLayers的副本,并将另一个副本作为呈现线程的引用。当一个框架正在呈现时,在swapBuffers()之前启动一个线程来更新未使用的副本。

我对这种方法很谨慎,因为我相信在每个帧之前创建副本会比我想要的更多地减缓系统的速度。

我的方法有意义吗?如果没有,你们对如何做到这一点有什么建议吗?我愿意进行一次彻底的重组。

更新:基于datenwolf的建议,将我的游戏内容更改为:

代码语言:javascript
复制
//DrawingLayers are wrappers for in game entities and has an update 
//and render method


//A future for the pre-processing task
Future preProcess = null

game-loop:

    //Update: checks if we have a preprocessed update to wait for
    //and waits for it to complete
    if(preProcess != null):
        preProcess.get()
        preProcess = null

    addInputEventsToInputStack()

    removeCompletedDrawingLayers()

    foreach layer in DrawingLayerQueue :
        layer.render() //performs OpenGL calls
        if(layer.isCompleted):
            addToCompletedDrawingLayersList()

    //UPDATE: the following just calls all the update methods for the layers
    // in a new thread
    preProcess = executorService.submit(new UpdateRunnable())

    swapBuffers() //blocks until scene is fully rendered
goto game-loop

到目前为止,我的表现有了很大的提高。可能有一些比赛条件的问题,我看不出来,但总的来说,我对这种改善感到满意。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-13 00:10:02

在swapBuffers()方法中,因为它会阻塞,直到呈现场景。

只有完成呈现,缓冲区交换的阻塞才是部分的。它通常也会因为等待回溯而阻塞。但是OpenGL向您保证,在任何绘图命令返回之后,可以安全地修改它访问的缓冲区,而不会损害任何挂起的呈现操作。实现需要对所有数据进行副本或复制-写入映射。

或者简单地说:修改缓冲区中的数据即可。一旦绘图调用(glDrawArrays、glDrawElements)返回,那么这样做是安全的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11462321

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档