This procedure implements the bunny using vertex arrays,anti-aliasing,three lights sources,Phong shading and a normalized Blinn-Phong shader.
Step 1.
load OBJ file into vertex arrays
void loadObj(char* filename)
{
char buf[128];
char lineHeader[128];
int temp=0;
int vcount=3,ncount=3,fcount=0;
file=fopen(filename,"r");
if(file==NULL)
printf("file error\n");
while(fscanf(file,"%s",buf)!=EOF)
{
switch(buf[0])
{
case '#':
fgets(buf,sizeof(buf),file);
break;
case 'v':
switch(buf[1])
{
case '\0':
numvertexs++;
fscanf(file,"%*[^\n]");
break;
case 'n':
numnormals++;
fscanf(file,"%*[^\n]");
break;
default:
printf("_glmFirstPass(): Unknown token \"%s\".\n", buf);
exit(1);
break;
}
break;
case 'f':
numfaces++;
fscanf(file,"%*[^\n]");
break;
}
}
points=(GLdouble*)malloc((numvertexs+1)*3*sizeof(GLdouble));
faces=((GLuint*)malloc((numfaces)*3*sizeof(GLuint)));
normals = (GLdouble* )malloc((numnormals+1)*3*sizeof(GLdouble));
rewind(file);
while(fscanf(file,"%s",lineHeader)!=EOF)
{
if(strcmp(lineHeader,"v")==0)
{
fscanf(file, "%lf %lf %lf",&points[vcount],&points[vcount+1],&points[vcount+2]);
vcount=vcount+3;
}
else if(strcmp(lineHeader,"vn")==0)
{
fscanf(file, "%lf %lf %lf",&normals[ncount],&normals[ncount+1],&normals[ncount+2]);
ncount=ncount+3;
}
else if (strcmp(lineHeader,"f")==0)
{
fscanf(file, "%d//%d %d//%d %d//%d",&faces[fcount],&temp,&faces[fcount+1],&temp,&faces[fcount+2],&temp);
fcount=fcount+3;
}
}
fclose(file);
vertices=(GLdouble*)malloc(numfaces*18*sizeof(GLdouble));
int i=0,index=0;
for(i=0;i<numfaces;i++)
{
vertices[18*i+0]=points[3*(faces[3*i+0])+0];
vertices[18*i+1]=points[3*(faces[3*i+0])+1];
vertices[18*i+2]=points[3*(faces[3*i+0])+2];
vertices[18*i+3]=normals[3*(faces[3*i+0])+0];
vertices[18*i+4]=normals[3*(faces[3*i+0])+1];
vertices[18*i+5]=normals[3*(faces[3*i+0])+2];
vertices[18*i+6]=points[3*(faces[3*i+1])+0];
vertices[18*i+7]=points[3*(faces[3*i+1])+1];
vertices[18*i+8]=points[3*(faces[3*i+1])+2];
vertices[18*i+9]=normals[3*(faces[3*i+1])+0];
vertices[18*i+10]=normals[3*(faces[3*i+1])+1];
vertices[18*i+11]=normals[3*(faces[3*i+1])+2];
vertices[18*i+12]=points[3*(faces[3*i+2])+0];
vertices[18*i+13]=points[3*(faces[3*i+2])+1];
vertices[18*i+14]=points[3*(faces[3*i+2])+2];
vertices[18*i+15]=normals[3*(faces[3*i+2])+0];
vertices[18*i+16]=normals[3*(faces[3*i+2])+1];
vertices[18*i+17]=normals[3*(faces[3*i+2])+2];
}
}
Step 2:
Anti-aliasing using Jitter View(My understanding:jitter the viewpoint, blur the jagger)
void jitter_view()
{
vertex jeye,jview,jup,vdir,utemp,vtemp;
jeye.x=-0.5;jeye.y=4.5;jeye.z=6.0;
jview.x=JITTER*genrand()-0.5;
jview.y=JITTER*genrand()+0.5;
jview.z=JITTER*genrand();
jup.x=0.0;jup.y=1.0;jup.z=0.0;
vdir.x=jview.x-jeye.x;
vdir.y=jview.y-jeye.y;
vdir.z=jview.z-jeye.z;
vtemp=cross(vdir,jup);
utemp=cross(vtemp,vdir);
jup=unit_length(utemp);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(jeye.x,jeye.y,jeye.z,jview.x,jview.y,jview.z,jup.x,jup.y,jup.z);
}
Step 3.
Three light source,one in the front(key), one in the lateral(fill), one in the back(back),then calculate the lights property and using Phong shading and a normalized Blinn-Phong shader.
//key light
light0_diffuse ={1.0,1.0,1.0, 0.0};
light0_specular= {0.35, 0.35, 0.35, 0.0}; light0_position = {-5.0, 5.0, 8.0, 1.0};
//fill light
light1_diffuse= {0.3,0.5,0.5, 0.0};
light1_specular = {0.1, 0.1, 0.1, 0.0};
light1_position= {5.0, 8.0, 5.0, 1.0};
//back light
light2_diffuse = {1.0,1.0,1.0, 0.0};
light2_specular = {0.4, 0.4, 0.4, 0.0};
light2_position = {8.0, 12.0, -11.0, 1.0};
P = ec_vposition;
N = normalize(ec_vnormal);
V = normalize(-P);
L = normalize(light0_position - P);
H = normalize(L+V);
light0_specular*=specular_color*pow(max(dot(H,N),0.0),shininess)*(shininess+2)/8/3.1415;
light0_diffuse *=diffuse_color*max(dot(N,L),0.0);
vec4 light0_color=light0_specular+light0_diffuse;
L = normalize(light1_position- P);
H = normalize(L+V);
light1_specular*=specular_color*pow(max(dot(H,N),0.0),shininess)*(shininess+2)/8/3.1415;
light1_diffuse *=diffuse_color*max(dot(N,L),0.0);
vec4 light1_color=light1_specular+light1_diffuse;
L = normalize(light2_position - P);
H = normalize(L+V);
light2_specular*=specular_color*pow(max(dot(H,N),0.0),shininess)*(shininess+2)/8/3.1415;
light2_diffuse *=diffuse_color*max(dot(N,L),0.0);
vec4 light2_color=light2_specular+light2_diffuse;
gl_FragColor = light0_color+light1_color + light2_color;
My Bunny :