Unaligned vertex weights in exported data

This topic contains 14 replies, has 7 voices, and was last updated by  Gordon 7 years, 8 months ago.

Viewing 15 posts - 1 through 15 (of 15 total)
  • Author
    Posts
  • #29865

    Tragnarion
    Member

    Hi,

    We’re still trying to get a model rendering on the iPhone, but glDrawElements is generating an exception.

    Looking a little deeper, I’ve noticed that the base pointer of the vertex weights (specified as GL_FLOAT) is not 4-byte aligned.  This seems to be because the previous vertex property is the matrix indices, which consists of 3 unsigned bytes.

    Is this misalignment likely to cause a problem in glDrawElements (I suspect so), and should the exporter not be aligning blocks consisting of GL_FLOATs to the next 4-byte boundary?

    Any advice appreciated!

    Thanks,
    Rich

    #33260

    Tragnarion
    Member

    Just to follow-up…. I found some documentation stating that unaligned data will work, but will probably incur a speed penalty.  The crash must be due to something else…

    But, the request still stands: would it be possible in a future version of the exporter to align blocks according to their type when generating interleaved vertices, or at least provide an option to enable this if you wish?

    #33261

    Scott
    Moderator
    Tragnarion wrote:
    But, the request still stands: would it be possible in a future version of the exporter to align blocks according to their type when generating interleaved vertices, or at least provide an option to enable this if you wish?

     

    Hi,

     

    Thanks for the suggestion. It is a little late to add to the next release of the SDK but it is something we will add to a future release.

     

    Thanks,

     

    Scott
    #33262

    I’d like to add my support for this feature request. Matrix Palette Indices have to be exported as unsigned bytes (ie. 1 byte) and they will mess up the stride to be non-aligned. Makes accessing the data outside of glDrawElements difficult too. Lots of slow memcpy’ing!

    Cheers,
    Donovan. 

    #33263

    ykang
    Member

    Hi everyone,

    I’m also experiencing a similar issue that my exported model works just fine on the iPhone simulator 3.x. However, it stops at “glDrawElements” when I tried to run it on the actual device (OS3.0).

    These are my exporting options (from Maya2009)

    Maya MB file

    Texture file

    POD file

    Can anyone please help me on this one? thanks!

    #33264

    When exporting from Maya to POD, does the PVRGeoPOD exporter have an error log of what it couldnt successful convert from Maya to POD?

    #33265

    Tragnarion
    Member

    @ykang – iPhone hardware only supports three bone influences per vertex (whilst the simulator will successfully run with 4)… so uncheck the last box in the exporter for “bone index” and “bone weight” and all should work OK.

    #33266

    Tragnarion
    Member

    @powervr – any news on whether this request will make it into a future version of the exporter any time soon?

    Thanks.

    #33267

    Gordon
    Moderator

    Aligning data will be supported in a new release of the SDK. A tthem moment a log of what the exporter ttries to export is produced and shown, I believe.

    #33268

    Tragnarion
    Member

    OK, many thanks Gordon.

    For the moment, I’m working around the problem by reallocating the ‘interleaved’ chunk at runtime, aligning the contents, and then patching up the data offset and strides of all the elements by hand – but obviously this is a pain and it’ll be great to have the elements aligned at export time 🙂

    For the benefit of anyone who finds this thread who might be suffering the same problem as I was – it seems that the iPhone implementation of OpenGL ES isn’t happy with interleaved unaligned vertex elements.  While it seems to work superficially, I was experiencing very strange and random problems regarding the lighting – some meshes were consistently rendered unlit while others were ok, and the behaviour could even be changed by rendering them in a different order.  All these problems go away when feeding glDrawElements() with a properly aligned set of interleaved data.

    #33269

    Hi Tragnerion,

    I have had the same lighting problem! Any chance you could share your alignment code in advance of Imagination’s next release?

    Would be very helpful Smile

    Cheers,
    Donovan.

    #33270

    Tragnarion
    Member

    Erm, sure, but it’s nothing particularly clever or robust!  It makes a few assumptions about the sort of models we export (e.g. no multitexturing, etc), and also assumes that the only vertex property which will be exported misaligned is the bone weight, and that this is the last property in the interleaved data.

    All I did was added the following function to PVRTModelPOD.cpp:

    static void AlignInterleavedData(SPODMesh& s)
    {
        // This is a hacked-in function to get around the problem that the exporter doesn’t align
        // its interleaved vertex data correctly.  OpenGL ES should be able to handle unaligned
        // data (albeit at a speed cost), but the iPhone implementation doesn’t.
       
        // It is assumed that the only unaligned data will be the bone weight (the only field
        // which occurs after the bone index field, which causes the problem).
       
        assert(s.sVertex.pData < s.sBoneIdx.pData);
        assert(s.sNormals.pData < s.sBoneIdx.pData);
        assert(s.sTangents.pData < s.sBoneIdx.pData);
        assert(s.sBinormals.pData < s.sBoneIdx.pData);
        assert(s.nNumUVW == 1 && s.psUVW[0].pData < s.sBoneIdx.pData);
        assert(s.sVtxColours.pData < s.sBoneIdx.pData);
        assert(s.sBoneWeight.pData > s.sBoneIdx.pData);
       
        unsigned int oldStride = s.sVertex.nStride;
        unsigned int alignedStride = (oldStride + 3) & ~3;
        unsigned int startUnaligned = reinterpret_cast<unsigned int>(s.sBoneWeight.pData);
       
        assert((oldStride & 3) != 0);
       
        SafeRealloc(s.pInterleaved, s.nNumVertex * alignedStride);
       
        for (int i = s.nNumVertex – 1; i >= 0; i–)
        {
            unsigned char* pSrc = s.pInterleaved + i * oldStride;
            unsigned char* pDest = s.pInterleaved + i * alignedStride;
           
            memmove(pDest + ((startUnaligned + 3) & ~3), pSrc + startUnaligned, oldStride – startUnaligned);
            memmove(pDest, pSrc, startUnaligned);
        }
       
        s.sVertex.nStride = alignedStride;
        s.sNormals.nStride = alignedStride;
        s.sTangents.nStride = alignedStride;
        s.sBinormals.nStride = alignedStride;
        s.psUVW[0].nStride = alignedStride;
        s.sVtxColours.nStride = alignedStride;
        s.sBoneIdx.nStride = alignedStride;
        s.sBoneWeight.nStride = alignedStride;
       
        s.sBoneWeight.pData = reinterpret_cast<unsigned char*>((startUnaligned + 3) & ~3);
    }

    and then added a call to it in ReadMesh() like so:

            case ePODFileMesh | PVRTMODELPOD_TAG_END:
                if(nUVWs != s.nNumUVW) return false;
                AlignInterleavedData(s);
                return true;

    I’m not proud of the solution by any means, but at least it works, even if it fragments the model data a bit 🙂

    #33271

    mono2k
    Member

    Same problem here, thank you very much for sharing the code. Btw, will the new version of SDK include a fix for this problem?

    #33272

    Tragnarion
    Member

    According to https://www.imgtec.com/forum/forum_posts.asp?TID=577, they have already fixed this in SDK version 2.6, but I have no idea when this will get an official release!

    #33273

    Gordon
    Moderator

    Our releases are always in late summer and spring – 2.6 should be available in the next month or so.

Viewing 15 posts - 1 through 15 (of 15 total)
You must be logged in to reply to this topic.