|
|
|
@ -14,6 +14,7 @@ TextureLoader::TextureLoader(const std::string name) :
|
|
|
|
|
state(TextureLoaderLoadState::INITIAL)
|
|
|
|
|
{
|
|
|
|
|
sharedTexture = std::make_shared<Texture>();
|
|
|
|
|
weakTexture = sharedTexture;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TextureLoader::updateAsync() {
|
|
|
|
@ -23,23 +24,124 @@ void TextureLoader::updateAsync() {
|
|
|
|
|
|
|
|
|
|
// Read in the header.
|
|
|
|
|
uint8_t buffer[TEXTURE_LOADER_HEADER_SIZE];
|
|
|
|
|
this->loader.read(buffer, TEXTURE_LOADER_HEADER_SIZE);
|
|
|
|
|
size_t pos = 0;
|
|
|
|
|
|
|
|
|
|
// Read Version
|
|
|
|
|
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
|
|
|
|
|
std::string version = std::string((char*)buffer, pos);
|
|
|
|
|
std::string version = std::string((char*)buffer);
|
|
|
|
|
assertTrue(version == "DT_2.00", "Invalid Texture Version!");
|
|
|
|
|
|
|
|
|
|
// Read Texture Width
|
|
|
|
|
this->loader.setPosition(pos);
|
|
|
|
|
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
|
|
|
|
|
width = std::stoi(std::string((char*)buffer));
|
|
|
|
|
assertTrue(width > 0, "Invalid Texture Width!");
|
|
|
|
|
|
|
|
|
|
// Read Texture Height
|
|
|
|
|
this->loader.setPosition(pos);
|
|
|
|
|
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
|
|
|
|
|
height = std::stoi(std::string((char*)buffer));
|
|
|
|
|
assertTrue(height > 0, "Invalid Texture Height!");
|
|
|
|
|
|
|
|
|
|
// Texture Format (RGBA, RGB, etc)
|
|
|
|
|
this->loader.setPosition(pos);
|
|
|
|
|
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
|
|
|
|
|
int32_t iFormat = std::stoi(std::string((char*)buffer));
|
|
|
|
|
switch(iFormat) {
|
|
|
|
|
case 1: format = TextureFormat::R; break;
|
|
|
|
|
case 2: format = TextureFormat::RG; break;
|
|
|
|
|
case 3: format = TextureFormat::RGB; break;
|
|
|
|
|
case 4: format = TextureFormat::RGBA; break;
|
|
|
|
|
default: assertUnreachable("Invalid Texture Format %i!", iFormat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Wrap X
|
|
|
|
|
this->loader.setPosition(pos);
|
|
|
|
|
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
|
|
|
|
|
int32_t iWrapX = std::stoi(std::string((char*)buffer));
|
|
|
|
|
switch(iWrapX) {
|
|
|
|
|
case 0: wrapX = TextureWrapMode::REPEAT; break;
|
|
|
|
|
case 1: wrapX = TextureWrapMode::MIRRORED_REPEAT; break;
|
|
|
|
|
case 2: wrapX = TextureWrapMode::CLAMP_TO_EDGE; break;
|
|
|
|
|
case 3: wrapX = TextureWrapMode::CLAMP_TO_BORDER; break;
|
|
|
|
|
default: assertUnreachable("Invalid Texture Wrap X %i!", iWrapX);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Wrap Y
|
|
|
|
|
this->loader.setPosition(pos);
|
|
|
|
|
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
|
|
|
|
|
int32_t iWrapY = std::stoi(std::string((char*)buffer));
|
|
|
|
|
switch(iWrapY) {
|
|
|
|
|
case 0: wrapY = TextureWrapMode::REPEAT; break;
|
|
|
|
|
case 1: wrapY = TextureWrapMode::MIRRORED_REPEAT; break;
|
|
|
|
|
case 2: wrapY = TextureWrapMode::CLAMP_TO_EDGE; break;
|
|
|
|
|
case 3: wrapY = TextureWrapMode::CLAMP_TO_BORDER; break;
|
|
|
|
|
default: assertUnreachable("Invalid Texture Wrap Y %i!", iWrapY);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Filter Min
|
|
|
|
|
this->loader.setPosition(pos);
|
|
|
|
|
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
|
|
|
|
|
int32_t iFilterMin = std::stoi(std::string((char*)buffer));
|
|
|
|
|
switch(iFilterMin) {
|
|
|
|
|
case 0: filterMin = TextureFilterMode::NEAREST; break;
|
|
|
|
|
case 1: filterMin = TextureFilterMode::LINEAR; break;
|
|
|
|
|
default: assertUnreachable("Invalid Texture Filter Min %i!", iFilterMin);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Filter Mag
|
|
|
|
|
this->loader.setPosition(pos);
|
|
|
|
|
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
|
|
|
|
|
int32_t iFilterMag = std::stoi(std::string((char*)buffer));
|
|
|
|
|
switch(iFilterMag) {
|
|
|
|
|
case 0: filterMag = TextureFilterMode::NEAREST; break;
|
|
|
|
|
case 1: filterMag = TextureFilterMode::LINEAR; break;
|
|
|
|
|
default: assertUnreachable("Invalid Texture Filter Mag %i!", iFilterMag);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Data begins here. This part is done synchronously directly to the GPU.
|
|
|
|
|
this->loader.setPosition(pos);
|
|
|
|
|
size_t bufferSize = width * height * iFormat;
|
|
|
|
|
data = new uint8_t[bufferSize];
|
|
|
|
|
assertNotNull(data, "Failed to allocate texture data!");
|
|
|
|
|
this->loader.read(data, bufferSize);
|
|
|
|
|
|
|
|
|
|
// Handoff to sync to buffer to GPU.
|
|
|
|
|
this->state = TextureLoaderLoadState::ASYNC_DONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TextureLoader::updateSync() {
|
|
|
|
|
if(this->state != TextureLoaderLoadState::ASYNC_DONE) return;
|
|
|
|
|
this->state = TextureLoaderLoadState::SYNC_LOADING;
|
|
|
|
|
|
|
|
|
|
assertNotNull(this->sharedTexture, "Texture is null!");
|
|
|
|
|
assertNotNull(this->data, "Texture data is null!");
|
|
|
|
|
|
|
|
|
|
// Setup Texture
|
|
|
|
|
this->sharedTexture->setSize(
|
|
|
|
|
this->width,
|
|
|
|
|
this->height,
|
|
|
|
|
this->format,
|
|
|
|
|
TextureDataFormat::UNSIGNED_BYTE
|
|
|
|
|
);
|
|
|
|
|
this->sharedTexture->buffer(this->data);
|
|
|
|
|
|
|
|
|
|
// Free data buffer
|
|
|
|
|
delete[] this->data;
|
|
|
|
|
this->data = nullptr;
|
|
|
|
|
|
|
|
|
|
// Leat go of the held pointer
|
|
|
|
|
this->sharedTexture = nullptr;
|
|
|
|
|
|
|
|
|
|
// Hand off and call done
|
|
|
|
|
this->state = TextureLoaderLoadState::SYNC_DONE;
|
|
|
|
|
this->loaded = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TextureLoader::~TextureLoader() {
|
|
|
|
|
if(this->data != nullptr) {
|
|
|
|
|
delete[] this->data;
|
|
|
|
|
this->data = nullptr;
|
|
|
|
|
}
|
|
|
|
|
this->sharedTexture = nullptr;
|
|
|
|
|
}
|