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\$

1 Answer 1

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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .