Hint: UpdateTexture. :roll:
Hint: UpdateTexture. :roll:
There are only 10 types of people in this world; those who understand binary and those who don't.
I checked MSDN but i still dont understand the exact function of Updatetexture. Why are the source/destenation parameters nessecary and where to put it in the code. This may be a stupid question but i never worked with UpdateTexture.
Can someone expain how it works??
Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.
First you create texture in SYSTEMMEM pool; next you fill it with your data; create texture in POOL_DEFAULT; do pd3dDevice.UpdateTexture(source_tex_in_sys_mem, destin_tex_in_default_pool) call.
That's all!
There are only 10 types of people in this world; those who understand binary and those who don't.
Thanx.. thats the info i needed. I implented Updatetexture and it seems to work now. :razz:
About the for i:=0 to fWidth*2-1 do thing.
I figured out why multiplying with 2 was nessecary.
It's just because i moved one byte instead of two (wich was nessecary because its 16bit mode )
[pascal]
//original wrong code
P := PWord(Dword(P) + 1);
//solution
P := PWord(Dword(P) + 2);
[/pascal]
I admit, it's a stupid mistake. :roll: ops:
Okay.. Transparency seems to work now, even without my own fancy lock/unlock stuff.
Although it's not needed, i will keep it in my engine and use it for texture-pre-processing,
The code below creates a texture from a given file, and sets transparency to the given color. you can also pass a PreProcessor to this procedure.
This allows you to easily manipulate the pixel data.
Here is the code (get ready... Its a lot) :twisted: :
[pascal]
//the procedure type
TBF_PPFunction = function (x,y: integer; TrueColor: boolean; color: cardinal): cardinal;
.....
procedure TBF_Texture.CreateFromFile(FileName: pChar; TransColor: cardinal; Preprocessor: TBF_PPFunction);
var HR: Hresult;
Desc: D3DSurface_Desc; //surface description
x,y: integer;
nFormat: TD3DFORMAT; //current color format
D3DRect: _D3DLOCKED_RECT;
P1: PWord; //pointer for 16 bit graphics
P2: PDword; //pointer for 32 bit graphics
Surf: IDirect3dSurface8; //Direct3d Surface
begin
if FileExists(FileName) then
begin
//determine texture format
if not (fParent.fDisplayMode in [dm640x480x16,dm800x600x16,dm1024x768x16]) then
nFormat := D3DFMT_a8r8g8b8
else
nFormat := D3DFMT_A1R5G5B5;
//create sysmem texture
HR := D3DXCreateTextureFromFileEx(fParent.fD3DDevice,Fil eName,0,0,0,0,
nFormat,D3DPOOL_SYSTEMMEM,D3DX_FILTER_NONE,
D3DX_DEFAULT,Transcolor,nil,nil,fSysTexture);
if Failed(HR) then
begin
ReportError(True,Self,E_SYSTEXTURE_CANNOTMAKE,0);
Exit;
end;
//Retrieve size
fSysTexture.GetLevelDesc(0,Desc);
fWidth := Desc.Width;
fHeight := Desc.Height;
if @Preprocessor <> nil then
begin
//retreving surface level
HR := fSysTexture.GetSurfaceLevel(0,surf);
if Failed(HR) then
begin
ReportError(True,Self,E_TEXTURE_CANNOTGETLVL,HR);
Exit;
end;
//locking surface
HR := Surf.LockRect(D3DRect,nil,D3DLOCk_NOSYSLOCK);
if Failed(HR) then
begin
ReportError(True,Self,E_CANNOT_LOCK_SURFACE,HR);
Exit;
end else
if nFormat = D3DFMT_A1R5G5B5 then
begin
//when in 16 bit mode, use words instead of Dwords
Log('start manipulating pixels');
try
for y:=0 to fHeight do
begin
P1 := PWord(Dword(D3DRect.pBits) + D3DRect.Pitch * y);
for x:=0 to fWidth do
begin
P1^ := Convert8888to1555(Preprocessor(x,y,False,Convert15 55to8888(P1^)));
P1 := PWord(Dword(P1) + 2);
end;
end;
finally
//finally unlock it
Surf.UnlockRect;
end;
end else begin
//do the same when using 32 bit mode
try
for y:=0 to fHeight do
begin
P2 := PDWord(Dword(D3DRect.pBits) + D3DRect.Pitch * y);
for x:=0 to fWidth do
begin
P2^ := Preprocessor(x,y,True,P2^);
P2 := PDWord(Dword(P2) + 4);
end;
end;
finally
Surf.UnlockRect;
end;
end;
end;
//create videomem texture
HR := D3DXCreateTexture(fParent.fD3DDevice,fWidth,fheigh t,0,0,nFormat,D3DPOOL_DEFAULT,fTexture);
if Failed(HR) then
begin
ReportError(True,Self,E_TEXTURE_CANNOTMAKE,0);
Exit;
end;
//update texture
HR := fParent.fD3DDevice.UpdateTexture(fsysTexture,fText ure);
if Failed(HR) then
begin
ReportError(True,Self,E_TEXTURE_UPDATE_FAILED,HR);
Exit;
end;
end else begin
ReportError(True,Self,E_FILE_NOT_FOUND,0);
Exit;
end;
end;
//----------------------------------------------
//the preprocessing function
//----------------------------------------------
function Process(x,y: integer; TrueColor: boolean; color: cardinal): cardinal;
var A,R,G,B: byte;
begin
//if color is transparent, leave it alone
if color = $00000000 then
A := 0
else
//when 32bit mode is active, use the alpha-channel for special fx.
if TrueColor then
A := Byte(x*4)
else
A := 255;
R := GetRValue(Color);
G := GetGValue(Color);
B := GetBValue(Color);
//make the final color
Result := MakeColor(a,r,g,b);
end;
//-----------------------------------------------
//the needed conversion functions
//-----------------------------------------------
function Convert8888To1555(Color: Cardinal): Word;
var R,G,B,A: word;
begin
B := Word(Color) and $01ff;
G := Word(Color shr and $01ff;
R := Word(Color shr 16) and $01ff;
A := Word(Color shr 24) and $0001;
B := B div 8;
G := G div 8;
R := R div 8;
Result := (A shl 15) or (R shl 10) or (G shl 5) or B;
end;
function Convert1555to8888(Color: Word): cardinal;
begin
//checking whether transparent
if ((Color and $8000) = $8000) then
Result := $ff000000
else
Result := $00000000;
//convert RGB data
Result := Result or ((Color and $7C00) shl 9);
Result := Result or ((Color and $03E0) shl 6);
Result := Result or ((Color and $001F) shl 3);
end;
//----------------------------------------------------
//Some other stuff needed in the "Process" function
//WARNING: these functions only work for D3DFMT_A8R8G8B8 color-format
//----------------------------------------------------
//get R component of a color
function GetRValue(Color: Cardinal): byte;
begin
Result := Byte(Color shr 16);
end;
//get G component of a color
function GetGValue(Color: Cardinal): byte;
begin
Result := Byte(Color shr ;
end;
//get b component of a color
function GetBValue(Color: Cardinal): byte;
begin
Result := Byte(Color);
end;
//make a color from single RGB values
function MakeColor(a,r,g,b: byte): Cardinal; overload;
begin
Result := (a shl 24) or (r shl 16) or (g shl or (b);
end;
[/pascal]
You should do this:
[pascal]
InitalizeFromFile('c:\texture.bmp',$ff0000ff,@Proc ess);
//or
InitalizeFromFile('c:\texture.bmp',$ff0000ff,nil);
//use the last one if you dont want to use
//preprocessing
[/pascal]
This code still contains some of my own error checking, wich you should remove before using.
This code has also some nice color manipulation and conversion routines, I have done some tests and they seem to work quite well.
feel free to use them for your games.
If anyone has a suggestion, or improvement Please post :razz:
Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.
Bookmarks