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

 doLogo();

 return true; // Keep Going

}

This function will do the whole mess in 2 passes with multitexturing support. We support two texel-units. More would be extreme complicated due to the blending equations. Better trim to TNT instead. Note that almost the only difference to doMesh1TexelUnits() is, that we send two sets of texture-coordinates for each vertex!

bool doMesh2TexelUnits(void) {

 GLfloat c[4]={0.0f,0.0f,0.0f,1.0f}; // Holds Current Vertex

 GLfloat n[4]={0.0f,0.0f,0.0f,1.0f}; // Normalized Normal Of Current Surface

 GLfloat s[4]={0.0f,0.0f,0.0f,1.0f}; // s-Texture Coordinate Direction, Normalized

 GLfloat t[4]={0.0f,0.0f,0.0f,1.0f}; // t-Texture Coordinate Direction, Normalized

 GLfloat l[4]; // Holds Our Lightposition To Be Transformed Into Object Space

 GLfloat Minv[16]; // Holds The Inverted Modelview Matrix To Do So

 int i;

 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer

 // Build Inverse Modelview Matrix First. This Substitutes One Push/Pop With One glLoadIdentity();

 // Simply Build It By Doing All Transformations Negated And In Reverse Order

 glLoadIdentity();

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

 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:

• No Blending

• No Lighting

Set up the texture-combiner 0 to

• Use bump-texture

• Use not-offset texture-coordinates

• Texture-Operation GL_REPLACE, resulting in texture just being drawn

Set up the texture-combiner 1 to

• Offset texture-coordinates

• Texture-Operation GL_ADD, which is the multitexture-equivalent to ONE, ONE– blending.

This will render a cube consisting out of the grey-scale erode map.

 // TEXTURE-UNIT #0

 glActiveTextureARB(GL_TEXTURE0_ARB);

 glEnable(GL_TEXTURE_2D);

 glBindTexture(GL_TEXTURE_2D, bump[filter]);

 glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);

 glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);

 // TEXTURE-UNIT #1

 glActiveTextureARB(GL_TEXTURE1_ARB);

 glEnable(GL_TEXTURE_2D);

 glBindTexture(GL_TEXTURE_2D, invbump[filter]);

 glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);

 glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);

 // General Switches

 glDisable(GL_BLEND);

 glDisable(GL_LIGHTING);

Now just render the faces one by one, as already seen in doMesh1TexelUnits(). Only new thing: Uses glMultiTexCoor2fARB() instead of just glTexCoord2f(). Note that you must specify which texture-unit you mean by the first parameter, which must be GL_TEXTUREi_ARB with i in [0..31]. (What hardware has 32 texture-units? And what for?)

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

   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, data[5*i], data[5*i+1]);

   glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 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);

   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, data[5*i], data[5*i+1]);

   glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 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);

   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, data[5*i], data[5*i+1]);

   glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 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);

   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, data[5*i], data[5*i+1]);

   glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 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);