locked
What step have i missed RRS feed

  • Question

  • I am trying to learn use Direct 3D (version 9b of the SDK) on windows after some experience with Open GL on linux machines in Computer Science.

    As I understand it the basic steps involved in drawing primitives are:

    Create a device
    Create a vertex buffer of an appropriate format
    lock the vertex buffer and copy the data into it.
    unlock the buffer.
    Set the stream source to the vertex buffer you just created and FVF to match the buffer format.
    Call beginscene
    call drawprimitives
    call endscene
    call present.

    However i do not see anything. I thought the problem was to do with my routines for loading vertex data from a file, and tried to use the hardcoded struct from the second tutorial that comes with the SDK.

    However i still do not see anything in the window except my blue background.

    I am using the Visual C++ express edition 2005 beta with the Platform SDK in order to compile as a native win32 application.

    my code for drawing my primitive (only a single triangle at this stage) is as follows:



    if
    (SUCCEEDED (lpDevice->BeginScene()) ) {

    // set the stream source

    lpDevice->SetStreamSource(0,vBuffer,0,sizeof(vbuffer));

    // and the kind of stream

    lpDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE);

    if (FAILED(lpDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1))) {

    //MessageBox(NULL,"Direct3D Error","Can't draw primitives from vertex buffer! Exiting.",MB_OK | MB_ICONEXCLAMATION);

    DebugWrite("Can't draw primitives from the vertex buffer.\n");

    } else {

    lpDevice->EndScene();

    lpDevice->Present(NULL,NULL,NULL,NULL);

    }

    } else {

    DebugWrite("Being scene failed!");

    }

    }
     



    my code for creating the vertex buffer is as follows:


    void createIndexBuffer(LPDIRECT3DDEVICE9 lpDevice) {

    vbuffer test[] = {

    {150.0f, 50.0f, 0.5f,0xffff0000,},

    {250.0f, 250.0f, 0.5f,0xff00ff00,},

    {50.0f, 250.0f, 0.5f,0xff00ffff,},

    };

    if (FAILED(lpDevice->CreateVertexBuffer(sizeof (test),D3DUSAGE_SOFTWAREPROCESSING,(D3DFVF_XYZ | D3DFVF_DIFFUSE),D3DPOOL_DEFAULT,&vBuffer,NULL))) {

    //MessageBox(NULL,"Direct3D Error","failed to create vertex buffer for target render device.",MB_OK);

    DebugWrite("failed to create vertex buffer for target render device.\n");

    }

    vertex vl = resman_get_glob_vlist(appRm);

    vbuffer *vptr;

    if (FAILED(vBuffer->Lock(0,0,(void**)&vptr,D3DLOCK_DISCARD))) {

    //MessageBox(NULL,"Direct3D error","can't lock inital vertex buffer.",MB_OK);

    DebugWrite("Lock inital vertex buffer failed.\n");

    }

    /* int i = 0;

    vl = vl->next;

    while (vl != 0) {

    vptr->x = vl->x;

    vptr->y = vl->y;

    vptr->z = vl->z;

    vptr->DiffuseColor = D3DCOLOR_ARGB(0xFF,0x00,0xFF,0x00);

    vl = vl->next;

    vptr++;

    }*/

    memcpy(vptr,&test,sizeof(test));

    vBuffer->Unlock();

    // set the stream source

    lpDevice->SetStreamSource(0,vBuffer,0,sizeof(vbuffer));

    // and the kind of stream

    lpDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE);

    // there now with some hope it'll draw something.

    // nope no good.

    // try turning lighting off

    //lpDevice->SetRenderState(D3DRS_LIGHTING,FALSE);

    //lpDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);

    }
     



    I am creating the device as follows:


    LPDIRECT3DDEVICE9 dx_init(HWND wnd) {

    D3DPRESENT_PARAMETERS PresentParams;

    if (NULL == (pDirect3D9 = Direct3DCreate9(D3D_SDK_VERSION)) ) {

    return (LPDIRECT3DDEVICE9) 0;

    }

    ZeroMemory(&PresentParams,sizeof(PresentParams));

    PresentParams.Windowed = TRUE;

    PresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;

    PresentParams.BackBufferFormat = D3DFMT_UNKNOWN;

    if (FAILED (pDirect3D9->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,wnd,

    D3DCREATE_SOFTWARE_VERTEXPROCESSING,

    &PresentParams,&pDevice))) {

    return (LPDIRECT3DDEVICE9) 0;

    }

    /* todo: set device state */

    //pDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );

    // pDevice->Present(NULL,NULL,NULL,NULL);

    return pDevice;

    }
     



    I can't understand what i've missed out.
    I apprechiate any help or pointers.

    I know my coding style is all over the place, but C is not my favourite language. I'd much rather do this in C# or java or something, but I doubt code running under an abstract stack machine environment such as the common language run time or java virtual machine could have suffecent performance when written by someone of my limited ability.

    Saturday, October 22, 2005 5:43 AM

