Hello,

I have a problem with DirectX 9 functions. I don't use includes made by homer because some functions are missing in my version and I did not get a newer one.
So I tried to use a method to call that functions that should work even if you have included nothing that has to do with DirectX.
I want to do it like ti_mo_n explained in his post from May 03, 2004:
consider the function:

IDirect3D9 *Direct3DCreate9 (UINT SDKVersion);

Return Value: If successful, this function returns a pointer to an IDirect3D9 interface; otherwise, a NULL pointer is returned.

"pointer to an IDirect3D9 interface" is actually a pointer to virtual table of all interface's methods.

let's say that it returned 100h

in my includes (attached above) u can find:

IDirect3D9_QueryInterface        EQU  000000000h
IDirect3D9_AddRef            EQU  000000004h
IDirect3D9_Release            EQU  000000008h
IDirect3D9_RegisterSoftwareDevice      EQU  00000000Ch
IDirect3D9_GetAdapterCount        EQU  000000010h
IDirect3D9_GetAdapterIdentifier      EQU  000000014h

etc. etc.

so:
at memory location "100h" there's a real addres to the method "Query Interface"
so u can do:

Code:

mydirect3d dd ?                                      ;will be a pointer d3d9's virtual table
myqueryintaddress dd ?                          ;will be a pointer to query interface
myGetAdapterIdentifier dd ?                    ;will be a pointer to GetAdapterIdentifier
myadident D3DADAPTER_IDENTIFIER9 ?  ;D3DADAPTER_IDENTIFIER9 structure


  call Direct3DCreate9, 31  ;create d3d9
  xchg ecx, eax
  jecxz failed  ;stop if eax == 0
  mov ecx,
  mov edx,
  mov , ecx
  mov , edx

from now on u can easily use these methods like standard API functions:

Code:

  push offset myadident
  push D3DENUM_WHQL_LEVEL
  push D3DADAPTER_DEFAULT
  push   ; this is required by COM architecture - u MUST push the pointer of the object you're
                                ; reffering to _AS_FIRST_PARAMETER_
  call
  xchg ecx, eax
  jecxz returned_S_OK

pointer to some interface is actually a pointer to Vtable.  vtable is a table of pointers to actual methods.

that's all


But that does not work for me, maybe I have made a mistake, please have a look at my code:

dllname        db 'd3d9.dll',0
funcname        db 'Direct3DCreate9',0
pD3D            dd 0
GetAdapterDisplayMode equ 20h
myGetAdapterDisplayMode dd 0

.code
    invoke LoadLibrary,addr dllname
    invoke GetProcAddress,eax,addr funcname

    push D3D_SDK_VERSION
    call eax
    .if eax == 0
        invoke MessageBox,0,0,0,0
        invoke ExitProcess,0
    .endif
    mov pD3D,eax                    ;till here everything seems fine

    mov ecx,
    mov ,ecx
    push offset d3d_displaymode
    push D3DADAPTER_DEFAULT
    push
    call     ;when executed this code does not go
                                                    ;past this point, program shuts down before


Can anyone see my mistake because I can't. Or tells ti_mo_n crap and this sort of using DirectX functions isn't possible. I personally think he isn't because I saw that kind of code already on another forum.
Posted on 2006-09-25 07:59:58 by ChigpA
It should be:
            mov eax,  ; this one is not required in your example, because eax still holds the pointer to the VTable.
            mov ecx,
            mov ecx, ; Make sure that 'GetAdapterDisplayMode' == 20h (dec: 32)
            mov , ecx
            push offset d3d_displaymode
            push D3DADAPTER_DEFAULT
            push eax
            call

or anything equivalent.
Posted on 2006-09-25 10:36:03 by ti_mo_n
Thanx man, seems to work.

regards ChigpA
Posted on 2006-09-25 13:07:44 by ChigpA
Next Problem. I want to draw simple Text using D3DXCreateFont function. And then between BeginScene and EndScene the DrawText function from the returned interface.

But when trying to resolve the ProcAddress of D3DXCreateFont it returns 0. Here is my code:
funcname2       db 'D3DXCreateFontA',0
convstr2        db '%X',0
buffer1        db 128 dup(0)

    invoke LoadLibrary,addr dllname
    invoke GetProcAddress,eax,addr funcname2
    mov ecx,eax
    invoke wsprintf,addr buffer1,addr convstr2,ecx      ;this stuff is just for showing me
    invoke MessageBox,0,addr buffer1,0,0                ;the result of GetProcAddress
    invoke ExitProcess,0                                                        ;and then exit


I already tried other names for the CreateFont function like "D3DXCreateFont" and "D3DXCreateFontW" but nothing happened ... always 0 (NULL) was returned
Posted on 2006-09-25 13:55:16 by ChigpA
This problem has been answered many times here (a.k.a. "where is my d3dx.dll?"). D3DX is a helper library that 'does stuff for you'. When debugging, people link with D3DXD.dll (note the letter 'D' after the "d3dx"). When not debugging, people link statically with d3dx.lib. There was no d3dx.dll up till a year ago (or something around that date). About a year ago MS released DX9.0c which came with d3dx.dll (they're named "d3dx9_24.dll", "d3dx9_25.dll", "d3dx9_26.dll" and so on. The newest one is "d3dx9_30.dll" which came with the August 2006 release). Just make sure you have this DLL and that you load it properly with LoadLibrary. Make sure that you're not loading the debug version (the one with 'd') which is slower and bigger.
Posted on 2006-09-25 14:07:06 by ti_mo_n
Thank you again.
Posted on 2006-09-25 14:27:51 by ChigpA
Aaaaaaaaaaaaaaand next Question  ;)

I created my DirectX App but it won't draw my text.

