Arsenal11
Arsenal11

Reputation: 1

How to make a square using Direct3D and c++?

I have been following a Directx tutorial online that had me draw a triangle and I've wanted to try and figure out how to turn it into a square. I understand that I can add an extra vertex so that it is virtually combining two triangles with 4 vertices. Now when I do all this the output only shows one triangle, I was wondering where in is the error. Here is my code currently:

#include <Windows.h>
#include <windowsx.h>
#include <d3d9.h>

#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600

#pragma comment (lib, "d3d9.lib")

LPDIRECT3D9 d3d;

LPDIRECT3DDEVICE9 d3ddev;

LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;

void initD3D(HWND hWnd);

void render_frame(void);

void cleanD3D(void);

void init_graphics(void);


struct CUSTOMVERTEX { FLOAT X, Y, Z, RHW; DWORD COLOR; };
#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)

LRESULT CALLBACK WindowProc(HWND hWnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow)
{
    HWND hWnd;

    WNDCLASSEX wc;

    ZeroMemory(&wc, sizeof(WNDCLASSEX));

    wc.cbSize = sizeof(WNDCLASSEX); 

    wc.style = CS_HREDRAW | CS_VREDRAW;

    wc.lpfnWndProc = WindowProc;

    wc.hInstance = hInstance;

    wc.hCursor = LoadCursor(NULL, IDC_ARROW);

    wc.lpszClassName = L"WindowClass1";

    RegisterClassEx(&wc);

    hWnd = CreateWindowEx(NULL,
        L"WindowClass1",
        L"Pretty Triangle",
        WS_OVERLAPPEDWINDOW,
        0,
        0,
        SCREEN_WIDTH,
        SCREEN_HEIGHT,
        NULL,
        NULL,
        hInstance,
        NULL);

    ShowWindow(hWnd, nCmdShow);

    initD3D(hWnd);

    MSG msg;

    while (TRUE)
    {
        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);

            DispatchMessage(&msg);
        }

        if (msg.message == WM_QUIT)
            break;

        render_frame();
    }

    cleanD3D();

    return msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case_WM_DESTROY:
    {
        PostQuitMessage(0);
        return 0;
    }
        break;
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}

void initD3D(HWND hWnd)
{
    d3d = Direct3DCreate9(D3D_SDK_VERSION);

    D3DPRESENT_PARAMETERS d3dpp;

    ZeroMemory(&d3dpp, sizeof(d3dpp));

    d3dpp.Windowed = TRUE;

    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

    d3dpp.hDeviceWindow = hWnd;

    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;

    d3dpp.BackBufferWidth = SCREEN_WIDTH;

    d3dpp.BackBufferHeight = SCREEN_HEIGHT;

    d3d->CreateDevice(D3DADAPTER_DEFAULT,
        D3DDEVTYPE_HAL,
        hWnd,
        D3DCREATE_SOFTWARE_VERTEXPROCESSING,
        &d3dpp,
        &d3ddev);

    init_graphics();
}

void render_frame(void)
{
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

    d3ddev->BeginScene();

    d3ddev->SetFVF(CUSTOMFVF);

    d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));

    d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

    d3ddev->EndScene();

    d3ddev->Present(NULL, NULL, NULL, NULL);
}

void cleanD3D(void)
{
    v_buffer->Release();
    d3ddev->Release();
    d3d->Release();
}

void init_graphics(void)
{
    CUSTOMVERTEX vertices[] =
    {
        { 100.0f, 100.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), },
        { 132.0f, 100.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 0), },
        { 100.0f, 132.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), },
        { 100.0f, 132.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), },
    };

    d3ddev->CreateVertexBuffer(4 * sizeof(CUSTOMVERTEX),
        0,
        CUSTOMFVF,
        D3DPOOL_MANAGED,
        &v_buffer,
        NULL);

    VOID*pVoid;

    v_buffer->Lock(0, 0, (void**)&pVoid, 0);
    memcpy(pVoid, vertices, sizeof(vertices));
    v_buffer->Unlock();
}

Any help would be greatly appreciated.

Upvotes: 0

Views: 522

Answers (2)

Gnietschow
Gnietschow

Reputation: 3180

Your last vertex is at the same position as your third, so your second triangle is a line and not visible. I think you have a typo in your vertex data and wanted to write

{ 132.0f, 132.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), }

as your last vertex to make the quad complete.

Upvotes: 1

Adrian Sanguineti
Adrian Sanguineti

Reputation: 2495

I'm very rusty at Direct3D but I believe your issue is that you do not have enough vertices to draw a square because you are using DrawPrimativemethod. This method expects that the duplicated vertices for drawing a square (using 2 trianges) are present in your array, meaning that you should have 6 vertices defined instead of 4.

If you change you code to call DrawIndexedPrimitive instead, then you don't have to define the duplicate vertices and you will find that your existing vertices array should work.

DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                0,                  // BaseVertexIndex
                0,                  // MinIndex
                4,                  // NumVertices
                0,                  // StartIndex
                2 );                // PrimitiveCount

Here is a good article on drawing a square in Direct3D that also explains Indexed Veritces: http://msdn.microsoft.com/en-us/library/windows/desktop/bb147325(v=vs.85).aspx

Upvotes: 0

Related Questions