#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 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 t(new Texture()); m_texMap[format&TEXTURE_DEBUG_MASK].insert(std::pair>(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 t(new Texture()); m_texMap[format&TEXTURE_DEBUG_MASK].insert(std::pair>(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