Direct2D Create SwapChain - direct2d

I am trying to program a Direct2D desktop app based on a Windows tutorial, but am having problems creating a SwapChain1. In the code below everything gets initialized until the CreateSwapChainForHwnd. The pointer m_pDXGISwapChain1 stays NULL. All the pointers except pOutput are ComPtrs.
D2D1_FACTORY_OPTIONS options;
ZeroMemory(&options, sizeof(D2D1_FACTORY_OPTIONS));
HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
__uuidof(ID2D1Factory1), &options, &m_pD2DFactory1);
if(SUCCEEDED(hr))
{
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0 };
hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, creationFlags,
featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &m_pD3DDevice,
&m_featureLevel, &m_pD3DDeviceContext);
}
if(SUCCEEDED(hr))
hr = m_pD3DDevice.As(&m_pDXGIDevice1);
if(SUCCEEDED(hr))
hr = m_pD2DFactory1->CreateDevice(m_pDXGIDevice1.Get(), &m_pD2DDevice);
if(SUCCEEDED(hr))
hr = m_pD2DDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &m_pD2DDeviceContext);
if(SUCCEEDED(hr))
hr = m_pDXGIDevice1->GetAdapter(&m_pDXGIAdapter);
if(SUCCEEDED(hr))
hr = m_pDXGIAdapter->GetParent(IID_PPV_ARGS(&m_pDXGIFactory2));
DXGI_SWAP_CHAIN_DESC1 swapChainDesc1 = {0};
swapChainDesc1.Width = 0;
swapChainDesc1.Height = 0;
swapChainDesc1.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
swapChainDesc1.Stereo = false;
swapChainDesc1.SampleDesc.Count = 1;
swapChainDesc1.SampleDesc.Quality = 0;
swapChainDesc1.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc1.BufferCount = 2;
swapChainDesc1.Scaling = DXGI_SCALING_NONE;
swapChainDesc1.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
swapChainDesc1.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
swapChainDesc1.Flags = 0;
IDXGIOutput *pOutput;
m_pDXGIAdapter->EnumOutputs(0, &pOutput);
if(SUCCEEDED(hr))
hr = m_pDXGIFactory2->CreateSwapChainForHwnd(
static_cast<IUnknown*>(m_pD3DDevice.Get()), m_hwnd, &swapChainDesc1,
NULL, pOutput, &m_pDXGISwapChain1);
if(SUCCEEDED(hr))
hr = m_pDXGIDevice1->SetMaximumFrameLatency(1);
if(SUCCEEDED(hr))
hr = m_pDXGISwapChain1->GetBuffer(0, IID_PPV_ARGS(&m_pDXGIBackBuffer));

If all your pointers are ComPtr, then the call should look like this:
ComPtr<ID3D11Device> d3dDevice;
ComPtr<IDXGIFactory2> dxgiFactory;
// assuming d3dDevice and dxgiFactory are initialized correctly:
ComPtr<IDXGISwapChain1> swapChain;
dxgiFactory->CreateSwapChainForHwnd(d3dDevice.Get(), hWnd, &swapChainDescription, nullptr, nullptr, swapChain.GetAddressOf())
As for your swap chain description, if you're making a non-Windows Store App, you should set
swapChainDescription.Scaling = DXGI_SCALING_STRETCH;
swapChainDescription.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
Both of those values are 0, so you can leave them out.
Here is the complete swap chain description that I use:
DXGI_SWAP_CHAIN_DESC1 swapChainDescription = {};
swapChainDescription.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
swapChainDescription.SampleDesc.Count = 1;
swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDescription.BufferCount = 2;
See this article for full a walkthrough of how to set up Direct2D 1.1 properly - including the CreateSwapChainForHwnd call: http://msdn.microsoft.com/en-us/magazine/dn198239.aspx

Direct2D don't have SwapChain at user level, SwapChain is for Direct3D, I see some DirectX 11 code in your post, do you really want Direct2D? or Direct3D?

Related

Performance loss with CopyResource() and then Map()/Unmap()

The problem is that if you do not use these methods, then the FPS differs by about 2 times in a big way. For example, I had about 5000 fps in a 3d scene. And it became about 2500. I know that the problem is that the application is waiting for the copy to wait. But it's only 4 bytes... If you use the D3D11_MAP_FLAG_DO_NOT_WAIT flag, Map() will always return DXGI_ERROR_WAS_STILL_DRAWING. What can be done so that I can use this method without losing fps? Here is my code:
Init
D3D11_BUFFER_DESC outputDesc;
outputDesc.Usage = D3D11_USAGE_DEFAULT;
outputDesc.ByteWidth = sizeof(float);
outputDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS;
outputDesc.CPUAccessFlags = 0;
outputDesc.StructureByteStride = sizeof(float);
outputDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
FOG_TRACE(mDevice->CreateBuffer(&outputDesc, nullptr, &outputBuffer));
outputDesc.Usage = D3D11_USAGE_STAGING;
outputDesc.BindFlags = 0;
outputDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
FOG_TRACE(mDevice->CreateBuffer(&outputDesc, nullptr, &outputResultBuffer));
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc{};
uavDesc.Buffer.FirstElement = 0;
uavDesc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_APPEND;
uavDesc.Buffer.NumElements = 1;
uavDesc.Format = DXGI_FORMAT_UNKNOWN;
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
FOG_TRACE(mDevice->CreateUnorderedAccessView(outputBuffer, &uavDesc, &unorderedAccessView));
Update
const UINT offset = 0;
mDeviceContext->OMSetRenderTargetsAndUnorderedAccessViews(1, &mRenderTargetView, mDepthStencilView, 1, 1, &unorderedAccessView, &offset);
mDeviceContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
ObjectManager::Draw();
mDeviceContext->CopyResource(outputResultBuffer, outputBuffer);
D3D11_MAPPED_SUBRESOURCE mappedBuffer;
HRESULT hr;
FOG_TRACE(hr = mDeviceContext->Map(outputResultBuffer, 0, D3D11_MAP_READ, 0/*D3D11_MAP_FLAG_DO_NOT_WAIT*/, &mappedBuffer));
if (SUCCEEDED(hr))
{
float* copy = (float*)(mappedBuffer.pData);
OutputDebugString(String::ToStr(*copy) + L"\n");
}
mDeviceContext->Unmap(outputResultBuffer, 0);
const UINT var[4]{};
mDeviceContext->ClearUnorderedAccessViewUint(unorderedAccessView, var);
I've already profiled and checked everything possible, the problem is exactly in pending. I would be very grateful if someone could explain everything in detail :)
The problem was solved very simply but for a long time! I just didn't make copy calls until I had read past data. Here is a small crutch:
static bool isWait = false;
if (!isWait)
{
mDeviceContext->CopyResource(outputResultBuffer, outputBuffer);
}
D3D11_MAPPED_SUBRESOURCE mappedBuffer;
HRESULT hr;
FOG_TRACE(hr = mDeviceContext->Map(outputResultBuffer, 0, D3D11_MAP_READ, D3D11_MAP_FLAG_DO_NOT_WAIT, &mappedBuffer));
if (SUCCEEDED(hr))
{
float* copy = (float*)(mappedBuffer.pData);
OutputDebugString(String::ToStr(*copy) + L"\n");
mDeviceContext->Unmap(outputResultBuffer, 0);
const UINT var[4]{};
mDeviceContext->ClearUnorderedAccessViewUint(unorderedAccessView, var);
isWait = false;
}
else
{
isWait = true;
}

Making a Cubemap in DX11 from 6 Textures

