Imagination PowerVR SDK Blog

Multiple POD Material loading


#1

Hi Folks,



Im having some issues loading multiple models and associated materials. I have a Model class that after instantiation loads up a .pod and associated materials.



I can load up 1 .pod exported from blender with multiple Materials fine and all separate materials render correctly.



However when i load up a second .pod the SDK fails to load the texture’s. Im pretty confused here, im pretty sure i dont need to use a separate Texture unit but my reading has set me slightly confused. SO my question is … Why does the second model fail to load the textures?



Here is the function i use , ignore my debug singleton…



bool D2R3DModel::LoadTextures(CPVRTString* const pErrorStr)

{

m_puiTextures = new GLuint[m_Scene.nNumMaterial];



for(unsigned int i = 0; i < m_Scene.nNumMaterial; ++i)

{

SPODMaterial* pMaterial = &m_Scene.pMaterial;

g_DebugManagerInstance.Log(" loading material: %s",pMaterial->pszName);



std::string extension = std::string(".pvr");



std::string pvrFile = pMaterial->pszName + extension;



if(PVRTTextureLoadFromPVR(pvrFile.c_str(), &m_puiTextures) != PVR_SUCCESS)

{

g_DebugManagerInstance.Log(" ERR: %s",pMaterial->pszName);



*pErrorStr = “ERROR: Failed to load texture.”;

return false;

}

}



return true;

}



This is using OpenGLES 1.1 and im using version 3.1 of the SDK.


#2

i propose



m_puiTextures = new GLuint[m_Scene[j].nNumMaterial];

and

SPODMaterial* pMaterial = &&m_Scene[j].pMaterial;

because you said that you are using two pods


#3

for 2 pods…


