Valhalla Legends Forums Archive | C/C++ Programming | There has got to be a better way to do this

AuthorMessageTime
Eibro
[code]bool XMesh::buildAABB( AABB3& bb ) const
{
   if ( m_meshObj ) // loaded mesh?    
   {   
      DWORD vertexSize, vertexCount;
      LPDIRECT3DVERTEXBUFFER9 vertexBuffer;

      // Retrieve vertex buffer
      m_meshObj->GetVertexBuffer( &vertexBuffer );
      // retrive vertex size
      vertexSize = m_meshObj->GetNumBytesPerVertex();
      vertexCount = m_meshObj->GetNumVertices();

      void* vertexData;
      void* currentPosition;
      vertexBuffer->Lock( 0, 0, &vertexData, 0 );
      
      // loop through the vertices
      for ( DWORD i = 0; i < vertexCount; ++i )
      {
         // Calculate offset to next vertex
         __int64 address = reinterpret_cast< __int64 >( vertexData ) + vertexSize * i;
         currentPosition = reinterpret_cast< void* >( address );
         // Get a pointer to actual vertex position & add vertex to AABB
         bb.add( *reinterpret_cast< D3DXVECTOR3* >( currentPosition ) );
      }

vertexBuffer->Unlock();
      return true;
   }

   return false; // not loaded
};[/code] Pay particular attention to the lines:
[code]__int64 address = reinterpret_cast< __int64 >( vertexData ) + vertexSize * i;
currentPosition = reinterpret_cast< void* >( address );[/code] Why do I have to do it this way? The compiler barked at me when I initially had [code]currentPosition = vertexData + vertexSize * i;[/code] with the error void*, unknown size. Why would the size of void* need to be known to add vertexSize * i?
Aside from that; how could I do this without casting to __int64? As I doubt that is very portable.
February 27, 2004, 5:11 AM
Yoni
You cannot use the + operator (pointer arithmetic) on void*, since sizeof(void) is undefined. The best solution is to temporarily cast to char*, since it's always 1 byte, to do the arithmetic, and then to cast back to void* for the result.
Instead of:
[code]currentPosition = vertexData + vertexSize * i;[/code]
Use:
[code]currentPosition = static_cast<char*>(vertexData) + vertexSize * i;[/code]
That should work.
(In Windows specific code like yours, you could also replace char* with BYTE* or LPBYTE if you think it's clearer).
Note the cast back to void* is implied.
February 27, 2004, 7:01 AM
Adron
[quote author=Eibro link=board=30;threadid=5474;start=0#msg46293 date=1077858696]
Why would the size of void* need to be known to add vertexSize * i?
[/quote]

When you add an integer to a pointer, the compiler multiplies by the size of an element. So, if you add 3 to a long*, the compiler will add 12 for you. As "void" has no size, you can't add integers to a void*.
February 27, 2004, 10:59 AM
Kp
Addendum:

As a documented extension, gcc defines sizeof(void) = 1, so the original code would have worked in gcc. However, for portability's sake, it's better to do it as rewritten in this thread.
February 27, 2004, 6:55 PM
Eibro
[quote author=Adron link=board=30;threadid=5474;start=0#msg46308 date=1077879554]
[quote author=Eibro link=board=30;threadid=5474;start=0#msg46293 date=1077858696]
Why would the size of void* need to be known to add vertexSize * i?
[/quote]

When you add an integer to a pointer, the compiler multiplies by the size of an element. So, if you add 3 to a long*, the compiler will add 12 for you. As "void" has no size, you can't add integers to a void*.
[/quote]Ahh perfect. I don't know how I got this far without knowing that. I suppose it wouldn't make much sense to allow an arbitrary number to be added to a pointer. Casting to a char seems to be the cleanest way.

Thanks everyone.
February 27, 2004, 8:31 PM

Search