I want to load in a skysphere, I know how to do it using a dds file, but I want to try and do it from 6 separate texture files.
The problem I have is that when I load in the texturecube, only 3 separate textures are visible, the other 3 are not. I'll show you my code and how it looks in Nsight. I am right now using just 6 different uniform colored png files, they are all 512x512 in size.
std::vector<std::string> paths = { "../Resources/Textures/posX.png", "../Resources/Textures/negX.png",
"../Resources/Textures/posY.png",
"../Resources/Textures/negY.png",
"../Resources/Textures/posZ.png", "../Resources/Textures/negZ.png" };
ID3D11Texture2D* cubeTexture = NULL;
WRL::ComPtr<ID3D11ShaderResourceView> shaderResourceView = NULL;
//Description of each face
D3D11_TEXTURE2D_DESC texDesc = {};
texDesc.Width = 512;
texDesc.Height = 512;
texDesc.MipLevels = 1;
texDesc.ArraySize = 6;
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
texDesc.CPUAccessFlags = 0;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DEFAULT;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = 0;
texDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
//The Shader Resource view description
D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc = {};
SMViewDesc.Format = texDesc.Format;
SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SMViewDesc.TextureCube.MipLevels = texDesc.MipLevels;
SMViewDesc.TextureCube.MostDetailedMip = 0;
D3D11_SUBRESOURCE_DATA pData[6] = {};
for (int i = 0; i < 6; i++)
{
ID3D11Resource* res = nullptr;
std::wstring pathWString(paths[j].begin(), paths[j].end());
HRESULT hr = DirectX::CreateWICTextureFromFileEx(Renderer::getDevice(), pathWString.c_str(), 0, D3D11_USAGE_STAGING, 0, D3D11_CPU_ACCESS_READ, 0,
WIC_LOADER_FLAGS::WIC_LOADER_DEFAULT,
&res, 0);
assert(SUCCEEDED(hr));
D3D11_MAPPED_SUBRESOURCE destRes = {};
Renderer::getContext()->Map(res, 0, D3D11_MAP_READ, 0, &destRes);
pData[i].pSysMem = destRes.pData;
pData[i].SysMemPitch = destRes.RowPitch;
pData[i].SysMemSlicePitch = destRes.DepthPitch;
Renderer::getContext()->Unmap(res, 0);
RELEASE_COM(res);
}
Renderer::getDevice()->CreateTexture2D(&texDesc, &pData[0], &cubeTexture);
Renderer::getDevice()->CreateShaderResourceView(cubeTexture, &SMViewDesc, shaderResourceView.GetAddressOf());
When graphics debugging, this is what the cubemap looks like, 3 textures are loaded in twice, overwriting the other 3.
When reading the documentation it says subresource should be relating to mip levels.
If I loop 9 times instead of 6, the other 3 images are shown instead of these current 3. All 6 should have unique colors.
What I'm doing in the code is creating a Texture2D Description, a Shader Resource View Descriptuion, then I try to fetch data from imported images using WIC, I put it in a resource then map that to a subresource struct.
When looking at the addresses of the subresource, all 6 are always unique so it seems they load in the textures correctly, I have tried moving around the rowpitch, changing the size of the image but it only seems to affect the single images inside the textureCube, it doesn't seem to move around the duplicates if you understand what I mean.
Any help is greatly appreciated.
So I found some code from a Frank D Luna example doing something else.
Here is the code I use that works, mip levels had to be taken into account.
I hope this helps if someone in the future has a similar issue.
ID3D11Texture2D* cubeTexture = NULL;
WRL::ComPtr<ID3D11ShaderResourceView> shaderResourceView = NULL;
//Description of each face
D3D11_TEXTURE2D_DESC texDesc = {};
D3D11_TEXTURE2D_DESC texDesc1 = {};
//The Shader Resource view description
D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc = {};
ID3D11Texture2D* tex[6] = { nullptr, nullptr, nullptr,nullptr, nullptr, nullptr };
for (int i = 0; i < 6; i++)
{
std::wstring pathWString(paths[i].begin(), paths[i].end());
HRESULT hr = DirectX::CreateWICTextureFromFileEx(Renderer::getDevice(), pathWString.c_str(), 0, D3D11_USAGE_STAGING, 0, D3D11_CPU_ACCESS_READ| D3D11_CPU_ACCESS_WRITE, 0,
WIC_LOADER_FLAGS::WIC_LOADER_DEFAULT,
(ID3D11Resource**)&tex[i], 0);
assert(SUCCEEDED(hr));
}
tex[0]->GetDesc(&texDesc1);
texDesc.Width = texDesc1.Width;
texDesc.Height = texDesc1.Height;
texDesc.MipLevels = texDesc1.MipLevels;
texDesc.ArraySize = 6;
texDesc.Format = texDesc1.Format;
texDesc.CPUAccessFlags = 0;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DEFAULT;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = 0;
texDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
SMViewDesc.Format = texDesc.Format;
SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SMViewDesc.TextureCube.MipLevels = texDesc.MipLevels;
SMViewDesc.TextureCube.MostDetailedMip = 0;
Renderer::getDevice()->CreateTexture2D(&texDesc, NULL, &cubeTexture);
for (int i = 0; i < 6; i++)
{
for (UINT mipLevel = 0; mipLevel < texDesc.MipLevels; ++mipLevel)
{
D3D11_MAPPED_SUBRESOURCE mappedTex2D;
HRESULT hr = (Renderer::getContext()->Map(tex[i], mipLevel, D3D11_MAP_READ, 0, &mappedTex2D));
assert(SUCCEEDED(hr));
Renderer::getContext()->UpdateSubresource(cubeTexture,
D3D11CalcSubresource(mipLevel, i, texDesc.MipLevels),
0, mappedTex2D.pData, mappedTex2D.RowPitch, mappedTex2D.DepthPitch);
Renderer::getContext()->Unmap(tex[i], mipLevel);
}
}
for (int i = 0; i < 6; i++)
{
RELEASE_COM(tex[i]);
}
Renderer::getDevice()->CreateShaderResourceView(cubeTexture, &SMViewDesc, shaderResourceView.GetAddressOf());

copy d3d11texture from another device

**CopyResource is not woorking,everyone knows why?i have setted GetSharedHandle and OpenSharedResource.
//desc1
m_desc.Width = rendererInfo.SrcBounds.Width;
m_desc.Height = rendererInfo.SrcBounds.Height;
m_desc.Format = rendererInfo.SrcFormat;
m_desc.ArraySize = 1;
m_desc.BindFlags = 0;
m_desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
m_desc.SampleDesc.Count = 1;
m_desc.SampleDesc.Quality = 0;
m_desc.MipLevels = 1;
m_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
m_desc.Usage = D3D11_USAGE_STAGING;
m_destdesc = m_desc;
//desc2
m_destdesc.Usage = D3D11_USAGE_DEFAULT;
m_destdesc.CPUAccessFlags = 0;
...
IDXGIResource* copyResource = nullptr;
hr = m_copyTexture2D->QueryInterface(__uuidof(IDXGIResource), (void**)&copyResource);
if (FAILED(hr))
return false;
HANDLE shareHandle = nullptr;
hr = copyResource->GetSharedHandle(&shareHandle);
copyResource->Release();
copyResource = nullptr;
ID3D11Resource* tempResource = nullptr;
ID3D11Texture2D* tempTex2D = nullptr;
hr = m_device->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource), (void**)(&tempResource));
tempResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)(&tempTex2D));
ID3D11Device* ppDevice = nullptr;
tempTex2D->GetDevice(&ppDevice);
tempResource->Release();
//DirectX::SaveWICTextureToFile(m_deviceContext, tempTex2D, GUID_ContainerFormatJpeg, L"d:/glinterop2.jpg");
ID3D11DeviceContext* tempContext = nullptr;
ppDevice->GetImmediateContext(&tempContext);
tempContext->CopyResource(m_destTexture2D, tempTex2D);
tempContext->Flush();
ID3D11DeviceContext* destContext = nullptr;
pContext->getCurrentD3D11Device()->GetImmediateContext(&destContext);
DirectX::SaveWICTextureToFile(destContext, m_destTexture2D, GUID_ContainerFormatJpeg, L"d:/glinterop3.jpg");
//destContext->Release();
//tempTex2D->Release();
if (m_deskDupl) {
hr = m_deskDupl->ReleaseFrame();
}**
IDXGIResource* copyResource = nullptr;
hr = m_destTexture2D->QueryInterface(__uuidof(IDXGIResource), (void**)&copyResource);
if (FAILED(hr))
return false;
HANDLE shareHandle = nullptr;
hr = copyResource->GetSharedHandle(&shareHandle);
copyResource->Release();
copyResource = nullptr;
ID3D11Texture2D* tempTex2D = nullptr;
hr = m_device->OpenSharedResource(shareHandle, __uuidof(ID3D11Texture2D), (void**)(&tempTex2D));
m_deviceContext->CopyResource(tempTex2D, m_copyTexture2D);
m_deviceContext->Flush();
ID3D11Device* ppDevice = nullptr;
tempTex2D->GetDevice(&ppDevice);
ID3D11DeviceContext* tempContext = nullptr;
ppDevice->GetImmediateContext(&tempContext);
DirectX::SaveWICTextureToFile(tempContext, tempTex2D, GUID_ContainerFormatJpeg, L"d:/glinterop2.jpg");
tempTex2D->Release();
tempTex2D = nullptr;
tempContext->Release();
tempContext = nullptr;
ppDevice->Release();
ppDevice = nullptr;
DirectX::SaveWICTextureToFile(m_destContext, m_destTexture2D, GUID_ContainerFormatJpeg, L"d:/glinterop3.jpg");
if (m_deskDupl) {
hr = m_deskDupl->ReleaseFrame();
}

DirectX 11 Render to Texture Not Working

