Thread: Directx 9 framework

  1. #1
    Student legit's Avatar
    Join Date
    Aug 2008
    Location
    UK -> Newcastle
    Posts
    156

    Directx 9 framework

    Hey guys
    After most of today coding my DirectX 9 Framework, I'm done! I only receive 1 error when I try to call the message wrapper function in WinMain that I can't fathom out, it's probably pretty simple but I can't get it, been a long day

    Anyways, here's the error:
    error C3867: 'D3D::bDisplay': function call missing argument list; use '&D3D::bDisplay' to create a pointer to member

    Here is the relevant code:

    DXEngine.h
    Code:
    #include "D3D.h"
    
    class DXEngine: public D3D
    {
    public:
        ....
        int iRunMessageLoop(bool(*)(float)); /*Function pointer to wrap the message loop*/
        ....
    }
    D3D.h
    Code:
    class D3D
    {
    public:
        ....
        bool bDisplay(float); /*Function to display graphics in the client window*/
        ....
    }
    ...and finally, here's my WinMain.cpp

    WinMain.cpp
    Code:
    include "DXEngine.h" /*Include the code written in the DXEngine header file*/
    
    int WINAPI iWinMain(HINSTANCE hInstance, /*Handle to the current instance of the application*/
    	        HINSTANCE hPrevInstance, /*Handle to the previous instance of the application - is set to NULL*/
    		LPSTR lpCmdLine, /*This string specifies the command line for the application*/
    		int nCmdShow) /*This value specifies how the window will be shown*/
    {
        /*Application Instances*/
        DXEngine EngineInstance;
        D3D Direct3DInstance;
    
        EngineInstance.vUpdateWindow();
        EngineInstance.iRunMessageLoop(Direct3DInstance.bDisplay);
    	
        return 0;
    }
    As you can see, most of the work is done in the constructors. This is most probably the hurdle that I need to get over, then my framework will work, hopefully
    Last edited by legit; 06-17-2009 at 05:31 PM.

  2. #2
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    You are trying to use a thiscall as a function pointer. Make that function static and pass in a pointer to this.

  3. #3
    Student legit's Avatar
    Join Date
    Aug 2008
    Location
    UK -> Newcastle
    Posts
    156
    Thanks, that worked, it looks ugly, but it worked, although I didn't pass a *this pointer into the function, I just made it static along with the variable it used But now i'm getting a Linker error:

    LINK : fatal error LNK1561: entry point must be defined

    I thought that the entry point was the iWinMain() function? S

    EDIT: It appears that my iWinMain() function needs to be called WinMain() :S but I get a tonne more errors when I do that, so i'll try to fix 'em and get back to y'all
    Last edited by legit; 06-18-2009 at 02:39 AM.

  4. #4
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    Did you tell the linker that? By default for a windows subsystem app it will be WinMain. Either change your entry point to WinMain(), or change the linker's entry point definition to iWinMain().

  5. #5
    Student legit's Avatar
    Join Date
    Aug 2008
    Location
    UK -> Newcastle
    Posts
    156
    Quote Originally Posted by valaris View Post
    Did you tell the linker that? By default for a windows subsystem app it will be WinMain. Either change your entry point to WinMain(), or change the linker's entry point definition to iWinMain().
    No, I just changed it to WinMain(), but then I got loads of errors concerning that static member function, so now i'm back to where I started I'm doing pretty much what it says to do in my book, although I used OOP whereas the book didn't. It tells me to pass in the bDisplay() function into the message wrapper with no parameters.

  6. #6
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    But that's the problem. The message wrapper expects a pointer to a function. Function pointers use whatever the standing calling convention is for a regular function. Member functions on the other hand use a thiscall convention, so the frame setup is not the same. That being said you will have to pass in a function that uses the expected convention with the expected paramaters. A static function that matches the signature of a function pointer will work.

    Of course when dealing with a static member, you can only access other static members of that type. To overcome this you can pass in a pointer to the enclosing type and access that instances members through the pointer.

    Post the code and errors if you want help on resolving them.

  7. #7
    Student legit's Avatar
    Join Date
    Aug 2008
    Location
    UK -> Newcastle
    Posts
    156
    Ok, i've tried passing pointers and declaring functions as static, but theres always some kind of error, so i'm going to post all the relevant code and error and hopefully someone will tell me where to go from there

    error C3867: 'DXGraphics::bDisplay': function call missing argument list; use '&DXGraphics::bDisplay' to create a pointer to member

    DXEngine.h
    Code:
    #include "DXGraphics"
    
    class DXEngine: public DXGraphics
    {
    public:
        ....
        int iRunMessageLoop(bool(*)(float)); /*Function pointer to wrap the message loop*/
        ....
    }
    DXGraphics.h
    Code:
    #include "D3D.h"
    
    class DXGraphics
    {
    public:
        ....
        bool bDisplay(float); /*Function to display graphics in the client window*/
        ....
    }
    DXEngine.cpp
    Code:
    int DXEngine::iRunMessageLoop(bool (*p_bPointerToDisplayFunction)(float))
    {
        m_fLastTime = (float)timeGetTime(); /*Record the time when the application entered the message queue
    										and store it in m_fLastTime*/
    
        ZeroMemory(&m_msg, /*The starting address of the block of memory to fill with zero's*/
    	sizeof(MSG)); /*The size of the block of memory to fill with zero's(bytes)*/
    
        while(m_msg.message != WM_QUIT) /*While the message identifier doesn't equal WM_QUIT*/
        {
            if(PeekMessage(&m_msg, /*Address of MSG instance passed into the function for info on the members of MSG*/
    		0, /*Handle to the associating window, if NULL, the function retrieves all messages for the thread*/
    		0, /*First input type filter, e.g. Keyboard or mouse. If NULL, the function retreives all messages, no filtering is carried out*/
    		0, /*Last input type filter, e.g. Keyboard or mouse. If NULL, the function retrieces all messahes, no filtering is carries out*/
    		PM_REMOVE)) /*Flag for removing the messages after the function has processed them*/
    	{
    	    TranslateMessage(&m_msg); /*Function for translating virtual key messages into character messages,
    									  takes an instance of a MSG struct that contains info processed by PeekMessage()*/
    	    DispatchMessage(&m_msg); /*Function for dispatching messages to the windows procedure, takes an instance
    									 of a MSG struct that contains the message info*/
    	}
    	else /*Otherwise...*/
    	{
    	    m_fCurrentTime = (float)timeGetTime(); /*Records the current time and stores it in m_fCurrentTime*/
    	    m_fTimeDifference = (m_fCurrentTime-m_fLastTime)*0.001f;
    
    	    p_bPointerToDisplayFunction(m_fTimeDifference); /*Call the display function after computing the above times*/
    
    	    m_fLastTime = m_fCurrentTime; /*Set the value of m_fLastTime to the value stored in m_fCurrentTime so the process can be repeated*/
    	}
        }
        return m_msg.wParam; /*Return the message information to the program*/
    }
    DXGraphics.cpp
    Code:
    bool DXGraphics::bDisplay(float) /*Function Definition*/
    {
        if(m_d3dDevice) /*If the object exists*/
        {
            m_d3dDevice->Clear(0, /*Number of rectangles in the following array...*/
    		0, /*An array of screen rectanges to clear*/
    		D3DCLEAR_TARGET | /*The render target surface, most likely the backbuffer*/
    		D3DCLEAR_ZBUFFER, /*The depth(z) buffer*/
    		BLACK, /*Colour that we wish to clear the render targer to (black)*/
    		1.0f, /*The value that we wish to set the depth(z) buffer to*/
    		0); /*The value that we wish to set the stencil buffer to*/
    
    		/*Function to Present the contents of the next buffer*/
    	m_d3dDevice->Present(0, /*This must be NULL as we didn't specify the swap chain as "D3DSWAPEFFECT_COPY"
    			                    as it is NULL, the whole surface is presented*/
    		0, /*This must also be NULL for the same reason, as it is NULL, the entire client area is filled*/
    		0, /*This is the destination window, if NULL, then the handle from D3DPRESENT_PARAMETERS is taken*/
    		0); /*This must also be NULL as "D3DSWAPEFFECT_COPY" wasn't specified*/
        }
        return true; /*Return a true value, indicating that the program can continue*/
    }
    Yes, i've added another class - DXGraphics. I did this because I thought that my D3D class shouldn't contain the bDisplay() function, as it only set's up Direct3D, and isn't supposed to display anything. So, can you help me?

  8. #8
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    I don't understand, you didn't even make it static. Make it static. It would be easier to just pass iRunMessageLoop a pointer to some interface representing a display function.

    Edit: Your dx engine derives from DXGraphics...just call the bDisplay function.
    Last edited by valaris; 06-18-2009 at 03:35 AM.

  9. #9
    Student legit's Avatar
    Join Date
    Aug 2008
    Location
    UK -> Newcastle
    Posts
    156
    Quote Originally Posted by valaris View Post
    I don't understand, you didn't even make it static. Make it static.
    Ok, I made the bDisplay() function static, I get 3 errors concerning non-static member variables:

    error C2597: illegal reference to non-static member 'D3D::m_d3dDevice'
    error C2227: left of '->Clear' must point to class/struct/union/generic type
    error C2227: left of '->Present' must point to class/struct/union/generic type

    Then to try and correct this, I make my member variable: m_d3dDevice static, and I get 9 linker errors:

    error LNK2001: unresolved external symbol "protected: static struct IDirect3DDevice9 * D3D::m_d3dDevice" (?m_d3dDevice@D3D@@1PAUIDirect3DDevice9@@A)
    error LNK2001: unresolved external symbol "protected: static struct IDirect3DDevice9 * D3D::m_d3dDevice" (?m_d3dDevice@D3D@@1PAUIDirect3DDevice9@@A)
    error LNK2019: unresolved external symbol _Direct3DCreate9@4 referenced in function "public: __thiscall D3D:3D(void)" (??0D3D@@QAE@XZ)
    error LNK2019: unresolved external symbol "public: virtual __thiscall DXEngine::~DXEngine(void)" (??1DXEngine@@UAE@XZ) referenced in function "public: virtual void * __thiscall DXEngine::`scalar deleting destructor'(unsigned int)" (??_GDXEngine@@UAEPAXI@Z)
    error LNK2001: unresolved external symbol "public: virtual __thiscall DXEngine::~DXEngine(void)" (??1DXEngine@@UAE@XZ)
    error LNK2019: unresolved external symbol __imp__timeGetTime@0 referenced in function "public: int __thiscall DXEngine::iRunMessageLoop(bool (__cdecl*)(float))" (?iRunMessageLoop@DXEngine@@QAEHP6A_NM@Z@Z)
    error LNK2019: unresolved external symbol "public: void __thiscall D3D::vRelease<struct IDirect3DDevice9 *>(struct IDirect3DDevice9 *)" (??$vRelease@PAUIDirect3DDevice9@@@D3D@@QAEXPAUIDi rect3DDevice9@@@Z) referenced in function "public: virtual __thiscall DXGraphics::~DXGraphics(void)" (??1DXGraphics@@UAE@XZ)
    error LNK2019: unresolved external symbol "public: void __thiscall DXEngine::vUpdateWindow(void)" (?vUpdateWindow@DXEngine@@QAEXXZ) referenced in function _WinMain@16

    Quote Originally Posted by valaris View Post
    It would be easier to just pass iRunMessageLoop a pointer to some interface representing a display function.
    How do you mean? I'm not understanding

    Quote Originally Posted by valaris View Post
    Your dx engine derives from DXGraphics...just call the bDisplay function.
    Yes, but I still need an instance of my class to call it.
    Last edited by legit; 06-18-2009 at 03:45 AM.

  10. #10
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    Yes, but I still need an instance of my class to call it.
    Then make an instance of it and call bDisplay in iRunMessageLoop. Simple.

    Sounds like you are declaring the variables static but not defining them. Define them in the cpp file.

    The interface bit is just an idea really since you said you are trying to write some extensible game framework.

  11. #11
    Student legit's Avatar
    Join Date
    Aug 2008
    Location
    UK -> Newcastle
    Posts
    156
    That seems to have worked, I just called my bDisplay function in my message wrapper like you said, thanks, although I get linker errors now, i'm not good with linker errors, i'll post 'em while I try to figure out how to fix 'em myself, thanks for all of your help!

    1>D3D.obj : error LNK2019: unresolved external symbol _Direct3DCreate9@4 referenced in function "public: __thiscall D3D:: D3D(void)" (??0D3D@@QAE@XZ)
    1>DXEngine.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall DXEngine::~DXEngine(void)" (??1DXEngine@@UAE@XZ) referenced in function "public: virtual void * __thiscall DXEngine::`scalar deleting destructor'(unsigned int)" (??_GDXEngine@@UAEPAXI@Z)
    1>WinMain.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall DXEngine::~DXEngine(void)" (??1DXEngine@@UAE@XZ)
    1>DXEngine.obj : error LNK2019: unresolved external symbol __imp__timeGetTime@0 referenced in function "public: int __thiscall DXEngine::iRunMessageLoop(void)" (?iRunMessageLoop@DXEngine@@QAEHXZ)
    1>DXGraphics.obj : error LNK2019: unresolved external symbol "public: void __thiscall D3D::vRelease<struct IDirect3DDevice9 *>(struct IDirect3DDevice9 *)" (??$vRelease@PAUIDirect3DDevice9@@@D3D@@QAEXPAUIDi rect3DDevice9@@@Z) referenced in function "public: virtual __thiscall DXGraphics::~DXGraphics(void)" (??1DXGraphics@@UAE@XZ)
    1>WinMain.obj : error LNK2019: unresolved external symbol "public: void __thiscall DXEngine::vUpdateWindow(void)" (?vUpdateWindow@DXEngine@@QAEXXZ) referenced in function _WinMain@16
    1>C:\Users\Ross\Desktop\DXEngine\DXEngine\Debug\DX Engine.exe : fatal error LNK1120: 5 unresolved externals
    Last edited by legit; 06-18-2009 at 06:04 AM.

  12. #12
    Student legit's Avatar
    Join Date
    Aug 2008
    Location
    UK -> Newcastle
    Posts
    156
    I solved 1 by defining the destructor of DXEngine But i still have four more, and i'm not sure how to fix them. I've searched the net and have came up with nothing here are the remaining linker problems:

    D3D.obj : error LNK2019: unresolved external symbol _Direct3DCreate9@4 referenced in function "public: __thiscall D3D:: D3D(void)" (??0D3D@@QAE@XZ)
    1>DXEngine.obj : error LNK2019: unresolved external symbol __imp__timeGetTime@0 referenced in function "public: int __thiscall DXEngine::iRunMessageLoop(void)" (?iRunMessageLoop@DXEngine@@QAEHXZ)
    1>DXGraphics.obj : error LNK2019: unresolved external symbol "public: void __thiscall D3D::vRelease<struct IDirect3DDevice9 *>(struct IDirect3DDevice9 *)" (??$vRelease@PAUIDirect3DDevice9@@@D3D@@QAEXPAUIDi rect3DDevice9@@@Z) referenced in function "public: virtual __thiscall DXGraphics::~DXGraphics(void)" (??1DXGraphics@@UAE@XZ)
    1>WinMain.obj : error LNK2019: unresolved external symbol "public: void __thiscall DXEngine::vUpdateWindow(void)" (?vUpdateWindow@DXEngine@@QAEXXZ) referenced in function _WinMain@16

    EDIT: I solved another by moving a function between destructors, only 3 more to go

    EDIT: I solved another by removing: m_d3d = Direct3DCreate9(D3D_SDK_VERSION); from my constructor. Not sure why I needed to, but i'm now having trouble with the other two:

    DXEngine.obj : error LNK2019: unresolved external symbol __imp__timeGetTime@0 referenced in function "public: int __thiscall DXEngine::iRunMessageLoop(void)" (?iRunMessageLoop@DXEngine@@QAEHXZ)
    1>WinMain.obj : error LNK2019: unresolved external symbol "public: void __thiscall DXEngine::vUpdateWindow(void)" (?vUpdateWindow@DXEngine@@QAEXXZ) referenced in function _WinMain@16

    I can't seem to find a way of sorting these. If I need to repost my iRunMessageLoop() function, let me know.

    EDIT: I solved another by moving my vUpdateWindow() function from WinMain() to my DXEngine constructor, now all that is left is:

    DXEngine.obj : error LNK2019: unresolved external symbol __imp__timeGetTime@0 referenced in function "public: int __thiscall DXEngine::iRunMessageLoop(void)" (?iRunMessageLoop@DXEngine@@QAEHXZ)
    Last edited by legit; 06-18-2009 at 06:27 AM.

  13. #13
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    It means it can't find a definition for timeGetTime().

  14. #14
    Student legit's Avatar
    Join Date
    Aug 2008
    Location
    UK -> Newcastle
    Posts
    156
    My book says that the definition is in <windows.h>, but when I include that, it makes no difference :S

    Ok, I commented out the time functions for now, and it all works, but I get runtime errors. My debug told me this:

    Unhandled exception at 0x00ad1754 in DXEngine.exe: 0xC0000005: Access violation reading location 0xcccccccc.

    This is where the violation happens:

    Code:
    int D3D::iSetDeviceCaps() /*Function definition*/
    {
    	/*Retrieve the information needed to check for hardware or software vertex processing*/
    	m_d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, /*The display adapter (primary)*/
    		m_d3dDeviceType, /*Device type that we will use (hardware or software)*/
    		&m_d3dDeviceCaps); /*Address of struct that contains capabilities of the display adapter*/ <-This is where the break occured
    
    	if(m_d3dDeviceCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) /*If Hardware processing is supported...*/
    	{
    		iVertexProcessing = D3DCREATE_HARDWARE_VERTEXPROCESSING; /*Store the value of hardware processing in iVertexProcessing*/
    	}
    	else /*Otherwise...*/
    	{
    		iVertexProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING; /*Store the value of software processing in iVertexProcessing*/
    	}
    	return iVertexProcessing; /*Return the altered member variable to the program*/
    }
    Last edited by legit; 06-18-2009 at 08:26 AM.

  15. #15
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    Has m_d3d ever been created via the dx helper functions? Place a breakpoint at the GetDeviceCaps() call and see the address of m_d3d, if it is 0xcccccccc then you either forgot to create it, or creation failed.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Isometric Tile Engine using DirectX
    By Wraithan in forum Game Programming
    Replies: 3
    Last Post: 07-17-2006, 12:16 PM
  2. DirectSound header issues
    By dxfoo in forum C++ Programming
    Replies: 0
    Last Post: 03-19-2006, 07:16 PM
  3. DirectX - Starting Guide?
    By Zeusbwr in forum Game Programming
    Replies: 13
    Last Post: 11-25-2004, 12:49 AM
  4. DirectX 8 with Borland
    By Tommaso in forum Game Programming
    Replies: 11
    Last Post: 08-12-2003, 09:30 AM