2017-01-14 5 views
0

안녕하세요 저는 최근에 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

미리 도움을 주셔서 감사합니다.

+0

빠른 한눈에 너무 많이 내밀어 아무것도 표시되지 않습니다. HRESULTS도 확인하고 있습니다. 셰이더 코드가 보이지 않습니다. 제공 할 수 있습니까? 또한 Visual Studio에서 개발 중이십니까? VS 2012를 포함한 모든 최신 버전에 포함 된 강력한 그래픽 디버거가 있습니다. GPU가 drawcall 및 스테이지 당 계산 한 내용 (정점 쉐이더 출력, 픽셀 출력 등)을 보여줄 수 있습니다. 그것은 많은 빛을 발산하는 것을 도울 것이고, 개인적으로 모든 종류의 그래픽 개발에 필수적입니다. – cehnehdeh

+0

각 꼭지점의 Z를 0으로 설정해 볼 수도 있습니다. 단, 1이 클리핑 범위 밖에 있는지 확인해야합니다. 그러나 이것은 버텍스 쉐이더에서 어떤 일이 발생하는지에 달려 있습니다. – cehnehdeh

+0

입력 레이아웃은 사용자가 해당 위치에 대해 float4를 사용한다고 가정하지만 실제로는 float3 만 있습니다. 두 번째 입력 레이아웃 요소를''{COLOR ", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}으로 변경해보십시오."또한 정점/픽셀 쉐이더에 대한 HLSL은 무엇입니까? –

답변

0

게시 한 디버거 이미지를 보면 두 번째 및 세 번째 버텍스는 모두 0입니다. 즉, 버텍스 버퍼를 제대로 채우지 못했음을 의미합니다.

코드를 보면 정점 버퍼를 채울 때 0 인덱스에서만 설정합니다.

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); 

을 그리고 그것은 다음과 같아야합니다 : 그래서 코드는 다음과 같습니다

vertexBuffer[0] = vertex(0.0f, 1.0f, 1.0f); 
vertexBuffer[1] = vertex(1.0f, -1.0f, 1.0f); 
vertexBuffer[2] = vertex(-1.0f, -1.0f, 1.0f); 
+0

도움을 줘서 고마워. 나는 그것을 간과 했어. 내게 어리석은 실수 야. 이런 일로 시간 낭비를해서 죄송합니다. :) – jaklh