예제 #1
0
파일: CelShadeApp.cpp 프로젝트: endy/Ivy
///////////////////////////////////////////////////////////////////////////////////////////////////
/// CelShadeApp::CelShadeD3D
///
/// @brief
///     Render a cel-shading demo using Direct3D
/// @return
///     N/A
///////////////////////////////////////////////////////////////////////////////////////////////////
void CelShadeApp::CelShadeD3D()
{
    ID3D11DeviceContext* pContext = m_pDxData->pD3D11Context;
    ID3D11Device* pDevice = m_pDxData->pD3D11Device;

    D3DX11_IMAGE_LOAD_INFO imageLoadInfo;
    memset( &imageLoadInfo, 0, sizeof(D3DX11_IMAGE_LOAD_INFO) );
    imageLoadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    imageLoadInfo.Format = DXGI_FORMAT_R8G8B8A8_UNORM;

    DxTextureCreateInfo shadeTexInfo;
    memset(&shadeTexInfo, 0, sizeof(DxTextureCreateInfo));
    shadeTexInfo.flags.RenderTarget = TRUE;
    shadeTexInfo.flags.ShaderInput = TRUE;
    shadeTexInfo.format = DXGI_FORMAT_R8G8B8A8_UNORM;
    shadeTexInfo.width = m_screenWidth;
    shadeTexInfo.height = m_screenHeight;
    DxTexture* pShadeTex = DxTexture::Create(pDevice, &shadeTexInfo);

    DxTextureCreateInfo edgeTexInfo;
    memset(&edgeTexInfo, 0, sizeof(DxTextureCreateInfo));
    edgeTexInfo.flags.RenderTarget = TRUE;
    edgeTexInfo.flags.ShaderInput = TRUE;
    edgeTexInfo.format = DXGI_FORMAT_R8G8B8A8_UNORM;
    edgeTexInfo.width = m_screenWidth;
    edgeTexInfo.height = m_screenHeight;
    DxTexture* pEdgeTex = DxTexture::Create(pDevice, &edgeTexInfo);

    // Samplers  /////////////////////////////////////////////////////////////////////////////

    // SamplerState PointSampler : register(s0);

    D3D11_SAMPLER_DESC pointSamplerDesc;
    memset(&pointSamplerDesc, 0, sizeof(D3D11_SAMPLER_DESC));
    pointSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
    pointSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
    pointSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
    pointSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
    pointSamplerDesc.MinLOD = -FLT_MAX;
    pointSamplerDesc.MaxLOD = FLT_MAX;
    pointSamplerDesc.MipLODBias = 0.0f;
    pointSamplerDesc.MaxAnisotropy = 16;

    ID3D11SamplerState* pPointSampler = NULL;
    pDevice->CreateSamplerState(&pointSamplerDesc, &pPointSampler);

    //
    UINT numVertices = 0, numIndices = 0;
    VertexPTN* pVB = NULL;
    UINT* pIB = NULL;
    ImportPly("Content/dragon_vrip_res3.ply", numVertices, &pVB, numIndices, &pIB);
    //ImportPly("Content/bun_zipper_res4.ply", numVertices, &pVB, numIndices, &pIB);
    DxMeshCreateInfo meshCreateInfo = {0};
    meshCreateInfo.indexCount = numIndices;
    meshCreateInfo.pIndexArray = pIB;
    meshCreateInfo.indexFormat = DXGI_FORMAT_R32_UINT;
    meshCreateInfo.pVertexArray = pVB;
    meshCreateInfo.vertexCount = numVertices;
    meshCreateInfo.vertexElementSize = sizeof(VertexPTN);
    DxMesh* pMesh = DxMesh::Create(pDevice, &meshCreateInfo);

    Plane p;
    DxMeshCreateInfo planeMeshInfo;
    memset(&planeMeshInfo, 0, sizeof(planeMeshInfo));
    planeMeshInfo.pVertexArray = p.GetVB();
    planeMeshInfo.vertexCount = p.NumVertices();
    planeMeshInfo.vertexElementSize = sizeof(VertexPTN);

    DxMesh* pPlaneMesh = DxMesh::Create(pDevice, &planeMeshInfo);

    Cube c;
    DxMeshCreateInfo cubeMeshInfo;
    memset(&cubeMeshInfo, 0, sizeof(cubeMeshInfo));
    cubeMeshInfo.pVertexArray = c.GetVB();
    cubeMeshInfo.vertexCount = c.NumVertices();
    cubeMeshInfo.vertexElementSize = sizeof(VertexPT);

    DxMesh* pCubeMesh = DxMesh::Create(pDevice, &cubeMeshInfo);

    D3D11_SUBRESOURCE_DATA cbInitData;
    memset(&cbInitData, 0, sizeof(D3D11_SUBRESOURCE_DATA));	

    // Camera Buffer
    CameraBufferData cameraData;
    memset(&cameraData, 0, sizeof(CameraBufferData));

    DxBufferCreateInfo cameraBufferCreateInfo = {0};
    cameraBufferCreateInfo.flags.cpuWriteable = TRUE;
    cameraBufferCreateInfo.elemSizeBytes = sizeof(CameraBufferData);
    cameraBufferCreateInfo.pInitialData = &cameraData;
    DxBuffer* pCameraBuffer = DxBuffer::Create(pDevice, &cameraBufferCreateInfo);

    // Shaders ////////////////////////////////////////////////////////////////////////////////////

    m_pPosTexTriVS = DxShader::CreateFromFile(pDevice, "PosTexTri", "Content/shaders/CelShade.hlsl", PosTexVertexDesc, PosTexElements);
    m_pPosTexNormVS = DxShader::CreateFromFile(pDevice, "PosTexNorm", "Content/shaders/CelShade.hlsl", PosTexNormVertexDesc, PosTexNormElements);

    m_pCelShadePS = DxShader::CreateFromFile(pDevice, "CelShade", "Content/shaders/CelShade.hlsl");
    DxShader* pDetectEdges = DxShader::CreateFromFile(pDevice, "DetectEdges", "Content/shaders/CelShade.hlsl");
    DxShader* pApplyTexPS = DxShader::CreateFromFile(pDevice, "ApplyTex", "Content/shaders/CelShade.hlsl");

    DxShader* pCubeVS = DxShader::CreateFromFile(pDevice, "PosTex", "Content/shaders/CelShade.hlsl", PosTexVertexDesc, PosTexElements);
    DxShader* pCubePS = DxShader::CreateFromFile(pDevice, "CubePS", "Content/shaders/CelShade.hlsl");


    ////////////////////////////////////////////////////////////////////////////////////////

    pContext->ClearState();

    // SET RENDER STATE

    FLOAT clearColor[4];
    clearColor[0] = 0.2f;
    clearColor[1] = 0.2f;
    clearColor[2] = 0.2f; 
    clearColor[3] = 1.0f;

    D3D11_RASTERIZER_DESC shadeDesc;
    shadeDesc.FillMode = D3D11_FILL_SOLID;
    shadeDesc.CullMode = D3D11_CULL_BACK;
    shadeDesc.FrontCounterClockwise = FALSE;
    shadeDesc.DepthBias = 0;
    shadeDesc.DepthBiasClamp = 0.0f;
    shadeDesc.SlopeScaledDepthBias = 0;
    shadeDesc.DepthClipEnable = false;
    shadeDesc.ScissorEnable = false;
    shadeDesc.MultisampleEnable = false;
    shadeDesc.AntialiasedLineEnable = false;

    ID3D11RasterizerState* pShadeRS = NULL;
    pDevice->CreateRasterizerState(&shadeDesc, &pShadeRS);

    pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    m_pWindow->Show();

    BOOL quit = false;
    FLOAT yRotationAngle = 0.0f;
    while (!quit)
    {
        ProcessUpdates();

        BeginFrame();

        CameraBufferData* pCameraData = NULL;

        // new frame, clear state
        pContext->ClearState();

        pContext->RSSetViewports(1, &m_pDxData->viewport);
        pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

        pContext->RSSetState(pShadeRS);
        pContext->PSSetSamplers(0, 1, &pPointSampler);

        pContext->OMSetRenderTargets(1,
                                       &m_pDxData->pAppRenderTargetView,
                                       m_pDxData->pAppDepthStencilTex->GetDepthStencilView());
        pContext->ClearRenderTargetView(m_pDxData->pAppRenderTargetView, clearColor);
        pContext->ClearDepthStencilView(m_pDxData->pAppDepthStencilTex->GetDepthStencilView(),
                                          D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL,
                                          1.0,
                                          0);

        ///// Draw Mesh ///////////////////////////////////////////////////////////////////////////

        FLOAT viewRotationY = (GetMousePos().x - (m_screenWidth / 2.0f)) /(m_screenWidth / 2.0f);
        viewRotationY *= (3.14159f / 4.0f);

        FLOAT viewRotationZ = (GetMousePos().y - (m_screenHeight / 2.0f)) /(m_screenHeight / 2.0f);
        viewRotationZ *= (3.14159f / 4.0f);

        pCameraData = reinterpret_cast<CameraBufferData*>(pCameraBuffer->Map(pContext));
        pCameraData->worldMatrix = XMMatrixScaling(25, 25, 25) * XMMatrixRotationY(yRotationAngle) *
                                   XMMatrixTranslation(m_pCamera->Position().x,
                                                       m_pCamera->Position().y,
                                                       m_pCamera->Position().z) ;
        // translate world +6 in Z to position camera -9 from world origin
        pCameraData->viewMatrix = m_pCamera->W2C();
        pCameraData->projectionMatrix = m_pCamera->C2S();

        pCameraBuffer->Unmap(pContext);

        pCameraBuffer->BindVS(pContext, 0);

        pMesh->Bind(pContext);

        m_pPosTexNormVS->Bind(pContext);
        m_pCelShadePS->Bind(pContext);
        pMesh->Draw(pContext);

        ///// Detect Edges ///////////////////////////////////////////////////////////////////////////


        ///// Draw Light Position ////////////////////////////////////////////////////////////////////

        //yRotationAngle = 0;
        pCameraData = reinterpret_cast<CameraBufferData*>(pCameraBuffer->Map(pContext));
        pCameraData->worldMatrix = XMMatrixScaling(1, 1, 1);
                                 //  XMMatrixRotationY(yRotationAngle);
                                  // XMMatrixTranslation(-10, 10, 10);
        // translate world +6 in Z to position camera -9 from world origin
        pCameraData->viewMatrix = XMMatrixTranslation(0, 0, 10) * m_pCamera->W2C();
        pCameraData->projectionMatrix = m_pCamera->C2S();

        pCameraBuffer->Unmap(pContext);
        pCameraBuffer->BindVS(pContext, 0);

        pCubeVS->Bind(pContext);

        pCubePS->Bind(pContext);

        pCubeMesh->Bind(pContext);
        pCubeMesh->Draw(pContext);

        ///// Draw UI ////////////////////////////////////////////////////////////////////////////////

        ///@todo Consider moving the following UI drawing to Draw2D()
        m_pUI->Begin();
        // Draw UI stuff
        m_pUI->RenderRect();
        m_pUI->RenderText();
        m_pUI->End();

        /// Blend UI onto final image
        DrawUI();

        m_pDxData->pDXGISwapChain->Present(0,0);

        EndFrame();

        Sleep(50);
        yRotationAngle += 3.14159f / 60.0f;
    }

    // Shader Resource Views

    pCameraBuffer->Destroy();

    // Shaders
    m_pCelShadePS->Destroy();
    m_pCelShadePS = NULL;

    m_pPosTexTriVS->Destroy();
    m_pPosTexTriVS = NULL;

    m_pPosTexNormVS->Destroy();
    m_pPosTexNormVS = NULL;

    pApplyTexPS->Destroy();
    pApplyTexPS = NULL;

    pPlaneMesh->Destroy();
    pPlaneMesh = NULL;

    // Samplers
    pPointSampler->Release();

    // Rasterizer State
    pShadeRS->Release();

    m_pDxData->pD3D11Context->ClearState();
    m_pDxData->pD3D11Context->Flush(); 
}
예제 #2
0
파일: IvyAppDX.cpp 프로젝트: endy/Ivy
///////////////////////////////////////////////////////////////////////////////////////////////////
/// IvyApp::InitDX
///
/// @brief
///     
/// @return
///     N/A
///////////////////////////////////////////////////////////////////////////////////////////////////
bool IvyApp::InitDX()
{
    bool success = true;

    m_pDxData = new IvyAppDxData();
    memset(&m_pDxData->viewport, 0, sizeof(D3D11_VIEWPORT));

    EnumerateAdapters();
    DxEnumDisplayDevices();

    // Create Swap Chain & Device
    DXGI_SWAP_CHAIN_DESC sd;
    ZeroMemory( &sd, sizeof( sd ) );
    sd.BufferCount = BufferCount;
    sd.BufferDesc.Width = m_screenWidth;
    sd.BufferDesc.Height = m_screenHeight;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferDesc.RefreshRate.Denominator = 1;
    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow = m_pWindow->GetHwnd();
    sd.SampleDesc.Count = 1;
    sd.SampleDesc.Quality = 0;
    sd.Windowed = TRUE;

    D3D_FEATURE_LEVEL  FeatureLevelsRequested[2];
    FeatureLevelsRequested[0] = D3D_FEATURE_LEVEL_11_0;
    FeatureLevelsRequested[1] = D3D_FEATURE_LEVEL_10_1;
    UINT               numLevelsRequested = 2;
    D3D_FEATURE_LEVEL  FeatureLevelsSupported;

    if( DxFAIL (D3D11CreateDeviceAndSwapChain( NULL, 
        D3D_DRIVER_TYPE_HARDWARE, 
        NULL, 
        D3D11_CREATE_DEVICE_DEBUG,
        FeatureLevelsRequested, 
        numLevelsRequested, 
        D3D11_SDK_VERSION, 
        &sd, 
        &m_pDxData->pDXGISwapChain, 
        &m_pDxData->pD3D11Device, 
        &FeatureLevelsSupported,
        &m_pDxData->pD3D11Context )))
    {
        success = false;
    }

    if (success)
    {
        ID3D11Texture2D* pBackBuffer = NULL;

        // Get a pointer to the back buffer
        if (DxFAIL(m_pDxData->pDXGISwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer)))
        {
            success = false;
        }
        else
        {
            // Create a render-target view
            m_pDxData->pD3D11Device->CreateRenderTargetView(pBackBuffer,
                NULL,
                &m_pDxData->pAppRenderTargetView );
            pBackBuffer->Release();
        }
    }


    HRESULT hr = S_OK;

    if (success)
    {
        DxTextureCreateInfo depthStencilCreateInfo;
        memset(&depthStencilCreateInfo, 0, sizeof(DxTextureCreateInfo));
        depthStencilCreateInfo.flags.DepthStencil = TRUE;
        depthStencilCreateInfo.flags.ShaderInput = TRUE;
        depthStencilCreateInfo.format = DXGI_FORMAT_D24_UNORM_S8_UINT; ///@todo texture doesnt read format currently
        depthStencilCreateInfo.width = m_screenWidth;
        depthStencilCreateInfo.height = m_screenHeight;

        m_pDxData->pAppDepthStencilTex = DxTexture::Create(m_pDxData->pD3D11Device, &depthStencilCreateInfo);
    }

    // Setup viewport
    m_pDxData->viewport.Width = static_cast<FLOAT>(m_screenWidth);
    m_pDxData->viewport.Height = static_cast<FLOAT>(m_screenHeight);
    m_pDxData->viewport.MinDepth = 0.0f;
    m_pDxData->viewport.MaxDepth = 1.0f;
    m_pDxData->viewport.TopLeftX = 0;
    m_pDxData->viewport.TopLeftY = 0;

    // Create UI
    ///@todo Move UI creation up into IvyApp once the creation of IvyUI exists
    m_pUI = DxUI::Create();
    m_pUIData = new IvyDxUIData();

    m_pUIData->pUserInterfaceVS = DxShader::CreateFromFile(m_pDxData->pD3D11Device, "PosTexTri", L"Content/shaders/DxUI.hlsl", PosTexVertexDesc, PosTexElements);
    m_pUIData->pUserInterfacePS = DxShader::CreateFromFile(m_pDxData->pD3D11Device, "ApplyTex", L"Content/shaders/DxUI.hlsl");

    CameraBufferData cameraData;
    memset(&cameraData, 0, sizeof(CameraBufferData));

    DxBufferCreateInfo cameraBufferCreateInfo = {0};
    cameraBufferCreateInfo.flags.cpuWriteable = TRUE;
    cameraBufferCreateInfo.elemSizeBytes = sizeof(CameraBufferData);
    cameraBufferCreateInfo.pInitialData = &cameraData;
    m_pUIData->pUserInterfaceCameraBuf = DxBuffer::Create(m_pDxData->pD3D11Device, &cameraBufferCreateInfo);

    Plane p;
    DxMeshCreateInfo planeMeshInfo;
    memset(&planeMeshInfo, 0, sizeof(planeMeshInfo));
    planeMeshInfo.pVertexArray = p.GetVB();
    planeMeshInfo.vertexCount = p.NumVertices();
    planeMeshInfo.vertexElementSize = sizeof(VertexPTN);

    m_pUIData->pUserInterfaceQuad = DxMesh::Create(m_pDxData->pD3D11Device, &planeMeshInfo);

    m_pUIData->pUserInterfaceOverlay = m_pUI->CreateSharedTextureOverlay(m_pDxData->pD3D11Device);

    if (DxFAIL(m_pUIData->pUserInterfaceOverlay->QueryInterface(__uuidof(IDXGIKeyedMutex),
        (LPVOID*) &m_pUIData->pUserInterfaceMutexD3D)))
    {
        success = false;
    }

    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    srvDesc.Texture2D.MipLevels = 1;
    srvDesc.Texture2D.MostDetailedMip = 0;
    srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;

    m_pDxData->pD3D11Device->CreateShaderResourceView(m_pUIData->pUserInterfaceOverlay, &srvDesc, &m_pUIData->pUserInterfaceSRV);

    D3D11_BLEND_DESC uiBlendDesc;
    memset(&uiBlendDesc, 0, sizeof(D3D11_BLEND_DESC));

    uiBlendDesc.AlphaToCoverageEnable = FALSE;
    uiBlendDesc.IndependentBlendEnable = FALSE;
    uiBlendDesc.RenderTarget[0].BlendEnable = TRUE;

    uiBlendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
    uiBlendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
    uiBlendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
    uiBlendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
    uiBlendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
    uiBlendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;

    uiBlendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

    ID3D11BlendState* pUIBlendState = NULL;
    m_pDxData->pD3D11Device->CreateBlendState(&uiBlendDesc, &m_pUIData->pUserInterfaceBlendState);

    return success;
}