2
\$\begingroup\$

I am trying to draw a 3D Wireframe (just the lines that connect each vertex) Cube and a 10x10 grid with D3D11. So far, this is my code

//************************************************************
//************ INCLUDES & DEFINES ****************************
//************************************************************

#include <iostream>
#include <ctime>
#include "XTime.h"

using namespace std;

#include <d3d11.h>
#include <d3dx11.h>
#include <d3d10.h>
#include <DirectXMath.h>
#include <DirectXColors.h>
#include <DirectXCollision.h>
#include <DirectXPackedVector.h>
#include <D3dx9math.h>
#include "Trivial_VS.csh"
#include "Trivial_PS.csh"

#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "d3d10.lib")

using namespace DirectX::Colors;
using namespace DirectX::Internal;
using namespace DirectX::PackedVector;
using namespace DirectX::TriangleTests;

#define BACKBUFFER_WIDTH    500
#define BACKBUFFER_HEIGHT   500

//************************************************************
//************ SIMPLE WINDOWS APP CLASS **********************
//************************************************************

class DEMO_APP
{   
    HINSTANCE                       application;
    WNDPROC                         appWndProc;
    HWND                            window;
    ID3D11Device *device = 0;
    ID3D11DeviceContext *deviceContext = 0;
    ID3D11RenderTargetView *RTV = 0;
    IDXGISwapChain *swapChain = 0;
    ID3D11View *view = 0;
    ID3D11Debug *debugger = 0;
    ID3D11Texture2D *swapChainBuffer = 0;
    D3D11_VIEWPORT viewport;
    ID3D11InputLayout* inputLayout;
    XTime timer;
    int XDir = 1;
    int YDir = 1;

    ID3D11Buffer *cubeBuffer;
    unsigned int numCubeVertices = 24;

    ID3D11Buffer *gridBufferC;
    unsigned int numGridVertices = 44;

    ID3D11VertexShader *vertexShader;
    ID3D11PixelShader *pixelShader;

    ID3D11Buffer * constantViewBuffer;

    struct SEND_TO_VRAM
    {
        DirectX::XMVECTORF32 constantColor;
        DirectX::XMFLOAT2 constantOffset;
        DirectX::XMFLOAT2 padding;
        DirectX::XMMATRIX worldMatrix;
        DirectX::XMMATRIX viewMatrix;
        DirectX::XMMATRIX projectionMatrix;
    };

    SEND_TO_VRAM toShaderCube;

    SEND_TO_VRAM toShaderGridC;


public:
    struct SIMPLE_VERTEX
    {
        DirectX::XMFLOAT2 position2D;
    };


    struct ROBUST_VERTEX
    {
        DirectX::XMFLOAT4 position;
    };

    DEMO_APP(HINSTANCE hinst, WNDPROC proc);
    bool Run();
    bool ShutDown();
};

//************************************************************
//************ CREATION OF OBJECTS & RESOURCES ***************
//************************************************************

DEMO_APP::DEMO_APP(HINSTANCE hinst, WNDPROC proc)
{
    application = hinst; 
    appWndProc = proc; 

    WNDCLASSEX  wndClass;
    ZeroMemory( &wndClass, sizeof( wndClass ) );
    wndClass.cbSize         = sizeof( WNDCLASSEX );             
    wndClass.lpfnWndProc    = appWndProc;                       
    wndClass.lpszClassName  = L"DirectXApplication";            
    wndClass.hInstance      = application;                     
    wndClass.hCursor        = LoadCursor( NULL, IDC_ARROW );    
    wndClass.hbrBackground  = ( HBRUSH )( COLOR_WINDOWFRAME ); 
    RegisterClassEx( &wndClass );

    RECT window_size = { 0, 0, BACKBUFFER_WIDTH, BACKBUFFER_HEIGHT };
    AdjustWindowRect(&window_size, WS_OVERLAPPEDWINDOW, false);

    window = CreateWindow(  L"DirectXApplication", L"CGS Hardware Project", WS_OVERLAPPEDWINDOW & ~(WS_THICKFRAME|WS_MAXIMIZEBOX), 
                            CW_USEDEFAULT, CW_USEDEFAULT, window_size.right-window_size.left, window_size.bottom-window_size.top,                   
                            NULL, NULL, application, this );                                                

    ShowWindow( window, SW_SHOW );

    DXGI_SWAP_CHAIN_DESC swapChainDesc;

    ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));

    swapChainDesc.BufferCount = 1;
    swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    swapChainDesc.BufferDesc.Height = BACKBUFFER_HEIGHT;
    swapChainDesc.BufferDesc.Width = BACKBUFFER_WIDTH;
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.OutputWindow = window;
    swapChainDesc.SampleDesc.Count = 4;
    swapChainDesc.Windowed = true;

    UINT flags = D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT;

    if (_DEBUG)
    {
        flags |= D3D11_CREATE_DEVICE_DEBUG;
    }

    HRESULT hr = D3D11CreateDeviceAndSwapChain(NULL,
        D3D_DRIVER_TYPE_HARDWARE,
        NULL,
        flags,
        NULL,
        NULL,
        D3D11_SDK_VERSION,
        &swapChainDesc,
        &swapChain,
        &device,
        NULL,
        &deviceContext);

    hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&swapChainBuffer);

    hr = device->CreateRenderTargetView(swapChainBuffer, NULL, &RTV);

    hr = device->QueryInterface(__uuidof(ID3D11Debug), (void**)&debugger);

    ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));

    viewport.TopLeftX = 0;
    viewport.TopLeftY = 0;
    viewport.Width = swapChainDesc.BufferDesc.Width;
    viewport.Height = swapChainDesc.BufferDesc.Height;
    viewport.MinDepth = 0;
    viewport.MaxDepth = 1;

    ROBUST_VERTEX cube[24];

    //Cube Init
    {
    for (unsigned int i = 0; i < numCubeVertices; ++i)
    {
        cube[i].position.w = 1;
    }
    //TOPLEFT
    cube[0].position.x = -0.25f;
    cube[0].position.y = 0.25f;
    cube[0].position.z = -0.25f;
    cube[1].position.x = -0.25f;
    cube[1].position.y = 0.25f;
    cube[1].position.z = 0.25f;

    //TOPBACK
    cube[2].position.x = -0.25f;
    cube[2].position.y = 0.25f;
    cube[2].position.z = 0.25f;
    cube[3].position.x = 0.25f;
    cube[3].position.y = 0.25f;
    cube[3].position.z = 0.25f;

    //TOPRIGHT
    cube[4].position.x = 0.25f;
    cube[4].position.y = 0.25f;
    cube[4].position.z = 0.25f;
    cube[5].position.x = 0.25f;
    cube[5].position.y = 0.25f;
    cube[5].position.z = -0.25f;

    //TOPFRONT
    cube[6].position.x = 0.25f;
    cube[6].position.y = 0.25f;
    cube[6].position.z = -0.25f;
    cube[7].position.x = -0.25f;
    cube[7].position.y = 0.25f;
    cube[7].position.z = -0.25f;

    //BOTTOMLEFT
    cube[8].position.x = -0.25f;
    cube[8].position.y = -0.25f;
    cube[8].position.z = -0.25f;
    cube[9].position.x = -0.25f;
    cube[9].position.y = -0.25f;
    cube[9].position.z = 0.25f;

    //BOTTOMBACK
    cube[10].position.x = -0.25f;
    cube[10].position.y = -0.25f;
    cube[10].position.z = 0.25f;
    cube[11].position.x = 0.25f;
    cube[11].position.y = -0.25f;
    cube[11].position.z = 0.25f;

    //BOTTOMRIGHT
    cube[12].position.x = 0.25f;
    cube[12].position.y = -0.25f;
    cube[12].position.z = 0.25f;
    cube[13].position.x = 0.25f;
    cube[13].position.y = -0.25f;
    cube[13].position.z = -0.25f;

    //BOTTOMFRONT
    cube[14].position.x = 0.25f;
    cube[14].position.y = -0.25f;
    cube[14].position.z = -0.25f;
    cube[15].position.x = -0.25f;
    cube[15].position.y = -0.25f;
    cube[15].position.z = -0.25f;

    //CORNER FRONTLEFT
    cube[16].position.x = -0.25f;
    cube[16].position.y = 0.25f;
    cube[16].position.z = -0.25f;
    cube[17].position.x = -0.25f;
    cube[17].position.y = -0.25f;
    cube[17].position.z = -0.25f;

    //CORNER BACKLEFT
    cube[18].position.x = -0.25f;
    cube[18].position.y = 0.25f;
    cube[18].position.z = 0.25f;
    cube[19].position.x = -0.25f;
    cube[19].position.y = -0.25f;
    cube[19].position.z = 0.25f;

    //CORNER BACKRIGHT
    cube[20].position.x = 0.25f;
    cube[20].position.y = 0.25f;
    cube[20].position.z = 0.25f;
    cube[21].position.x = 0.25f;
    cube[21].position.y = -0.25f;
    cube[21].position.z = 0.25f;

    //CORNER FRONTRIGHT
    cube[22].position.x = 0.25f;
    cube[22].position.y = 0.25f;
    cube[22].position.z = -0.25f;
    cube[23].position.x = 0.25f;
    cube[23].position.y = -0.25f;
    cube[23].position.z = -0.25f;
}


    ROBUST_VERTEX gridC[44];

    //Grid Init
    {
    for (unsigned int i = 0; i < numGridVertices; ++i)
    {
        gridC[i].position.y = 0;
        gridC[i].position.w = 1;
    }

    //Borders
    {
        gridC[0].position.x = -0.5;
        gridC[0].position.z = -0.5;
        gridC[1].position.x = -0.5;
        gridC[1].position.z = 0.5;

        gridC[2].position.x = -0.5;
        gridC[2].position.z = 0.5;
        gridC[3].position.x = 0.5;
        gridC[3].position.z = 0.5;

        gridC[4].position.x = 0.5;
        gridC[4].position.z = 0.5;
        gridC[5].position.x = 0.5;
        gridC[5].position.z = -0.5;

        gridC[6].position.x = 0.5;
        gridC[6].position.z = -0.5;
        gridC[7].position.x = -0.5;
        gridC[7].position.z = -0.5;
    }

        //CrossSections
    {
        float counter = -0.4;
        for (unsigned int i = 8; i < 26;)
        {
            gridC[i].position.x = -0.5;
            gridC[i].position.z = counter;
            ++i;
            gridC[i].position.x = 0.5;
            gridC[i].position.z = counter;
            ++i;
            if (counter >= -0.15 && counter <= -0.05)
            {
                counter = 0;
            }
            else
            {
                counter += 0.1;
            }
        }

        counter = -0.4;
        for (unsigned int i = 26; i < 44;)
        {
            gridC[i].position.z = -0.5;
            gridC[i].position.x = counter;
            ++i;
            gridC[i].position.z = 0.5;
            gridC[i].position.x = counter;
            ++i;
            if (counter >=-0.15 && counter<=-0.05)
            {
                counter = 0;
            }
            else
            {
                counter += 0.1;
            }
        }

    }

}

    D3D11_BUFFER_DESC cubeBufferDesc;
    ZeroMemory(&cubeBufferDesc, sizeof(D3D11_BUFFER_DESC));

    cubeBufferDesc.Usage = D3D11_USAGE_DEFAULT;
    cubeBufferDesc.ByteWidth = sizeof(ROBUST_VERTEX)*numCubeVertices;
    cubeBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    cubeBufferDesc.MiscFlags = 0;
    cubeBufferDesc.StructureByteStride = 0;

    D3D11_SUBRESOURCE_DATA subResDataCube;
    ZeroMemory(&subResDataCube, sizeof(D3D11_SUBRESOURCE_DATA));
    subResDataCube.pSysMem = cube;
    subResDataCube.SysMemPitch = 0;
    subResDataCube.SysMemSlicePitch = 0;

    device->CreateBuffer(&cubeBufferDesc, &subResDataCube, &cubeBuffer);



    D3D11_BUFFER_DESC gridBufferDesc;
    ZeroMemory(&gridBufferDesc, sizeof(D3D11_BUFFER_DESC));

    gridBufferDesc.Usage = D3D11_USAGE_DEFAULT;
    gridBufferDesc.ByteWidth = sizeof(ROBUST_VERTEX)*numGridVertices;
    gridBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    gridBufferDesc.MiscFlags = 0;
    gridBufferDesc.StructureByteStride = 0;

    D3D11_SUBRESOURCE_DATA subResDataGrid;
    ZeroMemory(&subResDataGrid, sizeof(D3D11_SUBRESOURCE_DATA));
    subResDataGrid.pSysMem = gridC;
    subResDataGrid.SysMemPitch = 0;
    subResDataGrid.SysMemSlicePitch = 0;

    device->CreateBuffer(&gridBufferDesc, &subResDataGrid, &gridBufferC);

    device->CreateVertexShader(Trivial_VS, sizeof(Trivial_VS), NULL, &vertexShader);
    device->CreatePixelShader(Trivial_PS, sizeof(Trivial_PS), NULL, &pixelShader);

    D3D11_INPUT_ELEMENT_DESC inputElementDesc[] = 
    {
        {"POSITION",0,DXGI_FORMAT_R32G32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}
    };

    device->CreateInputLayout(inputElementDesc, 1, &Trivial_VS, sizeof(Trivial_VS), &inputLayout);

    D3D11_BUFFER_DESC constantBufferDesc;
    ZeroMemory(&constantBufferDesc, sizeof(D3D11_BUFFER_DESC));

    constantBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
    constantBufferDesc.ByteWidth = sizeof(SEND_TO_VRAM);
    constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    constantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    constantBufferDesc.MiscFlags = 0;
    constantBufferDesc.StructureByteStride = 0;

    device->CreateBuffer(&constantBufferDesc, NULL, &constantViewBuffer);

    toShaderCube.constantOffset.x = 0;
    toShaderCube.constantOffset.y = 0;
    toShaderCube.constantColor = DirectX::Colors::Green;
    toShaderCube.worldMatrix = DirectX::XMMatrixIdentity();

    toShaderGridC.constantOffset.x = 0;
    toShaderGridC.constantOffset.y = 0;
    toShaderGridC.constantColor = DirectX::Colors::White;
    toShaderGridC.worldMatrix = DirectX::XMMatrixIdentity();

}

