?? dxrender.pas
字號:
{ Vendor ID }
mov eax,0
db $0F,$A2 ///cpuid
mov dword ptr [CPUIDVendor], ebx
mov dword ptr [CPUIDVendor+4], edx
mov dword ptr [CPUIDVendor+8], ecx
{ Features, Signature }
mov eax,1
db $0F,$A2 ///cpuid
mov CPUIDSignature,eax
mov CPUIDFeatures,edx
@@exit:
pop ebx
end;
UseMMX := CPUIDFeatures and CPUIDF_MMX<>0;
end;
function GetBitCount(B: Integer): DWORD;
begin
Result := 31;
while (Result>0) and (((1 shl Result) and B)=0) do Dec(Result);
end;
function GetFirstZeroBitCount(B: Integer): DWORD;
begin
Result := 0;
while (Result<31) and (((1 shl Result) and B)=0) do Inc(Result);
end;
function GetOneBitCount(B: Integer): DWORD;
var
i: Integer;
begin
Result := 0;
for i:=0 to 31 do
Inc(Result, Ord(b and (1 shl i)<>0));
end;
function dxrMakeColorChannel(Mask: DWORD; indexed: Boolean): TDXR_ColorChannel;
var
i: Integer;
begin
Result.BitCount := GetOneBitCount(Mask shr (GetFirstZeroBitCount(Mask)));
Result.Mask := Mask;
if indexed then
begin
Result.rshift := GetFirstZeroBitCount(Mask);
Result.lshift := 0;
end else
begin
i := GetFirstZeroBitCount(Mask)-(8-Result.BitCount);
if i<0 then
begin
Result.lshift := -i;
Result.rshift := 0;
end else
begin
Result.lshift := 0;
Result.rshift := DWORD(i);
end;
end;
end;
procedure dxrMakeIndexedSurface(var Surface: TDXR_Surface; Width, Height, BitCount: DWORD;
Bits: Pointer; pitch: Integer; idx_index, idx_alpha: DWORD);
begin
FillChar(Surface, SizeOf(Surface), 0);
Surface.ColorType := DXR_COLORTYPE_INDEXED;
Surface.Width := Width;
Surface.Height := Height;
Surface.WidthBit := GetBitCount(Width);
Surface.HeightBit := GetBitCount(Height);
Surface.Width2 := 1 shl Surface.WidthBit;
Surface.Height2 := 1 shl Surface.HeightBit;
Surface.WidthMask := Surface.Width-1;
Surface.HeightMask := Surface.Height2-1;
Surface.BitCount := BitCount;
Surface.Bits := Bits;
Surface.Pitch := Pitch;
Surface.PitchBit := GetBitCount(Abs(Pitch));
Surface.idx_index := dxrMakeColorChannel(idx_index, True);
Surface.idx_alpha := dxrMakeColorChannel(idx_alpha, False);
end;
procedure dxrMakeRGBSurface(var Surface: TDXR_Surface; Width, Height, BitCount: DWORD;
Bits: Pointer; pitch: Integer; rgb_red, rgb_green, rgb_blue, rgb_alpha: DWORD);
begin
FillChar(Surface, SizeOf(Surface), 0);
Surface.ColorType := DXR_COLORTYPE_RGB;
Surface.Width := Width;
Surface.Height := Height;
Surface.WidthBit := GetBitCount(Width);
Surface.HeightBit := GetBitCount(Height);
Surface.Width2 := 1 shl Surface.WidthBit;
Surface.Height2 := 1 shl Surface.HeightBit;
Surface.WidthMask := Surface.Width-1;
Surface.HeightMask := Surface.Height2-1;
Surface.BitCount := BitCount;
Surface.Bits := Bits;
Surface.Pitch := Pitch;
Surface.PitchBit := GetBitCount(Abs(Pitch));
Surface.rgb_red := dxrMakeColorChannel(rgb_red, False);
Surface.rgb_green := dxrMakeColorChannel(rgb_green, False);
Surface.rgb_blue := dxrMakeColorChannel(rgb_blue, False);
Surface.rgb_alpha := dxrMakeColorChannel(rgb_alpha, False);
end;
function dxrCompareSurface(const Surface1, Surface2: TDXR_Surface): Boolean;
begin
if Surface1.ColorType=DXR_COLORTYPE_INDEXED then
begin
Result := (Surface2.ColorType=DXR_COLORTYPE_INDEXED) and
(Surface1.idx_index.Mask=Surface2.idx_index.Mask) and
(Surface1.idx_alpha.Mask=Surface2.idx_alpha.Mask);
end else if Surface1.ColorType=DXR_COLORTYPE_RGB then
begin
Result := (Surface2.ColorType=DXR_COLORTYPE_RGB) and
(Surface1.rgb_red.Mask=Surface2.rgb_red.Mask) and
(Surface1.rgb_green.Mask=Surface2.rgb_green.Mask) and
(Surface1.rgb_blue.Mask=Surface2.rgb_blue.Mask) and
(Surface1.rgb_alpha.Mask=Surface2.rgb_alpha.Mask);
end else
Result := False;
end;
function dxrDDSurfaceLock(DDSurface: IDirectDrawSurface; var Surface: TDXR_Surface): Boolean;
var
ddsd: TDDSurfaceDesc;
begin
Result := dxrDDSurfaceLock2(DDSurface, ddsd, Surface);
end;
function dxrDDSurfaceLock2(DDSurface: IDirectDrawSurface; var ddsd: TDDSurfaceDesc;
var Surface: TDXR_Surface): Boolean;
const
DDPF_PALETTEINDEXED = DDPF_PALETTEINDEXED1 or DDPF_PALETTEINDEXED2 or
DDPF_PALETTEINDEXED4 or DDPF_PALETTEINDEXED8;
begin
ddsd.dwSize := SizeOf(ddsd);
Result := DDSurface.Lock(nil, ddsd, DDLOCK_WAIT, 0)=DD_OK;
if Result then
begin
FillChar(Surface, SizeOf(Surface), 0);
if ddsd.ddpfPixelFormat.dwFlags and DDPF_PALETTEINDEXED<>0 then
begin
dxrMakeIndexedSurface(Surface, ddsd.dwWidth, ddsd.dwHeight, ddsd.ddpfPixelFormat.dwRGBBitCount,
ddsd.lpSurface, ddsd.lPitch, (1 shl ddsd.ddpfPixelFormat.dwRGBBitCount)-1, 0);
end else
begin
{if ddsd.ddpfPixelFormat.dwFlags and DDPF_ALPHAPIXELS<>0 then
begin
dxrMakeRGBSurface(Surface, ddsd.dwWidth, ddsd.dwHeight, ddsd.ddpfPixelFormat.dwRGBBitCount,
ddsd.lpSurface, ddsd.lPitch, ddsd.ddpfPixelFormat.dwRBitMask, ddsd.ddpfPixelFormat.dwGBitMask,
ddsd.ddpfPixelFormat.dwBBitMask, ddsd.ddpfPixelFormat.dwRGBAlphaBitMask);
end else}
begin
dxrMakeRGBSurface(Surface, ddsd.dwWidth, ddsd.dwHeight, ddsd.ddpfPixelFormat.dwRGBBitCount,
ddsd.lpSurface, ddsd.lPitch, ddsd.ddpfPixelFormat.dwRBitMask, ddsd.ddpfPixelFormat.dwGBitMask,
ddsd.ddpfPixelFormat.dwBBitMask, 0);
end;
end;
end;
end;
procedure dxrDDSurfaceUnLock(DDSurface: IDirectDrawSurface; const Surface: TDXR_Surface);
begin
DDSurface.Unlock(Surface.Bits);
end;
function dxrScanLine(const Surface: TDXR_Surface; y: DWORD): Pointer;
begin
Result := Pointer(Integer(Surface.Bits)+Surface.Pitch*Integer(y));
end;
{ TDXRMachine }
constructor TDXRMachine.Create;
begin
inherited Create;
FBuf := VirtualAlloc(nil, 2048, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
end;
destructor TDXRMachine.Destroy;
begin
VirtualFree(FBuf, 0, MEM_RELEASE);
inherited Destroy;
end;
procedure TDXRMachine.Initialize;
begin
FCall := nil;
ColorIndexCount := 0;
TextureIndexCount := 0;
FTreeCount := 0;
Dest := nil;
FCompiled := False;
FMMXUsed := False;
FillChar(ColorList, SizeOf(ColorList), 0);
FillChar(TextureList, SizeOf(TextureList), 0);
FillChar(Dither, SizeOf(Dither), 0);
FillChar(Axis, SizeOf(Axis), 0);
end;
function TDXRMachine.CreateTree: PDXRMachine_Tree;
begin
Result := @FTreeList[FTreeCount];
FillChar(Result^, SizeOf(Result^), 0);
Inc(FTreeCount);
end;
function TDXRMachine.CreateTree2(Typ: TDXRMachine_TreeType): PDXRMachine_Tree;
begin
Result := CreateTree;
Result.Typ := Typ;
end;
function TDXRMachine.CreateTree_LoadColor(Color: DWORD): PDXRMachine_Tree;
begin
Result := CreateTree;
Result.Typ := DXR_TREETYPE_LOADCOLOR;
Result.Color := Color;
end;
function TDXRMachine.CreateTree_LoadConstColor(R, G, B, A: Byte): PDXRMachine_Tree;
begin
Result := CreateTree;
Result.Typ := DXR_TREETYPE_LOADCONSTCOLOR;
Result.ConstColor.R := R shl 8;
Result.ConstColor.G := G shl 8;
Result.ConstColor.B := B shl 8;
Result.ConstColor.A := A shl 8;
end;
function TDXRMachine.CreateTree_LoadTexture(Texture: DWORD): PDXRMachine_Tree;
begin
Result := CreateTree;
Result.Typ := DXR_TREETYPE_LOADTEXTURE;
Result.Texture := Texture;
end;
function TDXRMachine.CreateTree_Blend(Blend: TDXR_Blend; BlendTree1, BlendTree2: PDXRMachine_Tree): PDXRMachine_Tree;
begin
Result := CreateTree;
Result.Typ := DXR_TREETYPE_BLEND;
Result.Blend := Blend;
Result.BlendTree1 := BlendTree1;
Result.BlendTree2 := BlendTree2;
end;
procedure TDXRMachine.Compile;
function GetSurfaceChannels(const Surface: TDXR_Surface): TDXRColorChannels;
begin
Result := [];
if Surface.ColorType=DXR_COLORTYPE_INDEXED then
begin
if Surface.idx_index.Mask<>0 then Result := Result + [chRed, chGreen, chBlue];
if Surface.idx_alpha.Mask<>0 then Result := Result + [chAlpha];
end else
begin
if Surface.rgb_red.Mask<>0 then Result := Result + [chRed];
if Surface.rgb_green.Mask<>0 then Result := Result + [chGreen];
if Surface.rgb_blue.Mask<>0 then Result := Result + [chBlue];
if Surface.rgb_alpha.Mask<>0 then Result := Result + [chAlpha];
end;
end;
procedure OptimizeTree(var Tree: PDXRMachine_Tree);
procedure GetBlendChannels(Blend: TDXR_Blend; var Col1_1, Col1_2, Col2_1, Col2_2: TDXRColorChannels);
begin
case Blend of
DXR_BLEND_ZERO:
begin
Col1_1 := [];
Col1_2 := [];
Col2_1 := [];
Col2_2 := [];
end;
DXR_BLEND_ONE1:
begin
Col1_1 := [chRed, chGreen, chBlue, chAlpha];
Col1_2 := [];
Col2_1 := [];
Col2_2 := [];
end;
DXR_BLEND_ONE2:
begin
Col1_1 := [];
Col1_2 := [];
Col2_1 := [chRed, chGreen, chBlue, chAlpha];
Col2_2 := [];
end;
DXR_BLEND_ONE1_ADD_ONE2,
DXR_BLEND_ONE1_SUB_ONE2,
DXR_BLEND_ONE2_SUB_ONE1,
DXR_BLEND_ONE1_MUL_ONE2:
begin
Col1_1 := [chRed, chGreen, chBlue, chAlpha];
Col1_2 := [];
Col2_1 := [chRed, chGreen, chBlue, chAlpha];
Col2_2 := [];
end;
DXR_BLEND_SRCALPHA1:
begin
Col1_1 := [chRed, chGreen, chBlue];
Col1_2 := [chAlpha];
Col2_1 := [];
Col2_2 := [];
end;
DXR_BLEND_SRCALPHA1_ADD_ONE2:
begin
Col1_1 := [chRed, chGreen, chBlue];
Col1_2 := [chAlpha];
Col2_1 := [chRed, chGreen, chBlue, chAlpha];
Col2_2 := [];
end;
DXR_BLEND_ONE2_SUB_SRCALPHA1:
begin
Col1_1 := [chRed, chGreen, chBlue];
Col1_2 := [chAlpha];
Col2_1 := [chRed, chGreen, chBlue, chAlpha];
Col2_2 := [];
end;
DXR_BLEND_SRCALPHA1_ADD_INVSRCALPHA2:
begin
Col1_1 := [chRed, chGreen, chBlue];
Col1_2 := [chAlpha];
Col2_1 := [chRed, chGreen, chBlue, chAlpha];
Col2_2 := [];
end;
DXR_BLEND_INVSRCALPHA1_ADD_SRCALPHA2:
begin
Col1_1 := [chRed, chGreen, chBlue];
Col1_2 := [chAlpha];
Col2_1 := [chRed, chGreen, chBlue, chAlpha];
Col2_2 := [];
end;
DXR_BLEND_DECALALPHA:
begin
Col1_1 := [chRed, chGreen, chBlue];
Col1_2 := [];
Col2_1 := [];
Col2_2 := [chAlpha];
end;
DXR_BLEND_MODULATE:
begin
Col1_1 := [chRed, chGreen, chBlue];
Col1_2 := [chAlpha];
Col2_1 := [chRed, chGreen, chBlue];
Col2_2 := [chAlpha];
end;
DXR_BLEND_ADD:
begin
Col1_1 := [chRed, chGreen, chBlue, chAlpha];
Col1_2 := [];
Col2_1 := [chRed, chGreen, chBlue, chAlpha];
Col2_2 := [];
end;
end;
end;
var
c: TDXRColorChannels;
Col1_1, Col1_2, Col2_1, Col2_2: TDXRColorChannels;
begin
case Tree.Typ of
DXR_TREETYPE_LOADBLACK:
begin
// Load black color
end;
DXR_TREETYPE_LOADCOLOR:
begin
// Load color
end;
DXR_TREETYPE_LOADTEXTURE:
begin
// Load texel
end;
DXR_TREETYPE_LOADDESTPIXEL:
begin
// Load dest pixel
end;
DXR_TREETYPE_BLEND:
begin
// Blend color
GetBlendChannels(Tree.Blend, Col1_1, Col1_2, Col2_1, Col2_2);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -