C++ DirectX不画任何东西

C++ DirectX不画任何东西,c++,directx,directx-11,C++,Directx,Directx 11,您好,我最近尝试学习DirectX 11,但我的程序没有绘制任何内容。 我得到的唯一东西是我选择的背景色窗口 我已将程序分为库(引擎)和常规项目。 该库包含一个模型类、着色器类和一个Directx init函数 S3DData只是一个包含所有相关类(如交换链等)的结构 static bool initDX(logfile* errorlog, S3DData *data){ D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_

您好,我最近尝试学习DirectX 11,但我的程序没有绘制任何内容。
我得到的唯一东西是我选择的背景色窗口
我已将程序分为库(引擎)和常规项目。
该库包含一个模型类、着色器类和一个Directx init函数

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;
该功能主要创建:设备、交换链和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;
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;
这些是着色器类的成员:

ID3D11VertexShader *_vertexShader;
ID3D11PixelShader *_pixelShader;
ID3D11InputLayout *_layout;
S3DData *_S3DData;
此函数用于创建着色器,因为我现在只有一个着色器,
它设置着色器和输入布局

最后一个函数是model init函数:

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

这是调试程序的屏幕截图,留下了所有的绘制调用等,在中间可以看到顶点缓冲区。


提前感谢您的帮助。

查看您发布的调试器图像,第二个和第三个顶点都是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);
它应该是这样的:

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

快速看一眼,我看不出有什么东西太突出。你也在检查HRESULT。我没有看到任何着色器代码,你能提供吗?另外,您是否在VisualStudio中开发?包括VS2012在内的所有最新版本中都包含一个强大的图形调试器。它可以显示GPU在每个drawcall和每个阶段计算的内容(顶点着色器输出、像素输出等)。这将有助于释放大量光线,而且就个人而言,这对于任何类型的图形开发都是不可或缺的。我可能会尝试将每个顶点的Z设置为0,但不确定1是否超出剪裁范围。但是,这取决于顶点着色器中发生的情况。输入布局假定您使用float4作为位置,但实际上只有float3。尝试将第二个输入布局元素更改为
{“COLOR”,0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,D3D11_APPEND_ALIGNED_元素,D3D11_input_PER_VERTEX_DATA,0}
此外,顶点/像素着色器的HLSL是什么?@cehnehdeh我尝试将z设置为0,但它仍然没有绘制任何内容。顺便说一下,我编辑了问题并添加了着色器代码。@ChuckWalbourn谢谢你的提示。我更改了第二个输入元素。我误解了这个变量,我以为它是第二个变量的偏移量,但显然是两个元素之间的空间(如果我理解正确的话)谢谢你的帮助,我忽略了这一点,我犯了多么愚蠢的错误。很抱歉把你的时间浪费在这样的事情上。:)