I created my font this way:
    invoke LoadLibrary,addr dllname2
    invoke GetProcAddress,eax,addr funcname2
    mov ecx,eax
    push offset pfont
    push offset FontName
    push (DEFAULT_PITCH+FF_DONTCARE)
    push 4
    push OUT_DEFAULT_PRECIS
    push DEFAULT_CHARSET
    push FALSE
    push 1
    push FW_NORMAL
    push 0
    push 22
    push pd3d_device
    call ecx


and I render that stuff this way
    push 0
    push fp1pt0          ;that is a float I specified: 1.0f
    push 00000000h
    push D3DCLEAR_TARGET
    push 0
    push 0
    mov eax,pd3d_device
    push eax
    mov ecx,
    call dword ptr

    mov eax,pd3d_device
    push eax
    mov ecx,
    call dword ptr

    invoke GetClientRect,hwndDlg,addr rct
    push 00FFFFFFh
    push (DT_LEFT+DT_WORDBREAK)
    push offset rct
    push -1
    push offset TextToDisplay
    push 0
    mov eax,pfont
    push eax
    mov ecx,
    call dword ptr

    mov eax,pd3d_device
    push eax
    mov ecx,
    call dword ptr

    push 0
    push 0
    push 0
    push 0
    mov eax,pd3d_device
    push eax
    mov ecx,
    call dword ptr


This should at least draw a simple text with white color on a black background. But on my PC it doesn't. The text is simply not there or invisible I don't know. The rest of the code works, only the stuff that has to do with creating the font and drawing the text seems not to be right.
Help needed again ... please
Posted on 2006-09-25 15:20:39 by ChigpA
It's hard to debug with only this code. It may have something to do with the cameras and/or face culling. Try turning the face culling and the lighting off completely. Try playing with the camera to 'find' the text you're (supposedly) rendering.
Posted on 2006-09-25 15:44:16 by ti_mo_n
By default, Lighting is Disabled and the Camera is pointing in the Z+ direction (0,0,1), so you don't need to worry about Lighting, but you DO need to worry about where your geometry is placed in 3D space.

Need more help?
Posted on 2006-09-27 02:53:45 by Homer
Oh yes, any help is appreciated. Especially with that DirectX stuff which comes (of course because it is from Mickeysoft) only with C++ support.  :mad:

So what is up with this geometry in 3D space. I just followed a C++ Tutorial from www.drunkenhyena.com as good as I can.
...
You mentioned something about Z directive. I know that I can deal with X and Y directive by using the RECT structure, this should push my text (if I want) all over the screen.
But a Z directive is nowhere mentioned nor can I specify one.

P.S.: I attached my source to this post, simply compile it with:
ml /c /Cp /coff directx9test.asm
link /subsystem:windows directx9test.obj directx9test.res


Attachments:
Posted on 2006-09-27 11:11:21 by ChigpA
The first and most important piece of advice I'm going to give you is this: ALWAYS check the values returned from function calls.

Now about that Z component.. Direct3D is a 3D environment, you have to imagine that the screen has Depth as well as Width and Height.
When you draw stuff in 3D, you draw it at a location in 3D space, not 2D space..

I can tell you exactly why your code is failing though, and I will.
You're calling IDirect3DDevice9.DrawText, and it doesn't exist !!
DrawText is a method of the ID3DXFont class ;)
Don't use pD3DDevice for that call, use the interfacepointer you obtained when you created your font instead :P
Posted on 2006-09-28 11:06:20 by Homer
You're calling IDirect3DDevice9.DrawText, and it doesn't exist !!
DrawText is a method of the ID3DXFont class ;)

So ChigpA, you were calling IDirect3DDevice9.GetSwapChain, as it has the same offset in the vtable of the IDirect3DDevice9, as the DrawText has in the vtable of ID3DXFont ^^
Posted on 2006-09-29 13:36:12 by ti_mo_n

You're calling IDirect3DDevice9.DrawText, and it doesn't exist !!
DrawText is a method of the ID3DXFont class ;)

So ChigpA, you were calling IDirect3DDevice9.GetSwapChain, as it has the same offset in the vtable of the IDirect3DDevice9, as the DrawText has in the vtable of ID3DXFont ^^


No I don't use DrawText out of the vtable of IDirect3DDevice9, I use the right vtable, have a closer look to my code, I do it this way:
mov eax,pfont   ;here is my pointer to D3DXFont and not IDirect3DDevice9
push eax
mov ecx,
call dword ptr       ;DrawText=38h


Posted on 2006-09-29 13:50:31 by ChigpA
I was just guessing from Homer's post :mrgreen: Check out the return values. If everything returns S_OK or equivalent, then consider linking with the debug library (the one with 'd') and then using MS's D3Dspy (which comes with the DX SDK). The D3Dspy lets you see the return values as well ^^
Posted on 2006-09-29 14:08:27 by ti_mo_n
Yeah my mistake, sorry.
The problem is a really simple one.
I checked your binary executable with ollydebug.
First I checked that the Font is being created by checking the return value, its S_OK, so that wasn't a problem.
Then I looked at the params to the DrawText call, and I noticed that the color you chose is 0BGR , ie no alpha.
I edited the binary code , changing the color to -1 (white with full alpha) and your text appears - yay !!
It seems that Alpha Blending is enabled by default in D3D9, and that your text was being rendered with a 100% transparent color :P

I really don't recommend this style of programming for interfacing with COM objects.. it makes your life more painful than it has to be.. if you need a link to download a more recent SDK, just let me know.

Posted on 2006-09-30 00:04:08 by Homer
simple but heavy mistake, but now it works, thank you guys
Posted on 2006-09-30 08:20:42 by ChigpA