//************************************************************
//************ EXECUTION *************************************
//************************************************************

bool DEMO_APP::Run()
{

    float Yscale = 1.0f / (tan(DirectX::XMConvertToRadians(0.5*60)));
    float aspectRatio = viewport.Width / viewport.Height;
    float Xscale = Yscale*aspectRatio;
    float zNear = 0.1f;
    float zFar = 10.0f;

    DirectX::XMMATRIX viewMatrix;
    DirectX::XMMATRIX projectionMatrix(Xscale, 0, 0, 0,
        0, Yscale, 0, 0,
        0, 0, (zFar / (zFar - zNear)), 1,
        0, 0, -1.0f*(zFar*zNear) / (zFar - zNear), 0);

    projectionMatrix = DirectX::XMMatrixTranspose(projectionMatrix);

    toShaderCube.projectionMatrix = projectionMatrix;
    toShaderGridC.projectionMatrix = projectionMatrix;

    float cameraAngle = DirectX::XMConvertToRadians(18);
    viewMatrix = DirectX::XMMatrixRotationX(cameraAngle);
    viewMatrix = DirectX::XMMatrixMultiply(DirectX::XMMatrixTranslation(0, 0, -1.5), viewMatrix);
    viewMatrix = DirectX::XMMatrixInverse(NULL,viewMatrix);
    viewMatrix = DirectX::XMMatrixTranspose(viewMatrix);

    toShaderCube.viewMatrix = viewMatrix;
    toShaderGridC.viewMatrix = viewMatrix;

    //timer.TotalTime() just returns the amount of time since the program started
    toShaderCube.worldMatrix = DirectX::XMMatrixIdentity();
    toShaderCube.worldMatrix = DirectX::XMMatrixTranslation(0, 0.25, 0);
    toShaderCube.worldMatrix = DirectX::XMMatrixMultiply(DirectX::XMMatrixRotationY(DirectX::XMConvertToRadians(timer.TotalTime()*50)),
                            toShaderCube.worldMatrix);
    toShaderCube.worldMatrix = DirectX::XMMatrixTranspose(toShaderCube.worldMatrix);


    deviceContext->OMSetRenderTargets(1, &RTV, 0);
    deviceContext->RSSetViewports(1, &viewport);
    deviceContext->ClearRenderTargetView(RTV, DirectX::Colors::Black);

    D3D11_MAPPED_SUBRESOURCE mappedSubRes;
    ZeroMemory(&mappedSubRes, sizeof(mappedSubRes));
    deviceContext->Map(constantViewBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &mappedSubRes);
    memcpy(mappedSubRes.pData, &toShaderGridC, sizeof(SEND_TO_VRAM));
    deviceContext->Unmap(constantViewBuffer, NULL);

    deviceContext->VSSetConstantBuffers(0, 1, &constantViewBuffer);

    UINT stride = sizeof(ROBUST_VERTEX);
    UINT offset = 0;
    deviceContext->IASetVertexBuffers(0, 1, &gridBufferC, &stride, &offset);

    deviceContext->IASetInputLayout(inputLayout);
    deviceContext->VSSetShader(vertexShader, 0, 0);
    deviceContext->PSSetShader(pixelShader, 0, 0);

    deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);

    deviceContext->Draw(numGridVertices, 0);


    ZeroMemory(&mappedSubRes, sizeof(mappedSubRes));
    deviceContext->Map(constantViewBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &mappedSubRes);
    memcpy(mappedSubRes.pData, &toShaderCube, sizeof(SEND_TO_VRAM));
    deviceContext->Unmap(constantViewBuffer, NULL);


    stride = sizeof(ROBUST_VERTEX);
    offset = 0;
    deviceContext->IASetVertexBuffers(0, 1, &cubeBuffer, &stride, &offset);
    deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);

    deviceContext->Draw(numCubeVertices, 0);

    swapChain->Present(0, 0);
    return true; 
}

//************************************************************
//************ DESTRUCTION ***********************************
//************************************************************

bool DEMO_APP::ShutDown()
{
    deviceContext->ClearState();

    deviceContext->Release();
    deviceContext = NULL;
    swapChain->Release();
    swapChain = NULL;
    device->Release();
    device = NULL;
    RTV->Release();
    RTV = NULL;
    debugger->Release();
    debugger = NULL;
    swapChainBuffer->Release();
    swapChainBuffer = NULL;
    inputLayout->Release();
    inputLayout = NULL;
    cubeBuffer->Release();
    cubeBuffer = NULL;
    gridBufferC->Release();
    gridBufferC = NULL;
    vertexShader->Release();
    vertexShader = NULL;
    pixelShader->Release();
    pixelShader = NULL;
    constantViewBuffer->Release();
    constantViewBuffer = NULL;
    //view->Release();
    //view = NULL;

    UnregisterClass( L"DirectXApplication", application ); 
    return true;
}

//************************************************************
//************ WINDOWS RELATED *******************************
//************************************************************

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow );                        
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam );       
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE, LPTSTR, int )
{
    srand(unsigned int(time(0)));
    DEMO_APP myApp(hInstance,(WNDPROC)WndProc); 
    MSG msg; ZeroMemory( &msg, sizeof( msg ) );
    while ( msg.message != WM_QUIT && myApp.Run() )
    {   
        if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
        { 
            TranslateMessage( &msg );
            DispatchMessage( &msg ); 
        }
    }
    myApp.ShutDown(); 
    return 0; 
}
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    if(GetAsyncKeyState(VK_ESCAPE))
        message = WM_DESTROY;
    switch ( message )
    {
        case ( WM_DESTROY ): { PostQuitMessage( 0 ); }
        break;
    }
    return DefWindowProc( hWnd, message, wParam, lParam );
}

