Problem with normals in OpenGL ES in S60 app

i am using OpenGL ES to display 3D models on my Series 60 app. i imitated the applications avaialble in FP2 SDk but there was something going wrong with my lightening because of the normals data. in the SimpleLight SDk app, the duck model had a strange representation of normals, they are integers instead of floats and have the same number as the verticies of the duck. how could this be done? all the models that i created using 3D S Max had less or more normals than the available verticies of the object. without having the same nb of normals and vertices, i will always have a problem in the lighteneing and shading since i am using glDrawElement() and data list arrays.
any one can suggest anything???


I’ve the same problem!!
I try a lot of simple model, and all have wrong illumination!It’s a week that I try to understand why! :confused:


they are using vertex normals…

3dsmax uses smoothing groups. Each smoothing group is defined by an angle from 0 to 180. When the angle is 35 grads this means that all neighbour triangles having this or smaller angle between them share the same normal. No smoothing groups means an angle of 0 or 180 grads. My advice is calculate the normals additionaly, but be aware that 3dsmax keeps often dublicated vertices because of the texture coordinates, so in order to have good normals you must filter the dublicates at first. An easy approach is to to add a new vertex only if one with the same coordinates ± eps does not exist. Use octree to check the existance, otherwise you must wait hours. The approach above is tested on Symbian 6.1 with the 3ds file format and it works.

How do you import the 3ds file on OpenGL ES project?!
Can you post your loader? :wink:

i solved the problem i had concerning normals representation in OES long time ago. i forgot to post how i did it. so here u r:

first, i designed the object using 3D Max as i proposed b4. then i imported it as an OBJ file from which i could extract the vertices, normals, and faces data. i saved all these data in arrays of course.

the OBJ format represents the vertices, normals, and texture cordinate for each face as a tuple of the following format:

f v1/t1/n1 v2/t2/n2 v3/t3/n3

  • v1 represents the first vertex of the tiangle, v2 the seconnd and v3 the third.
  • t1 represents the texture coord. for the first vertex, t2 the coords. for the second and t3 for the third.
  • n1 represents the normal for the first vertex, n2 the norm of the second, and n3 for the third.

each face is composed of three vertices. u keep track of the faces by their vertices. from this format, it is clear that two or more adjacent faces may share one or two verteces or texture coords. say we have triangles T1 and T2 that are next to each other. T1 is compound of x, y, and z. since T2 is adjacent to it, it iwll share 1 vertex with T1 or two depending on the shaoe they represent. so T2 will be compound of x, y and w.

normals follow different discussion. as u know, normals are calculated from the crox produc of two vectors. since all vertices of a triangle belong to the same plane, any cros product to any two of its vectors will give the same normal, meaning that each face will have one normal and all vertices will have that same normal (a vector can be found by the subtraction of the x and y components of two vertices in a triangle side).
from this, you can see that since one or two vertices may belong to two or more faces which may not fall in the same plane, a common vertex will have different normal values for the different faces it belongs to. to solve this, we have to add the components of the normals together to get at the end an average normal from the addition composite. once u have got the resultant normal, make sure you normalise it. to do so, u have to find the square root of its x^2 + y^2 + z^2 as in the following:

lngth = sqrt(xx + yy + z*z);

then devide each of the components by the resultant lngth as:

x/lnght, y/lngth, z/lngth

in this case u will receive the normalised average normal on the vertex. apply this to all vertices of course.

now u have all the data that u need: vertices, faces, and normal. the faces and the vertices will be of an integer tyoe naturally but normals will have floating point type since they are normalised. we know that floating point variables take too much memory and computation power. so to het rid of this, what u have to is to multiply all normal components, x, y, and z, with a scalar say 250 (so u can save them in a small-dat-type array like GLbyte or GLshort). then round the result to its nearest integer value to remove the fraction part. at the end u have and integer representation for the normals.

so now we have all the data we need ready adn in an integer format. note that all this parsing and conversion process takes place outside ur OES applciation. what i did was i created a separate C++ application that reads from OBJ file and parses its data and generates a newfile that contains the finalised geometry data (vertices, faces, normals and texture coords.)

now, what is left to do is to copy these data adn save them in arrays in OES, or in an external file and load them to your application as i did in my Symbian-based. then perform the normal drawing using vertex arrays. note that u have to enable here GL_NORMALIZE as:

glEnable( GL_NORMALIZE );

this will recalculate ur normals to reget the normilised version. if u dont enable this, ur object will be dark sinc ethe light-normal are in-proper.
i know that this will be expensive calculation wise. but, in my applciation i need to make sure that i consume the samllest amount of memory as possible. this calculation expenss will not be a problem for me. if it was in appropertiate to ur case, then, dont do the scalar multiplication in ur external data generator application and keep instead the original normalised float type values of ur normals.

i hope this will be benificial. it is too long but comprehinsive though.


This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.