Questions tagged «scene-graph»

一种将场景的元素排列成逻辑表示形式的数据结构

1
滚动我自己的场景图
您好游戏开发SE! 我正在通过OpenGL爬行,希望创建一个简单且非常轻便的游戏引擎。我认为该项目是一种学习经验,最终可能会赚点钱,但无论哪种方式都会很有趣。 到目前为止,我已经使用GLFW获得了一些基本的I / O,一个窗口(带有一个非常漂亮的F11全屏键)以及一个OpenGL上下文。我还使用GLEW公开了其余的OpenGL扩展,因为我正在使用Windows,并且我想使用所有OpenGL 3.0+。 这使我进入了场景图。简而言之,我想自己动手。这个决定是在看完OSG并阅读了几篇有关场景图的概念如何扭曲,弯曲和折断之后做出的。一篇这样的文章描述了场景图如何发展为... 然后,我们添加了所有这些额外的东西,例如将装饰品挂在圣诞树上,除了一些装饰品是多汁的牛排,还有一些是整头活牛。 打个比方,我想要牛排,场景图应该是什么样的肉,而不必捆成一堆多余的代码或任何整头母牛。 因此,考虑到这一点,我发现自己确实想知道场景图应该是什么以及应该如何实现简单的场景图?到目前为止,这就是我所拥有的... 一棵父树,n子树或DAG,其中... 应该跟踪游戏对象的转换(位置,旋转,比例) 应该保留渲染状态以进行优化 应该提供剔除视锥范围内的对象的方法 具有以下属性... 所有节点都应视为可渲染的(即使它们不渲染),这意味着它们... 应该都具有cull(),state()和draw()方法(如果不可见,则返回0) cull()递归地在所有子节点上调用cull(),从而为整个节点和所有子节点生成一个完整的cull网格。另一种方法hasChanged()可以使所谓的静态网格物体不必在每帧中都计算出其剔除几何形状。这将起作用,如果子树中的任何节点发生了更改,则所有几何结构都将重建到根。 渲染状态将保存在一个简单的枚举中,每个节点将从该枚举中选择所需的OpenGL状态集,并且将在该节点上调用draw()之前设置该状态。这样可以进行批处理,将将给定状态集的所有节点一起呈现,然后设置下一个状态集,依此类推。 任何节点都不应直接保存几何/着色器/纹理数据,而应指向共享对象(可能由诸如资源管理器之类的单例对象管理)。 场景图应该能够引用其他场景图(也许使用代理节点),以允许像的情况下此,因此允许复杂的多网眼模型/对象周围的场景图被复制而不增加一吨的数据。 我希望获得有关当前设计的一些有价值的反馈。是否缺少功能?有没有更好的方法/设计模式?我是否错过了一些更简单的3D游戏必须包含在此设计中的更大概念?等等。 谢谢,-Cody
23 opengl  3d  scene-graph 

7
如何避免游戏对象在C ++中意外删除自身
假设我的游戏中有一个怪物,可以让神风敢死队在玩家身上爆炸。让我们随机选择一个怪物的名字:爬行者。因此,Creeper该类具有一个类似于以下内容的方法: void Creeper::kamikaze() { EventSystem::postEvent(ENTITY_DEATH, this); Explosion* e = new Explosion; e->setLocation(this->location()); this->world->addEntity(e); } 这些事件未排队,将立即分派。这会导致该Creeper对象在调用的内部某处被删除postEvent。像这样: void World::handleEvent(int type, void* context) { if(type == ENTITY_DEATH){ Entity* ent = dynamic_cast<Entity*>(context); removeEntity(ent); delete ent; } } 由于Creeper对象在kamikaze方法仍在运行时会被删除,因此在尝试访问时它将崩溃this->location()。 一种解决方案是将事件排队到缓冲区中,然后再分派它们。这是C ++游戏中的常见解决方案吗?感觉有点像破解,但这可能只是因为我在具有不同内存管理实践的其他语言上的经验。 在C ++中,对于对象从其方法之一内部意外删除自身的问题,是否有更好的一般解决方案?
20 c++  scene-graph 

1
单独线程中的场景图
我开发自己的游戏引擎是为了娱乐(但不是赢利)。我在一个线程中渲染,而我的场景图在另一个线程中更新(速度等)。当需要渲染时,渲染线程将可见节点添加到新的线性缓冲区中并遍历它们。 更详细地讲,我的场景图是三重缓冲的。我的场景图中的每个节点都有其相对和绝对转换矩阵(4x4)的三个副本。在任何给定时间,场景图线程都将写入一个副本,渲染器将读取一个副本,而第三个副本则存在,以便读取器或写入器可以继续移动到下一个,而无需等待另一个。这样可以防止在渲染时写东西,也不会渲染半更新的场景图。不知何故,我还获得了每个矩阵的第四份副本供用户使用,以免与更新线程冲突。通过避免始终保持同步,这似乎表现良好。 但是,这是一团糟。 这些是系统的最终目标: 渲染和场景图更新位于单独的线程中。 最小化这些线程必须等待的时间。 不要渲染已被更新线程中途更新的场景。如果相机快速移动并且有时是在更新之前或之后渲染的,则这一点尤其明显。 减少内存使用。我每个节点的矩阵太多。由于矩阵的浮点漂移增加,因此我也正在考虑移至矢量进行位置/旋转/缩放。 能够处理数万个节点。当前的系统可以做到这一点。 我也希望将来能结合Bullet(物理引擎)和网络,但我都没有考虑太多。 完成更好的场景图有哪些方法?

