Thought I'd create a thread where I can lay out a tutorial in steps starting with a basic win32 skeleton and working from there towards a full d3d game, since I'm teaching several would-be gamecoders at the moment, it seemed appropriate to share with the asm community at the same time.
I am looking forwards to seeing much feedback in this thread !!
Any sourcecode published here will be absolutely open-sourced.
That means you can do anything you like with it.

Does this thread sound like something that we can use?
Posted on 2003-10-08 02:38:46 by Homer
nice ideea :alright:

it would be nice to have it as a htm, more like Iczelion tutorials (.htm and sources in a zip file).
Posted on 2003-10-08 03:11:56 by TBD
Superb :alright:
Posted on 2003-10-08 03:31:12 by AceEmbler
I'm going to assume that the average village idiot who downloaded MASM and installed it has managed to find the ProStart tool and create a basic win32 skeleton.
I'm not going to get bogged down in refining the skeleton for now.

Without further ado...

The first thing we should know about Direct3D is that D3D basically has two modes of operation - it can run "Windowed", and it can run "FullScreen".
I'm sure we all understand what these look like.

What is less clear is that in order to fire up D3D in the first place, we already need to have an application window !!! That means we NEED a basic win32 skeleton to make at LEAST an application window.

The reason is because when we initialize D3D, it asks for the handle of an already existing window.

Most of the functions we will use in D3D programming are only available through COM interfaces, but don't be frightened, we have a solution.

My tutorials will rely on the "mcall" macro which we will use to call those nasty COM functions, and it works basically the same way as "invoke" does.
We'll cover that ground and more as we go.

Our first mission then is to lay out a SIMPLE win32 skeleton (use ProStart and disable all the bells and whistles). It doesn't need to do ANYTHING except create a window.

I'm not going to explain how the win32 skeleton works, I did that in my MASM FOR MORONS tutorial if you care to search for it.

Create a folder inside your MASM folder, and build your project skeleton inside it.
Next we'll describe a basic InitD3D procedure and basic D3DCleanup procedure, and maybe we'll also add a sketchy Render function that does little more than clear the screen to a color.
If we manage to fit those into the next post, we'll have a DirectX application that does "something". Nice start, eh?

I know I haven't actually said much, nevertheless, please don't hesitate to ask questions along the way.
Posted on 2003-10-08 08:59:22 by Homer
i'm looking forward for such a tutorial! it's all i waited for :)
which dx are you going to use? will you give sources for includes etc.?
thank you very much!

NOP
Posted on 2003-10-08 13:01:52 by NOP-erator
The tutorial will be based around DirectX8.1b which is in my opinion the most universal version in use at the moment and possibly for the next couple of years.
Source will be provided for includes where necessary, and we'll even have to make a few REPAIRS to the includes for some functions.

Mostly we'll be using Scronty's includes for DirectX8.1, search the board for a link to his download pages.

Anyway, I'm sure some of you are keen to get started, so let's :)

The first thing I'm going to post is a basic Win32 Skeleton, as well as two important procedures, InitD3D and D3DCleanup.
The Skeleton also contains a basic Render driver in the "MessagePump", but you'll notice it's been disabled until we add a basic Render function.

You will need to have libci.lib and uuid.lib in the project folder if you want to build the project as they are "late-bound" by masm's Linker.

Notice how tidy (and short) the source is when we use $invoke correctly?

This thread is officially open for debate.
Posted on 2003-10-10 02:23:51 by Homer
If you look at the D3DCleanup procedure, you'll notice we use a macro called _saferelease which is just to keep things tidy.

I'd just like to describe what _saferelease really does.
If you imagine the following code:

.if pInterface != NULL
mcall ,IUnknown_Release
mov pInterface, NULL
.endif

THATS WHAT _saferelease DOES !!!

We hand it a variable name. The macro checks if the variable is NULL, and if it IS NOT NULL, the macro assumes that the variable contains a pointer to a DX interface, which it will release with IUnknown_Release (works for all interfaces), and sets the Var to NULL so that we won't accidentally try to use it or release it again.
Posted on 2003-10-10 02:30:19 by Homer
Does anyone NOT understand what an "interface" is, or how to use the "mcall" macro to call functions belonging to an interface?
Posted on 2003-10-10 02:31:48 by Homer
I use my own interfacing macros, but I can grok what you mean.

Incidentally, the uuid.lib included with MASM v8 doesn't contain the IID_IUnknown GUID any more. This used to be covered for by its inclusion in dxguid.lib from the DirectX SDK, but as of the DX9 SDK it's been removed from there too. If you get a link error complaining about IID_IUnknown, get the uuid.lib from MASM v7, or define it yourself with this code in your .data section:



IID_IUnknown GUID {0,0,0,<0C0h,0,0,0,0,0,0,046h>}
Posted on 2003-10-10 03:17:29 by Tatterdemalian
All the GUIDS we will use have been defined manually in one of the header files included in the posted source (I can't remember which, but it's part of MASMv8 anyway...)

Even though we may define all guids manually, UUID.LIB is STILL required by the Linker, it seems that its used internally by DX.

As for your choice of COM Interface access methods, if you don't want to use MCALL or don't like that interface declaration method, and you understand what you are doing, by all means, choose what you like.
If you are new to COM method calls, or don't have a VERY good idea what we are doing when we call COM methods, I recommend sticking to MCALL at least until you do.

There's only one drawback to using MCALL, which is that internally it uses the EDX register, which it trashes during an MCALL, so if we WANT to use EDX and we WANT to use mcall, we should bear this in mind.
Posted on 2003-10-10 04:06:35 by Homer
it seems that the includes i once downloaded from scrontsofts site are not complete.. trying to build your project i'm always missing files! :mad:

some of them i could find in my dx7 include files, but some of them i can't find anywhere. the last i had to stop on was:

d3dx8math_fkt.def

i also had to change a line in your projectdata.inc file from
include c:\masm32\include\dx81include\d3dx8math.inc
to
include c:\masm32\include\d3dx8math.inc

why using an extra folder for just one file!?

is it possible that you can upload your complete include and lib files, and everything is needed, so that i can download them? the most important thing for me now is, that i can get started..
i also offer to upload the includes and libs to my webspace at university, so that it is accessible to everybody for a long time, so you don't need to bother yours.

thanks for help!

bye
Posted on 2003-10-10 04:28:56 by NOP-erator
I just ripped the guts out of one of my existing D3D projects - as for the path issue, I keep two folders with separate includes for DX8.0 and DX8.1, thats all.

The file you found missing is from Caleb's DX8 includes.
We aren't actually using this math include yet, so you COULD comment it out.
It contains a bunch of nice floating point math macros coded by Caleb.
We'll for SURE use it later because most of these macros are MUCH faster than their DX equivalents, even though they are coded "naively".
That means that if we reworked them with cpu-detecting casecode, they could be possibly even FASTER STILL.

Here it is :)
Posted on 2003-10-10 04:39:27 by Homer
Please expect some minor teething problems with include files.
Be aware that the DX8.0 and DX8.1 includes ARE NOT THE SAME !!!
Neither are the associated LIB files.

We are using the DX8.1a or DX8.1b libs, and we are using the DX8.1 includes from Scronty.

Should anyone have problems with their INC files, please verify that you have the correct dx version inc and lib files.

If you get it to compile ONCE, you know you are on the way.

A final note to disregard the "file not found" error during compile.
This is a result of the linker not finding an RC file, you will find that an exe file in fact WAS created, if you look :)
Posted on 2003-10-10 04:50:49 by Homer
ok.. downloaded calebs includes.. (actually only defs in the include folder)
now the following problem while building:



Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.

