DirectX没有绘制任何东西

时间:2017-01-14 17:40:54

标签: c++ directx directx-11

您好我最近尝试学习DirectX 11,但我的程序没有画任何东西 我唯一得到的是我选择的背景颜色的窗户 我把我的程序分成了一个库(引擎)和一个常规项目 该库包含模型类,着色器类和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;

该功能基本上创建:设备,交换链和设备上下文 并设置:渲染目标和视口

第二个功能是着色器初始化函数:

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

Pixel Shader:

float4 PS() :SV_TARGET{
float4 newColor = float4(1.0f, 1.0f, 0.0f, 1.0f);
return newColor;
}

这里是debuger的截图,你有所有的绘图调用等。在中间你可以看到顶点缓冲区 debuger

感谢你的帮助。

1 个答案:

答案 0 :(得分:0)

查看您发布的调试器图像,第2个和第3个顶点都是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);