2024-09-06 22:23:32 -03:00
|
|
|
#include "xna-dx/framework.hpp"
|
2024-03-18 15:41:46 -03:00
|
|
|
|
2024-05-04 21:07:39 -03:00
|
|
|
namespace xna {
|
2024-11-16 12:15:40 -03:00
|
|
|
HRESULT Texture2DImplementation::SetData(GraphicsDevice& device, UINT const* data) {
|
|
|
|
if (!Texture2D) {
|
|
|
|
auto hr = device.Implementation->Device->CreateTexture2D(&Description, nullptr, Texture2D.ReleaseAndGetAddressOf());
|
|
|
|
|
|
|
|
if (FAILED(hr)) {
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
comptr<ID3D11Resource> resource = nullptr;
|
|
|
|
auto hr = Texture2D->QueryInterface(IID_ID3D11Resource, (void**)resource.GetAddressOf());
|
|
|
|
|
|
|
|
if (FAILED(hr)) {
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr int R8G8B8A8U_BYTE_SIZE = 4;
|
|
|
|
device.Implementation->Context->UpdateSubresource(resource.Get(), 0, nullptr, data, Description.Width * R8G8B8A8U_BYTE_SIZE, 0);
|
|
|
|
|
|
|
|
ShaderDescription.Texture2D.MipLevels = Description.MipLevels;
|
|
|
|
hr = device.Implementation->Device->CreateShaderResourceView(resource.Get(), &ShaderDescription, ShaderResource.ReleaseAndGetAddressOf());
|
|
|
|
|
|
|
|
if (FAILED(hr)) {
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
Texture2D->GetDesc(&Description);
|
|
|
|
|
|
|
|
return NO_ERROR;
|
|
|
|
}
|
2024-05-04 21:07:39 -03:00
|
|
|
|
2024-08-05 15:42:56 -03:00
|
|
|
Texture2D::Texture2D() : Texture(nullptr) {
|
2024-11-16 12:15:40 -03:00
|
|
|
Implementation = unew<Texture2DImplementation>();
|
2024-08-05 15:42:56 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
Texture2D::Texture2D(sptr<GraphicsDevice> const& device, size_t width, size_t height) : Texture(device), width(width), height(height) {
|
2024-11-16 12:15:40 -03:00
|
|
|
Implementation = unew<Texture2DImplementation>();
|
|
|
|
Implementation->Description.Width = static_cast<UINT>(this->width);
|
|
|
|
Implementation->Description.Height = static_cast<UINT>(this->height);
|
2024-08-05 15:42:56 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
Texture2D::Texture2D(sptr<GraphicsDevice> const& device) : Texture(device) {
|
2024-11-16 12:15:40 -03:00
|
|
|
Implementation = unew<Texture2DImplementation>();
|
2024-08-05 15:42:56 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
Texture2D::Texture2D(sptr<GraphicsDevice> const& device, size_t width, size_t height, size_t mipMap, SurfaceFormat format)
|
|
|
|
: Texture(device), width(width), height(height), levelCount(mipMap) {
|
2024-11-16 12:15:40 -03:00
|
|
|
Implementation = unew<Texture2DImplementation>();
|
|
|
|
Implementation->Description.Width = static_cast<UINT>(this->width);
|
|
|
|
Implementation->Description.Height = static_cast<UINT>(this->height);
|
|
|
|
Implementation->Description.MipLevels = static_cast<UINT>(this->levelCount);
|
|
|
|
Implementation->Description.Format = DxHelpers::SurfaceFormatToDx(format);
|
2024-08-05 15:42:56 -03:00
|
|
|
}
|
|
|
|
|
2024-08-02 22:10:40 -03:00
|
|
|
void Texture2D::Initialize()
|
2024-05-04 21:07:39 -03:00
|
|
|
{
|
2024-11-14 21:44:46 -03:00
|
|
|
if (!BaseGraphicsDevice || !BaseGraphicsDevice->Implementation->Device) {
|
2024-12-02 19:02:51 -03:00
|
|
|
throw csharp::InvalidOperationException();
|
2024-08-05 16:12:53 -03:00
|
|
|
}
|
2024-05-04 21:07:39 -03:00
|
|
|
|
2024-11-14 21:44:46 -03:00
|
|
|
auto& deviceImpl = BaseGraphicsDevice->Implementation;
|
2024-05-04 21:07:39 -03:00
|
|
|
|
2024-08-05 16:12:53 -03:00
|
|
|
HRESULT hr = 0;
|
|
|
|
|
2024-11-16 12:15:40 -03:00
|
|
|
if (!Implementation->Texture2D) {
|
2024-11-14 15:25:11 -03:00
|
|
|
hr = deviceImpl->Device->CreateTexture2D(
|
2024-11-16 12:15:40 -03:00
|
|
|
&Implementation->Description,
|
2024-08-05 16:12:53 -03:00
|
|
|
nullptr,
|
2024-11-16 12:15:40 -03:00
|
|
|
Implementation->Texture2D.ReleaseAndGetAddressOf());
|
2024-08-05 15:42:56 -03:00
|
|
|
|
2024-08-05 16:12:53 -03:00
|
|
|
if FAILED(hr)
|
2024-12-02 19:02:51 -03:00
|
|
|
throw csharp::InvalidOperationException();
|
2024-08-05 15:42:56 -03:00
|
|
|
}
|
|
|
|
else {
|
2024-08-05 16:12:53 -03:00
|
|
|
//Updates description if texture is not null
|
2024-11-16 12:15:40 -03:00
|
|
|
Implementation->Texture2D->GetDesc(&Implementation->Description);
|
2024-05-04 21:07:39 -03:00
|
|
|
}
|
|
|
|
|
2024-06-25 17:06:37 -03:00
|
|
|
comptr<ID3D11Resource> resource = nullptr;
|
2024-11-16 12:15:40 -03:00
|
|
|
hr = Implementation->Texture2D->QueryInterface(IID_ID3D11Resource, (void**)resource.GetAddressOf());
|
2024-05-04 21:07:39 -03:00
|
|
|
|
2024-08-05 16:12:53 -03:00
|
|
|
if FAILED(hr)
|
2024-12-02 19:02:51 -03:00
|
|
|
throw csharp::InvalidOperationException();
|
2024-08-05 15:42:56 -03:00
|
|
|
|
2024-08-05 16:12:53 -03:00
|
|
|
//Only initializes if it is a ShaderResource
|
2024-11-16 12:15:40 -03:00
|
|
|
if (Implementation->Description.BindFlags & D3D11_BIND_SHADER_RESOURCE) {
|
2024-11-14 15:25:11 -03:00
|
|
|
hr = deviceImpl->Device->CreateShaderResourceView(
|
2024-08-05 16:12:53 -03:00
|
|
|
resource.Get(),
|
2024-11-16 12:15:40 -03:00
|
|
|
&Implementation->ShaderDescription,
|
|
|
|
Implementation->ShaderResource.ReleaseAndGetAddressOf());
|
2024-05-04 21:07:39 -03:00
|
|
|
|
2024-08-05 16:12:53 -03:00
|
|
|
if FAILED(hr)
|
2024-12-02 19:02:51 -03:00
|
|
|
throw csharp::InvalidOperationException();
|
2024-08-05 16:12:53 -03:00
|
|
|
|
2024-08-05 15:42:56 -03:00
|
|
|
}
|
2024-05-04 21:07:39 -03:00
|
|
|
|
2024-11-16 12:15:40 -03:00
|
|
|
surfaceFormat = DxHelpers::SurfaceFormatToXna(Implementation->Description.Format);
|
|
|
|
levelCount = static_cast<Int>(Implementation->ShaderDescription.Texture2D.MipLevels);
|
|
|
|
width = static_cast<Int>(Implementation->Description.Width);
|
|
|
|
height = static_cast<Int>(Implementation->Description.Height);
|
2024-08-05 15:42:56 -03:00
|
|
|
}
|
2024-05-05 15:50:17 -03:00
|
|
|
|
2024-06-22 11:02:01 -03:00
|
|
|
void Texture2D::SetData(std::vector<Uint> const& data, size_t startIndex, size_t elementCount)
|
2024-05-05 15:50:17 -03:00
|
|
|
{
|
2024-11-16 12:15:40 -03:00
|
|
|
if (!Implementation || !BaseGraphicsDevice || !BaseGraphicsDevice->Implementation->Device || !BaseGraphicsDevice->Implementation->Context) {
|
2024-12-02 19:02:51 -03:00
|
|
|
throw csharp::InvalidOperationException();
|
2024-05-05 15:50:17 -03:00
|
|
|
}
|
|
|
|
|
2024-11-16 12:15:40 -03:00
|
|
|
auto hr = Implementation->SetData(*BaseGraphicsDevice, data.data());
|
|
|
|
|
|
|
|
if (FAILED(hr))
|
2024-12-02 19:02:51 -03:00
|
|
|
throw csharp::InvalidOperationException();
|
2024-05-05 15:50:17 -03:00
|
|
|
}
|
|
|
|
|
2024-06-22 11:02:01 -03:00
|
|
|
void Texture2D::SetData(std::vector<Byte> const& data, size_t startIndex, size_t elementCount)
|
2024-05-05 15:50:17 -03:00
|
|
|
{
|
2024-11-14 21:44:46 -03:00
|
|
|
if (!BaseGraphicsDevice || !BaseGraphicsDevice->Implementation->Device || !BaseGraphicsDevice->Implementation->Context) {
|
2024-12-02 19:02:51 -03:00
|
|
|
throw csharp::InvalidOperationException();
|
2024-05-05 15:50:17 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<UINT> finalData(elementCount / 4);
|
|
|
|
auto fIndex = 0;
|
|
|
|
|
|
|
|
for (size_t i = startIndex; i < elementCount; ++i) {
|
|
|
|
const auto& r = data[i];
|
|
|
|
const auto& g = data[++i];
|
|
|
|
const auto& b = data[++i];
|
|
|
|
const auto& a = data[++i];
|
|
|
|
finalData[fIndex] = Color(r, g, b, a);
|
|
|
|
++fIndex;
|
|
|
|
}
|
|
|
|
|
2024-11-16 12:15:40 -03:00
|
|
|
auto hr = Implementation->SetData(*BaseGraphicsDevice, finalData.data());
|
|
|
|
|
|
|
|
if (FAILED(hr))
|
2024-12-02 19:02:51 -03:00
|
|
|
throw csharp::InvalidOperationException();
|
2024-08-03 12:32:30 -03:00
|
|
|
}
|
2024-05-05 15:50:17 -03:00
|
|
|
|
2024-06-22 11:02:01 -03:00
|
|
|
void Texture2D::SetData(Int level, Rectangle* rect, std::vector<Byte> const& data, size_t startIndex, size_t elementCount)
|
2024-05-05 15:50:17 -03:00
|
|
|
{
|
2024-11-14 21:44:46 -03:00
|
|
|
if (!BaseGraphicsDevice || !BaseGraphicsDevice->Implementation->Device || !BaseGraphicsDevice->Implementation->Context) {
|
2024-12-02 19:02:51 -03:00
|
|
|
throw csharp::InvalidOperationException();
|
2024-05-05 15:50:17 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<UINT> finalData(elementCount / 4);
|
|
|
|
auto fIndex = 0;
|
|
|
|
|
|
|
|
for (size_t i = startIndex; i < elementCount; ++i) {
|
|
|
|
const auto& r = data[i];
|
|
|
|
const auto& g = data[++i];
|
|
|
|
const auto& b = data[++i];
|
|
|
|
const auto& a = data[++i];
|
|
|
|
finalData[fIndex] = Color(r, g, b, a);
|
|
|
|
++fIndex;
|
|
|
|
}
|
|
|
|
|
2024-11-16 12:15:40 -03:00
|
|
|
if (!Implementation->Texture2D) {
|
|
|
|
auto hr = BaseGraphicsDevice->Implementation->Device->CreateTexture2D(&Implementation->Description, nullptr, Implementation->Texture2D.GetAddressOf());
|
2024-05-05 15:50:17 -03:00
|
|
|
|
|
|
|
if (FAILED(hr)) {
|
2024-12-02 19:02:51 -03:00
|
|
|
throw csharp::InvalidOperationException();
|
2024-05-05 15:50:17 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-25 17:06:37 -03:00
|
|
|
comptr<ID3D11Resource> resource = nullptr;
|
2024-11-16 12:15:40 -03:00
|
|
|
auto hr = Implementation->Texture2D->QueryInterface(IID_ID3D11Resource, (void**)resource.GetAddressOf());
|
2024-05-05 15:50:17 -03:00
|
|
|
|
|
|
|
if (FAILED(hr)) {
|
2024-12-02 19:02:51 -03:00
|
|
|
throw csharp::InvalidOperationException();
|
2024-05-05 15:50:17 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
D3D11_BOX box{};
|
|
|
|
|
|
|
|
if (rect) {
|
2024-06-25 17:06:37 -03:00
|
|
|
box.left = rect->Left();
|
|
|
|
box.right = rect->Right();
|
|
|
|
box.top = rect->Top();
|
|
|
|
box.bottom = rect->Bottom();
|
2024-05-05 15:50:17 -03:00
|
|
|
box.back = level;
|
|
|
|
box.front = 0;
|
|
|
|
}
|
|
|
|
|
2024-05-23 14:38:16 -03:00
|
|
|
constexpr int R8G8B8A8U_BYTE_SIZE = 4;
|
2024-11-16 12:15:40 -03:00
|
|
|
BaseGraphicsDevice->Implementation->Context->UpdateSubresource(resource.Get(), 0, rect ? &box : nullptr, finalData.data(), Implementation->Description.Width * R8G8B8A8U_BYTE_SIZE, 0);
|
2024-05-05 15:50:17 -03:00
|
|
|
|
2024-11-16 12:15:40 -03:00
|
|
|
Implementation->ShaderDescription.Format = Implementation->Description.Format;
|
|
|
|
Implementation->ShaderDescription.Texture2D.MipLevels = Implementation->Description.MipLevels;
|
|
|
|
hr = BaseGraphicsDevice->Implementation->Device->CreateShaderResourceView(resource.Get(), &Implementation->ShaderDescription, Implementation->ShaderResource.ReleaseAndGetAddressOf());
|
2024-05-05 15:50:17 -03:00
|
|
|
|
|
|
|
if (FAILED(hr)) {
|
2024-12-02 19:02:51 -03:00
|
|
|
throw csharp::InvalidOperationException();
|
2024-05-05 15:50:17 -03:00
|
|
|
}
|
|
|
|
|
2024-11-16 12:15:40 -03:00
|
|
|
Implementation->Texture2D->GetDesc(&Implementation->Description);
|
2024-05-05 15:50:17 -03:00
|
|
|
}
|
|
|
|
|
2024-06-22 11:02:01 -03:00
|
|
|
void Texture2D::SetData(std::vector<Color> const& data, size_t startIndex, size_t elementCount)
|
2024-05-05 15:50:17 -03:00
|
|
|
{
|
2024-11-14 21:44:46 -03:00
|
|
|
if (!BaseGraphicsDevice || !BaseGraphicsDevice->Implementation->Device || !BaseGraphicsDevice->Implementation->Context) {
|
2024-12-02 19:02:51 -03:00
|
|
|
throw csharp::InvalidOperationException();
|
2024-05-05 15:50:17 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<UINT> finalData(elementCount);
|
|
|
|
auto finalDataIndex = 0;
|
|
|
|
|
|
|
|
for (size_t i = startIndex; i < elementCount; ++i) {
|
|
|
|
finalData[finalDataIndex] = static_cast<UINT>(data[i]);
|
|
|
|
++finalDataIndex;
|
|
|
|
}
|
|
|
|
|
2024-11-16 12:15:40 -03:00
|
|
|
auto hr = Implementation->SetData(*BaseGraphicsDevice, finalData.data());
|
|
|
|
|
|
|
|
if (FAILED(hr))
|
2024-12-02 19:02:51 -03:00
|
|
|
throw csharp::InvalidOperationException();
|
2024-05-05 15:50:17 -03:00
|
|
|
}
|
|
|
|
|
2024-12-13 17:28:46 -03:00
|
|
|
P_Texture2D Texture2D::FromStream(GraphicsDevice& device, csharp::Stream& stream)
|
2024-08-03 12:32:30 -03:00
|
|
|
{
|
|
|
|
std::vector<Byte> data;
|
2024-12-13 17:28:46 -03:00
|
|
|
const auto lenght = stream.Length();
|
|
|
|
stream.Read(data.data(), data.size(), 0, lenght - 1);
|
2024-08-03 12:32:30 -03:00
|
|
|
|
|
|
|
return FromStream(device, data);
|
|
|
|
}
|
|
|
|
|
2024-12-13 17:28:46 -03:00
|
|
|
sptr<Texture2D> Texture2D::FromStream(GraphicsDevice& device, std::string const& fileName)
|
2024-08-03 12:32:30 -03:00
|
|
|
{
|
|
|
|
auto _this = device.shared_from_this();
|
|
|
|
auto texture2d = snew<Texture2D>(_this);
|
|
|
|
comptr<ID3D11Resource> resource = nullptr;
|
2024-12-02 14:42:09 -03:00
|
|
|
auto wstr = misc::ToWString(fileName);
|
2024-08-03 12:32:30 -03:00
|
|
|
|
|
|
|
HRESULT result = DirectX::CreateWICTextureFromFile(
|
2024-11-14 15:25:11 -03:00
|
|
|
device.Implementation->Device.Get(),
|
|
|
|
device.Implementation->Context.Get(),
|
2024-08-03 12:32:30 -03:00
|
|
|
wstr.c_str(),
|
|
|
|
resource.GetAddressOf(),
|
2024-11-16 12:15:40 -03:00
|
|
|
texture2d->Implementation->ShaderResource.ReleaseAndGetAddressOf(),
|
2024-08-03 12:32:30 -03:00
|
|
|
0U);
|
|
|
|
|
|
|
|
if (FAILED(result)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2024-11-16 12:15:40 -03:00
|
|
|
result = resource->QueryInterface(IID_ID3D11Texture2D, (void**)texture2d->Implementation->Texture2D.ReleaseAndGetAddressOf());
|
2024-08-03 12:32:30 -03:00
|
|
|
|
|
|
|
if (FAILED(result)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
D3D11_TEXTURE2D_DESC desc;
|
2024-11-16 12:15:40 -03:00
|
|
|
texture2d->Implementation->Texture2D->GetDesc(&desc);
|
|
|
|
texture2d->Implementation->Description = desc;
|
2024-08-03 12:32:30 -03:00
|
|
|
|
|
|
|
return texture2d;
|
|
|
|
}
|
|
|
|
|
|
|
|
sptr<Texture2D> Texture2D::FromStream(GraphicsDevice& device, std::vector<Byte> const& data)
|
2024-05-05 15:50:17 -03:00
|
|
|
{
|
2024-05-06 15:57:09 -03:00
|
|
|
auto _this = device.shared_from_this();
|
2024-06-22 11:52:21 -03:00
|
|
|
auto texture2d = snew<Texture2D>(_this);
|
2024-06-25 17:06:37 -03:00
|
|
|
comptr<ID3D11Resource> resource = nullptr;
|
2024-05-05 15:50:17 -03:00
|
|
|
|
|
|
|
auto hr = DirectX::CreateWICTextureFromMemory(
|
2024-11-14 15:25:11 -03:00
|
|
|
device.Implementation->Device.Get(),
|
|
|
|
device.Implementation->Context.Get(),
|
2024-05-05 15:50:17 -03:00
|
|
|
data.data(),
|
|
|
|
data.size(),
|
2024-06-25 17:06:37 -03:00
|
|
|
resource.GetAddressOf(),
|
2024-11-16 12:15:40 -03:00
|
|
|
texture2d->Implementation->ShaderResource.ReleaseAndGetAddressOf());
|
2024-05-05 15:50:17 -03:00
|
|
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2024-11-16 12:15:40 -03:00
|
|
|
hr = resource->QueryInterface(IID_ID3D11Texture2D, (void**)texture2d->Implementation->Texture2D.ReleaseAndGetAddressOf());
|
2024-05-05 15:50:17 -03:00
|
|
|
|
|
|
|
if (FAILED(hr)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
D3D11_TEXTURE2D_DESC desc;
|
2024-11-16 12:15:40 -03:00
|
|
|
texture2d->Implementation->Texture2D->GetDesc(&desc);
|
|
|
|
texture2d->Implementation->Description = desc;
|
2024-05-05 15:50:17 -03:00
|
|
|
|
|
|
|
return texture2d;
|
2024-11-16 12:15:40 -03:00
|
|
|
}
|
2024-03-18 15:41:46 -03:00
|
|
|
}
|