PDA

View Full Version : Problem with normals of inclined quads



c0de
12-09-2009, 04:31 AM
I have a problem in setting the correct normals for a QUAD surface of an object. The object is this:
http://rrg.utcluj.ro/~c0de/img/fl3.jpg
The object contains 2 side parts formed by half cylinders (cut with glClipPlane) and a middle part formed by quads. The problem is that I dont know how to set the normals for the inclined quads from the middle part in order to look like a continuous inclined surface (together with the inclined part of the cylinders). These are the functions I used to generate the object:


GLuint GLWidget::makeLink1(GLuint listid)
{
static GLUquadricObj *disk, *cylinder;
GLdouble eqn1[4] = {-1.0, 0.0, 0.0, 0.0};
GLdouble eqn2[4] = {1.0, 0.0, 0.0, 0.0}; //ax+by+cz+d=0
GLuint list = glGenLists(listid);
glNewList(list, GL_COMPILE_AND_EXECUTE);
disk = gluNewQuadric();
gluQuadricNormals(disk,GL_SMOOTH);
cylinder = gluNewQuadric();
gluQuadricNormals(cylinder,GL_SMOOTH);
gluQuadricOrientation(cylinder,GLU_OUTSIDE);
glPushMatrix();
setMaterial(SILVER);
glPushMatrix(); //round half cylinder
glClipPlane(GL_CLIP_PLANE0, eqn2);
glEnable(GL_CLIP_PLANE0);
glRotatef(-90.0, 1.0, 0.0, 0.0);
gluCylinder(cylinder,160,140,70,256,256);
gluQuadricOrientation(disk,GLU_INSIDE);
gluDisk(disk,0,160,256,256);
glTranslatef(0,0,70);
gluQuadricOrientation(disk,GLU_OUTSIDE);
gluDisk(disk,0,140,256,256);
glDisable(GL_CLIP_PLANE0);
glPopMatrix();
glPushMatrix(); //...
glRotatef(-90.0, 1.0, 0.0, 0.0);
quadXY(-200,-160,0,160,0,0,0,-1);
glPopMatrix();
glPushMatrix(); //round half cylinder
glTranslatef(-200,0,0);
glClipPlane(GL_CLIP_PLANE0, eqn1);
glEnable(GL_CLIP_PLANE0);
glRotatef(-90.0, 1.0, 0.0, 0.0);
gluCylinder(cylinder,160,140,70,256,256);
gluQuadricOrientation(disk,GLU_INSIDE);
gluDisk(disk,0,160,256,256);
glTranslatef(0,0,70);
gluQuadricOrientation(disk,GLU_OUTSIDE);
gluDisk(disk,0,140,256,256);
glDisable(GL_CLIP_PLANE0);
glPopMatrix();
glPushMatrix(); //...
glRotatef(-90.0, 1.0, 0.0, 0.0);
glTranslatef(0,0,70);
quadXY(-200,-140,0,140,0,0,0,1);
glPopMatrix();
glPushMatrix(); //...
glRotatef(-90.0, 1.0, 0.0, 0.0);
quadXYZ(-200,140,0,160,0,70);
quadXYZ(-200,-140,0,-160,0,70);
glPopMatrix();
glPopMatrix();
glEndList();
return list;
}


where:


void GLWidget::quadXY(GLfloat xmin, GLfloat ymin, GLfloat xmax, GLfloat ymax, GLfloat Z, GLfloat nx, GLfloat ny, GLfloat nz)
{
GLfloat i,j;
glBegin(GL_QUADS);
glNormal3f( nx, ny, nz );
for (i = xmin; i< xmax; i +=(xmax-xmin)/128)
{
for (j = ymin; j<ymax; j += (ymax-ymin)/128)
{
glVertex3f( i, j,Z);
glVertex3f( i, j+((ymax-ymin)/128),Z);
glVertex3f( i+((xmax-xmin)/128), j+((ymax-ymin)/128),Z);
glVertex3f( i+((xmax-xmin)/128), j,Z);

}

}
glEnd();
}

void GLWidget::quadXYZ(GLfloat xmin, GLfloat ymin, GLfloat xmax, GLfloat ymax, GLfloat zmin, GLfloat zmax)
{
GLfloat i;
int slices = 40;
glBegin(GL_QUADS);
glNormal3f( 0, ymax, zmax );
for (i = xmin; i< xmax; i +=(xmax-xmin)/slices)
{
glVertex3f( i, ymin,zmax);
glVertex3f( i, ymax,zmin);
glVertex3f( i+((xmax-xmin)/slices), ymax, zmin);
glVertex3f( i+((xmax-xmin)/slices), ymin ,zmax);
}
glEnd();
}


The inclined quads are generated with quadXYZ function. Also, in order to have a proper lighting on the plane surfaces I generate quads with quadXY (bigquad = (nxn) smallquads).
Function "setMaterial" sets the a material using glMaterialfv.
I use 2 directional lights in this view:
LIGHT0 and LIGHT1:
ambient: { 0.0, 0.0, 0.0, 1.0 }
diffuse: { 0.6, 0.6, 0.6, 1.0 }
specular: { 0.5, 0.5, 0.5, 1.0 }

position:
{ 1500.0, -1500.0, 1500.0, 0.0 } // for light0
{ -1500.0, -1500.0, 1500.0, 0.0 } // for light1

I really dont know how to set those normals correctly. On plane surfaces everything is ok... 2 half circles and a quad between look like a single surface (which is what I want). On inclined plane it looks like different surfaces and in picture.

P.S: 1. "glEnable(GL_NORMALIZE)" doesn't solve my problem.
2. Red axis is X axis, white (actually blue) is Y axis and yellow axis is Z axis.

Thanks in advance and sorry for my poor english.