Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Cal3D y la STL

Iniciado por davidgf, 23 de Agosto de 2008, 04:56:24 PM

« anterior - próximo »

davidgf

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àrraco: una aventura por la Tarragona romana (http://tarraco.davidgf.net)

davur

#1
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).

davidgf

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àrraco: una aventura por la Tarragona romana (http://tarraco.davidgf.net)

davur

#3
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 en GCC).

Y, de cara a la copia del vector, esto no te debería preocupar.

davidgf

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
Tàrraco: una aventura por la Tarragona romana (http://tarraco.davidgf.net)






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.