2012-01-06 31 views
0

我的一些问题在我的opengl游戏中实现子弹物理。问题是它不想不断更新我的translatef值,但只是在最后。 对子弹的代码如下所示:子弹物理与OpenGL

void CGL::initPhysics(void) { 
broadphase = new btDbvtBroadphase(); 
collisionConfiguration = new btDefaultCollisionConfiguration(); 
dispatcher = new btCollisionDispatcher(collisionConfiguration); 
solver = new btSequentialImpulseConstraintSolver; 
dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration); 

dynamicsWorld->setGravity(btVector3(0,-10,0)); 


ballShape = new btSphereShape(1); 
pinShape = new btCylinderShape(btVector3(1,1,1)); 
pinShape->setMargin(0.04); 

fallMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,10,0))); 
btScalar mass = 1; 
btVector3 fallInertia(0,0,0); 
ballShape->calculateLocalInertia(mass,fallInertia); 

btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),1); 

btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,-1,0))); 
btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0,groundMotionState,groundShape,btVector3(0,0,0)); 
btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI); 
dynamicsWorld->addRigidBody(groundRigidBody); 

btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass,fallMotionState,ballShape,fallInertia); 
btRigidBody* fallRigidBody = new btRigidBody(fallRigidBodyCI); 
dynamicsWorld->addRigidBody(fallRigidBody); 

for (int i=0 ; i<300 ; i++) { 
    dynamicsWorld->stepSimulation(1/60.f,10); 

    btTransform trans; 
    fallRigidBody->getMotionState()->getWorldTransform(trans); 

    fallY = trans.getOrigin().getY(); 
} 
state_list.remove(STATE_FALL_BALL); 
printf("stoped\n"); 

}

和被称为开头的绘图功能如下:

void CGL::fallingBall(void) { 
glPushMatrix(); 

float colBall2[4] = { 0.0f, 0.0f, 1.0f, 1.0f }; 
glMaterialfv(GL_FRONT, GL_AMBIENT, colBall2); 

glTranslatef(0.0f,fallY,0.0f); 

printf("fallY: %f\n",fallY); 

glutSolidSphere(1.0f,20,20); 

glPopMatrix(); 

}

的东西是它在这个函数的printf中显示正确的值,但翻译只在开始时被调用,我的意思是我只能看到最后一个状态。

EDIT

此被改变功能和循环。收集所有信息,我现在应该可以工作,但它不会。它没有画任何东西。

initPhysics(){ 
    for (int i=0 ; i<500 ; i++) 
    { 
     draw(); 

    } 
    state_list.remove(STATE_FALL_BALL); 
    printf("stoped\n"); 
} 

void CGL::draw(void) 
{ 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
      current_time = getTime(); 
      since_update = current_time - last_update; 
      printf("time: %f\n",since_update); 
      if(since_update>timestep) 
      { 
       dynamicsWorld->stepSimulation(timestep,10); 
       last_update = current_time; 
      } 
      btTransform trans; 
      fallRigidBody->getMotionState()->getWorldTransform(trans); 

      fallY = trans.getOrigin().getY(); 
      fallingBall(); 
      printf("fallY: %f\n",fallY); 
glFlush(); 
    } 

,并开始变declaratins看起来像:

last_update = 0; 
timestep = 100; 
current_time = 0; 
since_update = 0; 
+1

这与opengl无关,它与for循环有关。你运行循环300次,但你永远不会告诉它重画子弹? – deanWombourne 2012-01-06 12:28:46

+0

@deanWombourne fallingBall()函数一直在运行,所以它至少应该画出300个相邻的球。但事实并非如此。 – sebap123 2012-01-06 12:59:59

+0

它在同一个线程上“一直在运行”吗?如果你没有在后台线程上进行计算,那么它会等到循环完成之后才有机会运行。 – deanWombourne 2012-01-06 13:01:44

回答

1

,看起来有点混乱。我想基本的错误,而不深入研究多线程来解决眼前的问题是做这样的事情:

//pseudo-code to get the idea 
void draw(){ 
    // clear Buffers and setup matricies 
    .... 
    //calculate the time that has pased since the last time that the physics have been calculated 
    time_t current_time = getCurrentTime(); 
    time_t since_update = current_time - last_update; 

    //if enough time has passed since the last redraw calculate physics 
    if(since_update>timestep) 
    { 
     dynamicsWorld->stepSimulation(timestep,10); 
     last_update = current_time; 
    } 
    btTransform trans; 
    fallRigidBody->getMotionState()->getWorldTransform(trans); 

    fallY = trans.getOrigin().getY(); 

    //draw various object 
    .... 
    fallingBall(); 
    //swap buffers or flush() 
    glSwapBuffers(); 
} 

除非有明显的理由使用OpenGL直接我建议你使用一个更高级别的工具包。也是目前使用旧版OpenGL的常用免责声明。

+0

该项目是在OpenGL中开发的,所以我必须使用它。它看起来很好,但我有一个问题 - 这个drwa函数是在这个for循环中使用还是实现? – sebap123 2012-01-06 12:28:38

+0

是的,除非你使用一个单独的线程来计算物理,否则你应该检查每一帧(在你的循环中),如果你应该提前物理和提前他们,如果足够的时间过去了。 – PeterT 2012-01-06 12:30:34

+0

@ sebap123我认为你有什么根本的误解,什么是循环,以及如何使用它们?你在哪里使用'glClear(...)'和'glFlush()'或'glSwapBuffers()',并且在你尝试集成物理之前你是否调用过它们? – PeterT 2012-01-06 13:37:05