jma*_*erx 21 c c++ algorithm rendering
我正在制作一个个人学习项目来制作一个Minecraft克隆.除了一件事,它的工作非常好.类似于我的世界,我的地形有很多立方体堆叠在Y上,所以你可以挖掘.虽然我做了截头剔除,但这仍然意味着我无用地在我下面画出所有层的立方体.立方体是X,Y和Z有序的(虽然只在1个方向,所以从技术上讲,它不是Z订购到相机).我基本上从玩家的位置只添加指向玩家周围的立方体的指针.然后,我对这些进行了截击.我不做oct树细分.我想只是没有渲染玩家下面的图层,除非玩家向下看到一个洞时这不起作用.鉴于此,我怎么能避免在我下面渲染我看不到的立方体,或者还有其他立方体隐藏的立方体.
谢谢
void CCubeGame::SetPlayerPosition()
{
PlayerPosition.x = Camera.x / 3;
PlayerPosition.y = ((Camera.y - 2.9) / 3) - 1;
PlayerPosition.z = Camera.z / 3;
}
void CCubeGame::SetCollids()
{
SetPlayerPosition();
int xamount = 70;
int zamount = 70;
int yamount = 17;
int xamountd = xamount * 2;
int zamountd = zamount * 2;
int yamountd = yamount * 2;
PlayerPosition.x -= xamount;
PlayerPosition.y -= yamount;
PlayerPosition.z -= zamount;
collids.clear();
CBox* tmp;
for(int i = 0; i < xamountd; ++i)
{
for(int j = yamountd; j > 0; --j)
{
for(int k = zamountd; k > 0; --k)
{
tmp = GetCube(PlayerPosition.x + i, PlayerPosition.y + j, PlayerPosition.z + k);
if(tmp != 0)
{
if(frustum.sphereInFrustum(tmp->center,25) != NULL)
{
collids.push_back(tmp);
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Ben*_*son 16
这是我在编写自己的克隆时学到的:
我注意到的其他事情:
VBO和显示列表具有非常相似的性能.给定的OpenGL实现很可能在内部使用VBO来存储显示列表.我跳过了顶点数组(一种客户端VBO)所以我不确定那些.使用ARO扩展版本的VBO而不是GL 1.5标准,因为英特尔驱动程序仅实现扩展(尽管声称支持1.5)并且nvidia和ATI驱动程序不关心.
纹理地图集规则.如果您在每张脸上使用一个纹理,请查看地图集的工作原理.
如果你想看我的代码,请在github上找到我.
ybu*_*ill 13
从前到后渲染.为此,您不需要排序,使用八叉树.叶子不是单独的立方体,而是更大的群体.
每个这样的叶子的网格应该缓存在显示列表中(如Bobmitch建议的那样),或者在顶点缓冲区中更好(更新更便宜).生成此网格时,不要以强力方式生成所有立方体.相反,对于每个立方体面,检查它是否在同一个叶子中有一个不透明的邻居,如果是这样,你根本不需要生成这个面.您还可以将具有相同材质的相邻面统一到一个长矩形中.您还可以将网格分成六组,每个主方向一组:+/- XYZ面.仅绘制可能面向相机的那些面部组.
从前到后渲染本身并没有帮助.但是,您可以使用现代硬件提供的遮挡剔除来受益于此排序.在渲染八叉树叶之前,检查其bbox是否通过了遮挡查询.如果它没有通过你根本不需要绘制它.
遮挡查询的替代方法可以是光线跟踪.光线跟踪有利于渲染这样的环境.您可以投射一组稀疏的光线来近似可见的叶子并仅绘制那些叶子.但是,这会低估可见性集.
像其他人一样,我一直在玩一个使用Ogre的块世界"引擎",并在我去的时候写一些文章(参见Block World Articles).我一直在采取的基本方法是:
只需使用这些就可以在大型简单块世界中获得非常好的性能(例如,在合适的硬件上使用1024x1024x1024).