Triangle Strip Normals

Started by
6 comments, last by denger0 11 years, 9 months ago
Hi, I am wanting to use a triangle strip to draw a terrain that I have to randomly generate. However, I am unsure how to set the normals of the triangles in the strip (for lighting calculations). I'm not even positive for regular polygons, though I understand you set it with glNormal. I've tried googling this, looking in the red book, searching the forums here, etc and I've turned up nothing. So, any help would be appreciated. Thanks Edit: I should mention that I'm looking to do per-face normals. Edit 2: On further thinking, I realize that it might be possible to do this by setting the normal of the vertex that represents each triangle to the face normal. So that would be something like this:

glBegin(GL_TRIANGLE_STRIP);
glVertex3f(x1, y1, z1);
glVertex3f(x2, y2, z2);

glNormal3f(nx1, ny1, nz1);
glVertex3f(x3, y3, z3);

glNormal3f(nx2, ny2, nz2);
glVertex3f(x4, y4, z4);
etc...

glEnd();
Is this the way that is used? [Edited by - hallucinogenic on February 18, 2005 2:28:40 AM]
Advertisement
I would stick with per-vertex normals so that your terrain will look better, and calculate each one as the average of the cross products of any number of neighbouring vertices that are planar. If you are storing your heightmap in an array, then you will want to create a second array of the same size for holding your normals. Write a routine to loop through your heightfield array and calculate the normal for each vertex, and then in your render routine where you loop through the heightmap and call each vertex, also call the corresponding normal at the same time.

There are many ways to calculate the normals for a vertex. Each method does the same thing in principle, and that is to create a vertex, say v1, of a neighbour vertex minus the current vertex, create another vertex, say v2, of a different neighbour minus current one, and then take the cross product of v1 and v2. Normalise the result, and that's your normal.

eg.

a---b|   ||   |c---d


The normal for 'a' would be the normalised cross product of v1 and v2 where v1 is (b-a) and v2 is (c-a). Likewise, the normal for vertex 'c' would be the normalised cross product of v1 and v2 where v1 is vertex (a-c), and v2 is (d-c). Pretty straight forward.

The more vertices you put into the calculation, the more accurate the normal and better the overal results. Although when you factor into the calculation more cross-product pairs, you need to then take the sum of these and divide by the number of paris used, and then normalise that result. eg

Normal 'a' using v1 as (c-a), v2 as (d-a), and v3 as (b-a), would be the normalised sum of the cross products of the vertex pairs v1,v2 and v2,v3, divided by the number of pairs used, which is 2 in this case. In pseudo code that would be something like this:

assume we have VECTOR a,b,c,d defined
VECTOR v1,v2,v3;
VECTOR n1,n2;
v1=(c-a);
v2=(d-a);
v3=(b-a);
n1=cross_product(v1,v2);
n2=cross_product(v2,v3);
normal=(n1+n2)/2;
normalise the normal;

As mentioned above, I calculate the normals when I generate the terrain and store these in a separate array for easy lookup in the render routine. That way there are no render time performance hits and I can use a better routine to generate the normals and so gett better looking results.

       a---b---c    ^  |  /|  /|    |  |/  |/  |    z  d---e---f    |  |  /|  /|    v  |/  |/  |       g---h---i         <-x->


In my routine the normal for vertex 'a' would be the cross product of v1 and v2 where v1 is (b-a) and v2 is (d-a) only. Same as earlier. The cross product for vertex b however would be the sum of the cross products of (v1,v2), (v2,v3), and (v3,v4), divided by 3, where v1 is (a-b), v2 is (d-b), v2 is (e-b), and v4 is (c-b). Likewise, vertex e is calculated from 6 neighbouring vertices v1(b-e), v2(d-e), v3(g-e), v4(h-e), v5(f-e), and v6(c-e). That is the normalised sum of 5 cross product pairs (v1,v2),(v2,v3),(v3,v4),(v4,v5),(v5,v6) divided by 5. Vertex i would be normalised cross product of h-i and f-i, whereas f would be the normalised sum of 3 pairs from c-f, e-f, h-f, and i-f. This would be a completely unoptimised approach, but then again I am not calculating these on the fly, like you would for say, a mesh for water. For something like that I would use a different approach and a much simpler routine.

