# Lesson 28 Triangle Normal

This topic is 2564 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I want to calculate normals but i don't know how to get points from this function.

// Generates a display list based on the data in the patch// and the number of divisionsGLuint genBezier(BEZIER_PATCH patch, int divs) {	int			u = 0, v;	float		py, px, pyold; 	GLuint		drawlist = glGenLists(1);			POINT_3D	temp[4];	POINT_3D	*last = (POINT_3D*)malloc(sizeof(POINT_3D)*(divs+1));												// array of points to mark the first line of polys	if (patch.dlBPatch != 0)							glDeleteLists(patch.dlBPatch, 1);	temp[0] = patch.anchors[0][3];					temp[1] = patch.anchors[1][3];	temp[2] = patch.anchors[2][3];	temp[3] = patch.anchors[3][3];	for (v=0;v&lt;=divs;v++) {								px = ((float)v)/((float)divs);					last[v] = Bernstein(px, temp);	}	glNewList(drawlist, GL_COMPILE);					glBindTexture(GL_TEXTURE_2D, patch.texture);		for (u=1;u&lt;=divs;u++) {		py	  = ((float)u)/((float)divs);					pyold = ((float)u-1.0f)/((float)divs);				temp[0] = Bernstein(py, patch.anchors[0]);			temp[1] = Bernstein(py, patch.anchors[1]);		temp[2] = Bernstein(py, patch.anchors[2]);		temp[3] = Bernstein(py, patch.anchors[3]);		glBegin(GL_TRIANGLE_STRIP);							for (v=0;v&lt;=divs;v++) {			px = ((float)v)/((float)divs);						glTexCoord2f(pyold, px);							glVertex3d(last[v].x, last[v].y, last[v].z);				last[v] = Bernstein(px, temp);						glTexCoord2f(py, px);								glVertex3d(last[v].x, last[v].y, last[v].z);			}		glEnd();										}		glEndList();									free(last);										return drawlist;							}

The "last" array keeps the previous line of points

for (v=0;v&lt;=divs;v++) {			px = ((float)v)/((float)divs);						glTexCoord2f(pyold, px);							glVertex3d(last[v].x, last[v].y, last[v].z);				last[v] = Bernstein(px, temp);						glTexCoord2f(py, px);								glVertex3d(last[v].x, last[v].y, last[v].z);

so i need to save last[0] and last[1] in some temporary points and then take last[0] from second loop (for v=1)?

EDIT: put code in [ source lang="cpp"] [ /source] tags (without the space after [).

[Edited by - Caste on December 29, 2010 4:05:20 AM]

##### Share on other sites
As you said yourself, the last array stores the recently used points.
You could fill this array (with Bernstein()) before adding the 3 vertices to your GL triangle strip. Then use the last 3 vertices (let's call them a,b,c) to compute the normal with the cross product: (a-b)x(a-c).

Nevertheless, this only gives you per-face normals. If you want a smoothly shaded surface, you need to average the normals of all faces adjacent to a single vertex. This only makes sense as a preprocessing step as it requires you to compute and iterate over all faces several times - or reordering them by sorting.

Hope that helps :)

##### Share on other sites

I did this by adding some arrays and vectors for calculs.

[code]
GLfloat ra[3][99]; //for old vertices
GLfloat rb[3][99]; // for new vertices
GLfloat rn[3][99]; //for normals

GLfloat vn1[3];
GLfloat vn2[3];

GLfloat out1[3];
[/code]

I also needed to change loop for triangle strip.
So now it looks like this:

[code]
for (v=0;v<=divs;v++) {
px = ((float)v)/((float)divs);

glVertex3d(last[v].x, last[v].y, last[v].z);
ra[0][v]=last[v].x;
ra[1][v]=last[v].y;
ra[2][v]=last[v].z;

last[v] = Bernstein(px, temp);
glVertex3d(last[v].x, last[v].y, last[v].z);
rb[0][v]=last[v].x;
rb[1][v]=last[v].y;
rb[2][v]=last[v].z;

}

for (v=0;v<=divs;v++) {
px = ((float)v)/((float)divs);

vn1[0]=ra[0][v+1]-ra[0][v];
vn1[1]=ra[1][v+1]-ra[1][v];
vn1[2]=ra[2][v+1]-ra[2][v];

vn2[0]=rb[0][v]-ra[0][v];
vn2[1]=rb[1][v]-ra[1][v];
vn2[2]=rb[2][v]-ra[2][v];

rn[0][v]=-vn1[1]*vn2[2] + vn1[2]*vn2[1];
rn[1][v]=-vn1[2]*vn2[0] + vn1[0]*vn2[2];
rn[2][v]=-vn1[0]*vn2[1] + vn1[1]*vn2[0];

}

glBegin(GL_TRIANGLE_STRIP);

for (v=0;v<=divs;v++) {
px = ((float)v)/((float)divs);
out1[0]=rn[0][v];
out1[1]=rn[1][v];
out1[2]=rn[2][v];
glTexCoord2f(pyold, px);
glNormal3fv(out1);
glVertex3d(ra[0][v], ra[1][v], ra[2][v]);

glTexCoord2f(py, px);

glVertex3d(rb[0][v], rb[1][v], rb[2][v]);
}
[/code]

I know these are only per-face normnals but when I increase div it's looking good for me.