I am using DirectX 11, DirectX Toolkit and C++. How can I create a rectangle with a blue border for spritebatch ? I'm guessing I need to create a texture in memory perhaps with a 1 pixel blue border ?
ComPtr<ID3D11ShaderResourceView> spriteSheet_;
ComPtr<ID3D11Resource> resource;
CreateDDSTextureFromFile(d3dDevice_, L"mytex.dds", resource.GetAddressOf(),
spriteSheet_.ReleaseAndGetAddressOf());
batch->Draw(spriteSheet_.Get(), position, &sourceRect, DirectX::Colors::White,
rotation_, spriteOrigin_, scale_, DirectX::SpriteEffects_None, depth_);
You can use SpriteBatch to draw a single-pixel texture as you described--you could use a white texture and use the SpriteBatch tinting to make it Blue.
Here is some simple code for programmatically creating a 1x1 white texture in Direct3D 11:
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> pWhiteTexture;
static const uint32_t s_pixel = 0xffffffff;
D3D11_SUBRESOURCE_DATA initData = { &s_pixel, sizeof(uint32_t), 0 };
D3D11_TEXTURE2D_DESC desc;
memset( &desc, 0, sizeof(desc) );
desc.Width = desc.Height = desc.MipLevels = desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
Microsoft::WRL::ComPtr<ID3D11Texture2D> tex;
HRESULT hr = mDevice->CreateTexture2D( &desc, &initData, &tex );
DX::ThrowIfFailed(hr);
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
memset( &SRVDesc, 0, sizeof( SRVDesc ) );
SRVDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
SRVDesc.Texture2D.MipLevels = 1;
hr = mDevice->CreateShaderResourceView( tex.Get(), &SRVDesc, &pWhiteTexture );
DX::ThrowIfFailed(hr);
A more efficient solution would be to use PrimitiveBatch to draw a blue quad where you want it located.
See the DirectX Tool Kit tutorial Simple rendering
Related
I have a png file with a transparent background.
When i draw the image the transparency works.
as long as there is no other transparent image in front of it as seen below.
What changes do i need to make to my transparency code to solve this issue?
Depth stencil code:
// Initialize the description of the depth buffer.
ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));
// Set up the description of the depth buffer.
depthBufferDesc.Width = screenWidth;
depthBufferDesc.Height = screenHeight;
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 = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer);
Error::ErrorCheck(result, TEXT("m_device->CreateTexture2D()"));
// 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 = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState);
Error::ErrorCheck(result, TEXT("m_device->CreateDepthStencilState()"));
// Set the depth stencil state.
m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 0);
// Initailze 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 = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView);
Error::ErrorCheck(result, TEXT("m_device->CreateDepthStencilView()"));
// Bind the render target view and depth stencil buffer to the output render pipeline.
m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);
Transparency code:
//Setup Blend State for transperency
D3D11_BLEND_DESC BlendStateDescription;
ZeroMemory(&BlendStateDescription, sizeof(D3D11_BLEND_DESC));
ID3D11BlendState* blend;
BlendStateDescription.RenderTarget[0].BlendEnable = TRUE;
BlendStateDescription.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
BlendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
BlendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
BlendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
BlendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
BlendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
BlendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
m_device->CreateBlendState(&BlendStateDescription, &blend);
float blendFactor[] = { 0, 0, 0, 0 };
UINT sampleMask = 0xffffffff;
m_deviceContext->OMSetBlendState(blend, blendFactor, sampleMask);
Found the problem. Was in the depth buffer. Just a simple change depthStencilDesc.DepthFunc from D3D11_COMPARISON_LESS to D3D11_COMPARISON_LESS_EQUAL.
Found the answer here, follow link for more detailed description:
Detailed answer
Nothing is rendering in my DX program in C++(using PS_5_0 and VS_5_0).I have check all of the DX functions that return an HRESULT and they all return S_OK, I Have also gone through and carefully debugged and looked at everything and nothing is null or uninitialized. I even searched every where here and on bing and I did not find any post that helped me(tried all of there solutions to see if they worked, none of them did).I have no idea why it is not rendering, all of the parameters are good.
Here is my code the initializes the Depth stencil, Device context and Device.
//create the graphics device factory
result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
//use the factor to create the adapter for the primary graphics interface(video card)
result = factory->EnumAdapters(0, &adapter);
if (FAILED(result))
return false;
//enumerate the primary adapter output(monitor)
result = adapter->EnumOutputs(0, &adapterOutput);
if (FAILED(result))
return false;
//get the adapter(video card) description
result = adapter->GetDesc(&adapterDesc);
if (FAILED(result))
return false;
//zero out the swap chain description
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
//Set ot to a single back buffer
swapChainDesc.BufferCount = 1;
//set regular 32 bit surface for the back buffer.
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
//set the usage of the back buffer.
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
//set the handle for the window to render to.
swapChainDesc.OutputWindow = hwnd;
//turn multi sampling off
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
//set the scan line odering and scaling to unspecified.
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
//discard the back buffer contents after presenting
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
//donw set the advanced flags
swapChainDesc.Flags = 0;
//set the feature level to directX 11
featureLevel = D3D_FEATURE_LEVEL_11_0;
//create the swap chain,Direct3D, and the driect3D device context.
result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1,
D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext);
if (FAILED(result))
return false;
//Get the pointer to the back buffer
result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr);
if (FAILED(result))
return false;
//create the render target view with the back buffer pointer
result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTarget);
//set up the description of the depth buffer
depthBufferDesc.Width = screenWidth;
depthBufferDesc.Height = screenHeight;
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 = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer);
if (FAILED(result))
return false;
// 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 = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencil);
//set the depth stencil state
m_deviceContext->OMSetDepthStencilState(m_depthStencil, 1);
//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 = m_device->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
m_deviceContext->OMSetRenderTargets(1, &m_renderTarget, m_depthStencilView);
//Setup the raster description which determines how and what polygons get drawn
rasterDesc.AntialiasedLineEnable = false;
rasterDesc.CullMode = D3D11_CULL_BACK;
rasterDesc.DepthBias = 0;
rasterDesc.DepthBiasClamp = 0.0f;
rasterDesc.DepthClipEnable = true;
rasterDesc.FillMode = D3D11_FILL_SOLID;
rasterDesc.FrontCounterClockwise = false;
rasterDesc.MultisampleEnable = false;
rasterDesc.SlopeScaledDepthBias = 0.0f;
//create the rasterizer state from the description
result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState);
// Now set the rasterizer state.
m_deviceContext->RSSetState(m_rasterState);
//Setup the viewport for rendering
viewport.Width = (float)screenWidth;
viewport.Height = (float)screenHeight;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
viewport.TopLeftX = 0.0f;
viewport.TopLeftY = 0.0f;
// Create the view por
m_deviceContext->RSSetViewports(1, &viewport);
//set up the projection matrix
fieldOfView = (float)D3DX_PI / 4.0f;
screenAspect = (float)screenWidth / (float)screenHeight;
//create the projection matrix for 3d rendering
D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth);
Here is my code that renders the model(I made sure that all of the vertices where good)
float color[4];
//set up the color to clear the buffer to
color[0] = red;
color[1] = green;
color[2] = blue;
color[3] = alpha;
//clear the back buffer
m_deviceContext->ClearRenderTargetView(m_renderTarget, color);
//clear the depth buffer
m_deviceContext->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH, 1.0f,0);
unsigned int stride;
unsigned int offset;
//set the vertex buffer stride and offset
stride = sizeof(Vertex);
offset = 0;
//Set the vertex buffer to be active on the device context
deviceContext->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset);
//Set the index buffer to active in the input assembler so it can be renderered
deviceContext->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0);
//set the type of primitive topology to use for rendering
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
//Set the vertex input layout
deviceContext->IASetInputLayout(m_layout);
//Set the vertex and pixel shaders that will be used to render this triangle.
deviceContext->VSSetShader(m_vertexShader, NULL, 0);
deviceContext->PSSetShader(m_pixelShader, NULL, 0);
//Set the sampler state in the pixel shader.
deviceContext->PSSetSamplers(0, 1, &m_sampleState);
//Render the model
deviceContext->DrawIndexed(indexCount, 0, 0);
//present the back buffer to the screen now that rendering is complete
m_swapChain->Present(m_vsync, 0);
Does anyone know what I could be doing wrong?(P.S I have the most recent version of this program in GitHub here : https://github.com/JustinWeq/Test-Engine . It has all of the files in it(including the model and the shader files, so if you need to look at it to get more information you can).
I figured it out, it was a few parameters I was missing when I was setting it up. I fixed it, thank you for trying to help me everyone.
I have a function GetCamImage that returns the image from camera as:
unsigned char* p = GetCamImage(...);
I need to create ID3D11Texture2D from this data. How can I do it in DirectX 11?
Thanks
It depends on what the format of the actual content in that p is, as well as the width, height, and stride. Assuming the image is an RGBA 32-bit format with simple byte pitch alignment and sized as w by h, then it would be something simple like:
D3D11_SUBRESOURCE_DATA initData = {0};
initData.pSysMem = (const void*)p;
initData.SysMemPitch = w * 4;
initData.SysMemSlicePitch = h * w * 4;
D3D11_TEXTURE2D_DESC desc;
desc.Width = w;
desc.Height = h;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
ID3D11Texture2D* tex = nullptr;
HRESULT hr = d3dDevice->CreateTexture2D( &desc, &initData, &tex );
if (FAILED(hr))
...
I found this tutorial, i follow it and i create the class DirectX
class DirectX
{
private:
D3D_DRIVER_TYPE DriverType;
D3D_FEATURE_LEVEL FeatureLevel;
public:
int InitDirectX(HWND &hwnd, WinDesc &wd)
{
HRESULT result;
RECT dimensions;
GetClientRect( hwnd, &dimensions );
int width=dimensions.right-dimensions.left;
int height=dimensions.bottom-dimensions.top;
D3D_DRIVER_TYPE driverTypes[]=
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_SOFTWARE
};
unsigned int totalDriverTypes=ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[]=
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0
};
unsigned int totalFeatureLevels = ARRAYSIZE( featureLevels );
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc,sizeof(swapChainDesc));
swapChainDesc.BufferCount=1;
swapChainDesc.BufferDesc.Width=width;
swapChainDesc.BufferDesc.Height=height;
swapChainDesc.BufferDesc.Format=DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.RefreshRate.Numerator=60;
swapChainDesc.BufferDesc.RefreshRate.Denominator=1;
swapChainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow=hwnd;
swapChainDesc.Windowed=1;
swapChainDesc.SampleDesc.Count=1;
swapChainDesc.SampleDesc.Quality=0;
for(int driver=0;driver<totalDriverTypes;++driver)
{
result = D3D11CreateDeviceAndSwapChain( 0, driverTypes[driver], 0,
0, featureLevels, totalFeatureLevels,
D3D11_SDK_VERSION, &swapChainDesc, &SwapChain,
&Device, &FeatureLevel, &Context );
if( SUCCEEDED( result ) )
{
D3D_DRIVER_TYPE driverType_ = driverTypes[driver];
break;
}
}
}
D3D11_TEXTURE2D_DESC textureDesc;
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
ZeroMemory(&textureDesc, sizeof(textureDesc));
textureDesc.Width = width;
textureDesc.Height = height;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
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;
result=Device->CreateTexture2D(&textureDesc, NULL, &backBuffer);
renderTargetViewDesc.Format = textureDesc.Format;
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
renderTargetViewDesc.Texture2D.MipSlice = 0;
result=Device->CreateRenderTargetView(backBuffer, &renderTargetViewDesc, &RenderTargetView);
shaderResourceViewDesc.Format = textureDesc.Format;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
shaderResourceViewDesc.Texture2D.MipLevels = 1;
result=Device->CreateShaderResourceView(backBuffer, &shaderResourceViewDesc, &shaderResourceView);
float color[4]={1,1,0,0};
Context->ClearRenderTargetView(RenderTargetView,color);
Context->OMSetRenderTargets(1,&RenderTargetView,0);
}
};
When i run it it get no error put when i call SwapChain->Present(0,0) nothing is displayed althought the renderTargetView should to be yellow.
Why?? I cannot found the error.
PS if i create a renderTargetView with this code:
ID3D11Texture2D* backBufferTexture;
result = SwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ),
( LPVOID* )&backBufferTexture );
result = Device->CreateRenderTargetView( backBufferTexture, 0,
&RenderTargetView );
all works;
and in my code i check all the "result" values;
2°
this is code of the sprite i want render:
Init()//init vertex buffer, index buffer, texture, matrix....
the render functioon is this:
C->OMSetRenderTargets(1,&RT1,0);
C->Update(...)// matrix to sent vertex shader, set texture, vertex, buffer....
C->Draw(6,0)//draw the sprite;
It should render a sprite(ex. a ball) on RT1 then :
C->OMSetRenderTargets(1,&RT,0);
RT1->Update() //like the texture;
RT1->Draw(6,0)
...
Swapchain->present(1,0);
The RT1 is displayed(ex. if i have clear it with blue there is a blue shape on the screen i can translate, scale and rotate) but not the ball(i have render on RT1);
but if i render the ball without set RT1 as renderTargetView the ball is correct displayed
I cannot get my program to correctly choose which models to place in front. I have followed the MSDN code exactly. My code appears to correctly draw all polygons in a particular call of DrawIndexed, but each subsequent call seems to cause models to be drawn in the order they are drawn, not based on whether they are closer to the screen.
Here is my code for initializing Direct3d:
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 = hWnd;
sd.SampleDesc.Count = 4;
sd.SampleDesc.Quality = 0;
sd.Windowed = !fullScreen;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
D3D_FEATURE_LEVEL FeatureLevelsRequested = D3D_FEATURE_LEVEL_11_0;
UINT numFeatureLevelsRequested = 1;
D3D_FEATURE_LEVEL FeatureLevelsSupported;
HRESULT hr;
if( FAILED (hr = D3D11CreateDeviceAndSwapChain( adapters[0],
D3D_DRIVER_TYPE_UNKNOWN,
NULL,
NULL,
NULL,
NULL,
D3D11_SDK_VERSION,
&sd,
&swapchain,
&dev,
&FeatureLevelsSupported,
&devcon )))
{
//return;
}
ID3D11Texture2D *pBack = NULL;
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBack);
// use the back buffer address to create the render target
dev->CreateRenderTargetView(pBack, NULL, &backbuffer);
pBack->Release();
// set the render target as the back buffer
// Create depth stencil texture
D3D11_TEXTURE2D_DESC descDepth;
ZeroMemory(&descDepth, sizeof(descDepth));
descDepth.Width = width;
descDepth.Height = height;
descDepth.MipLevels = 1;
descDepth.ArraySize = 1;
descDepth.Format =DXGI_FORMAT_D24_UNORM_S8_UINT;
descDepth.SampleDesc.Count = 4;
descDepth.SampleDesc.Quality = 0;
descDepth.Usage = D3D11_USAGE_DEFAULT;
descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
descDepth.CPUAccessFlags = 0;
descDepth.MiscFlags = 0;
hr = dev->CreateTexture2D( &descDepth, NULL, &g_pDepthStencil);
if(FAILED(hr))
exit(hr);
// Create the depth stencil view
D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
ZeroMemory(&descDSV, sizeof(descDSV));
descDSV.Format = descDepth.Format;
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
descDSV.Texture2D.MipSlice = 0;;
//descDSV.Texture2DMS.UnusedField_NothingToDefine = 0;
hr = dev->CreateDepthStencilView( g_pDepthStencil, &descDSV, &g_pDepthStencilView);
if(FAILED(hr))
exit(hr);
devcon->OMSetRenderTargets(1, &backbuffer, g_pDepthStencilView);
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = width;
viewport.Height = height;
devcon->RSSetViewports(1, &viewport);
This is my code for rendering:
void Direct3DRenderer::Render()
{
devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));
devcon->ClearDepthStencilView(g_pDepthStencilView, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0 );
camera.location = simulation->GetWorld()->GetCameraCoordinates();
camera.direction = simulation->GetWorld()->GetCameraLookAt();
//camera.up = simulation->GetWorld()->GetCameraOrientation();
Vec3d lookAt = camera.location + camera.direction;
XMVECTOR eye = XMVectorSet((float)camera.location[0], (float)camera.location[1], (float)camera.location[2], 0.f);
XMVECTOR look = XMVectorSet(lookAt[0], lookAt[1], lookAt[2], 0);
XMVECTOR up = XMVectorSet(camera.up[0], camera.up[1], camera.up[2], 0);
g_View = XMMatrixLookAtLH(eye, look, up);
ConstantBuffer oncePerFrame;
oncePerFrame.matrix = XMMatrixTranspose(g_View);
devcon->UpdateSubresource(oncePerFrameBuffer, 0, NULL, &oncePerFrame, 0, 0);
UINT stride = sizeof(VERTEX);
UINT offset = 0;
const std::vector<Graphical*> graphicalList = simulation->GetWorld()->GetGraphicalList();
for(int ind = 0; ind < graphicalList.size(); ++ind)
{
switch(graphicalList[ind]->GetModelType())
{
case 1: //Sphere
{
ConstantBuffer oncePerModel2;
oncePerModel2.matrix = XMMatrixTranspose(XMMatrixScalingFromVector(graphicalList[ind]->GetScaleX()) * XMMatrixTranslationFromVector(graphicalList[ind]->GetTranslationX()));
devcon->UpdateSubresource(oncePerModelBuffer, 0, NULL, &oncePerModel2, 0, 0);
devcon->IASetVertexBuffers(0, 1, &(sphereModel.vertexBuffer), &stride, &offset);
devcon->IASetIndexBuffer(sphereModel.indexBuffer, DXGI_FORMAT_R32_UINT, 0);
devcon->DrawIndexed(sphereModel.indexCount, 0, 0);
}
break;
}
}
ConstantBuffer oncePerModel;
oncePerModel.matrix = XMMatrixTranspose(g_World);
devcon->UpdateSubresource(oncePerModelBuffer, 0, NULL, &oncePerModel, 0, 0);
devcon->IASetVertexBuffers(0, 1, &terrainModel.vertexBuffer, &stride, &offset);
devcon->IASetIndexBuffer(terrainModel.indexBuffer, DXGI_FORMAT_R32_UINT, 0);
devcon->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
devcon->DrawIndexed(terrainModel.indexCount, 0, 0);
swapchain->Present(0, 0);
}
I have tried searching extensively, and have followed every tutorial I could find. Nothing fixes it.
In the case of the spheres, depth appears to be correct if viewing from one side, but not the other.
Any help would be appreciated. Thanks.
From OP comment:
The problem ended up being much simpler. I did not set the minimum and
max depth for the viewport object. It worked once I did so.
I had the same problem, it works now:
D3D11_VIEWPORT screenViewport;
/* ... */
screenViewport.MinDepth = 0;
screenViewport.MaxDepth = 1;
/* ... */
context->RSSetViewports(1, &screenViewport);
There are three key steps to Z-Buffering.
Setting the Appropriate Presentation Parameters
Turning On Z-Buffering
Clearing the Z-Buffer
1) Setting the Appropriate Presentation Parameters
D3DPRESENT_PARAMETERS d3dpp;
//...
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
EnableAutoDepthStencil
In truth, z-buffering can be complex. Setting this value to TRUE tells Direct3D to automatically create the z-buffer and set it up in a way used most often. There are, of course, uses for the complex method, but we'll stick to simple for now. We'll cover ways the complex method can be useful later in the tutorial.
AutoDepthStencilFormat
This is the format for each pixel in the z-buffer. We don't use the regular pixel format defined in the Presentation Parameters. Instead, we use a special format for z-buffers. This format is D3DFMT_D16. This means that each pixel is 16-bit. There are other formats, but we will not need them for the extent of this tutorial.
2) Turning On Z-Buffering
// d3ddev is your Direct3D device - a variable of type LPDIRECT3DDEVICE9
d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);
3) Clearing the Z-Buffer
d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
By the way this works in DirectX 9.0c. Im not sure if it is compatible with DirectX 11.
Had a similar problem in DirectX10, seems it was initialisation code, I am not sure about the CreateDevice and SwapChain against UNKNOWN driver type, as I have not used that before.
There are a few differences I can see, the Stencil buffer does not specify the operations to perform depth stencil tests against. (Unless this has been specified in the HLSL which is not visible here)
eg:
// Stencil test parameters
dsDesc.StencilEnable = true;
dsDesc.StencilReadMask = 0xFF;
dsDesc.StencilWriteMask = 0xFF;
// Stencil operations if pixel is front-facing
dsDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_INCR;
dsDesc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
// Stencil operations if pixel is back-facing
dsDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_DECR;
dsDesc.BackFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
In any event, here is a working DirectX10 example, I am pretty sure you can adapt it quickly for DirectX11.
logger->debug("initD3D: Calling D3D10CreateDeviceAndSwapChain.\n");
SYSTEMTIME sysTime;
GetSystemTime(&sysTime);
srand((unsigned int)sysTime.wMilliseconds);
logger->debug("in initD3D.\n");
shutdownXX = false;
count = 1;
quality = 0;
//Create the back buffer desc.
ZeroMemory(&swapDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
swapDesc.BufferCount = 1;
swapDesc.BufferDesc.Width = width;
swapDesc.BufferDesc.Height = height;
swapDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapDesc.BufferDesc.RefreshRate.Numerator = 60;
swapDesc.BufferDesc.RefreshRate.Denominator = 1;
swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapDesc.OutputWindow = hwnd;
swapDesc.SampleDesc.Count = count;
swapDesc.SampleDesc.Quality = quality;
swapDesc.Windowed = FALSE;
swapDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
//Create the device.
HRESULT hr = D3D10CreateDeviceAndSwapChain(
NULL,
D3D10_DRIVER_TYPE_HARDWARE,
NULL,
0,
D3D10_SDK_VERSION,
&swapDesc,
&swapChain,
&device);
if (!chk(hr, TEXT("Could not create D3D Device D3D10CreateDeviceAndSwapChain failed.")))
return false;
ID3D10Texture2D *buffer;
logger->debug("initD3D: Calling swapChain->GetBuffer.\n");
hr = swapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*) &buffer);
if (!chk(hr, TEXT("Could not create D3D Device: swapChain->GetBuffer failed.")))
return false;
D3D10_TEXTURE2D_DESC BBDesc;
ZeroMemory(&BBDesc, sizeof(D3D10_TEXTURE2D_DESC));
buffer->GetDesc( &BBDesc );
D3D10_RENDER_TARGET_VIEW_DESC RTVDesc;
ZeroMemory(&RTVDesc, sizeof(D3D10_RENDER_TARGET_VIEW_DESC));
RTVDesc.Format = BBDesc.Format;
//RTVDesc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2D;
RTVDesc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2DMS;
RTVDesc.Texture2D.MipSlice = 0;
logger->debug("initD3D: Calling device->CreateRenderTargetView.\n");
hr = device->CreateRenderTargetView(buffer, &RTVDesc, &renderTView);
buffer->Release();
if (!chk(hr, TEXT("Could not create D3D Device: device->CreateRenderTargetView failed.")))
return false;
ZeroMemory(&descDepth, sizeof(D3D10_TEXTURE2D_DESC));
descDepth.Width = width;
descDepth.Height = height;
descDepth.MipLevels = 1;
descDepth.ArraySize = 1;
descDepth.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
//descDepth.Format = DXGI_FORMAT_D32_FLOAT;
descDepth.SampleDesc.Count = count;
descDepth.SampleDesc.Quality = quality;
descDepth.Usage = D3D10_USAGE_DEFAULT;
descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL;
descDepth.CPUAccessFlags = 0;
descDepth.MiscFlags = 0;
hr = device->CreateTexture2D(&descDepth, NULL, &stencil);
if (!chk(hr, TEXT("device->device->CreateTexture2D Failed\n")))
return false;
// Depth test parameters
dsDesc.DepthEnable = true;
dsDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
dsDesc.DepthFunc = D3D10_COMPARISON_LESS;
// Stencil test parameters
dsDesc.StencilEnable = true;
dsDesc.StencilReadMask = 0xFF;
dsDesc.StencilWriteMask = 0xFF;
// Stencil operations if pixel is front-facing
dsDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_INCR;
dsDesc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
// Stencil operations if pixel is back-facing
dsDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_DECR;
dsDesc.BackFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
hr = device->CreateDepthStencilState(&dsDesc, &pDSState);
if (!chk(hr, TEXT("device->device->CreateDepthStencilState Failed\n")))
return false;
device->OMSetDepthStencilState(pDSState, 1);
ZeroMemory(&descDSV, sizeof(D3D10_DEPTH_STENCIL_VIEW_DESC));
descDSV.Format = descDepth.Format;
//descDSV.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D;
descDSV.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2DMS;
descDSV.Texture2D.MipSlice = 0;
hr = device->CreateDepthStencilView(stencil, &descDSV, &depthStencil);
if (!chk(hr, TEXT("device->device->CreateDepthStencilView Failed\n")))
return false;
device->OMSetRenderTargets(1, &renderTView, depthStencil);
resizeD3D10Window(width, height);
return true;