View more

View more

View more

### Image of the Day Submit

IOTD | Top Screenshots

### The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

# Lesson 28 Triangle Normal

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

2 replies to this topic

### #1maledivius  Members

Posted 23 December 2010 - 04:10 PM

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]

### #2Caste  Members

Posted 28 December 2010 - 10:12 PM

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 :)

### #3maledivius  Members

Posted 12 January 2011 - 05:37 AM

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

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];


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

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]);
}


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

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.