DirectX 9 Mesh problem

Advanced game related topics
Motu
Enthusiast
Enthusiast
Posts: 160
Joined: Tue Oct 19, 2004 12:24 pm

DirectX 9 Mesh problem

Post by Motu »

I tried to convert an C++ example from a book to Purebasic. DX init and all this stuff is now fine, but I stuck on something.

I want to load a mesh from an x file (Dwarf.x - from the SDK examples).

Now to the problem:

----------------------------------------
DX9_String.s = "Dwarf.x" + Chr(0) ; File to be loaded
Result.l = D3DXLoadMeshFromX_(@DX9_String,#D3DXMESH_32BIT,D3DDevice,#Null,@*Mesh_ppMaterials,#Null,@Mesh_pNumMaterials,@Mesh_ppMesh) ; Load the X file - seems to work so far

If Result.l <> #D3D_OK: DX9_ErrorMSG(Result,#DX9ErrorSource002): EndIf ; Give Error if loading was not successful

*Mesh_ppMaterials2.S_D3DXMATERIAL ; Define second Pointer of the Typ D3DXMATERIAL
*Mesh_ppMaterials2 = *Mesh_ppMaterials ; Cast first Pointer to second on

*Mesh_ppMaterials2\GetBufferPointer() ; Use GetBufferPointer to get access to the buffer with the material and texture info
-------------------------------------------------

Well - and the last step is not working. It's obvious why - D3DXMATERIAL is a structure - not an interface and the funtion GetBufferPointer seems to be only part of the ID3DXBuffer Interface.

Anyway - my Book tells me to do so and directX examples also do. There it looks like:
D3DXMATERIAL* lpMaterials = (D3DXMATERIAL*)lpMatrialBuffer->GetBufferPointer()
And this seems to work for VC++ :?

Can anybody tell me how this is supose to work or what I have done wrong :?:
Codemonger
Enthusiast
Enthusiast
Posts: 384
Joined: Sat May 24, 2003 8:02 pm
Location: Canada
Contact:

I'm confused

Post by Codemonger »

Im' really really confused, did I miss something , but when did DX commands become an internal part of WinAPI or for that matter when did DX become an internal part of Pure Basic ?

I tried this (D3DXLoadMeshFromX_(1,2,3,4,5,6,7,8)) and it gave me a message that the function doesn't exist. How do you get this to work ?
<br>"I deliver Justice, not Mercy"

    - Codemonger, 2004 A.D.
Motu
Enthusiast
Enthusiast
Posts: 160
Joined: Tue Oct 19, 2004 12:24 pm

Post by Motu »

What version of Purebasic are you using?
Motu
Enthusiast
Enthusiast
Posts: 160
Joined: Tue Oct 19, 2004 12:24 pm

Post by Motu »

and you may want to take a Look at this:
viewtopic.php?t=9639&highlight=direct3dcreate9

D3D = Direct3DCreate9_(#D3D_SDK_VERSION)
works as well - only in the 3.9X Beta it allways crash.
Codemonger
Enthusiast
Enthusiast
Posts: 384
Joined: Sat May 24, 2003 8:02 pm
Location: Canada
Contact:

Post by Codemonger »

Motu wrote:and you may want to take a Look at this:
viewtopic.php?t=9639&highlight=direct3dcreate9

D3D = Direct3DCreate9_(#D3D_SDK_VERSION)
works as well - only in the 3.9X Beta it allways crash.
So you are using a wrapper library to a dll. Make sure that the DLL is in the same directory or in the system32 directory or in recognized path.

Maybe this is something you should post in the Beta thread, your code, and a link to the downloadable files for others to try. This is probably a problem the way functions are being called.
<br>"I deliver Justice, not Mercy"

    - Codemonger, 2004 A.D.
Motu
Enthusiast
Enthusiast
Posts: 160
Joined: Tue Oct 19, 2004 12:24 pm

Post by Motu »

Well, and what about the problem? :?
Codemonger
Enthusiast
Enthusiast
Posts: 384
Joined: Sat May 24, 2003 8:02 pm
Location: Canada
Contact:

Post by Codemonger »

here is the command you are looking for
HRESULT WINAPI D3DXLoadMeshFromX( LPCTSTR pFilename,
DWORD Options,
LPDIRECT3DDEVICE9 pD3DDevice,
LPD3DXBUFFER *ppAdjacency,
LPD3DXBUFFER *ppMaterials,
LPD3DXBUFFER *ppEffectInstances,
DWORD *pNumMaterials,
LPD3DXMESH *ppMesh
);
C/C++ language programmers are complicated and misleading, it's very hard to easily visualize at first glance and understand converting C/C++ to Basic. What you should be doing is go right from the MSDN library:

http://msdn.microsoft.com/library/defau ... irectx.asp

and not someone elses idea of simple programming (the book you mention). Converting Direct Headers from PB to C is simply not worth it and never mind converting existing code examples. It's damn hard and daunting.

Anyway you will notice that Buffer Interfaces are required and not materials, because it returns arrays of materials for you to use through the buffer interface. Seems like a pain in the ass, because it is. Sorry I can't provide any code, it's just too difficult and time consuming. What you could do is write wrapper commands in C++ to output c functions for you to use in PB, it would be much easier.
<br>"I deliver Justice, not Mercy"

    - Codemonger, 2004 A.D.
Moonshine
Enthusiast
Enthusiast
Posts: 263
Joined: Tue May 25, 2004 12:13 am
Location: UK

Post by Moonshine »

If you intend on getting anywhere with DX 9, download the SDK. The help files are invaluable at times like these. If you already have them, then you should be able to figure most things out on your own.
Mark my words, when you least expect it, your uppance will come...
Motu
Enthusiast
Enthusiast
Posts: 160
Joined: Tue Oct 19, 2004 12:24 pm

Typ casting

Post by Motu »

I think I figured out the problem now:

D3DXMATERIAL* lpMaterials = (D3DXMATERIAL*)lpMaterialBuffer->GetBufferPointer() Does some sort of explizit typ casting.

Anybody got an Idea how this works in Purebasic?
Codemonger
Enthusiast
Enthusiast
Posts: 384
Joined: Sat May 24, 2003 8:02 pm
Location: Canada
Contact:

Post by Codemonger »

Code: Select all

D3DXMATERIAL* lpMaterials = (D3DXMATERIAL*)lpMaterialBuffer->GetBufferPointer() Does some sort of explizit typ casting. 
Here is a breakdown of what this line is doing ...

Code: Select all

D3DXMATERIAL* lpMaterials 
This is a 32 pointer variable pointing to a D3DXMATERIAL structure. But no memory address has been given to it.

Code: Select all

=
Assignment operator - assigning the variable (above) the value to the right

Code: Select all

(D3DXMATERIAL*)
casting the return value to be compatible with the D3DXMATERIAL structure. This is compiler semantics and nothing more. Just tells the compiler what the return value should look like.

Code: Select all

lpMatrialBuffer
This is a pointer to a buffer object

Code: Select all

->GetBufferPointer()
This is a method being called by the buffer object to return a pointer to the start of the array of material data or D3DXMATERIAL structures

---------------------------------------------------------------------------------

This briefly explains it, I understand what's happening but to find the problem could even go back to your previous code which makes it very hard to debug. This is also why I detest C/C++ language, it's damn ugly, but powerful.
<br>"I deliver Justice, not Mercy"

    - Codemonger, 2004 A.D.
Motu
Enthusiast
Enthusiast
Posts: 160
Joined: Tue Oct 19, 2004 12:24 pm

Post by Motu »

So it should look like:

D3DXMATERIAL* lpMaterials = (D3DXMATERIAL*)lpMaterialBuffer->GetBufferPointer()

->

lpMaterials = lpMaterialBuffer\GetBufferPointer()

Right?

But this drives to a crash...
Motu
Enthusiast
Enthusiast
Posts: 160
Joined: Tue Oct 19, 2004 12:24 pm

Example

Post by Motu »

Okay here is an example of the problem - would be nice if anybody could take a look at it

Code: Select all


IncludeFile "Include\D3D9.pbi"           ; D3D9 Basis Funktionen
IncludeFile "Include\D3D9Interface.pbi"  ; D3DInterfaces
IncludeFile "Include\Error_Msg.pbi"      ; Standart Fehlermeluden
IncludeFile "Include\Zero_Memory.pbi"    ; Löscht Speicherbereiche
IncludeFile "Include\DX9_Constant.pbi"   ; Zusätzliche Constanten
IncludeFile "Include\DX9_Structure.pbi"  ; DirectX Structuren
#DXLib = 0

Global D3D.IDirect3D9
Global D3DDevice.IDirect3DDevice9
Global D3DVertexBuffer.IDirect3DVertexBuffer9
Global hWnd.l

Global Mesh_ppAdjacency.ID3DXBuffer       ;  
Global Mesh_ppMaterials.ID3DXBuffer       ;  
Global Mesh_ppEffectInstances.ID3DXBuffer ; 
Global Mesh_pNumMaterials.l               ;  
Global Mesh_ppMesh.ID3DXMesh              ;  

; Beendet DirectX und schliesst das Programm
Procedure DX9_ReInit()
; Fonts aus dem Speicher entfernen
If D3DDevice <> 0: D3DDevice\Release(): EndIf
If D3D <> 0: D3D\Release(): EndIf
End
EndProcedure
; Ende DX9_ReInit()

; Öffnet einen DirectX 9 Screen
Procedure DX9_InitScreen(LangX.l,LangY.l)
 If OpenLibrary(#DXLib, "d3dx9d.dll") = 0: Error_Msg("Cannot open D3DX9.dll"): EndIf
 hWnd = OpenWindow(1, 0, 0, LangX, LangY, #WS_OVERLAPPEDWINDOW|#PB_Window_ScreenCentered , "Master Engine")
 D3D = Direct3DCreate9_(#D3D_SDK_VERSION)
 If D3D = 0: Error_Msg("Can't init directX 9"): EndIf
 D3DPP.D3DPRESENT_PARAMETERS
 D3DPP\BackBufferWidth = LangX
 D3DPP\BackBufferHeight = LangY        
 D3DPP\BackBufferFormat = #D3DFMT_A8R8G8B8    ; 32bit
 D3DPP\BackBufferCount = 2                    ;(1:Doppelbuffering, 2:Trippelbuffering)
 D3DPP\MultiSampleType = #D3DMULTISAMPLE_NONE ; ??? Was macht das
 D3DPP\SwapEffect = #D3DSWAPEFFECT_DISCARD    ; Schnellst mögliche Methode
 D3DPP\Windowed = #False                      ; Fenster Modus
 D3DPP\EnableAutoDepthStencil =  #True        ; ??? Was macht das? Ist das toll?
 D3DPP\AutoDepthStencilFormat = #D3DFMT_D24S8; ??? Ist das am besten
 D3DPP\FullScreen_RefreshRateInHz = #D3DPRESENT_RATE_DEFAULT
 If #D3D_OK <> D3D\CreateDevice(#D3DADAPTER_DEFAULT,#D3DDEVTYPE_HAL,hWnd,#D3DCREATE_HARDWARE_VERTEXPROCESSING,@D3DPP,@D3DDevice) 
  Error_Msg("Can't create a DirectX 9 Device")
 EndIf
EndProcedure 
; Ende DX9_InitScreen(fullscreen.l,LangX.l,LangY.l,Bit.l)

DX9_InitScreen(1024,768)

If IsFunction(#DXLib,"D3DXCreateBuffer") = 0
 Error_Msg("D3DXCreateBuffer is not a function of Lib")
EndIf

If #D3D_OK <> CallFunction(#DXLib,"D3DXCreateBuffer",1000,@Mesh_ppMaterials)
 Error_Msg("Buffer cannot be created")
EndIf

; *****************
Value.l = Mesh_ppMaterials\GetBufferSize() ; Returns 2 !!!!
Error_Msg(Str(Value)) ; Make a comment out of this line -> Crash
Value.l = Mesh_ppMaterials\GetBufferPointer() ; Crashes everything !!!
Error_Msg(Str(Value))
; *****************

DX9_ReInit()

The main problem semse to be the last lines. Also the buffer is defined as 1000 Bytes, GetBufferSize() returns 2 8O
And if you remove the Error_Msg line befor it Mesh_ppMaterials\GetBufferPointer() will crash the program. :!: Any suggestions?

If you want to take a look at it download it here:

www.master-creating.de/files/DX9MeshBug.zip
Motu
Enthusiast
Enthusiast
Posts: 160
Joined: Tue Oct 19, 2004 12:24 pm

Post by Motu »

Juhu - I found the Error. 8)

There thems to be a bug in the includefiles I was using (not sure - but i guess they where from codemonger?) - THIS is pain in the ass :wink:

the ID3DXBuffer mised the IUnknowen Interface - @codemonger maybe you are going to change this (if they were from you)
Post Reply