5

创建光栅器时,我将光栅器描述设置为:

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 = true;
rasterDesc.MultisampleEnable = false;
rasterDesc.ScissorEnable = false;
rasterDesc.SlopeScaledDepthBias = 0.0f;

这工作正常。但是当我更改FrontCounterClockwisefalse. 什么都没有渲染(我猜一切都被剔除)。我是否误解了 的目的FrontCounterClockwise?因为我期待,它将顺时针的面作为正面,而不是逆时针的面。我究竟做错了什么?

编辑:这是完整的初始化代码:

bool irrFireDX11::INITIALIZE(int screenWidth, int screenHeight, bool vsync)
{
HRESULT result;
IDXGIFactory* factory;
IDXGIAdapter* adapter;
IDXGIOutput* adapterOutput;
unsigned int numModes, i, numerator, denominator, stringLength;
DXGI_MODE_DESC* displayModeList;
DXGI_ADAPTER_DESC adapterDesc;
int error;
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ID3D11Texture2D* backBufferPtr;
D3D11_TEXTURE2D_DESC depthBufferDesc;
D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
D3D11_RASTERIZER_DESC rasterDesc;
D3D11_VIEWPORT viewport;
float fieldOfView, screenAspect;
m_vsync_enabled = vsync;
D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc;

// Create a DirectX graphics interface factory.
result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
if(FAILED(result)) return false;

// Use the factory to create an 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 number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor).
result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL);
if(FAILED(result)) return false;

// Create a list to hold all the possible display modes for this monitor/video card combination.
displayModeList = new DXGI_MODE_DESC[numModes];
if(!displayModeList) return false;

// Now fill the display mode list structures.
result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList);
if(FAILED(result)) return false;

// Now go through all the display modes and find the one that matches the screen width and height.
// When a match is found store the numerator and denominator of the refresh rate for that monitor.
for(i=0; i<numModes; i++)
{
    if(displayModeList[i].Width == (unsigned int)screenWidth)
    {
        if(displayModeList[i].Height == (unsigned int)screenHeight)
        {
            numerator = displayModeList[i].RefreshRate.Numerator;
            denominator = displayModeList[i].RefreshRate.Denominator;
        }
    }
}

// Get the adapter (video card) description.
result = adapter->GetDesc(&adapterDesc);
if(FAILED(result)) return false;
m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024);
error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128);
if(error != 0) return false;

delete [] displayModeList;
displayModeList = 0;
adapterOutput->Release();
adapterOutput = 0;
adapter->Release();
adapter = 0;
factory->Release();
factory = 0;

// Initialize the swap chain description.
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc.Width = screenWidth;
swapChainDesc.BufferDesc.Height = screenHeight;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;

if(m_vsync_enabled)
{
    swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator;
    swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator;
}else{
    swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
    swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
}

swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = ifDEVICE->getWindowHandle();
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.Windowed = !ifDEVICE->getFullScreen();
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.Flags = 0;

D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;
D3D_FEATURE_LEVEL featureLevel[] =
{
    D3D_FEATURE_LEVEL_11_0,
    D3D_FEATURE_LEVEL_10_1,
    D3D_FEATURE_LEVEL_10_0,
};
result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, featureLevel, 3,
    D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, &g_featureLevel, &m_deviceContext);
if(FAILED(result)) return false;

result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr);
if(FAILED(result)) return false;

result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView);
if(FAILED(result)) return false;

backBufferPtr->Release();
backBufferPtr = 0;

ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));
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;

result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer);
if(FAILED(result)) return false;

ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));
depthStencilDesc.DepthEnable = true;
depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
depthStencilDesc.StencilEnable = true;
depthStencilDesc.StencilReadMask = 0xFF;
depthStencilDesc.StencilWriteMask = 0xFF;
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;
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;

result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState);
if(FAILED(result)) return false;
m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1);

ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));
depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
depthStencilViewDesc.Texture2D.MipSlice = 0;
    result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView);
    if(FAILED(result)) return false;
    m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);
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 = true;
rasterDesc.MultisampleEnable = false;
rasterDesc.ScissorEnable = false;
rasterDesc.SlopeScaledDepthBias = 0.0f;

result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState);
if(FAILED(result)) return false;
m_deviceContext->RSSetState(m_rasterState);

viewport.Width = (float)screenWidth;
viewport.Height = (float)screenHeight;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
viewport.TopLeftX = 0.0f;
viewport.TopLeftY = 0.0f;
m_deviceContext->RSSetViewports(1, &viewport);

fieldOfView = (float)D3DX_PI / 4.0f;
screenAspect = (float)screenWidth / (float)screenHeight;

D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, nearValue, farValue);
D3DXMatrixIdentity(&m_worldMatrix);
D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, nearValue, farValue);

// Clear the second depth stencil state before setting the parameters.
ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc));

depthDisabledStencilDesc.DepthEnable = false;
depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
depthDisabledStencilDesc.StencilEnable = true;
depthDisabledStencilDesc.StencilReadMask = 0xFF;
depthDisabledStencilDesc.StencilWriteMask = 0xFF;
depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
depthDisabledStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
depthDisabledStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthDisabledStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

result = m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState);
if(FAILED(result)) return false;

return true;
}
4

1 回答 1

4

首先要澄清的是Direct3D中的背面不是你身后的脸,这里的“背面”这个词并不是正常单词中的方向,而是顶点顺序,除了正面之外的所有面都被视为背面.

关于您的问题,您说下面的代码可以正常工作。

rasterDesc.CullMode = D3D11_CULL_BACK;
rasterDesc.FrontCounterClockwise = true;

这里的“好”是什么意思?每张脸都很好,还是其中一些很好?如果每张脸都很好,那意味着

  1. 你告诉 D3D 剔除背面
  2. 您为每个面逆时针定义顶点

因此,您会看到每个面都渲染得很好,因为它们被您的设置视为正面,然后您将 FrontCounterClockwise 更改为 false,如下所示。

rasterDesc.FrontCounterClockwise = false

这意味着,您告诉 d3d 逆时针定义的面是背面,因此 D3D 剔除所有面,因此没有渲染任何内容。

注意:在 Direct3D 10/11 中,正面不仅由顶点顺序确定,还取决于 FrontCounterClockwise 的值。,这与仅由顶点顺序确定的 Direct3D 9 不同。

所以在 Direct3D 10/11 中,如果

FrontCounterClockwise = true

  1. 如果顶点顺序为逆时针方向,则将面视为正面
  2. 如果顶点顺序为顺时针,则面被视为背面

FrontCounterClockwise = fase

  1. 如果顶点顺序为顺时针,则面被视为正面
  2. 如果顶点顺序为逆时针,则面被视为背面

“FrontCounterClockwise”这个名字可能会让人感到困惑,我们可以将这些词分开如下

  • FrontCounterClockwise = true,表示逆时针为顶点的正面为真。
  • FrontCounterClockwise = false,表示正面为顶点逆时针为假,换句话说,正面为顶点顺时针为真。
于 2013-07-16T12:17:48.363 回答