Sunday, February 6, 2011

DirectX 10 Programming Tutorial 1.2

/******************************************************************************
Our first program with DirectX!  Let's jump straight into code and then explain what is going on as we go.
If you are just joining me you should start here to get an idea of basic Win32 applications as this code just fits on top of that code.
******************************************************************************/

#include <D3D10.h>
#include <D3DX10.h>

//D3D Global variables
ID3D10Device *g_d3dDevice = NULL;
IDXGISwapChain *g_swapChain = NULL;
ID3D10RenderTargetView *g_renderTargetView = NULL;

//Function Declarations
bool Initialize(HWND hWnd);
void Render();
void ResizeWindow(int width, int height);
void ShutDown();

/***************************************************************************
To save space I've decided to put the definition of each of these on a separate page so click on each new type to go to a description of what each is and why we need it. Now, we have declared our device, swap chain and render target view and have functions to intialize, render, resize and shutdown. I'll start by defining these functions and then we'll go back through our Win32 app code to put them to use.
****************************************************************************/
 bool Initialize(HWND hWnd)
{
    DXGI_SWAP_CHAIN_DESC scDesc;
    ZeroMemory(&scDesc, sizeof(scDesc));
    
    //We need to define and create the swap chain
    scDesc.BufferCount = 2;
    scDesc.BufferDesc.Width = WINDOW_WIDTH;
    scDesc.BufferDesc.Height = WINDOW_HEIGHT;
    scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    scDesc.BufferDesc.RefreshRate.Numerator = 60;
    scDesc.BufferDesc.RefreshRate.Denominator = 1;
    scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    scDesc.OutputWindow = hWnd;
    scDesc.SampleDesc.Count = 1;
    scDesc.SampleDesc.Quality = 0;
    scDesc.Windowed = TRUE;

    //Setup the debug utility for testing
    unsigned int flags = 0;

#ifdef _DEBUG
    flags |= D3D10_CREATE_DEVICE_DEBUG;
#endif

    //Create a loop to test for availability of Reference or Hardware
    //Driver type
    D3D10_DRIVER_TYPE driverType = D3D10_DRIVER_TYPE_NULL;
    D3D10_DRIVER_TYPE driverTypes[] =
    {
        D3D10_DRIVER_TYPE_HARDWARE,
        D3D10_DRIVER_TYPE_REFERENCE,
    };

    HRESULT hr = NULL;

    unsigned int numDriverTypes = sizeof(driverTypes) / sizeof(driverTypes[0]);
    for (unsigned int i = 0; i < numDriverTypes; i++)
    {
        driverType = driverTypes[i];

        hr = D3D10CreateDeviceAndSwapChain(NULL,
            driverType,
            NULL,
            flags,
            D3D10_SDK_VERSION,
            &scDesc,
            &g_swapChain,
            &g_d3dDevice);

        if(SUCCEEDED(hr))
            break;
    }

    if(FAILED(hr))
        return false;

    ID3D10Texture2D *buffer = NULL;
    hr = g_swapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&buffer);
   
    if(FAILED(hr))
        return false;

    //Create the render target view

    hr = g_d3dDevice->CreateRenderTargetView(buffer, NULL, &g_renderTargetView);

    buffer->Release();

    if(FAILED(hr))
        return false;

    //Set the render target
    g_d3dDevice->OMSetRenderTargets(1, &g_renderTargetView, NULL);


    ResizeWindow(WINDOW_WIDTH, WINDOW_HEIGHT);

    return true;
}




 void ResizeWindow(int width, int height)
{
    if(g_d3dDevice == NULL)
        return;

    D3D10_VIEWPORT vp;

    vp.Width = width;
    vp.Height = height;
    vp.MaxDepth = 1.0f;
    vp.MinDepth = 0.0f;
    vp.TopLeftX = 0;
    vp.TopLeftY = 0;

    g_d3dDevice->RSSetViewports(1, &vp);
}

 void Render()
{
    float col[4] = { 1, 0, 0, 1 };

    g_d3dDevice->ClearRenderTargetView(g_renderTargetView, col);

    g_swapChain->Present( 0, 0 );
}

void ShutDown()
{
    // Release memory
    if(g_d3dDevice) g_d3dDevice->ClearState();
    if(g_swapChain) g_swapChain->Release();
    if(g_renderTargetView) g_renderTargetView->Release();
    if(g_d3dDevice) g_d3dDevice->Release();
}


/***************************************************************************
The Initialize() function is the longest function so far and it just gets us set up so we can do the fun stuff. Again it's description is posted separately, as well as the resize, render, and shutdown functions. Now we should put our code to use in our window.
****************************************************************************/
//To WndProc() we add:
int height,width;

//In WM_DESTROY... break;
case WM_SIZE:
    height = HIWORD(lParam);
    width = LOWORD(lParam);

    if(height == 0)
        height = 1;
    ResizeWindow(width, height);


//In WinMain()
//Replace old message loop from while(msg.message != WM_QUIT)
//to DispatchMessage(&msg) } } with:
if(Initialize(hWnd))
{
    while(true)
    {
        if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
        {
            if(msg.message == WM_QUIT) break;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            Render();
        }
    }
}

/***************************************************************************
And you're done! When you compile this code you should get a blank window filled with red. You can change this color by changing the values for col in Render() realizing that the values are Red, Green, Blue, and Alpha. Alpha is the opacity and values range from 0 being none to 1 maximum See the wiki article on RGBA for more information.
***************************************************************************/
DirectX 10 Programming Tutorial 1.1

No comments:

Post a Comment