Here's the Trivial_VS hlsl shader file. The trivial_Ps doesn't do anything currently

struct INPUT_VERTEX
{
    float2 coordinate : POSITION;
};

struct OUTPUT_VERTEX
{
    float4 colorOut : COLOR;
    float4 projectedCoordinate : SV_POSITION;
};

cbuffer THIS_IS_VRAM : register( b0 )
{
    float4 constantColor;
    float2 constantOffset;
    float2 padding;
    float4x4 worldMatrix;
    float4x4 viewMatrix;
    float4x4 projectionMatrix;
};

OUTPUT_VERTEX main( INPUT_VERTEX fromVertexBuffer )
{
    OUTPUT_VERTEX sendToRasterizer = (OUTPUT_VERTEX)0;
    sendToRasterizer.projectedCoordinate.w = 1;

    sendToRasterizer.projectedCoordinate.xy = fromVertexBuffer.coordinate.xy;

    sendToRasterizer.projectedCoordinate.xy += constantOffset;

    sendToRasterizer.projectedCoordinate = mul(sendToRasterizer.projectedCoordinate, worldMatrix);
    sendToRasterizer.projectedCoordinate = mul(sendToRasterizer.projectedCoordinate, viewMatrix);
    sendToRasterizer.projectedCoordinate = mul(sendToRasterizer.projectedCoordinate, projectionMatrix);

    sendToRasterizer.projectedCoordinate.x /= sendToRasterizer.projectedCoordinate.w;
    sendToRasterizer.projectedCoordinate.y /= sendToRasterizer.projectedCoordinate.w;
    sendToRasterizer.projectedCoordinate.z /= sendToRasterizer.projectedCoordinate.w;

    sendToRasterizer.colorOut = constantColor;

    return sendToRasterizer;
}

Right now, the only thing that is being drawn is a green square that rotates the way the cube should and a white line where the grid should be.

Ideally, I'd like to have the 10x10 white grid and the 3D Wireframe cube sitting on top of the grid and rotating. I don't want to fill in any of the faces with a texture and I don't want to have two triangles representing each face with a diagonal cutting through the face. I feel like I'm missing some aspect of working specifically in 3D.

Also, if you know how to debug what the values in the shader are changing to as I multiply them by each matrix, that would definitely be a help as well but really I just want to get my objects drawn.

Thanks for anything you can help out with!

\$\endgroup\$
2
\$\begingroup\$
D3D11_INPUT_ELEMENT_DESC inputElementDesc[] = 
{
    {"POSITION",0,DXGI_FORMAT_R32G32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}
};

You need to change the format to DXGI_FORMAT_R32G32B32A32 or you won't be able to send the z and w information of the vertex to the vertex shader.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.