Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Ogre + Sdl: Rarezas En El Bucle Principal

Iniciado por LC0, 23 de Mayo de 2006, 06:28:32 PM

« anterior - próximo »

LC0

 Hola a todos,

Pregunto esto en el foro de Ogre, pero se ve que no ha tenido mucho exito la pregunta :D, asi que a ver si alguien que se haya manejado con el motor podr�a echarme una manita, ya que es un problema ciertamente extragno y desconcertante:

Estoy trabajando en el framework del juego que estoy haciendo. Es una estrategia que he seguido en otros desarrollos que he hecho y que me resulta muy comoda (imagino que mas gente lo hara asi):


int main(int argc, char** argv)
{
   cMain main("titulo del juego");
   main.runApp();

   return 0;
}


cMain es la clase principal de la aplicacion; se encargara de iniciar el motor, SDL, y atesorar el tan preciado Ogre::Root. Al mismo tiempo, es el manejador de los multiples subsistemas de los que esta formado el juego (subsistema de menus iniciales, subsistema "ingame", etc.).

Lo primero a desarrollar es el sistema "ingame", y renderizar, renderiza. Pero solo si se llaman a las rutinas de render desde el constructor, una vez iniciados el resto de elementos que lo conforman. Y este es el problema: Obviamente, tengo que implementar un bucle principal de verdad (main.runApp()) , y este metodo parece que no se llama nunca.

Analizando un poco el comportamiento del engendro, primero pongo el constructor de la clase cMain:

cMain::cMain(const char* gt)
{
   //..Rutinas de inicio que no vienen al caso...

  //Try to create the game system setting one scene
  cPointer<cGameSystem> game_sys = new cGameSystem();
  game_sys->setScene("attempt");
  game_sys->setCurrent(); //Indicar al objeto main que este es el sistema actual a ejecutar
}


No pongo nada de setScene porque, depurando, parece que el problema no est� ah�.
setCurrent viene a ser:

void cGameSystem::setCurrent()
{
   root->getAutoCreatedWindow()->removeAllViewports(); //Solo se usa un viewport
   root->getAutoCreatedWindow()->addViewport(cam.getRaw(), 0);  //getRaw, simplemente, devuelve un Ogre::Camera*, ya que estoy usando smart pointers "caseros")
}


Y el main loop maldito, que nunca se ejecuta:

//Contenido de runApp()
bool q = false;
while(!q)
{
  //Esto es solo d prueba. La actualizaci�n de la l�gica del juego va a ir en un hilo SDL aparte.
  SDL_Event evt;
  while(SDL_PollEvent(&evt))
  {
     switch(evt.type)
     {
                    //...
     }
  }

  if(!root->_fireFrameStarted())
     break;
  root->_updateAllRenderTargets();
  if(!root->_fireFrameEnded())
     break;
}


Mirando el fichero Ogre.log que se genera tras cada ejecucion, este no indica nada erroneo. La aplicacion, sencillamente, inicializa las rutinas de video, se pone en pantalla completa, e inmediatamente se sale.

Muchisimas gracias de antemano y perdon por el tostonazo que he soltado :).

Shaitan

 Bueno, por lo poco que entiendo de Ogre, creo que te pasa una cosa bastante sencilla. Has tratado de 'eliminar' el bucle de Ogre para creat el tuyo propio y capturar eventos de SDL...
Por que no utilizas los métodos de la clase FrameListemer parra esto?
El main Loop que tienes solo deberia llamar al Root->startRendering() (bucle de render de Ogre), y luego crearías una clase que herede de FrameListener y creas una función FrameStarted() o FrameEnded() para hacer algo (por ejemplo, comprobar los eventos de SDL).

Otra forma sería crearte tu propio bucle y llamar a _fireFrameStarted() etc. como has hecho, pero te tienes que asegurar que esto se llama alguna vez (como lo has puesto, solo se llamaría una vez, esta fuiera del while de SDL). Yo uso esto en una aplicacion que tengo conogre y QT ya que QT me manda sus eventos de pintar (los capturo y hago el fireFrame.... etc.)

De todas formas, creo que es mejor hacer las cosas como las hacen los de Ogre (primera forma)

No se si te habrá servido de algo...

