Advertisement
Guest User

Bumpmap

a guest
Sep 26th, 2010
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 9.90 KB | None | 0 0
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  9.   nxGL, nxTypes, dglOpenGL, nxMath3D;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     Timer1: TTimer;
  17.     procedure FormCreate(Sender: TObject);
  18.     procedure FormDestroy(Sender: TObject);
  19.     procedure FormResize(Sender: TObject);
  20.     procedure Timer1Timer(Sender: TObject);
  21.   private
  22.   public
  23.     model: TGLModel;
  24.     texture,normalMap,cubemap: cardinal;
  25.     dl: TDisplayList;
  26.     tangentSpaceLight: array of TVector;
  27.   end;
  28.  
  29. var
  30.   Form1: TForm1;
  31.  
  32. implementation
  33.  
  34. {$R *.lfm}
  35.  
  36. procedure GenerateNormalisationCubeMap;
  37. var size: integer; offset, halfSize: single; data: array of byte;
  38.   procedure Generate(arb: byte);
  39.   var i, j, dp: integer; tempVector: TVector;
  40.   begin
  41.     dp:=0;
  42.     for j:=0 to size-1 do
  43.       for i:=0 to size-1 do begin
  44.         case arb of
  45.           0: begin // +X
  46.                tempVector.x:=halfSize;
  47.                tempVector.y:=-(j+offset-halfSize);
  48.                tempVector.z:=-(i+offset-halfSize);
  49.              end;
  50.           1: begin // -X
  51.                tempVector.x:=-halfSize;
  52.                tempVector.y:=-(j+offset-halfSize);
  53.                tempVector.z:=(i+offset-halfSize);
  54.              end;
  55.           2: begin // +Y
  56.                tempVector.x:=(i+offset-halfSize);
  57.                tempVector.y:=halfSize;
  58.                tempVector.z:=(j+offset-halfSize);
  59.              end;
  60.           3: begin // -Y
  61.                tempVector.x:=(i+offset-halfSize);
  62.                tempVector.y:=-halfSize;
  63.                tempVector.z:=-(j+offset-halfSize);
  64.              end;
  65.           4: begin // +Z
  66.                tempVector.x:=(i+offset-halfSize);
  67.                tempVector.y:=-(j+offset-halfSize);
  68.                tempVector.z:=halfSize;
  69.              end;
  70.           5: begin // -Z
  71.                tempVector.x:=-(i+offset-halfSize);
  72.                tempVector.y:=-(j+offset-halfSize);
  73.                tempVector.z:=-halfSize;
  74.              end;
  75.         end;
  76.         tempVector:=Norm(tempVector);
  77.         tempVector.x:=0.5*tempVector.x+0.5;
  78.         tempVector.y:=0.5*tempVector.y+0.5;
  79.         tempVector.z:=0.5*tempVector.z+0.5;
  80.         data[dp]:=round(tempVector.x*255);
  81.         data[dp+1]:=round(tempVector.y*255);
  82.         data[dp+2]:=round(tempVector.z*255);
  83.         inc(dp,3);
  84.       end;
  85.     arb:=GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB+arb;
  86.     glTexImage2D(arb, 0, GL_RGBA8, size, size, 0, GL_RGB,
  87.       GL_UNSIGNED_BYTE, @data[0]);
  88.   end;
  89. var i: integer;
  90. begin
  91.   size:=32; offset:=0.5; halfSize:=size/2;
  92.   setlength(data,size*size*3);
  93.   for i:=0 to 5 do Generate(i);
  94. end;
  95.  
  96. procedure MakeBumpTexture(index: integer; dest: TBitmap);
  97.   function GetBr(x,y: integer): single;
  98.   var d: integer;
  99.   begin
  100.     with tex.texture[index] do begin
  101.       d:=values*(sizeX*y+x);
  102.       result:=data[d]*0.2989+data[d+1]*0.5870+data[d+2]*0.1140;
  103.     end;
  104.   end;
  105. var i,j: integer; br: array[-1..1,-1..1] of single;
  106.     c: TVector;
  107. begin
  108.   if (index>=tex.count) then exit;
  109.   if tex.texture[index].Data=nil then exit;
  110.   with tex.texture[index] do begin
  111.     dest.PixelFormat:=pf32bit;
  112.     dest.SetSize(width,height);
  113.     for j:=0 to height-1 do
  114.       for i:=0 to width-1 do begin
  115.         br[0,0]:=GetBr(i,j);
  116.         if i>0 then        br[-1,0]:=GetBr(i-1,j)
  117.         else               br[-1,0]:=br[0,0];
  118.         if j>0 then        br[0,-1]:=GetBr(i,j-1)
  119.         else               br[0,-1]:=br[0,0];
  120.         if i<width-1 then  br[1,0]:=GetBr(i+1,j)
  121.         else               br[1,0]:=br[0,0];
  122.         if j<height-1 then br[0,1]:=GetBr(i,j+1)
  123.         else               br[0,1]:=br[0,0];
  124.         c.x:=((br[0,0]-br[-1,0])+(br[1,0]-br[0,0]))/2;
  125.         c.y:=((br[0,0]-br[0,-1])+(br[0,1]-br[0,0]))/2;
  126.         c.z:=64;
  127.         c:=Norm(c);
  128.         c.x:=c.x*0.5+0.5;
  129.         c.y:=c.y*0.5+0.5;
  130.         c.z:=c.z*0.5+0.5;
  131.         dest.Canvas.Pixels[i,j]:=RGBToColor(
  132.           round(c.x*255),round(c.y*255),round(c.z*255));
  133.       end;
  134.   end;
  135. end;
  136.  
  137. { TForm1 }
  138.  
  139. procedure TForm1.FormCreate(Sender: TObject);
  140. var bmp: TBitmap;
  141. begin
  142.   clientwidth:=800; clientheight:=600;
  143.   nx.CreateGlWindow(self);
  144.   nx.Perspective(false);
  145.   nx.DefaultLights;
  146.  
  147.   tex.Options:=tex.Options+[toKeepData];
  148.  
  149.   model:=TGLModel.Create;
  150.   model.LoadFromW3D('data\donut.w3d');
  151.   model.LoadTextures('data');
  152.   texture:=model.mat[0].texIndex;
  153.   model.MakeDisplayList(dl);
  154.   setlength(tangentSpaceLight,model.vCount);
  155.  
  156.   bmp:=TBitmap.Create;
  157.  
  158.   MakeBumpTexture(0,bmp);
  159.   //bmp.SaveToFile('bump_map_test.bmp');
  160.   normalMap:=tex.AddTexture('bump','');
  161.   tex.LoadBMPData(normalMap,bmp);
  162.   tex.Restore(normalMap);
  163.   //normalMap:=tex.AddTexture('bump','bump_map_test.bmp');
  164.   normalMap:=tex.texture[normalMap].index;
  165.   model.mat[0].texIndex:=normalMap;
  166.   //model.mat[0].addMode:=true;
  167.  
  168.   {MakeBumpTexture(tex.AddTexture('test','glow.png'),bmp);
  169.   bmp.SaveToFile('glow_bump.bmp');
  170.  
  171.   MakeBumpTexture(tex.AddTexture('test','water.png'),bmp);
  172.   bmp.SaveToFile('water_bump.bmp');
  173.  
  174.   MakeBumpTexture(tex.AddTexture('test','cracks.png'),bmp);
  175.   bmp.SaveToFile('cracks_bump.bmp');  }
  176.  
  177.   bmp.Free;
  178.  
  179.   cubemap:=tex.AddTexture('_cubemap_','');
  180.   cubemap:=tex.texture[cubemap].index;
  181.   glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, cubemap);
  182.   GenerateNormalisationCubeMap;
  183.   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  184.   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  185.   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  186.   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  187.   glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  188.  
  189.   nx.RSEnable([rsDepthTest]);
  190.   glDisable(GL_TEXTURE_2D);
  191.  
  192.   timer1.Enabled:=true;
  193. end;
  194.  
  195. procedure TForm1.FormDestroy(Sender: TObject);
  196. begin
  197.   dl.Free;
  198.   model.Free;
  199. end;
  200.  
  201. procedure TForm1.FormResize(Sender: TObject);
  202. begin
  203.   nx.SetView(0,0,clientwidth,clientheight);
  204. end;
  205.  
  206. procedure TForm1.Timer1Timer(Sender: TObject);
  207. var i: integer; objectLightPosition, lightVector: TVector;
  208.     sTangent, tTangent: TVector;
  209. begin
  210.   if not nx.AllOK then begin
  211.     timer1.Enabled:=false;
  212.     showmessage(nx.LastError); exit;
  213.   end;
  214.   nx.Clear(true,true);
  215.   glLoadIdentity;
  216.   glcolor3f(0.5,0.5,0.5);
  217.   glTranslatef(0,0,-1.3);
  218.   glRotatef(40,1,0,0);
  219.   glRotatef(nx.FrameTick*0.01,0,1,0);
  220.  
  221.   objectLightPosition:=vector(0,5,-10);
  222.  
  223.   for i:=0 to model.vCount-1 do begin
  224.     lightVector.x:=objectLightPosition.x-model.va[i].x;
  225.     lightVector.y:=objectLightPosition.y-model.va[i].y;
  226.     lightVector.z:=objectLightPosition.z-model.va[i].z;
  227.  
  228.     sTangent:=CrossProduct(model.na[i],vector(1,0,0));
  229.     tTangent:=CrossProduct(model.na[i],sTangent);
  230.     sTangent:=CrossProduct(model.na[i],tTangent);
  231.  
  232.     //Calculate tangent space light vector
  233.     tangentSpaceLight[i].x:=Dot(sTangent,lightVector);
  234.     tangentSpaceLight[i].y:=Dot(tTangent,lightVector);
  235.     tangentSpaceLight[i].z:=Dot(model.na[i],lightVector);
  236.   end;
  237.  
  238.   //nx.SetSpecular(true,1,1,1,30);
  239.  
  240.   // *** Start bumpmap rendering ***
  241.  
  242.   //Bind normal map to texture unit 0
  243.   glBindTexture(GL_TEXTURE_2D, normalMap);
  244.   glEnable(GL_TEXTURE_2D);
  245.  
  246.   //Bind normalisation cube map to texture unit 1
  247.   glActiveTextureARB(GL_TEXTURE1_ARB);
  248.   glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, CubeMap);
  249.   glEnable(GL_TEXTURE_CUBE_MAP_ARB);
  250.   glActiveTextureARB(GL_TEXTURE0_ARB);
  251.  
  252.   glVertexPointer(3, GL_FLOAT, 0, @model.va[0]);
  253.   glEnableClientState(GL_VERTEX_ARRAY);
  254.  
  255.   glTexCoordPointer(2, GL_FLOAT, 0, @model.ta[0]);
  256.   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  257.  
  258.   glClientActiveTextureARB(GL_TEXTURE1_ARB);
  259.   glTexCoordPointer(3, GL_FLOAT, 0, @tangentSpaceLight[0]);
  260.   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  261.   glClientActiveTextureARB(GL_TEXTURE0_ARB);
  262.  
  263.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
  264.   glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
  265.   glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
  266.  
  267.   glActiveTextureARB(GL_TEXTURE1_ARB);
  268.  
  269.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
  270.   glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
  271.   glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGB_ARB);
  272.   glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
  273.  
  274.   glActiveTextureARB(GL_TEXTURE0_ARB);
  275.  
  276.   // Render Bumps
  277.   glDrawElements(GL_TRIANGLES, model.fCount*3, GL_UNSIGNED_SHORT, @model.fa[0]);
  278.  
  279.   glDisable(GL_TEXTURE_2D);
  280.  
  281.   glActiveTextureARB(GL_TEXTURE1_ARB);
  282.   glDisable(GL_TEXTURE_CUBE_MAP_ARB);
  283.   glActiveTextureARB(GL_TEXTURE0_ARB);
  284.  
  285.   //disable vertex arrays
  286.   glDisableClientState(GL_VERTEX_ARRAY);
  287.  
  288.   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  289.  
  290.   glClientActiveTextureARB(GL_TEXTURE1_ARB);
  291.   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  292.   glClientActiveTextureARB(GL_TEXTURE0_ARB);
  293.  
  294.   //Return to standard modulate texenv
  295.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  296.  
  297.   //Enable multiplicative blending
  298.   glBlendFunc(GL_DST_COLOR, GL_ZERO);
  299.   glEnable(GL_BLEND);
  300.  
  301.   glBindTexture(GL_TEXTURE_2D, Texture);
  302.   glEnable(GL_TEXTURE_2D);
  303.  
  304.   glVertexPointer(3, GL_FLOAT, 0, @model.va[0]);
  305.   glEnableClientState(GL_VERTEX_ARRAY);
  306.  
  307.   glNormalPointer(GL_FLOAT, 0, @model.va[0]);
  308.   glEnableClientState(GL_NORMAL_ARRAY);
  309.  
  310.   glTexCoordPointer(2, GL_FLOAT, 0, @model.ta[0]);
  311.   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  312.  
  313.   // Render Object
  314.   //glDrawElements(GL_TRIANGLES, model.fCount*3, GL_UNSIGNED_SHORT, @model.fa[0]);
  315.  
  316.   //Disable texture
  317.   glDisable(GL_TEXTURE_2D);
  318.  
  319.   //disable vertex arrays
  320.   glDisableClientState(GL_VERTEX_ARRAY);
  321.   glDisableClientState(GL_NORMAL_ARRAY);
  322.   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  323.  
  324.   //Disable blending if it is enabled
  325.   glDisable(GL_BLEND);
  326.  
  327.   {nx.Enable2D;
  328.   tex.SetTex(0); nx.Draw(0,0,0);
  329.   tex.SetTex(normalMap); nx.Draw(0,256,0);
  330.   nx.Disable2D;}
  331.  
  332.   nx.Flip;
  333. end;
  334.  
  335. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement