我是DirectX的新手,已经阅读了大量的教程和示例,但是我找不到任何有关如何直接在屏幕上显示加载到Texture2D
中的图像的文档。我见过的几乎所有教程都涉及3D图形,着色器等。但是,我只想显示纹理的内容。
这是我到目前为止所拥有的:
DeviceResources.cpp :
#include "DeviceResources.h"
#include "Renderer.h"
DeviceResources::DeviceResources()
{
}
HRESULT DeviceResources::CreateDeviceResources(HWND hwnd)
{
D3D_FEATURE_LEVEL levels[] = {
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_12_0,
D3D_FEATURE_LEVEL_12_1
};
UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
DXGI_SWAP_CHAIN_DESC swap_chain_desc;
ZeroMemory(&swap_chain_desc, sizeof(DXGI_SWAP_CHAIN_DESC));
swap_chain_desc.Windowed = TRUE;
swap_chain_desc.BufferCount = 2;
swap_chain_desc.BufferDesc.Format = DXGI_FORMAT_R10G10B10A2_UNORM;
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swap_chain_desc.SampleDesc.Count = 1;
swap_chain_desc.SampleDesc.Quality = 0;
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
swap_chain_desc.OutputWindow = hwnd;
Microsoft::WRL::ComPtr<ID3D11Device> device;
Microsoft::WRL::ComPtr<ID3D11DeviceContext> context;
Microsoft::WRL::ComPtr<IDXGISwapChain> swapChain;
D3D11CreateDeviceAndSwapChain(
nullptr,
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
flags,
levels,
ARRAYSIZE(levels),
D3D11_SDK_VERSION,
&swap_chain_desc,
swapChain.GetAddressOf(),
device.GetAddressOf(),
&m_feature_level,
context.GetAddressOf()
);
device.As(&m_device);
context.As(&m_context);
swapChain.As(&m_swapChain);
cv::directx::ocl::initializeContextFromD3D11Device(m_device.Get());
auto hdr = Renderer::HDRMetadata();
m_swapChain->SetHDRMetaData(DXGI_HDR_METADATA_TYPE_HDR10, sizeof(DXGI_HDR_METADATA_HDR10), &hdr);
m_swapChain->SetColorSpace1(DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020);
m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), static_cast<void**>(& m_backBuffer));
m_backBuffer->GetDesc(&m_bbDesc);
ZeroMemory(&m_viewport, sizeof(D3D11_VIEWPORT));
m_viewport.Height = static_cast<float>(m_bbDesc.Height);
m_viewport.Width = static_cast<float>(m_bbDesc.Width);
m_viewport.MinDepth = 0;
m_viewport.MaxDepth = 1;
m_context->RSSetViewports(1, &m_viewport);
m_device->CreateRenderTargetView(m_backBuffer.Get(), nullptr, m_renderTargetView.GetAddressOf());
return S_OK;
}
HRESULT DeviceResources::ConfigureBackBuffer()
{
m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), static_cast<void**>(& m_backBuffer));
m_device->CreateRenderTargetView(m_backBuffer.Get(), nullptr, m_renderTargetView.GetAddressOf());
m_backBuffer->GetDesc(&m_bbDesc);
ZeroMemory(&m_viewport, sizeof(D3D11_VIEWPORT));
m_viewport.Height = static_cast<float>(m_bbDesc.Height);
m_viewport.Width = static_cast<float>(m_bbDesc.Width);
m_viewport.MinDepth = 0;
m_viewport.MaxDepth = 1;
m_context->RSSetViewports(1, &m_viewport);
return S_OK;
}
HRESULT DeviceResources::ReleaseBackBuffer()
{
m_renderTargetView.Reset();
m_backBuffer.Reset();
m_context->Flush();
return S_OK;
}
HRESULT DeviceResources::SetFullscreen(bool fullscreen)
{
m_swapChain->SetFullscreenState(fullscreen, nullptr);
ReleaseBackBuffer();
m_swapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
ConfigureBackBuffer();
return S_OK;
}
void DeviceResources::Present()
{
m_swapChain->Present(1, 0);
}
DeviceResources::~DeviceResources()
= default;
Renderer.cpp:
#include "Renderer.h"
#include <utility>
#include <comdef.h>
#include <vector>
Renderer::Renderer(std::shared_ptr<DeviceResources> resources) : m_resources(std::move(resources)), m_frameCount(0)
{
m_frameCount = 0;
}
HRESULT Renderer::CreateDeviceDependentResources()
{
return S_OK;
}
HRESULT Renderer::CreateWindowSizeDependentResources()
{
return S_OK;
}
void Renderer::Update()
{
//
}
void Renderer::Render()
{
cv::Mat mat = cv::imread("C:/Users/Richard/Downloads/orig_cave_L.ppm", cv::IMREAD_ANYCOLOR | cv::IMREAD_ANYDEPTH);
cv::Mat as4channelMat(mat.size(), CV_MAKE_TYPE(mat.depth(), 4));
int conversion[] = { 0, 0, 1, 1, 2, 2, -1, 3 };
cv::mixChannels(&mat, 1, &as4channelMat, 1, conversion, 4);
D3D11_TEXTURE2D_DESC desc;
desc.Width = 3840;
desc.Height = 2160;
desc.MipLevels = desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R16G16B16A16_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
desc.MiscFlags = 0;
ID3D11Texture2D* tex = nullptr;
auto hr = m_resources->GetDevice()->CreateTexture2D(&desc, nullptr, &tex);
if FAILED(hr)
{
_com_error err(hr);
auto errMsg = err.ErrorMessage();
}
try {
cv::directx::convertToD3D11Texture2D(as4channelMat, tex);
} catch (cv::Exception& e)
{
std::cerr << "ERROR: " << e.msg << std::endl;
throw e;
}
auto hr3 = m_resources->m_device->CreateShaderResourceView(tex.Get(), nullptr, m_texture.GetAddressOf());
if FAILED(hr3)
{
_com_error err(hr3);
auto errMsg = err.ErrorMessage();
}
std::unique_ptr<DirectX::SpriteBatch> m_spriteBatch;
DirectX::SimpleMath::Vector2 m_screenPos, m_origin;
m_spriteBatch = std::make_unique<DirectX::SpriteBatch>(m_resources->m_context.Get());
CD3D11_TEXTURE2D_DESC catDesc;
tex->GetDesc(&catDesc);
m_origin.x = float(catDesc.Width / 2);
m_origin.y = float(catDesc.Height / 2);
m_screenPos.x = m_resources->m_bbDesc.Width / 2.f;
m_screenPos.y = m_resources->m_bbDesc.Height / 2.f;
m_spriteBatch->Begin();
m_spriteBatch->Draw(
m_texture.Get(),
m_screenPos,
nullptr,
DirectX::Colors::White,
0.0f,
m_origin
);
m_spriteBatch->End();
}
DXGI_HDR_METADATA_HDR10 Renderer::HDRMetadata()
{
//
}
Renderer::~Renderer()
{
}
据我了解,我必须以某种方式创建一个“四元组”,对其应用纹理,然后显示四元组本身。但是,我不确定如何执行此操作,也找不到任何资源可以帮助您。
编辑:根据建议,我尝试使用DirectXTK,特别是SpriteBatch
。我遵循了文档中的相关说明,但是Draw
似乎没有执行任何操作或没有显示任何内容。 (在Renderer.cpp
中)