From Collada to openGL ES texture coordinates

i am developing a 3D engine on mobile phone and have a big problem with texture coordinates. initially it took me some time to find a decent collada exporter not using polygon mode and glBegin to create objects, and also which exports texture coordinates, currently i am dealing with maya to obtain collada files from 3d models.

but i fail to understand how to use the texture coordinates to draw a textured cube.

here is the complete dae file i obtained from maya :

<?xml version=“1.0” encoding=“utf-8”?>
<COLLADA xmlns=“COLLADA 1.4 Schema” version=“1.4.1”>
<asset>
<contributor>
<author>toto</author>
<authoring_tool>Maya2008 | ColladaMaya v3.05B</authoring_tool>
<comments>ColladaMaya export options: bakeTransforms=0;exportPolygonMeshes=1;bakeLighting=0;isSampling=0;
curveConstrainSampling=0;removeStaticCurves=1;exportCameraAsLookat=0;
exportLights=0;exportCameras=0;exportJointsAndSkin=0;
exportAnimations=0;exportTriangles=1;exportInvisibleNodes=0;
exportNormals=0;exportTexCoords=1;
exportVertexColors=0;exportVertexColorsAnimation=0;exportTangents=0;
exportTexTangents=0;exportConstraints=0;exportPhysics=0;exportXRefs=1;
dereferenceXRefs=0;cameraXFov=0;cameraYFov=1</comments>
<source_data>file:///D:/media/3D/cube/cube.mb</source_data>
</contributor>
<created>2009-06-22T13:54:21Z</created>
<modified>2009-06-22T13:54:21Z</modified>
<unit meter=“0.01” name=“centimeter”/>
<up_axis>Y_UP</up_axis>
</asset>
<library_images>
<image id=“file1” name=“file1”>
<init_from>cube.png</init_from>
<extra>
<technique profile=“MAYA”>
<dgnode_type>kFile</dgnode_type>
<image_sequence>0</image_sequence>
</technique>
</extra>
</image>
</library_images>
<library_materials>
<material id=“_01___Default” name=“_01___Default”>
<instance_effect url=“#_01___Default-fx”/>
</material>
</library_materials>
<library_effects>
<effect id=“_01___Default-fx”>
<profile_COMMON>
<newparam sid=“file1-surface”>
<surface type=“2D”>
<init_from>file1</init_from>
<format>A8R8G8B8</format>
</surface>
</newparam>
<newparam sid=“file1-sampler”>
<sampler2D>
<source>file1-surface</source>
<wrap_s>WRAP</wrap_s>
<wrap_t>WRAP</wrap_t>
<minfilter>NONE</minfilter>
<magfilter>NONE</magfilter>
<mipfilter>NONE</mipfilter>
</sampler2D>
</newparam>
<technique sid=“common”>
<blinn>
<emission>
<color>0 0 0 1</color>
</emission>
<ambient>
<color>0.588235 0.588235 0.588235 1</color>
</ambient>
<diffuse>
<texture texture=“file1-sampler” texcoord=“TEX0”>
<extra>
<technique profile=“MAYA”>
<wrapU>1</wrapU>
<wrapV>1</wrapV>
<mirrorU>0</mirrorU>
<mirrorV>0</mirrorV>
<coverageU>1</coverageU>
<coverageV>1</coverageV>
<translateFrameU>0</translateFrameU>
<translateFrameV>0</translateFrameV>
<rotateFrame>0</rotateFrame>
<stagger>0</stagger>
<fast>0</fast>
<repeatU>1</repeatU>
<repeatV>1</repeatV>
<offsetU>0</offsetU>
<offsetV>0</offsetV>
<rotateUV>0</rotateUV>
<noiseU>0</noiseU>
<noiseV>0</noiseV>
<blend_mode>NONE</blend_mode>
</technique>
</extra>
</texture>
</diffuse>
<specular>
<color>0 0 0 1</color>
</specular>
<shininess>
<float>0.3</float>
</shininess>
<reflective>
<color>0 0 0 1</color>
</reflective>
<reflectivity>
<float>0.3</float>
</reflectivity>
<transparent opaque=“RGB_ZERO”>
<color>0 0 0 1</color>
</transparent>
<transparency>
<float>1</float>
</transparency>
</blinn>
<extra>
<technique profile=“FCOLLADA”/>
</extra>
</technique>
</profile_COMMON>
</effect>
</library_effects>
<library_geometries>
<geometry id=“polySurfaceShape1” name=“polySurfaceShape1”>
<mesh>
<source id=“polySurfaceShape1-positions” name=“position”>
<float_array id=“polySurfaceShape1-positions-array” count=“24”>-50.0 -50.0 0 50.0 -50.0 0 -50.0 50.0 0 50.0 50.0 0 -50.0 -50.0 50.0 50.0 -50.0 50.0 -50.0 50.0 50.0 50.0 50.0 50.0</float_array>
<technique_common>
<accessor source=“#polySurfaceShape1-positions-array” count=“8” stride=“3”>
<param name=“X” type=“float”/>
<param name=“Y” type=“float”/>
<param name=“Z” type=“float”/>
</accessor>
</technique_common>
</source>
<source id=“polySurfaceShape1-map1” name=“map1”>
<float_array id=“polySurfaceShape1-map1-array” count=“60”>0 0 1 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1 0 1 1 1 1 0 1 0 0 0 0 1 0 1 1 1 1 0 1 0 0 0 0 1 0 1 1 1 1 0 1 0 0</float_array>
<technique_common>
<accessor source=“#polySurfaceShape1-map1-array” count=“30” stride=“2”>
<param name=“S” type=“float”/>
<param name=“T” type=“float”/>
</accessor>
</technique_common>
</source>
<vertices id=“polySurfaceShape1-vertices”>
<input semantic=“POSITION” source=“#polySurfaceShape1-positions”/>
</vertices>
<triangles material=“_01___DefaultSG” count=“12”>
<input semantic=“VERTEX” source=“#polySurfaceShape1-vertices” offset=“0”/>
<input semantic=“TEXCOORD” source=“#polySurfaceShape1-map1” offset=“1” set=“0”/>

