Box2D + Opengl ES 2.0(XCode,iPhone):高效更新身体顶点位置

问题描述:

如果您已经使用Box2d,则您已熟悉设置b2Body->userData属性,该属性将用于更新渲染后的形状x,y坐标:Box2D + Opengl ES 2.0(XCode,iPhone):高效更新身体顶点位置

// Physics update: 
    int32 velocityIterations = 6; 
    int32 positionIterations = 2; 
    world->Step(timeDelta, velocityIterations, positionIterations); 
    for (b2Body* b = world->GetBodyList(); b; b = b->GetNext()) { 
    id obj = (id)b->GetUserData(); 
    if ((obj != NULL)) { 
     Shape *s = (MyType*)obj; 
     CGPoint newCentre = CGPointMake(b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO); 
     [s drawAt:newCentre]; 
    } 
    } 

在概念上,用于该数据流的呈现过程非常简单:创建一个Shape类来表示每个体中,添加使用OpenGL ES 2.0渲染为身体所有期望的顶点(具有属性)一个drawAt方法,以及具有该类在其坐标改变时重绘。

但是,我想通过将所有物体的顶点粘贴到单个顶点缓冲区来优化渲染。因此,我打算修改类Shape以在顶点所在位置的缓冲区中包含偏移量,然后可以在drawAt上简单更新缓冲区中的这些偏移量。

我意识到这些偏移量的管理可能会对缓冲区的添加/移除造成混乱,但是在我的应用程序中这些偏移量并不频繁,我希望能够将每一滴渲染性能都挤出管道。

我的问题是:

  1. 不OpenGL ES 2.0的让我指定一组顶点作为 “形状”,然后可以用一个矩阵运算转换,或 我必须明确地以这种方式逐个更新顶点?
  2. 我必须创建一个独特的可更新对象来分配给每个 b2Body-> userData,还是有一些更有效的做法?
  3. 在自己的时间轴上更新图形对象,从关联的b2Body实例中读取位置或在上面列出的b2Body更新循环中立即更新图形对象是更好吗?

我会很感激一些建议,谢谢。

-1。如果在缓冲区为你的机构建立灯具时给了位置设定的顶点,应该应该能够做到这一点:

b2Vec2 pos = m_body->GetPosition(); 
float angle = m_body->GetAngle(); 
glPushMatrix(); 
    glTranslatef(pos.x, pos.y, 0); 
    glRotatef(angle * RADTODEG, 0, 0, 1);//OpenGL uses degrees here 
    glDrawArrays(GL_WHATEVER, startIndex, vertexCount); 
glPopMatrix(); 

进行了较深入的讨论参见http://www.iforce2d.net/b2dtut/drawing-objects

-2。通常你只想绘制可见的东西。上述方法只有在你确定应该绘制这个特定对象后才能完成。上面问题中的代码可能会不必要地更新从未绘制的对象的位置。

-3。呃......我想我只是回答了这个问题。我认为最好有一个你的游戏对象列表,每个对象都有一个指向b2Body *的指针,代表它们在物理世界中,而不是指向Box2D的主体列表。

+1

感谢您的贡献,iforce2d。我发布后不久就自己解决了这个问题,并忘记删除问题。我最终做了你在3推荐的内容,这很好;我现在在每个Shape类中存储一个b2Body引用,并更新我的形状,而不是通过b2Body-> userData进行更新。为了清楚起见:您发布的代码是ES 1.x,而不是ES 2。0这正是我正在讨论的。 (2)中提出的观点是我意识到的,但不完全确定如何处理。现在我关注的是单屏视图,后来我打算探讨是否可以限制b2d更新。 – KomodoDave

+0

这与ES 2.0不兼容。 – ManOx