Answers

  • 1) D3DFVF_XYZ tells the Direct3D fixed function pipeline "these vertices are untransformed, please transform them using the currently set world, view and projection matrices to them".

    The code you've posted doesn't set any transformation matrices, so D3D will use identity transformation matrices (the default) to transform your vertices from object space to homogeneous clip space. Transforming your particular input vertices by identity would result in all of the vertices being clipped (-w<=x<=w)...

    You'll need to call IDirect3DDevice9::SetTransform for D3DTS_WORLD, D3DTS_VIEW and D3DTS_PROJECTION to set the transforms D3D uses.

    - The world matrix transforms from object (aka model) space to world space.
    - The view matrix transforms from world space to view (aka camera) space.
    - The projection matrix transforms from view space to homogeneous clip space.

    The "modelview" matrix in OpenGL is the same as the concatenation of the world and view matrix in Direct3D. If you're more familiar with working that way, you can set the view matrix to identity and set the world matrix to the "modelview" matrix.

    You'll find an example of setting up each of those transformation matrices and use of various D3DX helper functions in the 3rd Direct3D SDK tutorial (Tut03_Matrices).


    2) If your intention was to pass pre-transformed/screen-space vertices to Direct3D, then you don't need to set any transformation matrices, but you do need to use a slightly different FVF code: D3DFVF_XYZRHW. You'll also need to ensure there's an "rhw" member of your vertex structure immediately after the xyz part (see Tutorial 2 for an example).

    RHW is "Reciprocal of Homogeneous W" (i.e. 1.0/W). The "W" and homogeneous part comes in when projecting from 3D space into 2D with perspective (you can't perform division and translation using matrices without W).

    If you only want flat 2D vertices (like with a sprite), you can just set the rhw member of your vertices to 1.0 as Tutorial 2 does.


    3) Ideally you should call IDirect3DDevice9::Clear() on the device before the start of your rendering for each scene so that any uninitialised garbage already in the frame buffer memory is cleared out.

    Additionally, if you created your device with a depth buffer (EnableAutoDepthStencil set to true) I'd advise clearing the Z buffer at the same time as the frame buffer with the both D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET flag combination. This is so that any any pixels rendered aren't rejected due to any existing data (or uninitialised garbage) in the Z buffer memory.

    HTH
    Sunday, October 23, 2005 3:09 PM

All replies

  • 1) D3DFVF_XYZ tells the Direct3D fixed function pipeline "these vertices are untransformed, please transform them using the currently set world, view and projection matrices to them".

    The code you've posted doesn't set any transformation matrices, so D3D will use identity transformation matrices (the default) to transform your vertices from object space to homogeneous clip space. Transforming your particular input vertices by identity would result in all of the vertices being clipped (-w<=x<=w)...

    You'll need to call IDirect3DDevice9::SetTransform for D3DTS_WORLD, D3DTS_VIEW and D3DTS_PROJECTION to set the transforms D3D uses.

    - The world matrix transforms from object (aka model) space to world space.
    - The view matrix transforms from world space to view (aka camera) space.
    - The projection matrix transforms from view space to homogeneous clip space.

    The "modelview" matrix in OpenGL is the same as the concatenation of the world and view matrix in Direct3D. If you're more familiar with working that way, you can set the view matrix to identity and set the world matrix to the "modelview" matrix.

    You'll find an example of setting up each of those transformation matrices and use of various D3DX helper functions in the 3rd Direct3D SDK tutorial (Tut03_Matrices).


    2) If your intention was to pass pre-transformed/screen-space vertices to Direct3D, then you don't need to set any transformation matrices, but you do need to use a slightly different FVF code: D3DFVF_XYZRHW. You'll also need to ensure there's an "rhw" member of your vertex structure immediately after the xyz part (see Tutorial 2 for an example).

    RHW is "Reciprocal of Homogeneous W" (i.e. 1.0/W). The "W" and homogeneous part comes in when projecting from 3D space into 2D with perspective (you can't perform division and translation using matrices without W).

    If you only want flat 2D vertices (like with a sprite), you can just set the rhw member of your vertices to 1.0 as Tutorial 2 does.


    3) Ideally you should call IDirect3DDevice9::Clear() on the device before the start of your rendering for each scene so that any uninitialised garbage already in the frame buffer memory is cleared out.

    Additionally, if you created your device with a depth buffer (EnableAutoDepthStencil set to true) I'd advise clearing the Z buffer at the same time as the frame buffer with the both D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET flag combination. This is so that any any pixels rendered aren't rejected due to any existing data (or uninitialised garbage) in the Z buffer memory.

    HTH
    Sunday, October 23, 2005 3:09 PM
  • Thanks for that :-)

    I made a similar mistake when I was first learning openGL. I got confused by there being default values for the viewport which is not anything to do with the view matrecies and assumed there were default values.

    I should be right now. On the whole the documentation for Direct3D is good, better than i found the openGL textbook in computer science.

    Monday, October 24, 2005 10:17 AM