0 9 2 11 3 10 3 10 1 8 0 9 4 12 5 13 7 14 7 15 6 16 4 17 0 4 1 5 5 7 5 7 4 6 0 4 1 0 3 1 7 3 7 3 5 2 1 0 3 18 2 19 6 20 6 21 7 22 3 23 2 24 0 25 4 26 4 27 6 28 2 29</p>
</triangles>
</mesh>
<extra>
<technique profile=“MAYA”>
<double_sided>1</double_sided>
</technique>
</extra>
</geometry>
</library_geometries>
<library_visual_scenes>
<visual_scene id=“VisualSceneNode” name=“cube”>
<node id=“Box01” name=“Box01” type=“NODE”>
<translate sid=“translate”>3.52794 0 -1.99493</translate>
<rotate sid=“rotateZ”>0 0 1 0</rotate>
<rotate sid=“rotateY”>0 1 0 0</rotate>
<rotate sid=“rotateX”>1 0 0 -90</rotate>
<instance_geometry url=“#polySurfaceShape1”>
<bind_material>
<technique_common>
<instance_material symbol=“_01___DefaultSG” target=“#_01___Default”>
<bind_vertex_input semantic=“TEX0” input_semantic=“TEXCOORD” input_set=“0”/>
</instance_material>
</technique_common>
</bind_material>
</instance_geometry>
</node>
<extra>
<technique profile=“MAYA”>
<layer name=“_0”>Box01 polySurfaceShape1</layer>
</technique>
<technique profile=“FCOLLADA”>
<start_time>0.041666</start_time>
<end_time>2</end_time>
</technique>
</extra>
</visual_scene>
</library_visual_scenes>
<scene>
<instance_visual_scene url=“#VisualSceneNode”/>
</scene>
</COLLADA>

