Files
GP1-DirectX/project/src/Texture.cpp
2025-01-13 17:12:23 +01:00

74 lines
2.5 KiB
C++

#include <algorithm>
#include "Texture.h"
Texture::~Texture() {
m_TextureResourceViewPtr->Release();
m_TexturePtr->Release();
}
Texture *Texture::LoadFromFile(const std::string &path, ID3D11Device *devicePtr) {
SDL_Surface *surface = IMG_Load(path.c_str());
if (!surface) {
std::cerr << "Failed to load texture: " << path << std::endl;
return nullptr;
}
if (surface->format->BytesPerPixel != 4)
{
std::cerr << "Texture::LoadFromFile > Texture is not in the right format: " << path << std::endl;
// throw std::runtime_error("Texture is not in the right format");
}
auto *texture = new Texture(surface, devicePtr);
return texture;
}
Texture::Texture(SDL_Surface *surfacePtr, ID3D11Device *devicePtr) {
DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM;
D3D11_TEXTURE2D_DESC desc{};
desc.Width = surfacePtr->w;
desc.Height = surfacePtr->h;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = format;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA initData;
initData.pSysMem = surfacePtr->pixels;
initData.SysMemPitch = static_cast<UINT>(surfacePtr->pitch);
initData.SysMemSlicePitch = static_cast<UINT>(surfacePtr->h * surfacePtr->pitch);
HRESULT hr = devicePtr->CreateTexture2D(&desc, &initData, &m_TexturePtr);
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc{};
SRVDesc.Format = format;
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
SRVDesc.Texture2D.MipLevels = 1;
hr = devicePtr->CreateShaderResourceView(m_TexturePtr, &SRVDesc, &m_TextureResourceViewPtr);
m_SurfacePtr = surfacePtr;
m_pSurfacePixels = static_cast<Uint32 *>(surfacePtr->pixels);
}
ColorRGB Texture::Sample(const Vector2 &uv) const {
Uint8 red, green, blue;
Vector2 wrapped = {fmod(uv.x, 1.0f), fmod(uv.y, 1.0f)};
if (wrapped.x < 0.0f) wrapped.x += 1.0f;
if (wrapped.y < 0.0f) wrapped.y += 1.0f;
SDL_GetRGB(m_pSurfacePixels[
static_cast<int>(wrapped.x * static_cast<float>(m_SurfacePtr->w - 1)) +
static_cast<int>(wrapped.y * static_cast<float>(m_SurfacePtr->h - 1)) * (m_SurfacePtr->w)
], m_SurfacePtr->format, &red, &green, &blue);
return ColorRGB{static_cast<float>(red) / 255.0f, static_cast<float>(green) / 255.0f, static_cast<float>(blue) / 255.0f};
}