OpenGL v Delphi4



Emboss Bumpmapping


Příklad a zdroják ke stažení (492k)


Nejdříve si musíme vytvořit dvě textury. První obyčejnou.



U druhé jsem invertoval barvy hodil do šedé stupnice a trochu zvýšil kontrast.



Jaký je princip?
Objekt se skládá ze tří čtverců, který jsou těsně za sebou. V prvním čtverci jsem nastavil základní texturu a vypnul světla.

  //base
  i := 1;                                                  //první čtverec
  glDisable(GL_LIGHTING);                                  //vypni světlo
  glBindTexture(GL_TEXTURE_2D, TextureBin[i]);             //načti základní texturu
  glEnable(GL_TEXTURE_2D);
  glBegin(GL_TRIANGLES);                                   //zobraz čtverec
    glTexCoord2f(Coord1[i].x,Coord1[i].y);
    glVertex3f(Point1[i].x,Point1[i].y,Point1[i].z);
    glTexCoord2f(Coord2[i].x,Coord2[i].y);
    glVertex3f(Point2[i].x,Point2[i].y,Point2[i].z);
    glTexCoord2f(Coord3[i].x,Coord3[i].y);
    glVertex3f(Point3[i].x,Point3[i].y,Point3[i].z);
    glTexCoord2f(Coord2[i].x,Coord2[i].y);
    glVertex3f(Point2[i].x,Point2[i].y,Point2[i].z);
    glTexCoord2f(Coord3[i].x,Coord3[i].y);
    glVertex3f(Point3[i].x,Point3[i].y,Point3[i].z);
    glTexCoord2f(Coord4[i].x,Coord4[i].y);
    glVertex3f(Point4[i].x,Point4[i].y,Point4[i].z);
  glEnd;

Druhý čtverec jsem vložil těsně před první. Textura je invertovaná černobílá. Zapnul jsem světla a průhlednost černé barvy.

  //invert
  i := 2;                                                //druhý čtverec
  glEnable(GL_LIGHTING);                                 //zapni světla
  glEnable(GL_BLEND);                                    //zapni průhlednost
  glBlendFunc(GL_ONE, GL_ONE);                           //průhledná černá barva
  glBindTexture(GL_TEXTURE_2D, TextureBin[i]);           //načti invertovanou černobílou texturu
  glEnable(GL_TEXTURE_2D);
  glBegin(GL_TRIANGLES);                                 //zobraz čtverec
    glTexCoord2f(Coord1[i].x,Coord1[i].y);
    glVertex3f(Point1[i].x,Point1[i].y,Point1[i].z);
    glTexCoord2f(Coord2[i].x,Coord2[i].y);
    glVertex3f(Point2[i].x,Point2[i].y,Point2[i].z);
    glTexCoord2f(Coord3[i].x,Coord3[i].y);
    glVertex3f(Point3[i].x,Point3[i].y,Point3[i].z);
    glTexCoord2f(Coord2[i].x,Coord2[i].y);
    glVertex3f(Point2[i].x,Point2[i].y,Point2[i].z);
    glTexCoord2f(Coord3[i].x,Coord3[i].y);
    glVertex3f(Point3[i].x,Point3[i].y,Point3[i].z);
    glTexCoord2f(Coord4[i].x,Coord4[i].y);
    glVertex3f(Point4[i].x,Point4[i].y,Point4[i].z);
  glEnd;

Třetí čtverec je těsně před druhým. Textura je základní. Nechal jsem zapnutý světla. Použil jsem funkci pro průhlednost ' glBlendFunc(GL_DST_COLOR,GL_SRC_COLOR); '. Tato funkce potřebuje masku průhlednosti. Jako maska průhlednosti nám složí invertovaná černobílá textura druhého čtverce. Kde je v masce černá, je na tom místě průhledná textura třetího čtverce, kde je v masce bílá, textura třetího čtverce je neprůhledná. Nakonec vypínám průhlednost a světla.

  //top
  i := 3;                                                //třetí čtverec
  glBlendFunc(GL_DST_COLOR,GL_SRC_COLOR);                //průhlednost jen tam kde je v masce černá barva
  glBindTexture(GL_TEXTURE_2D, TextureBin[i]);           //načti základní texturu
  glEnable(GL_TEXTURE_2D);
  glBegin(GL_TRIANGLES);                                 //zobraz čtverec
    glTexCoord2f(Coord1[i].x,Coord1[i].y);
    glVertex3f(Point1[i].x,Point1[i].y,Point1[i].z);
    glTexCoord2f(Coord2[i].x,Coord2[i].y);
    glVertex3f(Point2[i].x,Point2[i].y,Point2[i].z);
    glTexCoord2f(Coord3[i].x,Coord3[i].y);
    glVertex3f(Point3[i].x,Point3[i].y,Point3[i].z);
    glTexCoord2f(Coord2[i].x,Coord2[i].y);
    glVertex3f(Point2[i].x,Point2[i].y,Point2[i].z);
    glTexCoord2f(Coord3[i].x,Coord3[i].y);
    glVertex3f(Point3[i].x,Point3[i].y,Point3[i].z);
    glTexCoord2f(Coord4[i].x,Coord4[i].y);
    glVertex3f(Point4[i].x,Point4[i].y,Point4[i].z);
  glEnd;

  glDisable(GL_BLEND);                                   //vypni průhlednost
  glDisable(GL_LIGHTING);                                //vypni světla

Celá procedura vypadá takto:

procedure DrawBump;
var
  i: integer;
begin
  //base
  i := 1;
  glDisable(GL_LIGHTING);  
  glBindTexture(GL_TEXTURE_2D, TextureBin[i]);
  glEnable(GL_TEXTURE_2D);
  glBegin(GL_TRIANGLES);
    glTexCoord2f(Coord1[i].x,Coord1[i].y);
    glVertex3f(Point1[i].x,Point1[i].y,Point1[i].z);
    glTexCoord2f(Coord2[i].x,Coord2[i].y);
    glVertex3f(Point2[i].x,Point2[i].y,Point2[i].z);
    glTexCoord2f(Coord3[i].x,Coord3[i].y);
    glVertex3f(Point3[i].x,Point3[i].y,Point3[i].z);
    glTexCoord2f(Coord2[i].x,Coord2[i].y);
    glVertex3f(Point2[i].x,Point2[i].y,Point2[i].z);
    glTexCoord2f(Coord3[i].x,Coord3[i].y);
    glVertex3f(Point3[i].x,Point3[i].y,Point3[i].z);
    glTexCoord2f(Coord4[i].x,Coord4[i].y);
    glVertex3f(Point4[i].x,Point4[i].y,Point4[i].z);
  glEnd;

  //invert
  i := 2;
  glEnable(GL_LIGHTING);
  glEnable(GL_BLEND);
  glBlendFunc(GL_ONE, GL_ONE);
  glBindTexture(GL_TEXTURE_2D, TextureBin[i]);
  glEnable(GL_TEXTURE_2D);
  glBegin(GL_TRIANGLES);
    glTexCoord2f(Coord1[i].x,Coord1[i].y);
    glVertex3f(Point1[i].x,Point1[i].y,Point1[i].z);
    glTexCoord2f(Coord2[i].x,Coord2[i].y);
    glVertex3f(Point2[i].x,Point2[i].y,Point2[i].z);
    glTexCoord2f(Coord3[i].x,Coord3[i].y);
    glVertex3f(Point3[i].x,Point3[i].y,Point3[i].z);
    glTexCoord2f(Coord2[i].x,Coord2[i].y);
    glVertex3f(Point2[i].x,Point2[i].y,Point2[i].z);
    glTexCoord2f(Coord3[i].x,Coord3[i].y);
    glVertex3f(Point3[i].x,Point3[i].y,Point3[i].z);
    glTexCoord2f(Coord4[i].x,Coord4[i].y);
    glVertex3f(Point4[i].x,Point4[i].y,Point4[i].z);
  glEnd;

  //top
  i := 3;
  glBlendFunc(GL_DST_COLOR,GL_SRC_COLOR);
  glBindTexture(GL_TEXTURE_2D, TextureBin[i]);
  glEnable(GL_TEXTURE_2D);
  glBegin(GL_TRIANGLES);
    glTexCoord2f(Coord1[i].x,Coord1[i].y);
    glVertex3f(Point1[i].x,Point1[i].y,Point1[i].z);
    glTexCoord2f(Coord2[i].x,Coord2[i].y);
    glVertex3f(Point2[i].x,Point2[i].y,Point2[i].z);
    glTexCoord2f(Coord3[i].x,Coord3[i].y);
    glVertex3f(Point3[i].x,Point3[i].y,Point3[i].z);
    glTexCoord2f(Coord2[i].x,Coord2[i].y);
    glVertex3f(Point2[i].x,Point2[i].y,Point2[i].z);
    glTexCoord2f(Coord3[i].x,Coord3[i].y);
    glVertex3f(Point3[i].x,Point3[i].y,Point3[i].z);
    glTexCoord2f(Coord4[i].x,Coord4[i].y);
    glVertex3f(Point4[i].x,Point4[i].y,Point4[i].z);
  glEnd;

  glDisable(GL_BLEND);
  glDisable(GL_LIGHTING);

  glPopMatrix;
end;

Nyní stačí nepatrně pohnout s texturovou koordinací druhého čtverce a hrbolatý povrch objektu je na světě.

procedure BumpPlus;
begin
  Coord1[2].x := Coord1[2].x + 0.0001;
  Coord1[2].y := Coord1[2].y + 0.0001;
  Coord2[2].x := Coord2[2].x + 0.0001;
  Coord2[2].y := Coord2[2].y + 0.0001;
  Coord3[2].x := Coord3[2].x + 0.0001;
  Coord3[2].y := Coord3[2].y + 0.0001;
  Coord4[2].x := Coord4[2].x + 0.0001;
  Coord4[2].y := Coord4[2].y + 0.0001;
end;

procedure BumpMinus;
begin
  Coord1[2].x := Coord1[2].x - 0.0001;
  Coord1[2].y := Coord1[2].y - 0.0001;
  Coord2[2].x := Coord2[2].x - 0.0001;
  Coord2[2].y := Coord2[2].y - 0.0001;
  Coord3[2].x := Coord3[2].x - 0.0001;
  Coord3[2].y := Coord3[2].y - 0.0001;
  Coord4[2].x := Coord4[2].x - 0.0001;
  Coord4[2].y := Coord4[2].y - 0.0001;
end;                             

Hrbolatost se zvýší, nebo sníží tlačítkama ' + ' a ' - ' .

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
  case Key of
    '+': BumpPlus;
    '-': BumpMinus;
  end;
end;         

Celej zdroják je tady
BumpMap_f;


Alpha Blending Lepší detekce kolizí
Home