opengl has some limitations which imply to draw without glBegin, so i am using glDrawElements( GL_TRIANGLES, …) for that. geometry is fine, my only problem is texture coordinates.

if i follow the general collada information we find here or there on the web, the texture coordinates table is from this file : 1 0 1 1 0 1 0 1 0 0 1 0…
basically we check every 2nd value of the

list to get the texture coordinate ID to retrieve in the “polySurfaceShape1-map1-array” a couple of coordinates, so the previous list was given for the first face by the following ID list : 9 11 10 10 8 9…

now this texture coordinate table gives me at rendering a weird displayed texture, and i figured that the following table gives me a properly rendered texture :

GLfloat quadTexCoords[] = {
// FRONT
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
// BACK
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 0.0f,
0.0f, 1.0f,
// LEFT
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 0.0f,
0.0f, 1.0f,
// RIGHT
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 0.0f,
0.0f, 1.0f,
// TOP
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
// BOTTOM
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 0.0f,
0.0f, 1.0f
};

so it appears that the texture table i retrieve from the collada file gives me the texture coordinates for the triangles but opengl es is waiting for quad texture coordinates instead, as obviously the ID list : 9 11 10 10 8 9 contains 3 consecutive texture coordinates relative to a triangle but we cant have for a quad twice the same texture coordinate ID for a face

anyone has an idea of what is wrong in my engine ?

What does your function call to glTexCoordPointer look like?

the code to display the cube is the following one :

glVertexPointer( 3, GL_SHORT, 0, pshVertexTab );
glTexCoordPointer( iNbTexCoordPerVertex, GL_FLOAT, 0, pfTexCoordTab );
glBindTexture( GL_TEXTURE_2D, iTextureID );
glDrawElements( GL_TRIANGLES, iNbTriangleVertex, GL_UNSIGNED_BYTE, oVertexIDTab );

i have just verified the code of the collada dom viewer, which displays correctly the cube from the dae file and it uses same instructions than me and data structures sent to opengl are the same, so i really dont see any reason for opengl es to require some quad texture coordinates (as 4 UV coordinates) instead of the 6 texture coordinates you are supposed to provide when in GL_TRIANGLE mode

i also noticed that all opengl es texturing tutorials i found use quad texture coordinates to display a cube, there is something i absolutely fail to understand

fater tracing the collada dom viewer source at run, i have finaly reorganized data i was feeding opengl es with and now it functions

Glad to hear that you figured it out. Can you post how you solved it for OpenGL ES to conclude this thread for future reference? Thanks.

you have 3 tables to deliver to opengl es when you want to draw an object :

  • vertex coordinate table, with glVertexPointer
  • texture coordinate table, with glTexCoordPointer
  • vertex ID table, with glDrawElements

you may also have the normals table to provide but thats optional for some basic example

i was initialy rebuilding the texture coordinate table by getting each texture coordinate ID in

(dont forget the offset to get the right ID) and then rebuilding a table by retrieving the corresponding texture coordinate in the <float_array> node relative to texture coordinates, but i wasnt doing the same for vertices coordinates, i was using straight the <float_array> node relative to vertices coordinates and i was also retrieving from the

table only the vertex ID in a new table.

since we provide with glDrawElements a single table ID, the texture coordinates table and the vertices coordinates tables were not sorted the same way, and my texture was badly applied. so finaly i rebuild the vertices coordinates table the same way than the texture coordinates table. and the table i provide to glDrawElements is a new one, very simply created with each element having the same value than its rank in the table, basicaly the list is now :
vertexIDTab[0]=0;
vertexIDTab[1]=1;

vertexIDTab[n]=N;

I’ve written a step-by-step tutorial on how I parsed a COLLADA export taken from LightWave and imported it into OpenGL ES, which may be of use.