Assembling: c:\masm32\nop\dxproject1\dxproject\project.asm
c:\masm32\include\d3dx8math_fkt.def(5611) : error A2005: symbol redefinition : D
3DXVec2Length
c:\masm32\include\d3dx8math_fkt.def(5613) : error A2006: undefined symbol : pV
c:\masm32\include\d3dx8math_fkt.def(5618) : fatal error A1008: unmatched macro n
esting
_
Assembly Error
Dr?cken Sie eine beliebige Taste . . .


thank you for your effort
Posted on 2003-10-10 04:51:17 by NOP-erator
c:\masm32\include\d3dx8math_fkt.def(5611) : error A2005: symbol redefinition : D


look in the .FKT file for the PROTO associated with the redefined function.
Comment it out - it's defined in Scronty's include.
Posted on 2003-10-10 04:55:08 by Homer
When you are debugging compile errors like this, ALWAYS FIX THE VERY FIRST PROBLEM before trying to fix the rest.
Very often, subsequent errors are generated by the preceeding one.



If you want to disable Scronty's PROTO and use the macro version instead,

D3DXVec2Length macro pV : REQ

IFDIFI pV, <FPUStack>
__LoadFloat2 pV1
ENDIF
__LengthFloat2
endm


The problem to fix in the FKT file if you look, pV1 is the WRONG NAME
The macro uses the name pV
Change one of them so the name matches, and the macro will be ok.

As I said earlier, we'll find a few minor errors to repair in the includes as we go.
There will be more to come , but we should get a compile at this point.
Posted on 2003-10-10 04:56:15 by Homer
ok, there were some more symbol redefinitions.. some of them i could comment out in the inc file, but some others i had to comment out the whole macro in the d3dx8math_fkt.def file...
the pV error disappeared automatically, as you said when giving the hint to remove the first error first.
it assembles now, but linking is a problem.. missing a file again ^^'



LINK : fatal error LNK1104: cannot open file "c:\masm32\lib\d3dxof.lib"
_
Link error


my offer uploading the complete includes and libs to one location is still up to date :)

thanks for you PM, but i get notified about answers in the thread.

so long,
NOP
Posted on 2003-10-10 05:54:21 by NOP-erator
Your Missing File...


(I'd rather not post all the incs and libs, its an educational experience to fix these problems at least ONCE yourself, I am here to help..)\

D3DXOF is another file that could be commented out (for now), since to date we call NO functions that it contains (it provides support for XFile helper functions).
Posted on 2003-10-10 07:28:24 by Homer
The macros in the FKT file are ALTERNATIVES to the associated DX functions of the same name. We can't call a macro and a procedure the same name, so we have to disable either a PROTO to a procedure, or comment out the macro of the same name. I have stated that the FKT macros are in fact preferable to the DX functions, but they will BOTH work, and furthermore, you can happily mix and match them provided the names are not duplicated. If you WANT to, you can rename the macros and have the full complement of both codebases at your disposal.
Does this make sense?
Posted on 2003-10-10 07:40:57 by Homer
Moving right along, we can afford to add a rather sketchy Render function, so we can ummm ... SEE SOMETHING !!

The following source should be saved as "Render.inc"
It should be included in the Project.asm file Includez section (where the others are).
Project.asm contains a call to this procedure which needs to be uncommented.
Now we can compile again, and we should see a BLACK SCREEN instead of a simple GREY one. Big woops !! Are you excited yet? :tongue:

.data
fp1 FLOAT 1.0f
.code

Render PROC hWin:HWND, MyFillColor:DWORD
mcall ,IDirect3DDevice8_Clear,0, NULL, (D3DCLEAR_TARGET OR D3DCLEAR_ZBUFFER), MyFillColor, fp1, 0
mcall ,IDirect3DDevice8_BeginScene
;==================================
;We aren't drawing anything yet
;But if we were, it would happen here :)
;==================================
mcall ,IDirect3DDevice8_EndScene
mcall ,IDirect3DDevice8_Present, 0, 0, 0, 0 ;Present backbuffer to the screen
return S_OK
Render ENDP
Posted on 2003-10-10 07:53:25 by Homer