J.
<º))))><.·´¯`·.Shaitan´¯`·.¸.·´¯`·._.·

LC0

 Hola,

Citar
Por que no utilizas los métodos de la clase FrameListemer parra esto?

Bueno, en parte se podria decir que si que uso los framelisteners. De hecho, los subsistemas son clases derivadas de estos. El hecho de usar SDL para manejar la entrada es para posibilitar el uso de otras entradas, aparte del teclado y del ratón, como gamepads, joysticks y eso. Ellos hasta lo recomiendan en el wiki:

Citar
Although OGRE does already provide an input management system, it isn't meant to be complete and is only there for convenience. For example, it doesn't provide joystick support, which is quite an important feature for any arcade game. Success has been reported in the forums with the following input libraries :

    * SDL: MS Windows, Linux, BeOS, Solaris, IRIX, FreeBSD, MacOS; Free under the GNU LGPL. From the web page: " Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer." Look at this page to learn how to use SDL with OGRE.

   ...

Citar
El main Loop que tienes solo deberia llamar al Root->startRendering()

Me advirtieron en el IRC de Ogre que no usara ni de cogna el startRendering :D. La verdad es que antes de lo que he puesto, lo intentaba hacer asi, y resulto bastante problematico :D.

Citar

Otra forma sería crearte tu propio bucle y llamar a _fireFrameStarted() etc. como has hecho, pero te tienes que asegurar que esto se llama alguna vez (como lo has puesto, solo se llamaría una vez, esta fuiera del while de SDL). Yo uso esto en una aplicacion que tengo conogre y QT ya que QT me manda sus eventos de pintar (los capturo y hago

Es posible eso, pero ten en cuenta que el problema es que ni siquiera el bucle de captura de eventos de SDL se llama. La cosa parece estar en la mera llamada a runApp(), y es lo que me extraña. Aparte, trasteando y trasteando, acabe encontrando un tutorial en el wiki sobre las rutinas de inicialización de Ogre y de renderizado sin usar la famosa clase ExampleApplication. Es igualito a como lo estoy tratando de hacer (salvo por el hecho de que se usa el WinAPI, en vez de SDL:

Citar
     while (1)
     {
           MSG msg;
           while (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
           {
                 TranslateMessage(&msg);
                 DispatchMessage(&msg);
           }

           if (!root->_fireFrameStarted())
                 break;

           root->_updateAllRenderTargets();

           if (!root->_fireFrameEnded())
                 break;

           //....

Muchas gracias por tu ayuda :).

Shaitan

 Bueno, ya veo que no te ha servido de mucho, de todas formas, unos comentarios:
- Te entra en la función? Prueba a poner puntos de interrupción al principio. Puede que sea que SDL se 'queda' el control y no llegas al 'update' de ogre
- Haz pruebas sin los fireFrameStarted y asi... A ver si resulta que los ifs de estas funciones te devuelven siempre false!!
(o las tienes sobrecargadas y no devuelves bien el valor)

Bueno, son algunas ideas... Si lo llamas de esa forma, en princio deberia estar continuamente en el bucle, pero puede que alcance un 'break' en la primera pasada y el programa se cierre correctamente (pero sin pintar mas que un frame o ni eso)

J.
<º))))><.·´¯`·.Shaitan´¯`·.¸.·´¯`·._.·

LC0

  (nooo)

Creo que será mejor que corramos un (es)t(ú|u)pido velo.

Es curioso como los mayores problemas son originados por auténticas tonterias.
El caso es que, para probar el sistema, creé un objeto cGameSystem temporal, pensando que ya lo había declarado como miembro de la clase cMain. Evidentemente, era un objeto local que se destruía al final del constructor, y claro, el bucle de renderizado no podía hacer nada con un viewport inexistente.

Muchas gracias por tu ayuda, Shaitan.
En cuanto a mí, creo que me merezco encerrarme en El Cuarto Oscuro durante una temporadita, para reflexionar sobre mis estupideces  :lol:  

Shaitan

 jajaja, no te preocupes, a todos nos pasan cosas de estas... Cuantas veces habré estado 'atascado' por un punto y coma o por una variable no inicializada... Y el que no que tire la primera piedra!!!

:D
Suerte con Ogre!

J.
<º))))><.·´¯`·.Shaitan´¯`·.¸.·´¯`·._.·






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.