134 lines
4.0 KiB
ObjectPascal
134 lines
4.0 KiB
ObjectPascal
unit utexture;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
{ This unit creates textures. It is mainly based on Perlin noise maps,
|
|
which are random maps that have a natural look. Then a color is applied
|
|
by linear interpolation. The water texture is achieved by using
|
|
a Phong lighting based on the Perlin noise map. }
|
|
|
|
uses
|
|
Classes, SysUtils, BGRABitmap, BGRABitmapTypes;
|
|
|
|
function CreateGrassTexture(tx,ty: integer): TBGRABitmap;
|
|
function CreateVerticalWoodTexture(tx, ty: integer): TBGRABitmap;
|
|
function CreateWoodTexture(tx,ty: integer): TBGRABitmap;
|
|
function CreateWaterTexture(tx,ty: integer): TBGRABitmap;
|
|
|
|
implementation
|
|
|
|
uses {$IFNDEF NO_OPENGL_SURFACE}BGRAOpenGL, {$ENDIF}BGRAGradients;
|
|
|
|
function Interp256(value1,value2,position: integer): integer; inline;
|
|
begin
|
|
result := (value1*(256-position)+value2*position) shr 8;
|
|
end;
|
|
|
|
function Interp256(color1,color2: TBGRAPixel; position: integer): TBGRAPixel; inline;
|
|
begin
|
|
result.red := Interp256(color1.red,color2.red,position);
|
|
result.green := Interp256(color1.green,color2.green,position);
|
|
result.blue := Interp256(color1.blue,color2.blue,position);
|
|
result.alpha := Interp256(color1.alpha,color2.alpha,position);
|
|
end;
|
|
|
|
function CreateWoodTexture(tx,ty: integer): TBGRABitmap;
|
|
var
|
|
colorOscillation, globalColorVariation: integer;
|
|
p: PBGRAPixel;
|
|
i: Integer;
|
|
begin
|
|
result := CreateCyclicPerlinNoiseMap(tx,ty,1.5,1.5,1,rfBestQuality);
|
|
p := result.Data;
|
|
for i := 0 to result.NbPixels-1 do
|
|
begin
|
|
colorOscillation := round(sqrt((sin(p^.red*Pi/16)+1)/2)*256);
|
|
globalColorVariation := p^.red;
|
|
p^:= Interp256( Interp256(BGRA(247,188,120),BGRA(255,218,170),colorOscillation),
|
|
Interp256(BGRA(157,97,60),BGRA(202,145,112),colorOscillation), globalColorVariation);
|
|
inc(p);
|
|
end;
|
|
{$IFNDEF NO_OPENGL_SURFACE}
|
|
BGRAReplace(result, TBGLBitmap.Create(result));
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function CreateVerticalWoodTexture(tx, ty: integer): TBGRABitmap;
|
|
var
|
|
globalPos: single;
|
|
colorOscillation, globalColorVariation: integer;
|
|
p: PBGRAPixel;
|
|
i: Integer;
|
|
x,nbVertical: integer;
|
|
begin
|
|
result := CreateCyclicPerlinNoiseMap(tx,ty,1,1,1,rfBestQuality);
|
|
p := result.Data;
|
|
x := 0;
|
|
nbVertical := tx div 128;
|
|
if nbVertical = 0 then nbVertical := 1;
|
|
for i := 0 to result.NbPixels-1 do
|
|
begin
|
|
globalPos := p^.red*Pi/32 + nbVertical*x*2*Pi/tx*8;
|
|
colorOscillation := round(sqrt((sin(globalPos)+1)/2)*256);
|
|
globalColorVariation := p^.red; //round(sin(globalPos/8)*128+128);
|
|
p^:= Interp256( Interp256(BGRA(247,188,120),BGRA(255,218,170),colorOscillation),
|
|
Interp256(BGRA(157,97,60),BGRA(202,145,112),colorOscillation), globalColorVariation);
|
|
inc(p);
|
|
inc(x);
|
|
if x = tx then x := 0;
|
|
end;
|
|
{$IFNDEF NO_OPENGL_SURFACE}
|
|
BGRAReplace(result, TBGLBitmap.Create(result));
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function CreateGrassTexture(tx,ty: integer): TBGRABitmap;
|
|
var
|
|
p: PBGRAPixel;
|
|
i: Integer;
|
|
begin
|
|
result := CreateCyclicPerlinNoiseMap(tx,ty,1,1,1,rfBestQuality);
|
|
p := result.Data;
|
|
for i := 0 to result.NbPixels-1 do
|
|
begin
|
|
p^ := Interp256( BGRA(0,128,0), BGRA(192,255,0), p^.red );
|
|
inc(p);
|
|
end;
|
|
{$IFNDEF NO_OPENGL_SURFACE}
|
|
BGRAReplace(result, TBGLBitmap.Create(result));
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function CreateWaterTexture(tx,ty: integer): TBGRABitmap;
|
|
const blurSize = 5;
|
|
var
|
|
map: TBGRABitmap;
|
|
phong: TPhongShading;
|
|
begin
|
|
result := TBGRABitmap.Create(tx,ty);
|
|
map := CreateCyclicPerlinNoiseMap(tx,ty,1,1,1.2,rfBestQuality);
|
|
BGRAReplace(map,map.GetPart(rect(-blurSize,-blurSize,tx+blurSize,ty+blurSize)));
|
|
BGRAReplace(map,map.FilterBlurRadial(blurSize,rbFast));
|
|
phong := TPhongShading.Create;
|
|
phong.LightSourceDistanceFactor := 0;
|
|
phong.LightDestFactor := 0;
|
|
phong.LightSourceIntensity := 150;
|
|
phong.LightPositionZ := 80;
|
|
phong.LightColor := BGRA(105,233,240);
|
|
phong.NegativeDiffusionFactor := 0.3;
|
|
phong.SpecularIndex := 20;
|
|
phong.AmbientFactor := 0.4;
|
|
phong.Draw(result,map,20,-blurSize,-blurSize,BGRA(28,139,166));
|
|
phong.Free;
|
|
map.Free;
|
|
{$IFNDEF NO_OPENGL_SURFACE}
|
|
BGRAReplace(result, TBGLBitmap.Create(result));
|
|
{$ENDIF}
|
|
end;
|
|
|
|
|
|
end.
|
|
|