There are of course ways to optimise the calculation of normals, and you certainly do not have to do it the way I explained above. Here are some extracts from my terrain generator:

VECTOR CPoint[size][size];	// heightfieldVECTOR CNormal[size][size];	// vertex normalsand in my initialise routineterrain.InitialiseHeightMap();	// generate heightmapterrain.SetUpNormals();		// calculate normals for each vertexterrain.CalcVertexSlope();	// calcualte slope of each vertexterrain.GetMinMaxHeight();	// obtain min/max heights of terrainterrain.SetTerrainFogLevels();	// setup volumetric foxand so on...and in the render routine// render terrain heightmap using triangle stripGLfloat a,b,c;for (int z=0; z<(terrain.size-1); z++) {  glBegin(GL_TRIANGLE_STRIP);    for (int x=0; x<terrain.size; col++) {      // caclulate texture coordinates for this vertex      a=(float)row/(terrain.size-1);      b=(float)col/(terrain.size-1);      c=(float)(row+1)/(terrain.size-1);      // set normal       glNormal3f( terrain.CNormal[z][x].x,                  terrain.CNormal[z][x].y,                  terrain.CNormal[z][x].z );      // set texture coordinates      glMultiTexCoord2fARB(GL_TEXTURE0_ARB,a,b);      glMultiTexCoord2fARB(GL_TEXTURE1_ARB,a*terrain.detailRepeat,b*terrain.detailRepeat);      // first vertex      glVertex3f( terrain.CPoint[z][x].x*terrain.scale,                  terrain.CPoint[z][x].y*terrain.scale,                  terrain.CPoint[z][x].z*terrain.scale );      // set next normal      glNormal3f( terrain.CNormal[z+1][x].x,                  terrain.CNormal[z+1][x].y,                  terrain.CNormal[z+1][x].z);      // next vertex texture coordinates      glMultiTexCoord2fARB(GL_TEXTURE0_ARB,c,b);      glMultiTexCoord2fARB(GL_TEXTURE1_ARB,c*terrain.detailRepeat,b*terrain.detailRepeat);      // next vertex      glVertex3f( terrain.CPoint[z+1][x].x*terrain.scale,                  terrain.CPoint[z+1][x].y*terrain.scale,                  terrain.CPoint[z+1][x].z*terrain.scale );    }  glEnd();}and my normal calc routine that should be easy to follow:GLvoid SetUpNormals(){  VECTOR v1,v2,v3,v4,v5,v6;  VECTOR n,n1,n2,n3,n4,n5,n6;  for (int z = 0; z < terrain.size; z++ ) {    for (int x = 0; x < terrain.size; x++ ) {	if ( z == 0 && x == 0 ) {		// back left corner - 1 tri 2 vertices		v1 = terrain.CPoint[z+1][x] - terrain.CPoint[z][x];		v2 = terrain.CPoint[z][x+1] - terrain.CPoint[z][x];		n.Cross(v1,v2);	} else if ( (z > 0 && z < (terrain.size-1)) && x == 0 ) {		// left edge - 3 tri 4 vertices		v1 = terrain.CPoint[z][x+1]   - terrain.CPoint[z][x];		v2 = terrain.CPoint[z-1][x+1] - terrain.CPoint[z][x];		v3 = terrain.CPoint[z-1][x]   - terrain.CPoint[z][x];		v4 = terrain.CPoint[z][x+1]   - terrain.CPoint[z][x];		n1.Cross(v1,v2); n2.Cross(v2,v3); n3.Cross(v3,v4);		n = (n1+n2+n3)/3.0f;	} else if ( z == (terrain.size-1) && x == 0  ) {		// front left corner - 2 tri 3 vertices		v1 = terrain.CPoint[z][x+1]   - terrain.CPoint[z][x];		v2 = terrain.CPoint[z-1][x+1] - terrain.CPoint[z][x];		v3 = terrain.CPoint[z-1][x]   - terrain.CPoint[z][x];		n1.Cross(v1,v2); n2.Cross(v2,v3);		n = (n1+n2)/2.0f;	} else if ( z == (terrain.size-1) && (x > 0 && x < (terrain.size-1)) ) {		// front edge - 3 tri 4 vertices		v1 = terrain.CPoint[z][x+1]   - terrain.CPoint[z][x];		v2 = terrain.CPoint[z-1][x+1] - terrain.CPoint[z][x];		v3 = terrain.CPoint[z-1][x]   - terrain.CPoint[z][x];		v4 = terrain.CPoint[z][x-1]   - terrain.CPoint[z][x];		n1.Cross(v1,v2); n2.Cross(v2,v3); n3.Cross(v3,v4);		n = (n1+n2+n3)/3.0f;	} else if ( z == (terrain.size-1) && x == (terrain.size-1) ) {		// front right corner - 1 tri 2 vertices		v1 = terrain.CPoint[z-1][x]   - terrain.CPoint[z][x];		v2 = terrain.CPoint[z][x-1]   - terrain.CPoint[z][x];		n1.Cross(v1,v2);		n = n1;	} else if ( ( z > 0 && z < (terrain.size-1)) && x == (terrain.size-1)  ) {		// right edge - 3 tri 4 vertices		v1 = terrain.CPoint[z-1][x]   - terrain.CPoint[z][x];		v2 = terrain.CPoint[z][x-1]   - terrain.CPoint[z][x];		v3 = terrain.CPoint[z+1][x-1] - terrain.CPoint[z][x];		v4 = terrain.CPoint[z+1][x]   - terrain.CPoint[z][x];		n1.Cross(v1,v2); n2.Cross(v2,v3); n3.Cross(v3,v4);		n = (n1+n2+n3)/3.0f;	} else if ( z == 0 && x == (terrain.size-1) ) {		// back right corner - 2 tri 3 vertices		v1 = terrain.CPoint[z][x-1]   - terrain.CPoint[z][x];		v2 = terrain.CPoint[z+1][x-1] - terrain.CPoint[z][x-1];		v3 = terrain.CPoint[z+1][x-1] - terrain.CPoint[z][x];		v4 = terrain.CPoint[z+1][x]   - terrain.CPoint[z][x];		n1.Cross(v1,v2); n2.Cross(v3,v4);		n = (n1+n2)/2.0f;	} else if ( z == 0 && ( x > 0 && x < (terrain.size-1)) ) {		// back edge - 3 tri 4 vertices		v1 = terrain.CPoint[z][x-1]   - terrain.CPoint[z][x];		v2 = terrain.CPoint[z+1][x-1] - terrain.CPoint[z][x];		v3 = terrain.CPoint[z+1][x]   - terrain.CPoint[z][x];		v4 = terrain.CPoint[z][x+1]   - terrain.CPoint[z][x];		n1.Cross(v1,v2); n2.Cross(v2,v3); n3.Cross(v3,v4);		n = (n1+n2+n3)/3.0f;	} else {		// internal - 6 tri 6 vertices		v1 = terrain.CPoint[z][x+1]   - terrain.CPoint[z][x];		v2 = terrain.CPoint[z-1][x+1] - terrain.CPoint[z][x];		v3 = terrain.CPoint[z-1][x]   - terrain.CPoint[z][x];		v4 = terrain.CPoint[z][x-1]   - terrain.CPoint[z][x];		v5 = terrain.CPoint[z+1][x-1] - terrain.CPoint[z][x];		v6 = terrain.CPoint[z+1][x]   - terrain.CPoint[z][x];		n1.Cross(v1,v2); n2.Cross(v2,v3); n3.Cross(v3,v4);		n4.Cross(v4,v5); n5.Cross(v5,v6); n6.Cross(v6,v1);		n = (n1+n2+n3+n4+n5+n6)/6.0f;	}	n.Normalize();	terrain.CNormal[z][x].Set(n.x,n.y,n.z);    }  }}and a slightly more optimised version I use for water:CalcNormals(){  #define ax(x) ((x<0)?(x+1):((x>=WATERX)?(x-1):x))  VECTOR v1,v2,v3,v4,n1,n2,n3,n4,n;  for (j=0; j<WATERY; j++) {    for (int i=0; i<WATERX; i++) {      v1=waterHeight[ax(i+1) + j * WATERX] - waterHeight[i+j*WATERX];      v4=waterHeight - waterHeight[i+j*WATERX];<br>      v3=waterHeight[ax(i-<span class="cpp-number">1</span>) + j * WATERX] - waterHeight[i+j*WATERX];<br>      v2=waterHeight - waterHeight[i+j*WATERX];<br>      n1.Cross(v4,v1); n2.Cross(v1,v2); n3.Cross(v2,v3); n4.Cross(v3,v4);<br>      n = (n1+n2+n3+n4)/<span class="cpp-number">4</span>.0f;<br>      n.Normalize();<br>      waterNormal[i+j*WATERX]=n;<br>    }<br>  }<br>}<br><br><br><br></pre></div><!–ENDSCRIPT–><br><br>You will need to do a little research &#111;n cross-products. <a href="http://chortle.ccsu.ctstateu.edu/VectorLessons/vectorIndex.html">Here</a> is a good place to start.<br><br>HTH<br>F451<br><br><!–EDIT–><span class=editedby><!–/EDIT–>[Edited by - Fahrenheit451 on October 20, 2005 9:55:00 PM]<!–EDIT–></span><!–/EDIT–>
Quote:
Edit: I should mention that I'm looking to do per-face normals.
+
glBegin(GL_TRIANGLE_STRIP);

