2024-03-18 15:41:46 -03:00
|
|
|
#ifndef XNA_PLATFORM_TEXTURE_DX_HPP
|
|
|
|
#define XNA_PLATFORM_TEXTURE_DX_HPP
|
|
|
|
|
2024-05-04 21:07:39 -03:00
|
|
|
#include "../common/rectangle.hpp"
|
|
|
|
#include "../csharp/buffer.hpp"
|
2024-03-18 15:41:46 -03:00
|
|
|
#include "../graphics/texture.hpp"
|
2024-04-07 14:06:12 -03:00
|
|
|
#include "../xnaerror.hpp"
|
2024-05-04 21:07:39 -03:00
|
|
|
#include "dxheaders.hpp"
|
|
|
|
#include <WICTextureLoader.h>
|
|
|
|
#include "../graphics/gresource.hpp"
|
|
|
|
#include "device-dx.hpp"
|
|
|
|
#include <SimpleMath.h>
|
2024-03-18 15:41:46 -03:00
|
|
|
|
|
|
|
namespace xna {
|
2024-05-04 21:07:39 -03:00
|
|
|
class Texture2D : public ITexture2D, public GraphicsResource {
|
2024-03-21 16:01:47 -03:00
|
|
|
public:
|
2024-05-04 21:07:39 -03:00
|
|
|
Texture2D(GraphicsDevice* device, size_t width, size_t height) : GraphicsResource(device) {
|
|
|
|
dxDescription.Width = static_cast<UINT>(width);
|
|
|
|
dxDescription.Height = static_cast<UINT>(height);
|
|
|
|
setDefaultDesc();
|
|
|
|
}
|
|
|
|
|
|
|
|
Texture2D(GraphicsDevice* device) : GraphicsResource(device) {
|
|
|
|
setDefaultDesc();
|
|
|
|
}
|
2024-03-18 15:41:46 -03:00
|
|
|
|
2024-03-21 16:01:47 -03:00
|
|
|
virtual ~Texture2D() override {
|
2024-05-04 21:07:39 -03:00
|
|
|
if (dxTexture2D) {
|
|
|
|
dxTexture2D->Release();
|
|
|
|
dxTexture2D = nullptr;
|
2024-03-21 16:01:47 -03:00
|
|
|
}
|
2024-04-14 16:11:15 -03:00
|
|
|
|
2024-05-04 21:07:39 -03:00
|
|
|
if (dxShaderResourceView) {
|
|
|
|
dxShaderResourceView->Release();
|
|
|
|
dxShaderResourceView = nullptr;
|
2024-04-14 16:11:15 -03:00
|
|
|
}
|
2024-03-21 16:01:47 -03:00
|
|
|
}
|
|
|
|
|
2024-04-07 14:06:12 -03:00
|
|
|
virtual constexpr Int Width() const override {
|
2024-05-04 21:07:39 -03:00
|
|
|
return dxDescription.Width;
|
2024-04-07 14:06:12 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual constexpr Int Height() const override {
|
2024-05-04 21:07:39 -03:00
|
|
|
return dxDescription.Height;
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr Rectangle Bounds() const override {
|
|
|
|
return { 0, 0, static_cast<Int>(dxDescription.Width), static_cast<Int>(dxDescription.Height) };
|
2024-04-07 14:06:12 -03:00
|
|
|
}
|
|
|
|
|
2024-05-04 21:07:39 -03:00
|
|
|
bool Initialize(xna_error_nullarg) override;
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void SetData(std::vector<T> const& data, xna_error_ptr_arg);
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void SetData(std::vector<T> const& data, size_t startIndex, size_t elementCount, xna_error_nullarg);
|
|
|
|
|
|
|
|
static sptr<Texture2D> FromStream(GraphicsDevice& device, String const& fileName, xna_error_nullarg);
|
2024-04-07 14:06:12 -03:00
|
|
|
|
2024-03-21 16:01:47 -03:00
|
|
|
public:
|
2024-05-04 21:07:39 -03:00
|
|
|
ID3D11Texture2D* dxTexture2D{ nullptr };
|
|
|
|
ID3D11ShaderResourceView* dxShaderResourceView{ nullptr };
|
|
|
|
D3D11_SUBRESOURCE_DATA dxSubResource{};
|
|
|
|
D3D11_TEXTURE2D_DESC dxDescription{};
|
|
|
|
D3D11_SHADER_RESOURCE_VIEW_DESC dxShaderDecription{};
|
|
|
|
|
|
|
|
private:
|
|
|
|
static constexpr int R8G8B8A8U_BYTE_SIZE = 4;
|
|
|
|
|
|
|
|
void setDefaultDesc() {
|
|
|
|
dxDescription.MipLevels = 1;
|
|
|
|
dxDescription.ArraySize = 1;
|
|
|
|
dxDescription.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
|
|
dxDescription.SampleDesc.Count = 1;
|
|
|
|
dxDescription.Usage = D3D11_USAGE_DEFAULT;
|
|
|
|
dxDescription.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
|
|
|
|
|
|
|
dxShaderDecription.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
|
|
dxShaderDecription.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
|
|
|
dxShaderDecription.Texture2D.MipLevels = dxDescription.MipLevels;
|
|
|
|
dxShaderDecription.Texture2D.MostDetailedMip = 0;
|
|
|
|
}
|
2024-03-18 15:41:46 -03:00
|
|
|
};
|
2024-05-04 21:07:39 -03:00
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
inline void Texture2D::SetData(std::vector<T> const& data, xna_error_ptr_arg) {
|
|
|
|
SetData(data, 0, data.size(), err);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
inline void Texture2D::SetData(std::vector<T> const& data, size_t startIndex, size_t elementCount, xna_error_ptr_arg) {
|
|
|
|
if (!m_device || !m_device->_device || !m_device->_context) {
|
|
|
|
xna_error_apply(err, XnaErrorCode::INVALID_OPERATION);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<UINT> finalData(elementCount);
|
|
|
|
auto finalDataIndex = 0;
|
|
|
|
|
|
|
|
for (size_t i = startIndex; i < elementCount; ++i) {
|
|
|
|
finalData[finalDataIndex] = static_cast<UINT>(data[i]);
|
|
|
|
++finalDataIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dxTexture2D) {
|
|
|
|
auto hr = m_device->_device->CreateTexture2D(&dxDescription, nullptr, &dxTexture2D);
|
|
|
|
|
|
|
|
if (FAILED(hr)) {
|
|
|
|
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ID3D11Resource* resource = nullptr;
|
|
|
|
auto hr = dxTexture2D->QueryInterface(IID_ID3D11Resource, (void**)&resource);
|
|
|
|
|
|
|
|
if (FAILED(hr)) {
|
|
|
|
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
dxShaderDecription.Texture2D.MipLevels = dxDescription.MipLevels;
|
|
|
|
m_device->_context->UpdateSubresource(resource, 0, nullptr, finalData.data(), dxDescription.Width * R8G8B8A8U_BYTE_SIZE, 0);
|
|
|
|
|
|
|
|
if (dxShaderResourceView) {
|
|
|
|
dxShaderResourceView->Release();
|
|
|
|
dxShaderResourceView = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
hr = m_device->_device->CreateShaderResourceView(resource, &dxShaderDecription, &dxShaderResourceView);
|
|
|
|
|
|
|
|
if (resource) {
|
|
|
|
resource->Release();
|
|
|
|
resource = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FAILED(hr)) {
|
|
|
|
xna_error_apply(err, XnaErrorCode::FAILED_OPERATION);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
dxTexture2D->GetDesc(&dxDescription);
|
|
|
|
}
|
2024-03-18 15:41:46 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|