for(GLuint j = 0 ; j < 2 ; ++j)<br />
{<br />
m_puiTextures[j] = new GLuint[m_Scene[j].nNumMaterial];<br />
<br />
if(!m_puiTextures[j])<br />
{<br />
*pErrorStr = "ERROR: Insufficient memory.";<br />
return false;<br />
}<br />
<br />
for(int i = 0; i < (int) m_Scene[j].nNumMaterial; ++i)<br />
{<br />
m_puiTextures[j]<i> = 0;<br />
SPODMaterial* pMaterial = &m_Scene[j].pMaterial<i>;
```<br />
</code></pre><br />
<br />
where :<br />
CPVRTModelPOD	m_Scene[2];<br />
GLuint* m_puiTextures[2];<br />
etc etc</i></i>

#4

Hi Dgu,



Sorry maybe i wasn’t being detailed enough.



The above function is unique to a specific D2R3DModel object which loads a single .pod file.



So there are n D2R3DObject’s each with there own copies of m_puiTextures (and other members). When i load a single D2R3DObject with 4 textures, it loads those separate textures fine and renders fine. So the issue isn’t with the size of texture handle array or getting the materials out of the .pod, or it would have failed the first time.



The problem lies with PVRTTextureLoadFromPVR() failing for the loading of the second instance of D2R3DModel.



Its practically identical to how the Skinning demo works, so im wondering if there is some texture param i need to set or gl state ive missed. Ive included the code snippet of how the whole loading routine’s work.



Its worth noting that i get the correct material name out of the model, and it renders the model with no texture second model and beyond.





void D2R3DModel::InitialiseModel( string modelName )

{

CPVRTResourceFile::SetReadPath((char*)m_Shell->PVRShellGet(prefReadPath));



CPVRTResourceFile::SetLoadReleaseFunctions(m_Shell->PVRShellGet(prefLoadFileFunc), m_Shell->PVRShellGet(prefReleaseFileFunc));



if(m_Scene.ReadFromFile(modelName.c_str()) != PVR_SUCCESS)

{

m_Shell->PVRShellSet(prefExitMessage, “Error: Failed to load scene.n”);

return;

}



CPVRTString error;



// Check to see whether the matrix palette extension is supported.

if(!CPVRTglesExt::IsGLExtensionSupported(“GL_OES_matrix_palette”))

{

m_Shell->PVRShellSet(prefExitMessage, “ERROR: The extension GL_OES_matrix_palette is unsupported.n”);

return;

}



// Initialise the matrix palette extensions

m_Extensions.LoadExtensions();



// Load the textures

if(!LoadTextures(&error))

{

m_Shell->PVRShellSet(prefExitMessage, error.c_str());

return;

}



if(!m_puiVbo)

m_puiVbo = new GLuint[m_Scene.nNumMesh];



if(!m_puiIndexVbo)

m_puiIndexVbo = new GLuint[m_Scene.nNumMesh];



glGenBuffers(m_Scene.nNumMesh, m_puiVbo);



for(unsigned int i = 0; i < m_Scene.nNumMesh; ++i)

{

// Load vertex data into buffer object

SPODMesh& Mesh = m_Scene.pMesh;

unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride;



glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo);

glBufferData(GL_ARRAY_BUFFER, uiSize, Mesh.pInterleaved, GL_STATIC_DRAW);



// Load index data into buffer object if available

m_puiIndexVbo = 0;



if(Mesh.sFaces.pData)

{

glGenBuffers(1, &m_puiIndexVbo);

uiSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo);

glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, Mesh.sFaces.pData, GL_STATIC_DRAW);

}

}



glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);



m_fFrame = 0;

m_modelState = D2R_MODEL_STATE_RENDERING;

}



bool D2R3DModel::LoadTextures(CPVRTString* const pErrorStr)

{

m_puiTextures = new GLuint[m_Scene.nNumMaterial];



for(unsigned int i = 0; i < m_Scene.nNumMaterial; ++i)

{

SPODMaterial* pMaterial = &m_Scene.pMaterial;

g_DebugManagerInstance.Log(" loading material: %s",pMaterial->pszName);



std::string extension = std::string(".pvr");



std::string pvrFile = pMaterial->pszName + extension;



if(PVRTTextureLoadFromPVR(pvrFile.c_str(), &m_puiTextures) != PVR_SUCCESS)

{

g_DebugManagerInstance.Log(" ERR: %s",pMaterial->pszName);



*pErrorStr = “ERROR: Failed to load texture.”;

return false;

}

}



return true;

}


#5

hello ,



we can get the texture name directly by the way

CPVRTString sTextureName = m_Scene.pTexture[pMaterial->nIdxTexDiffuse].pszName;<br />
if(PVRTTextureLoadFromPVR(sTextureName &m_puiTextures<i>) != PVR_SUCCESS)
```<br />
<br />
are you sure about the texture name  ?<br />
<br />
<br />
</i>

#6

Yeah 100% , Each model in my scene loads fine on its own. Its only when i try and load multiple models in my scene it fails to load the textures.


#7

that is wierd …



if none answer to this one i will make a test case tonite


#8

Im still working on this as we speak and will into the evening too, so if i find the solution ill let you know. If you want to get a copy of the source and usage, email me and ill pass the class across. Jim


#9

did you solve it ?

did you see the skybox2 demo and how the apply “effect” and texture

for(int i = 0; i < 3; ++i)

{

if(PVRTTextureLoadFromPVR(g_aszTextureNames, &m_ui32TextureIDs) != PVR_SUCCESS)

return false;



glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

}



// Load cube maps

for(int i = 3; i < 5; ++i)

{

if(PVRTTextureLoadFromPVR(g_aszTextureNames, &m_ui32TextureIDs))

{

*pErrorStr = CPVRTString("ERROR: Could not open texture file ") + g_aszTextureNames;

return false;

}



glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

}


#10

Thanks Dgu,



No im still working at it. I was just putting it in an example project to send you over to take a look at if you have time, i just need to sort out the model matrices on each model to render in the right position.



For the moment i might spend the day hacking away to see if i can fix it. Im sure there is some setting im missing.



Looking at the example above in the skybox sample , the only difference i can see is the setting of the glTexParameteri Filter for cube maps, which is irrelevant to what im doing. Ill keep plugging away and try and find the line in the OS where it fails, or send you the finished example later on today.


#11

Hi Guys,



So to wrap this up, sort of…



The loading fails on glBindTexture(GL_TEXTURE_2D, *texName); call on line 474 PVRTTextureAPI.cpp throws an out of memory error when calling glError().



So something fails on the HTC Desire S when loading the second texture through the SDK. Not sure why though. When i load the texture after this time it works fine. I will investigate again at some point but will stick to the workaround at the moment.



Jim


#12

it s not an PowerVR GPU :slight_smile: , what encoding did you use ?

good luck


#13

Yeah im blaming the devices hardware implementation, dont worry hehe!



Ive just suppressed that error to free up any allocated memory so should be fine, just take awhile longer to loaded my world.



I used PVRTC 4bpp t keep the size down.