I want to render one triangle to texture and then that render to texture need to be displayed in a smaller size at top-left corner of screen with the original triangle at center of the screen.
I have developed one application but not succeeded. Please help me on this.
My code is as follows -
#include <windows.h>
#include <d3d11_1.h>
#include <d3dcompiler.h>
#include <directxmath.h>
#include <directxcolors.h>
#include "resource.h"
using namespace DirectX;
//--------------------------------------------------------------------------------------
// Structures
//--------------------------------------------------------------------------------------
struct SimpleVertex
{
XMFLOAT3 Pos;
};
//--------------------------------------------------------------------------------------
// Global Variables
//--------------------------------------------------------------------------------------
HINSTANCE g_hInst = nullptr;
HWND g_hWnd = nullptr;
D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;
ID3D11Device* g_pd3dDevice = nullptr;
ID3D11Device1* g_pd3dDevice1 = nullptr;
ID3D11DeviceContext* g_pImmediateContext = nullptr;
ID3D11DeviceContext1* g_pImmediateContext1 = nullptr;
IDXGISwapChain* g_pSwapChain = nullptr;
IDXGISwapChain1* g_pSwapChain1 = nullptr;
ID3D11RenderTargetView* g_pRenderTargetView = nullptr;
ID3D11VertexShader* g_pVertexShader = nullptr;
ID3D11PixelShader* g_pPixelShader = nullptr;
ID3D11InputLayout* g_pVertexLayout = nullptr;
ID3D11Buffer* g_pVertexBuffer = nullptr;
ID3D11Texture2D* m_renderTargetTexture=nullptr;
ID3D11RenderTargetView* m_renderTargetView=nullptr;
ID3D11ShaderResourceView* m_shaderResourceView=nullptr;
ID3D11DepthStencilView* m_depthStencilView;
ID3D11Texture2D* m_depthStencilBuffer;
ID3D11DepthStencilState* m_depthStencilState;
//--------------------------------------------------------------------------------------
// Forward declarations
//--------------------------------------------------------------------------------------
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
HRESULT InitDevice();
void CleanupDevice();
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
void Render();
void RenderOnTexture();
//--------------------------------------------------------------------------------------
// Entry point to the program. Initializes everything and goes into a message processing
// loop. Idle time is used to render the scene.
//--------------------------------------------------------------------------------------
int WINAPI wWinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow )
{
UNREFERENCED_PARAMETER( hPrevInstance );
UNREFERENCED_PARAMETER( lpCmdLine );
if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
return 0;
if( FAILED( InitDevice() ) )
{
CleanupDevice();
return 0;
}
// Main message loop
MSG msg = {0};
while( WM_QUIT != msg.message )
{
if( PeekMessage( &msg, nullptr, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render();
}
}
CleanupDevice();
return ( int )msg.wParam;
}
//--------------------------------------------------------------------------------------
// Register class and create window
//--------------------------------------------------------------------------------------
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow )
{
// Register class
WNDCLASSEX wcex;
wcex.cbSize = sizeof( WNDCLASSEX );
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
wcex.hCursor = LoadCursor( nullptr, IDC_ARROW );
wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
wcex.lpszMenuName = nullptr;
wcex.lpszClassName = L"TutorialWindowClass";
wcex.hIconSm = LoadIcon( wcex.hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
if( !RegisterClassEx( &wcex ) )
return E_FAIL;
// Create window
g_hInst = hInstance;
RECT rc = { 0, 0, 800, 600 };
AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
g_hWnd = CreateWindow( L"TutorialWindowClass", L"Direct3D 11 Tutorial 2: Rendering a Triangle",
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, nullptr, nullptr, hInstance,
nullptr );
if( !g_hWnd )
return E_FAIL;
ShowWindow( g_hWnd, nCmdShow );
return S_OK;
}
//--------------------------------------------------------------------------------------
// Helper for compiling shaders with D3DCompile
//
// With VS 11, we could load up prebuilt .cso files instead...
//--------------------------------------------------------------------------------------
HRESULT CompileShaderFromFile( WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut )
{
HRESULT hr = S_OK;
DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#ifdef _DEBUG
// Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
// Setting this flag improves the shader debugging experience, but still allows
// the shaders to be optimized and to run exactly the way they will run in
// the release configuration of this program.
dwShaderFlags |= D3DCOMPILE_DEBUG;
// Disable optimizations to further improve shader debugging
dwShaderFlags |= D3DCOMPILE_SKIP_OPTIMIZATION;
#endif
ID3DBlob* pErrorBlob = nullptr;
hr = D3DCompileFromFile( szFileName, nullptr, nullptr, szEntryPoint, szShaderModel,
dwShaderFlags, 0, ppBlobOut, &pErrorBlob );
if( FAILED(hr) )
{
if( pErrorBlob )
{
OutputDebugStringA( reinterpret_cast<const char*>( pErrorBlob->GetBufferPointer() ) );
pErrorBlob->Release();
}
return hr;
}
if( pErrorBlob ) pErrorBlob->Release();
return S_OK;
}
//--------------------------------------------------------------------------------------
// Create Direct3D device and swap chain
//--------------------------------------------------------------------------------------
HRESULT InitDevice()
{
HRESULT hr = S_OK;
RECT rc;
GetClientRect( g_hWnd, &rc );
UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top;
UINT createDeviceFlags = 0;
#ifdef _DEBUG
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
UINT numDriverTypes = ARRAYSIZE( driverTypes );
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
};
UINT numFeatureLevels = ARRAYSIZE( featureLevels );
for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
{
g_driverType = driverTypes[driverTypeIndex];
hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );
if ( hr == E_INVALIDARG )
{
// DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it
hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1,
D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );
}
if( SUCCEEDED( hr ) )
break;
}
if( FAILED( hr ) )
return hr;
// Obtain DXGI factory from device (since we used nullptr for pAdapter above)
IDXGIFactory1* dxgiFactory = nullptr;
{
IDXGIDevice* dxgiDevice = nullptr;
hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice) );
if (SUCCEEDED(hr))
{
IDXGIAdapter* adapter = nullptr;
hr = dxgiDevice->GetAdapter(&adapter);
if (SUCCEEDED(hr))
{
hr = adapter->GetParent( __uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory) );
adapter->Release();
}
dxgiDevice->Release();
}
}
if (FAILED(hr))
return hr;
// Create swap chain
IDXGIFactory2* dxgiFactory2 = nullptr;
hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2) );
if ( dxgiFactory2 )
{
// DirectX 11.1 or later
hr = g_pd3dDevice->QueryInterface( __uuidof(ID3D11Device1), reinterpret_cast<void**>(&g_pd3dDevice1) );
if (SUCCEEDED(hr))
{
(void) g_pImmediateContext->QueryInterface( __uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&g_pImmediateContext1) );
}
DXGI_SWAP_CHAIN_DESC1 sd;
ZeroMemory(&sd, sizeof(sd));
sd.Width = width;
sd.Height = height;
sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.BufferCount = 1;
hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1 );
if (SUCCEEDED(hr))
{
hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain), reinterpret_cast<void**>(&g_pSwapChain) );
}
dxgiFactory2->Release();
}
else
{
// DirectX 11.0 systems
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = width;
sd.BufferDesc.Height = height;
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 = g_hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
hr = dxgiFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain );
}
// Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut
dxgiFactory->MakeWindowAssociation( g_hWnd, DXGI_MWA_NO_ALT_ENTER );
dxgiFactory->Release();
if (FAILED(hr))
return hr;
// Create a render target view
ID3D11Texture2D* pBackBuffer = nullptr;
hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast<void**>( &pBackBuffer ) );
if( FAILED( hr ) )
return hr;
hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, nullptr, &g_pRenderTargetView );
pBackBuffer->Release();
if( FAILED( hr ) )
return hr;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
D3D11_TEXTURE2D_DESC textureDesc;
HRESULT result;
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
// Initialize the render target texture description.
ZeroMemory(&textureDesc, sizeof(textureDesc));
// Setup the render target texture description.
textureDesc.Width = 400/*textureWidth*/;
textureDesc.Height = 400/*textureHeight*/;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
textureDesc.SampleDesc.Count = 1;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = 0;
// Create the render target texture.
result = g_pd3dDevice->CreateTexture2D(&textureDesc, NULL, &m_renderTargetTexture);
if (FAILED(result))
{
return false;
}
// Setup the description of the render target view.
renderTargetViewDesc.Format = textureDesc.Format;
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
renderTargetViewDesc.Texture2D.MipSlice = 0;
// Create the render target view.
result = g_pd3dDevice->CreateRenderTargetView(m_renderTargetTexture, &renderTargetViewDesc, &m_renderTargetView);
if (FAILED(result))
{
return false;
}
// Setup the description of the shader resource view.
shaderResourceViewDesc.Format = textureDesc.Format;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
shaderResourceViewDesc.Texture2D.MipLevels = 1;
// Create the shader resource view.
result = g_pd3dDevice->CreateShaderResourceView(m_renderTargetTexture, &shaderResourceViewDesc, &m_shaderResourceView);
//D3D11_TEXTURE2D_DESC depthBufferDesc;
//D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
//D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
//// Initialize the description of the depth buffer.
//ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));
//// Set up the description of the depth buffer.
//depthBufferDesc.Width = 400;
//depthBufferDesc.Height = 400;
//depthBufferDesc.MipLevels = 1;
//depthBufferDesc.ArraySize = 1;
//depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
//depthBufferDesc.SampleDesc.Count = 1;
//depthBufferDesc.SampleDesc.Quality = 0;
//depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
//depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
//depthBufferDesc.CPUAccessFlags = 0;
//depthBufferDesc.MiscFlags = 0;
//// Create the texture for the depth buffer using the filled out description.
//result = g_pd3dDevice->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer);
//if (FAILED(result))
//{
// return false;
//}
//// Initialize the description of the stencil state.
//ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));
//// Set up the description of the stencil state.
//depthStencilDesc.DepthEnable = true;
//depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
//depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
//depthStencilDesc.StencilEnable = true;
//depthStencilDesc.StencilReadMask = 0xFF;
//depthStencilDesc.StencilWriteMask = 0xFF;
//// Stencil operations if pixel is front-facing.
//depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
//depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
//depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
//depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
//// Stencil operations if pixel is back-facing.
//depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
//depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
//depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
//depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
//// Create the depth stencil state.
//result = g_pd3dDevice->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState);
//if (FAILED(result))
//{
// return false;
//}
//// Set the depth stencil state.
//g_pImmediateContext->OMSetDepthStencilState(m_depthStencilState, 1);
//// Initialize the depth stencil view.
//ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));
//// Set up the depth stencil view description.
//depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
//depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
//depthStencilViewDesc.Texture2D.MipSlice = 0;
//// Create the depth stencil view.
//result = g_pd3dDevice->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView);
//if (FAILED(result))
//{
// return false;
//}
// Bind the render target view and depth stencil buffer to the output render pipeline.
g_pImmediateContext->OMSetRenderTargets(1, &m_renderTargetView, /*m_depthStencilView*/nullptr);
// Clear the back buffer.
g_pImmediateContext->ClearRenderTargetView(m_renderTargetView, Colors::Red);
// Clear the depth buffer.
//g_pImmediateContext->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Setup the viewport
D3D11_VIEWPORT vp;
vp.Width = (FLOAT)width;
vp.Height = (FLOAT)height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_pImmediateContext->RSSetViewports( 1, &vp );
// Compile the vertex shader
ID3DBlob* pVSBlob = nullptr;
hr = CompileShaderFromFile( L"Tutorial02.fx", "VS", "vs_4_0", &pVSBlob );
if( FAILED( hr ) )
{
MessageBox( nullptr,
L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
return hr;
}
// Create the vertex shader
hr = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &g_pVertexShader );
if( FAILED( hr ) )
{
pVSBlob->Release();
return hr;
}
// Define the input layout
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
UINT numElements = ARRAYSIZE( layout );
// Create the input layout
hr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(),
pVSBlob->GetBufferSize(), &g_pVertexLayout );
pVSBlob->Release();
if( FAILED( hr ) )
return hr;
// Set the input layout
g_pImmediateContext->IASetInputLayout( g_pVertexLayout );
// Compile the pixel shader
ID3DBlob* pPSBlob = nullptr;
hr = CompileShaderFromFile( L"Tutorial02.fx", "PS", "ps_4_0", &pPSBlob );
if( FAILED( hr ) )
{
MessageBox( nullptr,
L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
return hr;
}
// Create the pixel shader
hr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &g_pPixelShader );
pPSBlob->Release();
if( FAILED( hr ) )
return hr;
// Create vertex buffer
SimpleVertex vertices[] =
{
XMFLOAT3( 0.0f, 0.5f, 0.5f ),
XMFLOAT3( 0.5f, -0.5f, 0.5f ),
XMFLOAT3( -0.5f, -0.5f, 0.5f ),
};
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( SimpleVertex ) * 3;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = vertices;
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
if( FAILED( hr ) )
return hr;
// Set vertex buffer
UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );
// Set primitive topology
g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
RenderOnTexture();
return S_OK;
}
//--------------------------------------------------------------------------------------
// Clean up the objects we've created
//--------------------------------------------------------------------------------------
void CleanupDevice()
{
if( g_pImmediateContext ) g_pImmediateContext->ClearState();
if( g_pVertexBuffer ) g_pVertexBuffer->Release();
if( g_pVertexLayout ) g_pVertexLayout->Release();
if( g_pVertexShader ) g_pVertexShader->Release();
if( g_pPixelShader ) g_pPixelShader->Release();
if( g_pRenderTargetView ) g_pRenderTargetView->Release();
if( g_pSwapChain1 ) g_pSwapChain1->Release();
if( g_pSwapChain ) g_pSwapChain->Release();
if( g_pImmediateContext1 ) g_pImmediateContext1->Release();
if( g_pImmediateContext ) g_pImmediateContext->Release();
if( g_pd3dDevice1 ) g_pd3dDevice1->Release();
if( g_pd3dDevice ) g_pd3dDevice->Release();
}
//--------------------------------------------------------------------------------------
// Called every time the application receives a message
//--------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT ps;
HDC hdc;
switch( message )
{
case WM_PAINT:
hdc = BeginPaint( hWnd, &ps );
EndPaint( hWnd, &ps );
break;
case WM_DESTROY:
PostQuitMessage( 0 );
break;
// Note that this tutorial does not handle resizing (WM_SIZE) requests,
// so we created the window without the resize border.
default:
return DefWindowProc( hWnd, message, wParam, lParam );
}
return 0;
}
//--------------------------------------------------------------------------------------
// Render a frame
//--------------------------------------------------------------------------------------
void Render()
{
// Clear the back buffer
g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, Colors::MidnightBlue );
// Render a triangle
/*g_pImmediateContext->VSSetShader( g_pVertexShader, nullptr, 0 );
g_pImmediateContext->PSSetShader( g_pPixelShader, nullptr, 0 );
g_pImmediateContext->Draw( 3, 0 );*/
g_pImmediateContext->PSSetShaderResources(0, 1, &m_shaderResourceView);
// Present the information rendered to the back buffer to the front buffer (the screen)
g_pSwapChain->Present( 0, 0 );
}
void RenderOnTexture()
{
g_pImmediateContext->VSSetShader(g_pVertexShader, nullptr, 0);
g_pImmediateContext->PSSetShader(g_pPixelShader, nullptr, 0);
g_pImmediateContext->Draw(3, 0);
g_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, nullptr);
}
Your Render() function has no draw calls in it.

