我一直在玩游戏一段时间,首先使用SDL,然后使用SFML。很高兴为我完成了基础知识,但现在我想采取另一个步骤,学习如何从头开始制作图形。所以我正在尝试学习Direct3D的绳索,并且已经开始阅读有关D3D 11的几个教程。我只是想通过在黑暗的背景上绘制一个白色三角形来获得绝对的基础知识......但我无法让它发挥作用。
我正在使用Visual Studio 2012 RC和Windows 8 SDK,因此这里有一些C ++ 11语法,而且没有D3DX。我已设法设置窗口,Direct3D的初始化似乎很好。它运行主循环的渲染部分,因为它以我指定的颜色清除屏幕。但是,我喜欢的白色三角形不会出现。我已经多次查看过我的代码了,由于缺乏经验,我无法分辨它有什么问题。我已经删除了窗口初始化/ d3d关闭和其他不相关的部分,但我害怕切断太多,以防其中一些与我的问题相关,所以...大墙代码警告
我想我已经完成了所有必要的步骤;我创建了设备,设备上下文,交换链和渲染目标。然后我创建一个顶点着色器+输入布局和一个像素着色器。之后我创建了一个顶点缓冲区,为我的三角形添加了顶点,并将原始拓扑设置为TRIANGLELIST,这就是初始化。在我的主循环中,我将D3D指向我的顶点/像素着色器,并告诉它绘制我插入缓冲区的3个顶点。但只有ClearRenderTargetView调用的深蓝色背景才显示出来;没有三角形。我错过了任何步骤,或者在路上做错了什么?
这是我的代码(我可耻地承认在这个代码约定上有点松懈,所以在指针变量等之前没有p。):
主循环:
while ( msg.message != WM_QUIT )
{
if ( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
g_d3dContext->ClearRenderTargetView( g_renderTarget, clearColor );
g_d3dContext->VSSetShader( g_vertexShader, nullptr, 0 );
g_d3dContext->PSSetShader( g_pixelShader, nullptr, 0 );
g_d3dContext->Draw( 3, 0 );
g_swapChain->Present( 0, 0 );
}
}
Direct3D init:
HRESULT hr = S_OK;
RECT rc;
GetClientRect( g_hWnd, &rc );
float width = static_cast<float>( rc.right - rc.left );
float height = static_cast<float>( rc.bottom - rc.top );
uint createDeviceFlags = 0;
const uint numDriverTypes = 3;
D3D_DRIVER_TYPE driverTypes[ numDriverTypes ] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE
};
const uint numFeatureLevels = 3;
D3D_FEATURE_LEVEL featureLevels[ numFeatureLevels ] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0
};
DXGI_SWAP_CHAIN_DESC sd = { 0 };
sd.BufferCount = 1;
sd.BufferDesc.Width = static_cast<uint>( width );
sd.BufferDesc.Height = static_cast<uint>( 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;
for( uint driverTypeIndex : driverTypes )
{
g_driverType = driverTypes[ driverTypeIndex ];
hr = D3D11CreateDeviceAndSwapChain( nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &sd, &g_swapChain, &g_d3d, &g_featureLevel, &g_d3dContext );
if( SUCCEEDED( hr ))
break;
}
if( FAILED( hr ))
return hr;
// Create a render target view
ID3D11Texture2D* backBuffer = nullptr;
hr = g_swapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast<void**>( &backBuffer ));
if( FAILED( hr ))
return hr;
hr = g_d3d->CreateRenderTargetView( backBuffer, nullptr, &g_renderTarget );
backBuffer->Release();
if( FAILED( hr ))
return hr;
g_d3dContext->OMSetRenderTargets( 1, &g_renderTarget, nullptr );
// Setup the viewport
D3D11_VIEWPORT vp = { 0 };
vp.Width = width;
vp.Height = height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_d3dContext->RSSetViewports( 1, &vp );
// Create vertex shader and input layout
ID3DBlob* vsBlob = nullptr;
ID3DBlob* errorBlob = nullptr;
hr = D3DCompileFromFile( L"VertexShader.hlsl", nullptr, nullptr, "main", "vs_4_0", 0, 0, &vsBlob, &errorBlob );
if ( FAILED( hr ))
return hr;
hr = g_d3d->CreateVertexShader( vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, &g_vertexShader );
if ( FAILED( hr ))
{
vsBlob->Release();
return hr;
}
D3D11_INPUT_ELEMENT_DESC ied = { 0 };
ied.AlignedByteOffset = 0;
ied.Format = DXGI_FORMAT_R32G32B32_FLOAT;
ied.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
ied.InputSlot = 0;
ied.InstanceDataStepRate = 0;
ied.SemanticIndex = 0;
ied.SemanticName = "POSITION";
hr = g_d3d->CreateInputLayout( &ied, 1, vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), &g_inputLayout );
vsBlob->Release();
if ( FAILED ( hr ))
return hr;
g_d3dContext->IASetInputLayout( g_inputLayout );
// Create pixel shader
ID3DBlob* psBlob = nullptr;
errorBlob = nullptr;
hr = D3DCompileFromFile( L"PixelShader.hlsl", nullptr, nullptr, "main", "ps_4_0", 0, 0, &psBlob, &errorBlob );
if ( FAILED( hr ))
return hr;
hr = g_d3d->CreatePixelShader( psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, &g_pixelShader );
psBlob->Release();
if ( FAILED( hr ))
return hr;
// Put some vertices up in this bitch
Vector3f vertices[] =
{
Vector3f( 0.5f, -0.5f, 0.5f ),
Vector3f( 0.5f, -0.5f, 0.5f ),
Vector3f( -0.5f, -0.5f, 0.5f )
};
D3D11_BUFFER_DESC bd = { 0 };
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.ByteWidth = sizeof( Vector3f ) * 3;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
bd.StructureByteStride = 0;
bd.Usage = D3D11_USAGE_DEFAULT;
D3D11_SUBRESOURCE_DATA initData = { 0 };
initData.pSysMem = vertices;
initData.SysMemPitch = 0;
initData.SysMemSlicePitch = 0;
hr = g_d3d->CreateBuffer( &bd, &initData, &g_vertexBuffer );
if ( FAILED( hr ))
return hr;
uint stride = sizeof( Vector3f );
uint offset = 0;
g_d3dContext->IASetVertexBuffers( 0, 1, &g_vertexBuffer, &stride, &offset );
g_d3dContext->IASetPrimitiveTopology( D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
return S_OK;
我的顶点类型:
struct Vector3f
{
Vector3f( float ix, float iy, float iz )
: x( ix ), y( iy ), z( iz ) {}
float x;
float y;
float z;
};
我的顶点着色器:
float4 main( float4 pos : POSITION ) : SV_POSITION
{
return pos;
}
我的像素着色器:
float4 main() : SV_TARGET
{
return float4( 1.0f, 1.0f, 1.0f, 1.0f );
}
答案 0 :(得分:2)
当然,这是一次令人难以置信的愚蠢疏忽。我只是输入了不好的顶点数据 - 所有的顶点都在同一个Y维度上;两者首先是相同的。
改为:
Vector3f( -0.5f, 0.5f, 0.5f ),
Vector3f( 0.5f, 0.5f, 0.5f ),
Vector3f( -0.5f, -0.5f, 0.5f )
有很多歌舞,幸福。