Foros - Stratos

Programadores => Programación gráfica => Mensaje iniciado por: davidgf en 23 de Agosto de 2008, 04:56:24 PM

Título: Cal3D y la STL
Publicado por: davidgf en 23 de Agosto de 2008, 04:56:24 PM
Hola de nuevo chicos,

La duda que os expongo es muy básica, pero es que me ha dejado pasmado.
Estaba revisando la implementación de Cal3D para optimizar el render de mis personajes, concretamente las funciones getVertices, getFaces, etc. A éstas les paso un puntero con un espacio de memoria suficiente para que ellas me copien los vertices, los indices, coords de textura, etc...
Pero al ver como estan implementadas me surge una duda.

...
std::vector<CalVector>& vectorVertex = m_pSelectedSubmesh->getVectorVertex();

    // get the number of vertices in the submesh
    int vertexCount;
    vertexCount = m_pSelectedSubmesh->getVertexCount();
    // copy the internal vertex data to the provided vertex buffer
   if(stride == sizeof(CalVector) || stride <= 0)
   {
      memcpy(pVertexBuffer, &vectorVertex[0], vertexCount * sizeof(CalVector));
   }
...


Como véis internamente tiene un vector de CalVector. CalVector es una clase. Y lo unico que hace es un memcpy del vector al buffer que le paso yo (pVertexBuffer). Eso está bien hecho? Entiendo como bien hecho que sea 100% legal, no que funciona y ya está. Yo tenía entendido que un vector internamente podía estar implementado como le dé la gana y que no tenía por qué estar toda la información agrupada. Además CalVector es una clase. Sólo contiene float x,y,x pero si hubiera algun campo más esto dejaría de funcionar no?? Además el gcc podría añadir espacio adicional a una clase (yo que se, que ocupara mucho más que 3 simples floats).

Estos de Cal3D son mu listos!!!

Gracias!

David
Título: Re: Cal3D y la STL
Publicado por: davur en 23 de Agosto de 2008, 06:33:30 PM
std::vector<> es el único container de la librería estándar que garantiza almacenamiento contiguo en memoria (lo cual es necesario para ofrecer compatibilidad con APIs de C).

El código que citas funciona en este caso porque CalVector es un tipo POD (Plain Old Data). Lo cual no quiere decir que sea una muestra de buen estilo, y de hecho no lo es (no es la manera idiomática de copiar un vector en C++). Y ni tan siquiera puede justificarse desde el punto de vista del rendimiento, porque un compilador moderno utilizará memcpy siempre que sea posible (e incluso puede ser peor, porque en el caso de std::copy el compilador puede decidir hacerla inline).
Título: Re: Cal3D y la STL
Publicado por: davidgf en 23 de Agosto de 2008, 06:43:58 PM
Si?? Realmente lo garantiza? No lo había leído en ningún lado.
Y el tema de la clase? Si la clase CalVector tiene 3 miembros float puedo garantizar que ocupará lo mismo en todos los pc?? Hay alguna directiva para decirle al GCC o al compilador que sea que lo alinee de una manera o de otra. En principio si son floats no me debería preocupar no??

Gracias!!

Saludos
Título: Re: Cal3D y la STL
Publicado por: davur en 23 de Agosto de 2008, 06:53:50 PM
No puedes garantizar que ocupará lo mismo en cualquier arquitectura. El compilador es libre de insertar el padding que considere oportuno después de una variable miembro. Y sí, los compiladores definen extensiones específicas (no estándares) para personalizar las reglas de alineamiento (ésta (http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html) en GCC).

Y, de cara a la copia del vector, esto no te debería preocupar.
Título: Re: Cal3D y la STL
Publicado por: davidgf en 23 de Agosto de 2008, 09:03:39 PM
Uff, me dejas más tranquilo, entonces lo intentaré.

Lo que quería yo era no tener que hacer un memcpy de los bufferes internos de cal3d, asi me ahorro un buen tiempo.

Muchas gracias!

David