mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-23 22:25:41 +00:00
105 lines
2.4 KiB
C++
105 lines
2.4 KiB
C++
|
#include "TextureSheet.h"
|
||
|
|
||
|
namespace New3D {
|
||
|
|
||
|
TextureSheet::TextureSheet()
|
||
|
{
|
||
|
m_temp.resize(512 * 512 * 4); // temporay buffer for textures
|
||
|
}
|
||
|
|
||
|
int TextureSheet::ToIndex(int x, int y)
|
||
|
{
|
||
|
return (y * 2048) + x;
|
||
|
}
|
||
|
|
||
|
std::shared_ptr<Texture> TextureSheet::BindTexture(const UINT16* src, int format, bool mirrorU, bool mirrorV, int x, int y, int width, int height)
|
||
|
{
|
||
|
//========
|
||
|
int index;
|
||
|
//========
|
||
|
|
||
|
x &= 2047;
|
||
|
y &= 2047;
|
||
|
|
||
|
if ((x + width) > 2048 || (y + height) > 2048) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (width > 512 || height > 512) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
index = ToIndex(x, y);
|
||
|
|
||
|
if (m_texMap[format&TEXTURE_DEBUG_MASK].count(index) == 0) {
|
||
|
|
||
|
//no textures at this position or format so add it to the map
|
||
|
|
||
|
std::shared_ptr<Texture> t(new Texture());
|
||
|
m_texMap[format&TEXTURE_DEBUG_MASK].insert(std::pair<int, std::shared_ptr<Texture>>(index, t));
|
||
|
t->UploadTexture(src, m_temp.data(), format, mirrorU, mirrorV, x, y, width, height);
|
||
|
return t;
|
||
|
}
|
||
|
else {
|
||
|
//scan for duplicates
|
||
|
//only texture width/height and wrap modes can change here. Since key is based on x/y pos, and each map is a separate format
|
||
|
|
||
|
auto range = m_texMap[format&TEXTURE_DEBUG_MASK].equal_range(index);
|
||
|
|
||
|
for (auto it = range.first; it != range.second; ++it) {
|
||
|
|
||
|
int x2, y2, width2, height2, format2;
|
||
|
|
||
|
it->second->GetDetails(x2, y2, width2, height2, format2);
|
||
|
|
||
|
if (width == width2 && height == height2) {
|
||
|
return it->second;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
std::shared_ptr<Texture> t(new Texture());
|
||
|
m_texMap[format&TEXTURE_DEBUG_MASK].insert(std::pair<int, std::shared_ptr<Texture>>(index, t));
|
||
|
t->UploadTexture(src, m_temp.data(), format, mirrorU, mirrorV, x, y, width, height);
|
||
|
|
||
|
return t;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void TextureSheet::Release()
|
||
|
{
|
||
|
for (int i = 0; i < 8; i++) {
|
||
|
m_texMap[i].clear();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void TextureSheet::Invalidate(int x, int y, int width, int height)
|
||
|
{
|
||
|
//==========
|
||
|
int count;
|
||
|
int sWidth; // sample width
|
||
|
int sHeight; // sample height
|
||
|
//==========
|
||
|
|
||
|
// since the smallest sized texture is 32x32 pixels?
|
||
|
// we can invalidate 32x32 tiles over the width/height of the area
|
||
|
|
||
|
sWidth = width / 32;
|
||
|
sHeight = height / 32;
|
||
|
count = sWidth * sHeight;
|
||
|
|
||
|
for (int i = 0; i < count; i++) {
|
||
|
|
||
|
int index = ToIndex(x + ((i%sWidth) * 32), y + ((i / sWidth) * 32));
|
||
|
|
||
|
for (int j = 0; j<8; j++) {
|
||
|
|
||
|
if (m_texMap[j].count(index) > 0) {
|
||
|
|
||
|
m_texMap[j].erase(index);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} // New3D
|