Direct3D problem

This is a discussion on Direct3D problem within the Game Programming forums, part of the General Programming Boards category; I'm trying my best to get into Direct3D by more or less just sifting through MSDN examples and the occasional ...

  1. #1
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709

    Direct3D problem

    I'm trying my best to get into Direct3D by more or less just sifting through MSDN examples and the occasional online tutorial. I found this one for Direct3D 8: http://www.robertwrose.com/d3d/tutorial.html

    It's pretty good all I've had to do so far is swap the 8's around for 9's and the occasional function call is different by one parameter, which is usually NULL anyway.

    So anyway I'm here: http://www.robertwrose.com/d3d/tutorial3.html

    Near the end where I draw the vertex buffer, I get an error trying to compile this:

    Code:
    // ...
    g_pD3DDevice->SetVertexShader(D3DFVF_D3DVertex);
    // ...
    Error:

    Code:
    c:\Documents and Settings\lee\Desktop\d3d\d3d.cpp(165) : error C2664: 'IDirect3DDevice9::SetVertexShader' : cannot convert parameter 1 from 'int' to 'IDirect3DVertexShader9 *'
            Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
    So I tried this, which compiled:

    Code:
        g_pD3DDevice->SetVertexShader(reinterpret_cast<IDirect3DVertexShader9 *> (D3DFVF_D3DVertex));
    But then I get a runtime error when it reaches that call:

    Code:
    Unhandled exception at 0x4fe5831f in d3d.exe: 0xC0000005: Access violation writing location 0x0000004e.
    In my other day to day programming I can get these quite a lot and usually have no trouble solving them (more often than not it's a pointer pointing somewhere it shouldn't be) but I can't figure out what's going wrong here.

    D3DFVF_D3DVertex is the same #define from the tutorial page:

    Code:
    #define D3DFVF_D3DVertex (D3DFVF_XYZ | D3DFVF_DIFFUSE)
    Tis madness, madness ah tells ya!
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  2. #2
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Well, you're trying to pass an integral value when you should pass a vertex shader (an object). Are you sure you know what you're doing, perhaps you're trying to (want to) call SetFVF() instead?
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  3. #3
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    Quote Originally Posted by Magos
    Well, you're trying to pass an integral value when you should pass a vertex shader (an object). Are you sure you know what you're doing, perhaps you're trying to (want to) call SetFVF() instead?
    I'm just following that tutorial but it seems D3D9 is different... or something. So thinking it over, do I need to create an instance of IDirect3DVertexShader9 (LPDIRECT3DVERTEXSHADER9) and use that? Trouble is MSDN has really crappy documentation when it comes to DX9 (well, the one I've installed has, Jan 2004, so I guess I'll try online in a minute).

    In other news and completely off-topic, I just had my 3rd driving lesson and it's been the worst so far: stalled 3 times and just generally bad. Oh and I almost had a head on collision with a minibus. Almost? My instructor stopped me about 1 foot away from his nose.

    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  4. #4
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    You know what, after hours of doing this, you know what I say?
    Screw this until I can buy some books. As soon as I get enough money I'm having a field day on Amazon.
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  5. #5
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,598
    SetVertexShader has been changed in DirectX9.

    Use SetFVF() instead.

    Bad tutorials; outdated tutorials; and in general most net tutorials will leave you in the dark.

    Get a book and also check the SDK docs.

    And you cannot make an integral value into an aggregated object by simply doing a re-interpret cast or any type of cast for that matter.

    COM is like polymorphic C++.

    If one function takes a IDirect3DTexture9 argument and yet you have an IDirect3DSurface9, you can still use it. IDirect3DTexture9 inherits from IDirect3DSurface9.

    Even though COM is not pure C++ in its operation, it is quite close to C++ in concept. Think of COM as how C++ should have been to begin with. You will like COM once you get the hang of it.
    Last edited by VirtualAce; 04-08-2006 at 08:34 PM.

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    847
    Quote Originally Posted by Bubba
    And you cannot make an integral value into an aggregated object by simply doing a re-interpret cast or any type of cast for that matter.
    While this is almost always true there are exceptions when a function has been specifically written to accept an integral value or pointer such as the hbrBackground member of WNDCLASSEX which can be a pointer to a Brush or color value cast as HBRUSH.

  7. #7
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,598
    While this is almost always true there are exceptions when a function has been specifically written to accept an integral value or pointer such as the hbrBackground member of WNDCLASSEX which can be a pointer to a Brush or color value cast as HBRUSH.
    This is not casting to an aggregated type. Look in the SDK.

    A pointer is a value at it's core - an integral value that specifies a location in memory. Therefore, again, you are not casting to an aggregated type.

    Platform SDK: Win32 API
    Data Types
    The data types supported by the Microsoft® Win32® API are used to define function return values, function and message parameters, and structure members. They define the size and meaning of these elements

    The following table contains the following types: character, integer, Boolean, pointer, and handle. The character, integer, and Boolean types are common to most C compilers. Most of the pointer-type names begin with a prefix of P or LP. Handles refer to a resource that has been loaded into memory.

    Type Definition
    ATOM Atom (a reference to a character string in an atom table).
    BOOL Boolean variable (should be TRUE or FALSE).
    BOOLEAN Boolean variable (should be TRUE or FALSE).
    BYTE Byte (8 bits).
    CALLBACK Calling convention for callback functions.
    CHAR 8-bit Windows (ANSI) character. For more information, see Character Sets Used By Fonts.
    COLORREF Red, green, blue (RGB) color value (32 bits). See COLORREF for information on this type.
    CONST Variable whose value is to remain constant during execution.
    CRITICAL_SECTION Critical-section object.
    CTRYID Country identifier.
    DWORD 32-bit unsigned integer.
    DWORD_PTR Unsigned long type for pointer precision. Use when casting a pointer to a long type to perform pointer arithmetic.
    DWORD32 32-bit unsigned integer.
    DWORD64 64-bit unsigned integer.
    FLOAT Floating-point variable.
    FILE_SEGMENT_ELEMENT 64-bit pointer to a buffer.
    HACCEL Handle to an accelerator table.
    HANDLE Handle to an object.
    HBITMAP Handle to a bitmap.
    HBRUSH Handle to a brush.
    HCOLORSPACE Handle to a logical color space.
    HCONV Handle to a dynamic data exchange (DDE) conversation.
    HCONVLIST Handle to a DDE conversation list.
    HCURSOR Handle to a cursor.
    HDC Handle to a device context (DC).
    HDDEDATA Handle to DDE data.
    HDESK Handle to a desktop.
    HDROP Handle to an internal drop structure.
    HDWP Handle to a deferred window position structure.
    HENHMETAFILE Handle to an enhanced metafile.
    HFILE Handle to a file opened by OpenFile, not CreateFile.
    HFONT Handle to a font.
    HGDIOBJ Handle to a GDI object.
    HGLOBAL Handle to a global memory block.
    HHOOK Handle to a hook.
    HICON Handle to an icon.
    HIMAGELIST Handle to an image list.
    HIMC Handle to input context.
    HINSTANCE Handle to an instance.
    HKEY Handle to a registry key.
    HKL Input locale identifier.
    HLOCAL Handle to a local memory block.
    HMENU Handle to a menu.
    HMETAFILE Handle to a metafile.
    HMODULE Handle to a module.
    HMONITOR Handle to a display monitor.
    HPALETTE Handle to a palette.
    HPEN Handle to a pen.
    HRGN Handle to a region.
    HRSRC Handle to a resource.
    HSZ Handle to a DDE string.
    HWINSTA Handle to a window station.
    HWND Handle to a window.
    INT 32-bit signed integer.
    INT_PTR Signed integral type for pointer precision. Use when casting a pointer to an integer to perform pointer arithmetic.
    INT32 32-bit signed integer.
    INT64 64-bit signed integer.
    IPADDR IP address. To convert this value to the "a.b.c.d" string form of an IP address, map the high-order byte to a, the low-order byte to d, and so on.
    IPMASK Subnet mask. Uses the same format as IPADDR.
    LANGID Language identifier. For more information, see Locales.
    LCID Locale identifier. For more information, see Locales.
    LCSCSTYPE Color space type.
    LCSGAMUTMATCH Gamut-matching method.
    LCTYPE Locale information type. For a list, see Locale and Language Information
    LONG 32-bit signed integer.
    LONG_PTR Signed long type for pointer precision. Use when casting a pointer to a long to perform pointer arithmetic.
    LONG32 32-bit signed integer.
    LONG64 64-bit signed integer.
    LONGLONG 64-bit signed integer.
    LPARAM Message parameter.
    LPBOOL Pointer to a BOOL.
    LPBYTE Pointer to a BYTE.
    LPCOLORREF Pointer to a COLORREF value.
    LPCRITICAL_SECTION Pointer to a CRITICAL_SECTION.
    LPCSTR Pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters. For more information, see Character Sets Used By Fonts.
    LPCTSTR An LPCWSTR if UNICODE is defined, an LPCSTR otherwise.
    LPCVOID Pointer to a constant of any type.
    LPCWSTR Pointer to a constant null-terminated string of 16-bit Unicode characters. For more information, see Character Sets Used By Fonts.
    LPDWORD Pointer to a DWORD.
    LPHANDLE Pointer to a HANDLE.
    LPINT Pointer to an INT.
    LPLONG Pointer to a LONG.
    LPSTR Pointer to a null-terminated string of 8-bit Windows (ANSI) characters. For more information, see Character Sets Used By Fonts.
    LPTSTR An LPWSTR if UNICODE is defined, an LPSTR otherwise.
    LPVOID Pointer to any type.
    LPWORD Pointer to a WORD.
    LPWSTR Pointer to a null-terminated string of 16-bit Unicode characters. For more information, see Character Sets Used By Fonts.
    LRESULT Signed result of message processing.
    LUID Locally unique identifier.
    PBOOL Pointer to a BOOL.
    PBOOLEAN Pointer to a BOOL.
    PBYTE Pointer to a BYTE.
    PCHAR Pointer to a CHAR.
    PCRITICAL_SECTION Pointer to a CRITICAL_SECTION.
    PCSTR Pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters. For more information, see Character Sets Used By Fonts.
    PCTSTR A PCWSTR if UNICODE is defined, a PCSTR otherwise.
    PCWCH Pointer to a constant WCHAR.
    PCWSTR Pointer to a constant null-terminated string of 16-bit Unicode characters. For more information, see Character Sets Used By Fonts.
    PDWORD Pointer to a DWORD.
    PFLOAT Pointer to a FLOAT.
    PHANDLE Pointer to a HANDLE.
    PHKEY Pointer to an HKEY.
    PINT Pointer to an INT.
    PLCID Pointer to an LCID.
    PLONG Pointer to a LONG.
    PLUID Pointer to a LUID.
    POINTER_32 32-bit pointer. On a 32-bit system, this is a native pointer. On a 64-bit system, this is a truncated 64-bit pointer.
    POINTER_64 64-bit pointer. On a 64-bit system, this is a native pointer. On a 32-bit system, this is a sign-extended 32-bit pointer.
    PSHORT Pointer to a SHORT.
    PSTR Pointer to a null-terminated string of 8-bit Windows (ANSI) characters. For more information, see Character Sets Used By Fonts.
    PTBYTE Pointer to a TBYTE.
    PTCHAR Pointer to a TCHAR.
    PTSTR A PWSTR if UNICODE is defined, a PSTR otherwise.
    PUCHAR Pointer to a UCHAR.
    PUINT Pointer to a UINT.
    PULONG Pointer to a ULONG.
    PUSHORT Pointer to a USHORT.
    PVOID Pointer to any type.
    PWCHAR Pointer to a WCHAR.
    PWORD Pointer to a WORD.
    PWSTR Pointer to a null-terminated string of 16-bit Unicode characters. For more information, see Character Sets Used By Fonts.
    REGSAM Security access mask for registry key.
    SC_HANDLE Handle to a service control manager database.
    SC_LOCK Handle to a service control manager database lock.
    SERVICE_STATUS_HANDLE Handle to a service status value.
    SHORT Short integer (16 bits).
    SIZE_T The maximum number of bytes to which a pointer can point. Use for a count that must span the full range of a pointer.
    SSIZE_T Signed SIZE_T.
    TBYTE A WCHAR if UNICODE is defined, a CHAR otherwise.
    TCHAR A WCHAR if UNICODE is defined, a CHAR otherwise.
    UCHAR Unsigned CHAR.
    UINT Unsigned INT.
    UINT_PTR Unsigned INT_PTR.
    UINT32 Unsigned INT32.
    UINT64 Unsigned INT64.
    ULONG Unsigned LONG.
    ULONG_PTR Unsigned LONG_PTR.
    ULONG32 Unsigned LONG32.
    ULONG64 Unsigned LONG64.
    ULONGLONG 64-bit unsigned integer.
    UNSIGNED Unsigned attribute.
    USHORT Unsigned SHORT.
    VOID Any type.
    WCHAR 16-bit Unicode character. For more information, see Character Sets Used By Fonts.
    WINAPI Calling convention for the Win32 API.
    WORD 16-bit unsigned integer.
    WPARAM Message parameter.

    Last edited by VirtualAce; 04-08-2006 at 08:55 PM.

  8. #8
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    Ok thanks Bubba I see what you mean.
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  9. #9
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,598
    A handle in Windows API is a DWORD or UINT or unsigned 32 bit integer.

    Once you get the Windows crapola out of the way ahluka, it becomes much easier to work with Direct3D. I think you will come to enjoy working with it as you dive into it deeper. Direct3D makes a lot of things simple and DirectX makes a lot of nitty gritty mundane code come to life by implementing default objects to control playback of movies, MP3's, sound, music, etc. I thoroughly enjoy the entire API even though at times it makes me pull my hair out - but that's just game programming for ya.

  10. #10
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    Could you take a look at this. It compiles but nothing is drawn:

    (~192 lines, mostly win32 crapola)
    Code:
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    #include <d3d9.h>
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    HRESULT Direct3DInit(HWND hWnd);
    void Direct3DShutdown();
    void Direct3DRender();
    
    const char *lpszClassName = "D3D_App";
    LPDIRECT3D9 g_pD3D = NULL;
    LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
    
    struct D3DVertex
    {
        float x, y, z;
        DWORD color;
    };
    
    #define D3DFVF_D3DVertex (D3DFVF_XYZ | D3DFVF_DIFFUSE)
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
        WNDCLASSEX wc;
        HWND hWnd;
        MSG mMsg;
    
        wc.cbClsExtra = 0;
        wc.cbSize = sizeof(wc);
        wc.cbWndExtra = 0;
        wc.hbrBackground = static_cast<HBRUSH> (GetStockObject(GRAY_BRUSH));
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
        wc.hInstance = hInstance;
        wc.lpfnWndProc = WndProc;
        wc.lpszClassName = lpszClassName;
        wc.lpszMenuName = NULL;
        wc.style = CS_VREDRAW | CS_HREDRAW;
    
        if (! RegisterClassEx(&wc))
        {
            MessageBox(0, "Error registering window class", "Error",
                       MB_OK | MB_ICONERROR);
            return 1;
        }
    
        hWnd = CreateWindowEx(NULL, lpszClassName, "Direct3D App", WS_OVERLAPPEDWINDOW, 0, 0, 300, 300, NULL,
                              NULL, hInstance, NULL);
        if (! hWnd)
        {
            MessageBox(0, "Error creating window", "Error",
                       MB_OK | MB_ICONERROR);
            return 1;
        }
    
        if (SUCCEEDED(Direct3DInit(hWnd)))
        {
            ShowWindow(hWnd, SW_SHOWNORMAL);
            UpdateWindow(hWnd);
            SetFocus(hWnd);
    
            ZeroMemory(&mMsg, sizeof(mMsg));
            while (mMsg.message != WM_QUIT)
            {
                if (PeekMessage(&mMsg, NULL, 0, 0, PM_REMOVE))
                {
                    TranslateMessage(&mMsg);
                    DispatchMessage(&mMsg);
                }
                else
                    Direct3DRender();
            }
        }
        else
        {
            UnregisterClass(lpszClassName, hInstance);
            MessageBox(0, "Error initialising Direct3D", "Error", MB_OK | MB_ICONERROR);
            return 1;
        }
    
        Direct3DShutdown();
        UnregisterClass(lpszClassName, hInstance);
        return 0;
    }
    
    // WndProc
    //
    LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        switch (uMsg)
        {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
    
        case WM_PAINT:
            Direct3DRender();
            ValidateRect(hWnd, NULL);
            break;
    
        default:
            return DefWindowProc(hWnd, uMsg, wParam, lParam);
        }
    
        return 0;
    }
    
    // Direct3DInit
    //
    HRESULT Direct3DInit(HWND hWnd)
    {
        D3DDISPLAYMODE d3ddm;
        D3DPRESENT_PARAMETERS d3dpp;
    
        if ((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
            return E_FAIL;
    
        if (FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
            return E_FAIL;
    
        ZeroMemory(&d3dpp, sizeof(d3dpp));
        d3dpp.Windowed = true;
        d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
        d3dpp.BackBufferFormat = d3ddm.Format;
        d3dpp.EnableAutoDepthStencil = true;
        d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
    
        if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                        D3DCREATE_HARDWARE_VERTEXPROCESSING,
                                        &d3dpp, &g_pD3DDevice)))
        {
            return E_FAIL;
        }
    
        g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
        g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
    
        return S_OK;
    }
    
    // Direct3DShutdown
    //
    void Direct3DShutdown()
    {
        if (g_pD3DDevice != NULL)
            g_pD3DDevice->Release();
    
        if (g_pD3D != NULL)
            g_pD3D->Release();
    }
    
    // Direct3DRender
    //
    void Direct3DRender()
    {
        LPDIRECT3DVERTEXBUFFER9 vBuffer;
        D3DVertex *pVertices;
        D3DVertex tri[3] = {
            {-0.5f, 0.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0)},
            {0.5f, 0.5f, 0.0f,  D3DCOLOR_XRGB(0, 255, 0)},
            {0.5f, -0.5f, 0.0f, D3DCOLOR_XRGB(0, 0, 255)}
        };
    
        if (g_pD3DDevice == NULL) return;
    
        g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
        if (FAILED(g_pD3DDevice->CreateVertexBuffer(3 * sizeof(D3DVertex), 0, 
                                                    D3DFVF_D3DVertex, D3DPOOL_DEFAULT, &vBuffer, NULL)))
        {
            return;
        }
    
        if (FAILED(vBuffer->Lock(0, sizeof(D3DVertex) * 3, (void **) &pVertices, 0)))
            return;
    
        memcpy(pVertices, tri, sizeof(D3DVertex) * 3);
        vBuffer->Unlock();
    
        g_pD3DDevice->BeginScene();
    
        g_pD3DDevice->SetStreamSource(0, vBuffer, sizeof(D3DVertex), 0);
        g_pD3DDevice->SetFVF(D3DFVF_D3DVertex);
        g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
        vBuffer->Release();
    
        g_pD3DDevice->EndScene();
    
    
        g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
    }
    EDIT: I'm going to write a little DLL to wrap up window creation for me. In the past 24 hours I've copied and pasted the same crap 7 times.
    Last edited by cboard_member; 04-09-2006 at 04:12 AM.
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  11. #11
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,598
    Well don't release the vertex buffer until you shut down the entire system.

    I will look at your code a bit closer later.

    EDIT:

    No message loop. Call message loop from main.
    Last edited by VirtualAce; 04-09-2006 at 07:26 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 03:51 PM
  2. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 07:54 PM
  3. Need help with getting DirectX 9.0 initilization
    By DarkMortar in forum Windows Programming
    Replies: 7
    Last Post: 05-09-2006, 09:58 PM
  4. Laptop Problem
    By Boomba in forum Tech Board
    Replies: 1
    Last Post: 03-07-2006, 06:24 PM
  5. beginner problem
    By The_Nymph in forum C Programming
    Replies: 4
    Last Post: 03-05-2002, 05:46 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21