not possible for per face normals u need to use triangles
Quote:Original post by hallucinogenic
Edit: I should mention that I'm looking to do per-face normals.


Well you may be able to get what you want with glShadeModel(GL_FLAT). This will cause the calculated vertex color of the third vertex (in the case of tri strips) to be used for the entire triangle. Then you can just supply the face normals for each face in the last vertex for that face.
Thanks for the responses, everyone.

Here is the problem, though. This is a project for one of my classes, and in the specifications, it says that we must do both per-face and per-vertex normal calculations. In fact, we have to include a function to draw the normals.

So, at this point, everything could be considered fine. I'd just use triangles and resend vertices. But, in the "hints" section, the assignment says that "if you're feeling ambitious, you could gain efficiency by using GL_TRIANGLE_STRIP mode." So, in the name of practicality, I would like to try this out.

Also, I couldn't just use flat shading, because another part of the specification is that we implement a toggle between flat shading and smooth shading.


Quote:Original post by zedzeek
Quote:
Edit: I should mention that I'm looking to do per-face normals.
+
glBegin(GL_TRIANGLE_STRIP);

not possible for per face normals u need to use triangles


Are you positive about this? Because, if so, I guess I'll just have to use regular triangles.

Quote:Original post by Fahrenheit451
...helpful stuff...


Thanks, this is really helpful!
Alright, let's go into a little more detail on the problem here. First off, opengl really doesn't support the concept of face normals, it always works with vertex normals. Consider the case where you have a single triangle, if you supply different normals for each vertex you will get different lighting values calculated at each vertex and interpolated across the face of the tri, this gives the illusion of a curved surface. You could also of course supply the same normal for all 3 verts (the face normal), in this case the same lighting value is calculated at each vertex and the triangle appears "flat". The flat shading model has a similar affect because it chooses only one of the vertex lighting values to use for the whole triangle.

(This actually assumes that the only variable into the lighting calculation is the normal, which is true for directional diffuse lighting. In the general case the position of the vertex will also affect the calculated vertex color at each corner of the face, but I'm going to ignore that for this discussion. This does mean however that flat shading is not exactly the same as supplying the same normal for each vertex.)

Now lets say we have several triangles. For each face we could either supply 3 vertex normals or 1 face normal 3 times. However if the faces are adjacent some of their verts are in the same place, it would be nice if the faces could share these verts to reduce the number we need to send to the gpu. This is where tri-strips come in. However faces can only share a vertex if that vertex has exactly the same position and normal for both faces (this is obvious, since the vertex data is only sent once, it has to be the same for both faces). If the faces are not coplanar and you are using face normals then the shared verts must have different normals, which means they must be sent twice, which means you can't use tri-strips for them.

You can however use tri-strips with vertex normals as long as you choose a vertex normal which works for both faces. Generally you do this by averaging the face normals of all faces which share the vertex. It should be noted that vertex normals look better for curved surfaces as it allows you to smooth shade across the face boundries giving the illusion of a continuous smooth curve.
Okay, I see it now. Thanks a lot!
hi all i got weird lighting even if i compute the normal form triangles

i draw my triangle in this order


p1 --- p3 p4
| / / |
p2 p5 ---p6


///this is how i construct my terrain

for (int l = 0 ; l <= length ; l++){
for (int w = 0 ; w <= width ; w++){
//0--.2
//| . |
//./ .
//1---3
VECTOR tmp;
TEXCOORD tmpTexCoord;
//int p1,p2,p3,p4;// points
int iP1,iP2,iP3,iP4,iP5,iP6;// index point
//switch((int)randomMaxHeight){
//case 0:
// randomMaxHeight = (rand() % 10 );
// break;
//case 1:
// randomMaxHeight = (rand() % 2 );
// break;
//case 2:
// randomMaxHeight = ((double) rand() / (RAND_MAX+1)) * (3-1+1) + 1;
// break;
//case 3:
// randomMaxHeight = ((double) rand() / (RAND_MAX+1)) * (4-2+1) + 2;
// break;
//case 4:
// randomMaxHeight = ((double) rand() / (RAND_MAX+1)) * (5-3+1) + 3;
// break;
//case 5:
// randomMaxHeight = ((double) rand() / (RAND_MAX+1)) * (6-4+1) + 4;
// break;
//case 6:
// randomMaxHeight = ((double) rand() / (RAND_MAX+1)) * (7-5+1) + 5;
// break;
//case 7:
// randomMaxHeight = ((double) rand() / (RAND_MAX+1)) * (8-6+1) + 6;
// break;
//case 8:
// randomMaxHeight = ((double) rand() / (RAND_MAX+1)) * (9-7+1) + 7;
// break;
//case 9:
// randomMaxHeight = ((double) rand() / (RAND_MAX+1)) * (10-9+1) + 9;
// break;
//case 10:
// randomMaxHeight = (float)(rand() % 10 );
// break;
//}
randomMaxHeight=0;
if ( (w >= 5 && w <=10) && (l >= 5 && l <= 10))
randomMaxHeight=l;
if (l < length)
//randomMaxHeight = info->imageData[(l * width ) + w] / 255.0f;
//printf("ind %i" ,(l * width ) + w);

tmp.x = w;
tmp.y = randomMaxHeight ;
tmp.z = l;
vertexes.push_back(tmp);
tmpTexCoord.u = (w ) ;
tmpTexCoord.v = (l ) ;
textCoords.push_back(tmpTexCoord);
//tmp.normalize();
//normals.push_back(tmp);
if (w==0 && l==0){
tmp.x = 237/255;
tmp.y = 28/255;
tmp.z = 36/255;
vertColor.push_back(tmp);
}else{
tmp.x =1.0f;
tmp.y =1.0f;
tmp.z = 1.0f;
vertColor.push_back(tmp);
}
////GET NOTMAL
//VECTOR sum(0.0f, 0.0f, 0.0f);
//VECTOR out;
//if (l > 0) {
// out = VECTOR(0.0f, randomMaxHeight, -1.0f);
//}
//VECTOR in;
//if (l < lenght - 1) {
// in = VECTOR(0.0f, randomMaxHeight, 1.0f);
//}
//VECTOR left;
//if (w > 0) {
// left = VECTOR(-1.0f, randomMaxHeight, 0.0f);
//}
//VECTOR right;
//if (w < width - 1) {
// right = VECTOR(1.0f, randomMaxHeight, 0.0f);
//}
//if (w > 0 && l > 0) {
// sum += out.cross(left).normalize();
//}
//if (w > 0 && l < lenght - 1) {
// sum += left.cross(in).normalize();
//}
//if (w < width - 1 && l < lenght - 1) {
// sum += in.cross(right).normalize();
//}
//if (w < width - 1 && l > 0) {
// sum += right.cross(out).normalize();
//}
//normals.push_back(sum);
//==========================
if(w < width & l <length){//length
if (vertexIndexes.size() <= (width * length)*6 ){
iP1 = vIndex;
iP2 = (vIndex) + width + 1;
iP3 = (vIndex) + 1;
vertexIndexes.push_back( iP1 );
vertexIndexes.push_back( iP2 );
vertexIndexes.push_back( iP3 );
//printf("index pint 2 %i %i %i \n",iP1,iP2,iP3);
// p1 --- p3
// | /
// p2
iP4 = vIndex + 1;
iP5 = (vIndex) + width + 1;
iP6 = (vIndex) + (width) + 2;

vertexIndexes.push_back( iP4 );
vertexIndexes.push_back( iP5 );
vertexIndexes.push_back( iP6 );
//printf("index pint 3 %i %i %i \n",iP4,iP5,iP6);
// p4
// / |
// p5 --- p6

}
}
vIndex++;
}
}


and this is how i compute my normals

for (int iN = 0 ; iN < vertexIndexes.size();iN+=6){
int iP1 = iN, iP2 = iN + 1, iP3 = iN + 2;
int iP4 = iN + 3, iP5 = iN + 4, iP6 = iN + 5;
VECTOR _v,v1,v2,v3,v4,v5,v6;
VECTOR n1,n2,n3,n4,n5,n6,normal;

iP1 = vertexIndexes[iP1];
iP2 = vertexIndexes[iP2];
iP3 = vertexIndexes[iP3];
iP4 = vertexIndexes[iP4];
iP5 = vertexIndexes[iP5];
iP6 = vertexIndexes[iP6];
v1 = vertexes[ iP1 ];
v2 = vertexes[ iP2 ];
v3 = vertexes[ iP3 ];
n1 = v1 - v3;
n2 = v2 - v3;
n3.cross(n1,n2);
centric.push_back( ( v1 + v2 + v3 ) / 3 ) ;
v4 = vertexes[ iP4 ];
v5 = vertexes[ iP5 ];
v6 = vertexes[ iP6 ];
n4 = v4 - v6;
n5 = v5 - v6;
n6.cross(n1,n2);
centric.push_back( ( v4 + v5 + v6 ) / 3 );
normals.push_back(n3.normalize());
normals.push_back(n6.normalize());
////printf("index pint 1 %i %i %i \n",iP1,iP2,iP3);
////printf("index pint 2 %i %i %i \n",iP4,iP5,iP6);
////===========================
//// GET NOTMALS
//// step #1 : to form square use eliminate p4 and p5 because it is equal to p2 and p3
//// p1 ----- p3
//// | / |
//// p2 ----- p6
//// step #2 form a Vecto3 Vecto1 Vecto3 from Vector inside vertexes Index point p1 p2 p3 p6
//// Vecto1 == vertexes[ p2 ] - vertexes[ p1 ]
//// Vecto2 == vertexes[ p6 ] - vertexes[ p1 ]
//// Vecto3 == vertexes[ p6 ] - vertexes[ p1 ]
////===========================
////_v = vertexes[ vertexIndexes[iN]];
////
////if ( ( _v.x > 0 && _v.x < width ) && ( _v.z > 0 && _v.z < length )){
//// int _i1,_i2,_i3,_i4,_i5,_i6;
//// // i6----i5
//// // / | |
//// // i1-----iN-----i4
//// // | | /
//// // i2 i3
//// _i1 = iN - 6;
//// _i2 = _i1 + 1;
//// _i3 = _i1 + 5;
//// _i6 = iN - (width * 6);
//// _i4 = _i6 + 5;
//// _i5 = _i6 + 2;
////
//// iP1 = vertexIndexes[_i1];
//// iP2 = vertexIndexes[_i2];
//// iP3 = vertexIndexes[_i3];
//// iP4 = vertexIndexes[_i4];
//// iP5 = vertexIndexes[_i5];
//// iP6 = vertexIndexes[_i6];
//// v1 = vertexes [ iP1 ] - vertexes[vertexIndexes[iN]];
//// v2 = vertexes [ iP2 ] - vertexes[vertexIndexes[iN]];
//// v3 = vertexes [ iP3 ] - vertexes[vertexIndexes[iN]];
//// v4 = vertexes [ iP4 ] - vertexes[vertexIndexes[iN]];
//// v5 = vertexes [ iP5 ] - vertexes[vertexIndexes[iN]];
//// v6 = vertexes [ iP6 ] - vertexes[vertexIndexes[iN]];
//// n1.cross(v1,v2);n2.cross(v2,v3);n3.cross(v3,v4);
//// n4.cross(v4,v5);n5.cross(v5,v6);n6.cross(v6,v1);
//// normal = (n1 + n2 + n3 + n4 + n5 + n6) / 6.0f;
//// normals.push_back(normal.normalize());
//// //printf("(i1)=%i (vi)%i (xz)%f %f\n",_i1,vertexIndexes[_i1],v1.x,v1.z);//vertexes[vertexIndexes[_i1]].x,vertexes[vertexIndexes[_i1]].z);
//// //printf("(i2)=%i (vi)%i (xz)%f %f\n",_i2,vertexIndexes[_i2],v2.x,v2.z);//,vertexes[vertexIndexes[_i2]].x,vertexes[vertexIndexes[_i2]].z);
//// //printf("(i3)=%i (vi)%i (xz)%f %f\n",_i3,vertexIndexes[_i3],v3.x,v3.z);//,vertexes [vertexIndexes[_i3]].x,vertexes[vertexIndexes[_i3]].z);
//// //printf("(i4)=%i (vi)%i (xz)%f %f\n",_i4,vertexIndexes[_i4],v4.x,v4.z);//vertexes[vertexIndexes[_i4]].x,vertexes[vertexIndexes[_i4]].z);
//// //printf("(i5)=%i (vi)%i (xz)%f %f\n",_i5,vertexIndexes[_i5],v5.x,v5.z);//vertexes[vertexIndexes[_i5]].x,vertexes[vertexIndexes[_i5]].z);
//// //printf("(i6)=%i (vi)%i (xz)%f %f\n",_i6,vertexIndexes[_i6],v6.x,v6.z);//vertexes[vertexIndexes[_i6]].x,vertexes[vertexIndexes[_i6]].z);
////}
////

}


// to Render the world

void WorldEngine::drawWorldFromPlain(){
glMatrixMode(GL_MODELVIEW);
glTranslatef(0.0f, 0.0f, 0.0f);
glBindTexture(GL_TEXTURE_2D, texID[0]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

GLfloat ambientColor[] = {0.4f, 0.4f, 0.4f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);

GLfloat lightColor0[] = {0.6f, 0.6f, 0.6f, 1.0f};
GLfloat lightPos0[] = {25, 0.0, 50.0f, 0.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);

float no_mat[] = {0.0f, 0.0f, 0.0f, 1.0f};
float mat_ambient[] = {0.7f, 0.7f, 0.7f, 1.0f};
float mat_ambient_color[] = {0.8f, 0.8f, 0.2f, 1.0f};
float mat_diffuse[] = {0.1f, 0.5f, 0.8f, 1.0f};
float mat_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
float no_shininess = 0.0f;
float low_shininess = 5.0f;
float high_shininess = 100.0f;
float mat_emission[] = {0.3f, 0.2f, 0.2f, 0.0f};
glTranslatef(0.0f, 10, -50.0f);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_color);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialf(GL_FRONT, GL_SHININESS, high_shininess);
glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);
//==========
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);

glNormalPointer(GL_FLOAT,sizeof(VECTOR),&normals[0].x);
glTexCoordPointer (2,GL_FLOAT,sizeof(TEXCOORD),&textCoords[0].u);
glColorPointer(3,GL_FLOAT,0,&vertColor[0].x);
glVertexPointer(3,GL_FLOAT,0,&vertexes[0].x);
glDrawElements(GL_TRIANGLES, vertexIndexes.size() ,GL_UNSIGNED_INT, &vertexIndexes[0] );//TriangleArray[0].Vertex[0]);//&vecIndexes[0]);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
// show normal
glBegin(GL_LINES);
glTranslated(0.0f,0.0f,0.0f);
glLoadIdentity();
for (int i = 0 ; i < normals.size(); i++){
glColor3f(0.0f,0.0f,0.0f);
VECTOR vect,vect2;
vect = centric; //center or the Triangle
vect2 = vect + normals; //add normals centric or the Triangle to show the face direction
glVertex3f (vect2.x,vect2.y,vect2.z );
glVertex3f (vect.x,vect.y,vect.z );
}
glEnd();
}


direction of normal + center of each tri is correct but i got broken lighting
can you help me

thanks

This topic is closed to new replies.

Advertisement