How to control the Microphone Boost in Windows 7?

I am trying to control the Microphone Boost (level/(un)mute) in Windows 7 using the MIXER API in a C/C++ application, but I do not get the controls for the same. Can it be done using WASAPI? Can somebody suggest any other API to control the Microphone Boost in Windows 7?
This is what I have written so far ...
const IID IID_IDeviceTopology = __uuidof(IDeviceTopology);
const IID IID_IPart = __uuidof(IPart);
const IID IID_IAudioAutoGainControl = __uuidof(IAudioAutoGainControl);
HRESULT hr = S_OK;
CoInitialize(NULL);
IMMDeviceEnumerator *deviceEnumerator = NULL;
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
IMMDevice *pEndptDev = NULL;
hr = deviceEnumerator->GetDefaultAudioEndpoint(eCapture, eConsole, &pEndptDev);
deviceEnumerator->Release();
deviceEnumerator = NULL;
IDeviceTopology *pDevTopoEndpt = NULL;
IConnector *pConnEndpt = NULL;
IConnector *pConnHWDev = NULL;
IPart *pPartConn = NULL;
IAudioAutoGainControl *pAGC = NULL;
IControlInterface *pControl = NULL;
UINT pCount = 0;
LPCGUID pIID = ;
// Get the endpoint device's IDeviceTopology interface.
hr = pEndptDev->Activate(IID_IDeviceTopology, CLSCTX_ALL, NULL, (void**)&pDevTopoEndpt);
// The device topology for an endpoint device always
// contains just one connector (connector number 0).
hr = pDevTopoEndpt->GetConnector(0, &pConnEndpt);
// Use the connector in the endpoint device to get the
// connector in the adapter device.
hr = pConnEndpt->GetConnectedTo(&pConnHWDev);
// Query the connector in the adapter device for
// its IPart interface.
hr = pConnHWDev->QueryInterface(IID_IPart, (void**)&pPartConn);
// Use the connector's IPart interface to get the
// IDeviceTopology interface for the adapter device.
hr = pPartConn->Activate(CLSCTX_ALL, IID_IAudioAutoGainControl, (void**)&pAGC);
hr = pPartConn->GetControlInterfaceCount(&pCount);
hr = pPartConn->GetControlInterface(pCount - 1, &pControl);
hr = pControl->GetIID((GUID *)pIID);
//BOOL bEnabled = false;
hr = pAGC->SetEnabled(true, pIID);
WASAPI is the way to do this.
http://msdn.microsoft.com/en-us/library/windows/desktop/dd316531%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/dd370853%28v=vs.85%29.aspx

Resources