안녕하세요 저는 최근에 DirectX 11을 배우려고했지만 프로그램에서 아무 것도 그려지지 않습니다.
내가 선택한 유일한 배경은 내가 선택한 배경색의 창입니다.
나는 내 프로그램을 라이브러리 (엔진)와 일반 프로젝트로 나누었다.
라이브러리에는 모델 클래스, 셰이더 클래스 및 Directx 초기화 함수가 포함되어 있습니다.DirectX에서 아무 것도 그려지지 않습니다
S3DData는 모든 관련 클래스를 포함하는 구조체입니다. 스왑 체인 등.
static bool initDX(logfile* errorlog, S3DData *data){
D3D_FEATURE_LEVEL featureLevels[] = {
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0
};
UINT numFeatureLevels = 3;
D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;
HRESULT result = ERROR_SUCCESS;
DXGI_MODE_DESC bufferDesc;
ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC));
//swapchain and device
bufferDesc.Height = data->WindowHeight;
bufferDesc.Width = data->WindowWidth;
bufferDesc.RefreshRate.Denominator = 1;
bufferDesc.RefreshRate.Numerator = 60;
bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
swapChainDesc.BufferDesc = bufferDesc;
swapChainDesc.OutputWindow = data->Handle;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.Windowed = data->Windowed;
swapChainDesc.BufferCount = 1;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.SampleDesc.Count = 1;
result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL,
D3D11_SDK_VERSION, &swapChainDesc, &data->SwapChain, &data->Device, NULL, &data->DeviceContext);
if(FAILED(result)){
std::string error;
errorlog->write("failed to create swapchain or device:");
if(result == E_INVALIDARG)
error = "invalid argument";
else if(result == E_OUTOFMEMORY)
error = " no memory";
else if(result == DXGI_ERROR_MORE_DATA)
error = " more data needed for buffer";
else if(result == E_NOTIMPL)
error = " not implemented";
else if(result == DXGI_ERROR_INVALID_CALL)
error = " invalid call";
else
error = std::to_string((unsigned int)result);
errorlog->write(error);
return false;
}
//back buffer and rendertargetview
ID3D11Texture2D *backbuffer;
result = data->SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backbuffer);
if(FAILED(result)){
errorlog->write("failed to get backbuffer");
return false;
}
result = data->Device->CreateRenderTargetView(backbuffer, NULL, &data->RenderTargetView);
if(FAILED(result)){
errorlog->write("failed to create render target view");
return false;
}
data->DeviceContext->OMSetRenderTargets(1, &data->RenderTargetView, nullptr);
backbuffer->Release();
ZeroMemory(&data->viewport, sizeof(D3D11_VIEWPORT));
data->viewport.Height = data->WindowHeight;
data->viewport.Width = data->WindowWidth;
data->viewport.TopLeftX = 0;
data->viewport.TopLeftY = 0;
data->DeviceContext->RSSetViewports(1, &data->viewport);
errorlog->write("directx success");
return true;
이 함수는 기본적으로 장치, swapchain 및 devicecontext를 만듭니다.
및 설정 :
bool shader::init(std::string vsFile, std::string psFile, S3DData * data){
std::ofstream output;
output.open("shaderErrorLog.txt", std::ios::binary);
_S3DData = data;
_pixelShader = nullptr;
_vertexShader = nullptr;
_layout = nullptr;
HRESULT result;
ID3D10Blob *errorMsg, *pixelShader, *vertexShader;;
unsigned int numElements;
errorMsg = 0;
pixelShader = 0;
vertexShader = 0;
result = D3DX11CompileFromFile(vsFile.c_str(), 0, 0, "VS", "vs_5_0", 0, 0, 0, &vertexShader, &errorMsg, 0);
if(FAILED(result)){
if(errorMsg != nullptr){
char *compilerErrors = (char*)errorMsg->GetBufferPointer();
unsigned int size = errorMsg->GetBufferSize();
output.write(compilerErrors, size);
}
else
{
std::string error ="failed to find file";
output.write(error.c_str(), error.size());
}
return false;
}
result = D3DX11CompileFromFile(psFile.c_str(), 0, 0, "PS", "ps_5_0", 0, 0, 0, &pixelShader, &errorMsg, 0);
if(FAILED(result)){
if(errorMsg){
char *compilerErrors = (char*)errorMsg->GetBufferPointer();
unsigned int size = errorMsg->GetBufferSize();
output.write(compilerErrors, size);
}
else
{
std::string noFileMsg = "file " +psFile +"not found";
output.write(noFileMsg.c_str(), noFileMsg.size());
}
return false;
}
result = _S3DData->Device->CreateVertexShader(vertexShader->GetBufferPointer(), vertexShader->GetBufferSize(), nullptr, &_vertexShader);
if(FAILED(result)){
return false;
}
result = _S3DData->Device->CreatePixelShader(pixelShader->GetBufferPointer(), pixelShader->GetBufferSize(), nullptr, &_pixelShader);
if(FAILED(result)){
return false;
}
//layout of vertex
//in case of color.fx position and color
D3D11_INPUT_ELEMENT_DESC layout[] ={
{"POSITION",0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}
};
//get num of elements
numElements = 2;
result = _S3DData->Device->CreateInputLayout(layout, numElements, vertexShader->GetBufferPointer(), vertexShader->GetBufferSize(), &_layout);
if(FAILED(result))
return false;
vertexShader->Release();
vertexShader = 0;
pixelShader->Release();
pixelShader = 0;
std::string success = "shader init : success";
output.write(success.c_str() , success.size());
_S3DData->DeviceContext->IASetInputLayout(_layout);
_S3DData->DeviceContext->VSSetShader(_vertexShader, 0, 0);
_S3DData->DeviceContext->PSSetShader(_pixelShader, 0, 0);
return true;
이들은 쉐이더 클래스의 구성원 :
ID3D11VertexShader *_vertexShader;
ID3D11PixelShader *_pixelShader;
ID3D11InputLayout *_layout;
S3DData *_S3DData;
이 기능 타겟 및 제 연료 소모량 셰이더 초기화 기능이
뷰포트 렌더링 셰이더를 만들고 이후 셰이더가 1 개 밖에 없으므로
셰이더와 입력 레이아웃을 설정합니다.
bool model::init(S3DData *data){
_S3DData = data;
HRESULT result;
vertex *vertexBuffer;
unsigned long* indexBuffer;
D3D11_BUFFER_DESC indexDesc, vertexDesc;
D3D11_SUBRESOURCE_DATA indexData, vertexData;
//create buffers
_vertexCount = 3;
_indexCount = 3;
vertexBuffer = new vertex[_vertexCount];
if(!vertexBuffer)return false;
indexBuffer = new unsigned long[_indexCount];
if(!indexBuffer)return false;
//fill buffers
vertexBuffer[0] = vertex(0.0f, 1.0f, 1.0f);
vertexBuffer[0] = vertex(1.0f, -1.0f, 1.0f);
vertexBuffer[0] = vertex(-1.0f, -1.0f, 1.0f);
indexBuffer[0] = 0;
indexBuffer[1] = 1;
indexBuffer[2] = 2;
//bufferDesc
vertexDesc.Usage = D3D11_USAGE_DEFAULT;
vertexDesc.ByteWidth = sizeof(vertex) * _vertexCount;
vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexDesc.CPUAccessFlags = 0;
vertexDesc.MiscFlags = 0;
vertexDesc.StructureByteStride = 0;
//set subressource data
vertexData.pSysMem = vertexBuffer;
vertexData.SysMemPitch = 0;
vertexData.SysMemSlicePitch = 0;
result = _S3DData->Device->CreateBuffer(&vertexDesc, &vertexData, &_vertex);
if(FAILED(result))return false;
indexDesc.ByteWidth = sizeof(unsigned long) * _indexCount;
indexDesc.Usage = D3D11_USAGE_DEFAULT;
indexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexDesc.MiscFlags = 0;
indexDesc.CPUAccessFlags = 0;
indexDesc.StructureByteStride = 0;
//set subressource
indexData.pSysMem = indexBuffer;
indexData.SysMemPitch = 0;
indexData.SysMemSlicePitch = 0;
result = _S3DData->Device->CreateBuffer(&indexDesc, &indexData, &_index);
if(FAILED(result))return false;
delete []indexBuffer;
indexBuffer = nullptr;
delete []vertexBuffer;
vertexBuffer = nullptr;
정점 구조체 :
struct vertex{
XMFLOAT3 pos;
vertex(){}
vertex(float x, float y, float z):pos(x, y, z){
}
그래서이 기능은 나머지 변수는 렌더링 함수 버퍼
를 생성
마지막 기능 모델 초기화 함수 세트 :
void model::render(shader *Shader){
unsigned int stride = sizeof(vertex);
unsigned int offset = 0;
_S3DData->DeviceContext->IASetVertexBuffers(0, 1, &_vertex, &stride, &offset);
_S3DData->DeviceContext->IASetIndexBuffer(_index, DXGI_FORMAT_R32_UINT, 0);
//set form of vertex: triangles
_S3DData->DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
_S3DData->DeviceContext->DrawIndexed(_indexCount, 0, 0);
,
}
편집 :
struct VSout{
float4 position :SV_POSITION;
};
VSout VS(float4 position:POSITION){
VSout output;
output.position = position;
return output;
}
픽셀 쉐이더 : 이 당신이
버텍스 쉐이더 요청 쉐이더 코드입니다
float4 PS() :SV_TARGET{
float4 newColor = float4(1.0f, 1.0f, 0.0f, 1.0f);
return newColor;
}
이 여기가 debuger의 스크린 샷은 당신이 왼쪽입니다 모든 그리기 호출 등. 그리고 중간에 정점 버퍼를 볼 수 있습니다. debuger
미리 도움을 주셔서 감사합니다.
빠른 한눈에 너무 많이 내밀어 아무것도 표시되지 않습니다. HRESULTS도 확인하고 있습니다. 셰이더 코드가 보이지 않습니다. 제공 할 수 있습니까? 또한 Visual Studio에서 개발 중이십니까? VS 2012를 포함한 모든 최신 버전에 포함 된 강력한 그래픽 디버거가 있습니다. GPU가 drawcall 및 스테이지 당 계산 한 내용 (정점 쉐이더 출력, 픽셀 출력 등)을 보여줄 수 있습니다. 그것은 많은 빛을 발산하는 것을 도울 것이고, 개인적으로 모든 종류의 그래픽 개발에 필수적입니다. – cehnehdeh
각 꼭지점의 Z를 0으로 설정해 볼 수도 있습니다. 단, 1이 클리핑 범위 밖에 있는지 확인해야합니다. 그러나 이것은 버텍스 쉐이더에서 어떤 일이 발생하는지에 달려 있습니다. – cehnehdeh
입력 레이아웃은 사용자가 해당 위치에 대해 float4를 사용한다고 가정하지만 실제로는 float3 만 있습니다. 두 번째 입력 레이아웃 요소를''{COLOR ", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}으로 변경해보십시오."또한 정점/픽셀 쉐이더에 대한 HLSL은 무엇입니까? –