Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- unit Unit1;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
- nxGL, nxTypes, dglOpenGL, nxMath3D;
- type
- { TForm1 }
- TForm1 = class(TForm)
- Timer1: TTimer;
- procedure FormCreate(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- procedure FormResize(Sender: TObject);
- procedure Timer1Timer(Sender: TObject);
- private
- public
- model: TGLModel;
- texture,normalMap,cubemap: cardinal;
- dl: TDisplayList;
- tangentSpaceLight: array of TVector;
- end;
- var
- Form1: TForm1;
- implementation
- {$R *.lfm}
- procedure GenerateNormalisationCubeMap;
- var size: integer; offset, halfSize: single; data: array of byte;
- procedure Generate(arb: byte);
- var i, j, dp: integer; tempVector: TVector;
- begin
- dp:=0;
- for j:=0 to size-1 do
- for i:=0 to size-1 do begin
- case arb of
- 0: begin // +X
- tempVector.x:=halfSize;
- tempVector.y:=-(j+offset-halfSize);
- tempVector.z:=-(i+offset-halfSize);
- end;
- 1: begin // -X
- tempVector.x:=-halfSize;
- tempVector.y:=-(j+offset-halfSize);
- tempVector.z:=(i+offset-halfSize);
- end;
- 2: begin // +Y
- tempVector.x:=(i+offset-halfSize);
- tempVector.y:=halfSize;
- tempVector.z:=(j+offset-halfSize);
- end;
- 3: begin // -Y
- tempVector.x:=(i+offset-halfSize);
- tempVector.y:=-halfSize;
- tempVector.z:=-(j+offset-halfSize);
- end;
- 4: begin // +Z
- tempVector.x:=(i+offset-halfSize);
- tempVector.y:=-(j+offset-halfSize);
- tempVector.z:=halfSize;
- end;
- 5: begin // -Z
- tempVector.x:=-(i+offset-halfSize);
- tempVector.y:=-(j+offset-halfSize);
- tempVector.z:=-halfSize;
- end;
- end;
- tempVector:=Norm(tempVector);
- tempVector.x:=0.5*tempVector.x+0.5;
- tempVector.y:=0.5*tempVector.y+0.5;
- tempVector.z:=0.5*tempVector.z+0.5;
- data[dp]:=round(tempVector.x*255);
- data[dp+1]:=round(tempVector.y*255);
- data[dp+2]:=round(tempVector.z*255);
- inc(dp,3);
- end;
- arb:=GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB+arb;
- glTexImage2D(arb, 0, GL_RGBA8, size, size, 0, GL_RGB,
- GL_UNSIGNED_BYTE, @data[0]);
- end;
- var i: integer;
- begin
- size:=32; offset:=0.5; halfSize:=size/2;
- setlength(data,size*size*3);
- for i:=0 to 5 do Generate(i);
- end;
- procedure MakeBumpTexture(index: integer; dest: TBitmap);
- function GetBr(x,y: integer): single;
- var d: integer;
- begin
- with tex.texture[index] do begin
- d:=values*(sizeX*y+x);
- result:=data[d]*0.2989+data[d+1]*0.5870+data[d+2]*0.1140;
- end;
- end;
- var i,j: integer; br: array[-1..1,-1..1] of single;
- c: TVector;
- begin
- if (index>=tex.count) then exit;
- if tex.texture[index].Data=nil then exit;
- with tex.texture[index] do begin
- dest.PixelFormat:=pf32bit;
- dest.SetSize(width,height);
- for j:=0 to height-1 do
- for i:=0 to width-1 do begin
- br[0,0]:=GetBr(i,j);
- if i>0 then br[-1,0]:=GetBr(i-1,j)
- else br[-1,0]:=br[0,0];
- if j>0 then br[0,-1]:=GetBr(i,j-1)
- else br[0,-1]:=br[0,0];
- if i<width-1 then br[1,0]:=GetBr(i+1,j)
- else br[1,0]:=br[0,0];
- if j<height-1 then br[0,1]:=GetBr(i,j+1)
- else br[0,1]:=br[0,0];
- c.x:=((br[0,0]-br[-1,0])+(br[1,0]-br[0,0]))/2;
- c.y:=((br[0,0]-br[0,-1])+(br[0,1]-br[0,0]))/2;
- c.z:=64;
- c:=Norm(c);
- c.x:=c.x*0.5+0.5;
- c.y:=c.y*0.5+0.5;
- c.z:=c.z*0.5+0.5;
- dest.Canvas.Pixels[i,j]:=RGBToColor(
- round(c.x*255),round(c.y*255),round(c.z*255));
- end;
- end;
- end;
- { TForm1 }
- procedure TForm1.FormCreate(Sender: TObject);
- var bmp: TBitmap;
- begin
- clientwidth:=800; clientheight:=600;
- nx.CreateGlWindow(self);
- nx.Perspective(false);
- nx.DefaultLights;
- tex.Options:=tex.Options+[toKeepData];
- model:=TGLModel.Create;
- model.LoadFromW3D('data\donut.w3d');
- model.LoadTextures('data');
- texture:=model.mat[0].texIndex;
- model.MakeDisplayList(dl);
- setlength(tangentSpaceLight,model.vCount);
- bmp:=TBitmap.Create;
- MakeBumpTexture(0,bmp);
- //bmp.SaveToFile('bump_map_test.bmp');
- normalMap:=tex.AddTexture('bump','');
- tex.LoadBMPData(normalMap,bmp);
- tex.Restore(normalMap);
- //normalMap:=tex.AddTexture('bump','bump_map_test.bmp');
- normalMap:=tex.texture[normalMap].index;
- model.mat[0].texIndex:=normalMap;
- //model.mat[0].addMode:=true;
- {MakeBumpTexture(tex.AddTexture('test','glow.png'),bmp);
- bmp.SaveToFile('glow_bump.bmp');
- MakeBumpTexture(tex.AddTexture('test','water.png'),bmp);
- bmp.SaveToFile('water_bump.bmp');
- MakeBumpTexture(tex.AddTexture('test','cracks.png'),bmp);
- bmp.SaveToFile('cracks_bump.bmp'); }
- bmp.Free;
- cubemap:=tex.AddTexture('_cubemap_','');
- cubemap:=tex.texture[cubemap].index;
- glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, cubemap);
- GenerateNormalisationCubeMap;
- glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
- nx.RSEnable([rsDepthTest]);
- glDisable(GL_TEXTURE_2D);
- timer1.Enabled:=true;
- end;
- procedure TForm1.FormDestroy(Sender: TObject);
- begin
- dl.Free;
- model.Free;
- end;
- procedure TForm1.FormResize(Sender: TObject);
- begin
- nx.SetView(0,0,clientwidth,clientheight);
- end;
- procedure TForm1.Timer1Timer(Sender: TObject);
- var i: integer; objectLightPosition, lightVector: TVector;
- sTangent, tTangent: TVector;
- begin
- if not nx.AllOK then begin
- timer1.Enabled:=false;
- showmessage(nx.LastError); exit;
- end;
- nx.Clear(true,true);
- glLoadIdentity;
- glcolor3f(0.5,0.5,0.5);
- glTranslatef(0,0,-1.3);
- glRotatef(40,1,0,0);
- glRotatef(nx.FrameTick*0.01,0,1,0);
- objectLightPosition:=vector(0,5,-10);
- for i:=0 to model.vCount-1 do begin
- lightVector.x:=objectLightPosition.x-model.va[i].x;
- lightVector.y:=objectLightPosition.y-model.va[i].y;
- lightVector.z:=objectLightPosition.z-model.va[i].z;
- sTangent:=CrossProduct(model.na[i],vector(1,0,0));
- tTangent:=CrossProduct(model.na[i],sTangent);
- sTangent:=CrossProduct(model.na[i],tTangent);
- //Calculate tangent space light vector
- tangentSpaceLight[i].x:=Dot(sTangent,lightVector);
- tangentSpaceLight[i].y:=Dot(tTangent,lightVector);
- tangentSpaceLight[i].z:=Dot(model.na[i],lightVector);
- end;
- //nx.SetSpecular(true,1,1,1,30);
- // *** Start bumpmap rendering ***
- //Bind normal map to texture unit 0
- glBindTexture(GL_TEXTURE_2D, normalMap);
- glEnable(GL_TEXTURE_2D);
- //Bind normalisation cube map to texture unit 1
- glActiveTextureARB(GL_TEXTURE1_ARB);
- glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, CubeMap);
- glEnable(GL_TEXTURE_CUBE_MAP_ARB);
- glActiveTextureARB(GL_TEXTURE0_ARB);
- glVertexPointer(3, GL_FLOAT, 0, @model.va[0]);
- glEnableClientState(GL_VERTEX_ARRAY);
- glTexCoordPointer(2, GL_FLOAT, 0, @model.ta[0]);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glClientActiveTextureARB(GL_TEXTURE1_ARB);
- glTexCoordPointer(3, GL_FLOAT, 0, @tangentSpaceLight[0]);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
- glActiveTextureARB(GL_TEXTURE1_ARB);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGB_ARB);
- glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
- glActiveTextureARB(GL_TEXTURE0_ARB);
- // Render Bumps
- glDrawElements(GL_TRIANGLES, model.fCount*3, GL_UNSIGNED_SHORT, @model.fa[0]);
- glDisable(GL_TEXTURE_2D);
- glActiveTextureARB(GL_TEXTURE1_ARB);
- glDisable(GL_TEXTURE_CUBE_MAP_ARB);
- glActiveTextureARB(GL_TEXTURE0_ARB);
- //disable vertex arrays
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glClientActiveTextureARB(GL_TEXTURE1_ARB);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- //Return to standard modulate texenv
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- //Enable multiplicative blending
- glBlendFunc(GL_DST_COLOR, GL_ZERO);
- glEnable(GL_BLEND);
- glBindTexture(GL_TEXTURE_2D, Texture);
- glEnable(GL_TEXTURE_2D);
- glVertexPointer(3, GL_FLOAT, 0, @model.va[0]);
- glEnableClientState(GL_VERTEX_ARRAY);
- glNormalPointer(GL_FLOAT, 0, @model.va[0]);
- glEnableClientState(GL_NORMAL_ARRAY);
- glTexCoordPointer(2, GL_FLOAT, 0, @model.ta[0]);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- // Render Object
- //glDrawElements(GL_TRIANGLES, model.fCount*3, GL_UNSIGNED_SHORT, @model.fa[0]);
- //Disable texture
- glDisable(GL_TEXTURE_2D);
- //disable vertex arrays
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- //Disable blending if it is enabled
- glDisable(GL_BLEND);
- {nx.Enable2D;
- tex.SetTex(0); nx.Draw(0,0,0);
- tex.SetTex(normalMap); nx.Draw(0,256,0);
- nx.Disable2D;}
- nx.Flip;
- end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement