PDA

View Full Version : D3DXFill2D for Filling a cubemap ?



Avatar
25-07-2004, 08:46 AM
Hi all !

I've been recently working on Per Pixel Lighting, and I've got a little problem with D3DXFill2D and D3DXFillCubeMap.

The function D3DXFillCubeMap seems to require a TD3DXFill2D. That type is a procedure/function pointer.

So, I define my own procedure to fill in the Cubemap, and then I have the D3DXFill2D points towards the procedure.

The problem is the error during the compilation :)

"Incompatible types "normal procedure and method pointer"" (this might be a bad translation from the French :) But I hope you see what I mean).

My procedure is defined with the same parameters(same name, same type) and is called FillCubeMap

After that, I just call the function D3DXFillCubeMap . this way :

D3DXFillCubeMap(CubeMap, FillCubeMap, nil);

And I get my error ... Any ideas ? (CubeMap is my output texture)

Thanks in advance :)

Bye
Avatar

Useless Hacker
26-07-2004, 02:03 PM
It sounds like you are trying to pass a method (of a class) and not a procedure. Even though the parameters as you see them are the same, methods have an additional hidden parameter which is the pointer to the instance of the class (Self).

The solution is to declare "FillCubeMap" as a normal procedure outside the class, and then pass the pointer to the class instance in as the third parameter to the function ("pData"). In the body of your "FillCubeMap" procedure you can then cast the "pData" parameter to your class in order to access members of the class.

Also note that the FillCubeMap procedure should have been declared exactly as the prototype:
TD3DXFill2D = procedure (out pOut: TD3DXVector4; const pTexCoord, pTexelSize: TD3DXVector2; var pData); cdecl;

For example:

TYourClass = class
public
blah: Integer;
end;

...

implementation

procedure (out pOut: TD3DXVector4; const pTexCoord, pTexelSize: TD3DXVector2; var pData); cdecl;
var
Self: TYourClass;
begin
Self := TYourClass(@pData);

...
Self.blah := 31337;
...
end;

...
var
YourClass: TYourClass;
...
D3DXFillCubeMap(CubeMap, FillCubeMap, YourClass^);
...

Try that; though you will probably find I have got something wrong somewhere, especially with the @s and ^s.

Avatar
26-07-2004, 03:32 PM
Welle since I just build a normalizing cubemap, I don't need pData :)

But thanks.

I have only 2 stupid questions after your post :)

1-

In the implementation ... The procedure needs a name doesn't it ? You just forgot it ? Or did I missed something ?

2-

What is cdecl ?

I'll look in delphi's help, but I never seen that before :)

anyway ! Thanks a lot for the answer ^^

Bye
Avatar

Avatar
26-07-2004, 04:17 PM
Okay ! I found my problem :) As you said my FillCubeMap function was a method of my Form's class and that didn't work !

But now I've got another problem. I got an exception when the function is called, during the transfer of one of the parameters into a local variable.

I compared to C sources and ... I saw something strange ... In C, the function D3DXFillCubeTexture is called with a TD3DXFill3D function ... not a 2D. But here in delphi, it is called with a 2D ... Why ?

Just to give an idea of what I'm doing here is my code (oh by the way ! No need of cdecl)


procedure FillCubeMap(out pOut : TD3DXVector4; const pTexCoord : TD3DXVector2; const pTexelSize : TD3DXVector2; var pData);
var
tC : TD3DXVector2;
Begin

tC := pTexCoord; // Seems to crash here

D3DXVec2Normalize(tC, tC);

D3DXVec2Scale(tC, tC, 0.5);
tC := D3DXVec2Add(tC, D3DXVector2(0.5, 0.5));

pOut := D3DXVector4(tC.x, tC.y, 0.0, 1.0);

end;

And here the code for the creation :

if Failed(Device.CreateCubeTexture(256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, CubeMap, nil)) then
Begin
ShowMessage('The creation of the CubeMap failed');
dxReady := False;
exit;
end;

if Failed(D3DXFillCubeTexture(CubeMap, FillCubeMap, tmp)) then
Begin
ShowMessage('D3DXFillCubeTexture failed');
dxReady := False;
exit;
end;

Any idea of what makes the app crash ?

Another question, since we can't put "nil" in the 3rd parameter of the function, any type is good ? Or should I have something special ?

Thanks :)
bye
Avatar

Clootie
26-07-2004, 07:42 PM
Please modify function declaration in D3DX9.pas you have. It should be:
function D3DXFillCubeTexture(
pCubeTexture: IDirect3DCubeTexture9;
pFunction: TD3DXFill3D;
pData: Pointer): HResult; stdcall; external d3dx9texDLL;

So, your code should be:
procedure FillCubeMap(out pOut: TD3DXVector4; const pTexCoord, pTexelSize: TD3DXVector3; var pData); stdcall;
Sorry for bug in headers :oops:

Clootie
26-07-2004, 07:48 PM
You CAN call D3DXFillCubeTexture(CubeMap, FillCubeMap, nil) and just do not use pData inside "generation" function. Probably it's better to use Pointer type for "generation" function too, I'll consider this for next SDK update.

And you NEED stdcall calling convention!!!

Avatar
26-07-2004, 07:50 PM
No problem Clootie :) Thanks for the correction :P

Avatar
26-07-2004, 08:20 PM
Hmmm ... There is no stdcall for TD3DXFill3D ... at least in my sources.

And it doesn't want of my nil since it's not a variable.

Finally, it's still crashing ...

Clootie
26-07-2004, 08:51 PM
Whats why I pointed you have to have new declaration.
Just insert this code in your source file:

type
TD3DXFill3D = procedure (out pOut: TD3DXVector4; const pTexCoord, pTexelSize: TD3DXVector3; var pData); stdcall;

function D3DXFillCubeTexture(
pCubeTexture: IDirect3DCubeTexture9;
pFunction: TD3DXFill3D;
pData: Pointer): HResult; stdcall; external d3dx9texDLL;

procedure FillCubeTexture(out pOut: TD3DXVector4; const pTexCoord, pTexelSize: TD3DXVector3; var pData); stdcall;
begin
// Do something
end;

begin
D3DXFillCubeTexture(texture, FillCubeTexture, nil);
end.

It should compile and run fine (but I have not tested it, too busy right now. You'll soon will know why 8)

Avatar
26-07-2004, 09:09 PM
hmmmm okay !

I bet you're working on the new version of the headers :)

Clootie
26-07-2004, 09:21 PM
Tssss.... :twisted:

Avatar
27-07-2004, 09:19 AM
Thanks ! It works !

Lova ya Clootie :lol:

Avatar
27-07-2004, 09:45 AM
Hum, just a stupid question but.

Can a stdcall raise a Violation exception ?

I just put the code in the init of my app (It wasn't there before), and it crashes during a simple affectation (external to the function D3DXFillCubeTexture) but only if I have D3DXFillCubeTexture called before ...

Strange isn't it ? Or did I miss (once again) something ?

Clootie
27-07-2004, 01:42 PM
Yes, calling convention can affect your stack, so just calling function with wrong calling conventions can make your app behave like a crazy!

I don't know about your code, but this one is working correctly:
[background=#FFFFFF][normal=#000000][number=#0000FF][string=#0000FF][comment=#248F24][reserved=#000000]
type
TD3DXFill3D = procedure (out pOut: TD3DXVector4; const pTexCoord, pTexelSize: TD3DXVector3; var pData); stdcall;

function D3DXFillCubeTexture(
pCubeTexture: IDirect3DCubeTexture9;
pFunction: TD3DXFill3D;
pData: Pointer): HResult; stdcall; external d3dx9texDLL;

procedure MineFillNormalizeCubeMap(out pOut: TD3DXVector4; const pTexCoord, pTexelSize: TD3DXVector3; var pData); stdcall;
var
v: TD3DXVector3;
begin
v.x:= Abs(v.x); v.y:= Abs(v.y); v.z:= Abs(v.z);
D3DXVec3Normalize(v, pTexCoord);
pOut:= D3DXVector4(v, 1);
end;

function CMyD3DApplication.InitDeviceObjects:HRESULT;
begin
// Initialize the font's internal textures
m_pFont.InitDeviceObjects(m_pd3dDevice);

// Cube map texture creation
D3DXCreateCubeTexture(m_pd3dDevice, 128, D3DX_DEFAULT, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, fCubeTexture);
D3DXFillCubeTexture(fCubeTexture, MineFillNormalizeCubeMap, nil);
D3DXSaveTextureToFile('CheckMe.dds', D3DXIFF_DDS, fCubeTexture, nil);

Result:= S_OK;
end;

Avatar
27-07-2004, 02:18 PM
ok :) Thanks a lot !

It's nearly working ;) But now I have to fix my shaders !

Clootie
28-07-2004, 08:02 PM
OK, final Delphi headers for DirectX 9 SDK Summer 2003 are out!
They contain fixes mentioned above and some others. 8)

Also some additional samples are posted at: http://clootie.narod.ru