2
自上次git commit以来,如何以视觉方式查看对场景所做的更改
在将它们提交给git之前,我想查看在场景(.unity文件)中所做的更改。 我研究了几种GIT / Unity解决方案,但所有这些解决方案都是为了合并更改,而不是为了与上一版本显示差异。 场景文件的问题在于它们使用指向其他资产的GUID,而当我打开一个场景文件的差异时,我无法真正使用它进​​行任何处理。 例如: 相反,我想看到这样的东西: 有什么可以做到的吗?

1
如何在自制渲染系统中缓存资源
背景: 我正在为使用C ++和OpenGL的实体组件系统类型体系结构设计一个简单的3D渲染系统。该系统由一个渲染器和一个场景图组成。完成渲染器的第一次迭代后,我可能会将场景图分发到ECS架构中。目前,它是一种占位符。如果可能,以下是我对渲染器的目标: 简单性。这是一个研究项目,我希望能够轻松更改和扩展我的系统(因此采用ECS方法)。 表现。我的场景可能有很多小型模型,也有很多具有很多几何图形的体积。从OGL上下文中获取对象并在每个渲染帧中缓冲几何体是不可接受的。我的目标是数据本地化,以避免缓存未命中。 灵活性强。它必须能够渲染精灵,模型和体积(体素)。 解耦。编写渲染器后,场景图可以重构为核心ECS体系结构。 模块化。能够在不更改场景图的情况下交换不同的渲染器将是很好的。 参照透明性,表示在任何时间点我都可以给它任何有效的场景,并且它将始终为该场景渲染相同的图像。特别地,该目标不是必需的。我认为这将有助于简化场景序列化(我将需要能够保存和加载场景),并为我提供了在运行时出于测试/实验目的而在不同场景中交换的灵活性。 问题与思路: 我想出了一些不同的方法来尝试,但是我正在努力为每个渲染节点缓存OGL资源(VAO,VBO,着色器等)。以下是到目前为止我已经想到的不同的缓存概念: 集中式缓存。每个场景节点都有一个ID,渲染器具有将ID映射到渲染节点的缓存。每个渲染节点包含与几何图形关联的VAO和VBO。高速缓存未命中获取资源并将几何图形映射到高速缓存中的渲染节点。更改几何形状后,将设置脏标志。如果渲染器在遍历场景节点时看到肮脏的几何标志,则它将使用渲染节点重新缓冲数据。移除场景节点后,会广播事件,并且渲染器会在释放资源的同时从缓存中删除关联的渲染节点。或者,将节点标记为要删除,而渲染器负责将其删除。我认为这种方法最接近目标6,同时也考虑了4和5。2遭受了额外的复杂性和丢失了使用地图查找而不是数组访问的数据局部性的麻烦。 分布式缓存。除了每个场景节点都有一个渲染节点外,其他与上面类似。这会绕过地图查找。为了解决数据局部性,可以将渲染节点存储在渲染器中。然后场景节点可以改为具有指向渲染节点的指针,并且渲染器将指针设置在高速缓存未命中。我认为这种模仿实体组件方法,因此与架构的其余部分保持一致。这里的问题是,现在场景节点保存渲染器实现特定的数据。如果更改了事物在渲染器中的渲染方式(如渲染精灵与体积),则现在需要更改渲染节点或向场景节点添加更多“组件”(这也意味着更改场景图)。从好的方面来说,这似乎是启动并运行我的第一迭代渲染器的最简单方法。 分布式元数据。渲染器缓存元数据组件存储在每个场景节点中。此数据不是特定于实现的,而是包含ID,类型以及缓存所需的任何其他相关数据。然后,可以使用ID直接在数组中完成缓存查找,并且该类型可以指示要使用的呈现方法的类型(如精灵与体积)。 访客+分布式映射。渲染器是一个访客,场景节点是访客模式中的元素。每个场景节点都拥有一个只有渲染器才能操作的缓存键(就像元数据一样,只是一个ID)。该ID可以用于数组,而不是广义的地图查找。渲染器可以允许场景节点根据场景节点的类型调度不同的渲染功能,并且ID可以由任何缓存使用。默认或超出范围的ID将指示高速缓存未命中。 您将如何解决这个问题?或您有什么建议吗?感谢您阅读我的文字墙!

1
引擎渲染管道:使着色器通用
我正在尝试使用OpenGL ES 2.0(目前为iOS)制作2D游戏引擎。我已经在Objective C中编写了Application层,并在C ++中编写了一个独立的RendererGLES20。在渲染器外部不会进行GL特定的调用。运行良好。 但是在使用着色器时,我有一些设计问题。每个着色器都有自己的唯一属性和统一体,需要在主绘制调用之前进行设置(在本例中为glDrawArrays)。例如,为了绘制一些几何图形,我要做: void RendererGLES20::render(Model * model) { // Set a bunch of uniforms glUniformMatrix4fv(.......); // Enable specific attributes, can be many glEnableVertexAttribArray(......); // Set a bunch of vertex attribute pointers: glVertexAttribPointer(positionSlot, 2, GL_FLOAT, GL_FALSE, stride, m->pCoords); // Now actually Draw the geometry glDrawArrays(GL_TRIANGLES, 0, m->vertexCount); // …

1
要场景图还是不场景图?
我一直在努力决定是否在游戏中实现场景图。我有一些使用这种工具的用例,但我无法获得一些实现细节。 背景知识:我正在写针对移动平台(主要是Android)的太空射击游戏,我的代码几乎完全是C ++。我没有使用任何中间件;渲染引擎和物理引擎特别是我自己的作品。我的物理引擎会根据力和脉冲来更新对象的位置。到目前为止,我还没有动画系统,但是可能会在某些时候访问它(可能与本次讨论无关)。 首先,我将描述一个很好的用例。我想拥有一个由几个独立的零件组成的老板,每个零件都可以独立损坏/破坏。例如,我可能有一个老板的胳膊可以独立于其他老板实体而受到伤害。当手臂被销毁时,位于凸台肩部的火焰微粒效应可能表明手臂已被销毁。 实际上,我决定尝试在物理引擎中解决具有约束的此类问题,以将此类复合对象保持在一起。一个这样的约束条件提供了0个自由度,并且本质上是一个变换矩阵。这实际上是在试图解决一个最终使我脱离场景图的问题的尝试,如下所述。 我不使用场景图的主要原因是因为我找不到在物理世界和渲染场景中都保留嵌套对象(从其父级继承了转换的对象)的有效方法。物理世界需要对象位于世界空间(或至少相同的空间)中,而渲染场景需要对象位于父空间中。跟踪两个空间中的位置可能会有所帮助(并且是不可避免的),但会引起自身的担忧,其中至少与性能有关。 但是,考虑到上述用例,我认为能够在父空间中“工作”将变得非常重要,而试图通过约束来迫使我的物理引擎保持这些关系将变得成问题。 给定上述用例和困境,我是否应该使用图结构将转换从一个对象传递到另一个对象?如果是这样,我的物理引擎应该如何计算新位置并针对不同空间中的对象执行相交测试?

2
延迟渲染引擎的场景图
作为学习练习,我编写了一个延迟渲染引擎。现在,我想向该引擎添加一个场景图,但是我有点困惑如何做到这一点。 在普通的(前向渲染引擎)上,我只将所有项目(全部实现IDrawable和IUpdateAble)添加到场景图中,而不是先遍历场景图宽度并在任何地方调用Draw()。 但是,在延迟渲染引擎中,我必须分开进行绘图调用。首先,我必须先绘制几何图形,然后绘制阴影投射器,然后绘制灯光(所有灯光都绘制到不同的渲染目标),然后再将它们组合在一起。因此,在这种情况下,我不能只遍历场景图并仅调用draw。我的观察方式要么是我要遍历整个场景图3次,检查必须绘制哪种对象,要么必须创建3个以某种方式相互连接的独立场景图。这两个似乎都是较差的解决方案,我想使场景对象更透明。 我想到的另一种解决方案是像往常一样通过场景图,然后将项目添加到3个单独的列表中,分离几何图形,阴影投射器和灯光,然后迭代这些列表以绘制正确的内容,这更好吗?明智的每帧重新填充3个列表?
10 xna  c#  scene-graph 

2
游戏场景图中应包含什么?
请您帮我弄清楚游戏场景图应包含什么内容?请参阅以下列表: 游戏演员?(显然是的,所有更改状态的对象都应该是“场景图”的主要部分) 简单的静态游戏对象?(我的意思是,背景中没有动画的地方也不会发生碰撞) 游戏触发器? 游戏灯? 游戏摄影机? 武器子弹? 游戏爆炸和特效? 上面考虑的对象类型。现在来看场景图: 自关卡开始以来,场景图应该包含整个游戏关卡地图,还是仅包含地图的可见部分?如果第二个为真,则意味着随着玩家的移动,场景图将通过添加/删除游戏对象而不断更新。但是,仅包含地图的可见区域显然会更快地遍历和更新。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.