Выбрать главу

 glRotatef(-xrot,1.0f,0.0f,0.0f);

 glTranslatef(0.0f,0.0f,-z);

 glGetFloatv(GL_MODELVIEW_MATRIX,Minv);

 glLoadIdentity();

 glTranslatef(0.0f,0.0f,z);

 glRotatef(xrot,1.0f,0.0f,0.0f);

 glRotatef(yrot,0.0f,1.0f,0.0f);

 // Transform The Lightposition Into Object Coordinates:

 l[0]=LightPosition[0];

 l[1]=LightPosition[1];

 l[2]=LightPosition[2];

 l[3]=1.0f; // Homogenous Coordinate

 VMatMult(Minv,l);

First Pass:

• Use bump-texture

• Disable Blending

• Disable Lighting

• Use non-offset texture-coordinates

• Do the geometry

This will render a cube only consisting out of bump map.

 glBindTexture(GL_TEXTURE_2D, bump[filter]);

 glDisable(GL_BLEND);

 glDisable(GL_LIGHTING);

 doCube();

Second Pass:

• Use inverted bump-texture

• Enable Blending GL_ONE, GL_ONE

• Keep Lighting disabled

• Use offset texture-coordinates (This means that you call SetUpBumps() before each face of the cube

• Do the geometry

This will render a cube with the correct emboss bump mapping, but without colors.

You could save computing time by just rotating the lightvector into inverted direction. However, this didn't work out correctly, so we do it the plain way: rotate each normal and center-point the same way we rotate our geometry!

 glBindTexture(GL_TEXTURE_2D, invbump[filter]);

 glBlendFunc(GL_ONE,GL_ONE);

 glDepthFunc(GL_LEQUAL);

 glEnable(GL_BLEND);

 glBegin(GL_QUADS);

  // Front Face

  n[0]=0.0f;

  n[1]=0.0f;

  n[2]=1.0f;

  s[0]=1.0f;

  s[1]=0.0f;

  s[2]=0.0f;

  t[0]=0.0f;

  t[1]=1.0f;

  t[2]=0.0f;

  for (i=0; i<4; i++) {

   c[0]=data[5*i+2];

   c[1]=data[5*i+3];

   c[2]=data[5*i+4];

   SetUpBumps(n,c,l,s,t);

   glTexCoord2f(data[5*i]+c[0], data[5*i+1]+c[1]);

   glVertex3f(data[5*i+2], data[5*i+3], data[5*i+4]);

  }

  // Back Face

  n[0]=0.0f;

  n[1]=0.0f;

  n[2]=-1.0f;

  s[0]=-1.0f;

  s[1]=0.0f;

  s[2]=0.0f;

  t[0]=0.0f;

  t[1]=1.0f;

  t[2]=0.0f;

  for (i=4; i<8; i++) {

   c[0]=data[5*i+2];

   c[1]=data[5*i+3];

   c[2]=data[5*i+4];

   SetUpBumps(n,c,l,s,t);

   glTexCoord2f(data[5*i]+c[0], data[5*i+1]+c[1]);

   glVertex3f(data[5*i+2], data[5*i+3], data[5*i+4]);

  }

  // Top Face

  n[0]=0.0f;

  n[1]=1.0f;

  n[2]=0.0f;

  s[0]=1.0f;

  s[1]=0.0f;

  s[2]=0.0f;

  t[0]=0.0f;

  t[1]=0.0f;

  t[2]=-1.0f;

  for (i=8; i<12; i++) {

   c[0]=data[5*i+2];

   c[1]=data[5*i+3];

   c[2]=data[5*i+4];

   SetUpBumps(n,c,l,s,t);

   glTexCoord2f(data[5*i]+c[0], data[5*i+1]+c[1]);

   glVertex3f(data[5*i+2], data[5*i+3], data[5*i+4]);

  }

  // Bottom Face

  n[0]=0.0f;

  n[1]=-1.0f;

  n[2]=0.0f;

  s[0]=-1.0f;

  s[1]=0.0f;

  s[2]=0.0f;

  t[0]=0.0f;

  t[1]=0.0f;

  t[2]=-1.0f;

  for (i=12; i<16; i++) {

   c[0]=data[5*i+2];

   c[1]=data[5*i+3];

   c[2]=data[5*i+4];

   SetUpBumps(n,c,l,s,t);

   glTexCoord2f(data[5*i]+c[0], data[5*i+1]+c[1]);

   glVertex3f(data[5*i+2], data[5*i+3], data[5*i+4]);

  }

  // Right Face

  n[0]=1.0f;

  n[1]=0.0f;

  n[2]=0.0f;

  s[0]=0.0f;

  s[1]=0.0f;

  s[2]=-1.0f;

  t[0]=0.0f;

  t[1]=1.0f;

  t[2]=0.0f;

  for (i=16; i<20; i++) {

   c[0]=data[5*i+2];

   c[1]=data[5*i+3];

   c[2]=data[5*i+4];

   SetUpBumps(n,c,l,s,t);

   glTexCoord2f(data[5*i]+c[0], data[5*i+1]+c[1]);

   glVertex3f(data[5*i+2], data[5*i+3], data[5*i+4]);

  }

  // Left Face

  n[0]=-1.0f;

  n[1]=0.0f;

  n[2]=0.0f;

  s[0]=0.0f;

  s[1]=0.0f;

  s[2]=1.0f;

  t[0]=0.0f;

  t[1]=1.0f;

  t[2]=0.0f;

  for (i=20; i<24; i++) {

   c[0]=data[5*i+2];

   c[1]=data[5*i+3];

   c[2]=data[5*i+4];

   SetUpBumps(n,c,l,s,t);

   glTexCoord2f(data[5*i]+c[0], data[5*i+1]+c[1]);

   glVertex3f(data[5*i+2], data[5*i+3], data[5*i+4]);

  }

 glEnd();

Third Pass:

• Use (colored) base-texture

• Enable Blending GL_DST_COLOR, GL_SRC_COLOR

• This blending equation multiplies by 2: (Cdst*Csrc)+(Csrc*Cdst)=2(Csrc*Cdst)!

• Enable Lighting to do the ambient and diffuse stuff

• Reset GL_TEXTURE-matrix to go back to "normal" texture coordinates

• Do the geometry

This will finish cube-rendering, complete with lighting. Since we can switch back and forth between multitexturing and non-multitexturing, we have to reset the texture-environment to "normal" GL_MODULATE first. We only do the third pass, if the user doesn't want to see just the emboss.

 if (!emboss) {

  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

  glBindTexture(GL_TEXTURE_2D,texture[filter]);

  glBlendFunc(GL_DST_COLOR,GL_SRC_COLOR);

  glEnable(GL_LIGHTING);

  doCube();

 }

Last Pass:

• update geometry (esp. rotations)

• do the Logos

 xrot+=xspeed;

 yrot+=yspeed;

 if (xrot>360.0f) xrot-=360.0f;

 if (xrot<0.0f) xrot+=360.0f;

 if (yrot>360.0f) yrot-=360.0f;

 if (yrot<0.0f) yrot+=360.0f;

 /* LAST PASS: Do The Logos! */