Jump to content

  • Log In with Google      Sign In   
  • Create Account

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.

  • You cannot reply to this topic
2 replies to this topic

#1 maledivius   Members   -  Reputation: 100

Like
0Likes
Like

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 divisions
GLuint 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<=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<=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<=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<=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]

Sponsor:

#2 Caste   Moderators   -  Reputation: 969

Like
0Likes
Like

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

#3 maledivius   Members   -  Reputation: 100

Like
0Likes
Like

Posted 12 January 2011 - 05:37 AM

Thanks for your reply!

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.



PARTNERS