mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-07 03:12:36 +01:00
Merge pull request #254 from danhedron/texture-slots
Load textures into separate groups
This commit is contained in:
commit
04e79a5117
@ -5,7 +5,6 @@
|
|||||||
#include <engine/GameState.hpp>
|
#include <engine/GameState.hpp>
|
||||||
#include <engine/GameWorld.hpp>
|
#include <engine/GameWorld.hpp>
|
||||||
#include <loaders/LoaderCOL.hpp>
|
#include <loaders/LoaderCOL.hpp>
|
||||||
#include <loaders/LoaderDFF.hpp>
|
|
||||||
#include <loaders/LoaderIDE.hpp>
|
#include <loaders/LoaderIDE.hpp>
|
||||||
#include <loaders/LoaderIPL.hpp>
|
#include <loaders/LoaderIPL.hpp>
|
||||||
#include <script/SCMFile.hpp>
|
#include <script/SCMFile.hpp>
|
||||||
@ -23,6 +22,10 @@
|
|||||||
|
|
||||||
GameData::GameData(Logger* log, const std::string& path)
|
GameData::GameData(Logger* log, const std::string& path)
|
||||||
: datpath(path), logger(log), engine(nullptr) {
|
: datpath(path), logger(log), engine(nullptr) {
|
||||||
|
dffLoader.setTextureLookupCallback(
|
||||||
|
[&](const std::string& texture, const std::string&) {
|
||||||
|
return findSlotTexture(currenttextureslot, texture);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
GameData::~GameData() {
|
GameData::~GameData() {
|
||||||
@ -37,13 +40,13 @@ void GameData::load() {
|
|||||||
/// @todo cuts.img files should be loaded differently to gta3.img
|
/// @todo cuts.img files should be loaded differently to gta3.img
|
||||||
loadIMG("anim/cuts.img");
|
loadIMG("anim/cuts.img");
|
||||||
|
|
||||||
loadLevelFile("data/default.dat");
|
textureslots["particle"] = loadTextureArchive("particle.txd");
|
||||||
loadLevelFile("data/gta3.dat");
|
textureslots["icons"] = loadTextureArchive("icons.txd");
|
||||||
|
textureslots["hud"] = loadTextureArchive("hud.txd");
|
||||||
loadTXD("particle.txd");
|
textureslots["fonts"] = loadTextureArchive("fonts.txd");
|
||||||
loadTXD("icons.txd");
|
textureslots["generic"] = loadTextureArchive("generic.txd");
|
||||||
loadTXD("hud.txd");
|
auto misc = loadTextureArchive("misc.txd");
|
||||||
loadTXD("fonts.txd");
|
textureslots["generic"].insert(misc.begin(), misc.end());
|
||||||
|
|
||||||
loadCarcols("data/carcols.dat");
|
loadCarcols("data/carcols.dat");
|
||||||
loadWeather("data/timecyc.dat");
|
loadWeather("data/timecyc.dat");
|
||||||
@ -52,6 +55,9 @@ void GameData::load() {
|
|||||||
loadWeaponDAT("data/weapon.dat");
|
loadWeaponDAT("data/weapon.dat");
|
||||||
|
|
||||||
loadIFP("ped.ifp");
|
loadIFP("ped.ifp");
|
||||||
|
|
||||||
|
loadLevelFile("data/default.dat");
|
||||||
|
loadLevelFile("data/gta3.dat");
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameData::loadLevelFile(const std::string& path) {
|
void GameData::loadLevelFile(const std::string& path) {
|
||||||
@ -63,6 +69,9 @@ void GameData::loadLevelFile(const std::string& path) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset texture slot
|
||||||
|
currenttextureslot = "generic";
|
||||||
|
|
||||||
for (std::string line, cmd; std::getline(datfile, line);) {
|
for (std::string line, cmd; std::getline(datfile, line);) {
|
||||||
if (line.size() == 0 || line[0] == '#') continue;
|
if (line.size() == 0 || line[0] == '#') continue;
|
||||||
#ifndef RW_WINDOWS
|
#ifndef RW_WINDOWS
|
||||||
@ -296,23 +305,41 @@ void GameData::loadWater(const std::string& path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GameData::loadTXD(const std::string& name) {
|
void GameData::loadTXD(const std::string& name) {
|
||||||
if (loadedFiles.find(name) != loadedFiles.end()) {
|
auto slot = name;
|
||||||
|
auto ext = name.find(".txd");
|
||||||
|
if (ext != std::string::npos) {
|
||||||
|
slot = name.substr(0, ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the current texture slot
|
||||||
|
currenttextureslot = slot;
|
||||||
|
|
||||||
|
// Check if this texture slot is loaded already
|
||||||
|
auto slotit = textureslots.find(slot);
|
||||||
|
if (slotit != textureslots.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadedFiles[name] = true;
|
textureslots[slot] = std::move(loadTextureArchive(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureArchive GameData::loadTextureArchive(const std::string& name) {
|
||||||
/// @todo refactor loadTXD to use correct file locations
|
/// @todo refactor loadTXD to use correct file locations
|
||||||
auto file = index.openFile(name);
|
auto file = index.openFile(name);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
logger->error("Data", "Failed to open txd: " + name);
|
logger->error("Data", "Failed to open txd: " + name);
|
||||||
return;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextureArchive textures;
|
||||||
|
|
||||||
TextureLoader l;
|
TextureLoader l;
|
||||||
if (!l.loadFromMemory(file, textures)) {
|
if (!l.loadFromMemory(file, textures)) {
|
||||||
logger->error("Data", "Error loading txd: " + name);
|
logger->error("Data", "Error loading txd: " + name);
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return textures;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameData::getNameAndLod(std::string& name, int& lod) {
|
void GameData::getNameAndLod(std::string& name, int& lod) {
|
||||||
@ -329,8 +356,7 @@ Model* GameData::loadClump(const std::string& name) {
|
|||||||
logger->error("Data", "Failed to load model " + name);
|
logger->error("Data", "Failed to load model " + name);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
LoaderDFF l;
|
auto m = dffLoader.loadFromMemory(file);
|
||||||
auto m = l.loadFromMemory(file);
|
|
||||||
if (!m) {
|
if (!m) {
|
||||||
logger->error("Data", "Error loading model file " + name);
|
logger->error("Data", "Error loading model file " + name);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -344,8 +370,7 @@ void GameData::loadModelFile(const std::string& name) {
|
|||||||
logger->log("Data", Logger::Error, "Failed to load model file " + name);
|
logger->log("Data", Logger::Error, "Failed to load model file " + name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LoaderDFF l;
|
auto m = dffLoader.loadFromMemory(file);
|
||||||
auto m = l.loadFromMemory(file);
|
|
||||||
if (!m) {
|
if (!m) {
|
||||||
logger->log("Data", Logger::Error, "Error loading model file " + name);
|
logger->log("Data", Logger::Error, "Error loading model file " + name);
|
||||||
return;
|
return;
|
||||||
@ -374,14 +399,14 @@ void GameData::loadModel(ModelID model) {
|
|||||||
auto info = modelinfo[model].get();
|
auto info = modelinfo[model].get();
|
||||||
/// @todo replace openFile with API for loading from CDIMAGE archives
|
/// @todo replace openFile with API for loading from CDIMAGE archives
|
||||||
auto name = info->name;
|
auto name = info->name;
|
||||||
|
auto slotname = info->textureslot;
|
||||||
|
|
||||||
// Re-direct special models
|
// Re-direct special models
|
||||||
switch (info->type()) {
|
switch (info->type()) {
|
||||||
case ModelDataType::ClumpInfo:
|
case ModelDataType::ClumpInfo:
|
||||||
// Re-direct the hier objects to the special object ids
|
// Re-direct the hier objects to the special object ids
|
||||||
name = engine->state->specialModels[info->id()];
|
name = engine->state->specialModels[info->id()];
|
||||||
/// @todo remove this from here
|
slotname = name;
|
||||||
loadTXD(name + ".txd");
|
|
||||||
break;
|
break;
|
||||||
case ModelDataType::PedInfo:
|
case ModelDataType::PedInfo:
|
||||||
static const std::string specialPrefix("special");
|
static const std::string specialPrefix("special");
|
||||||
@ -389,8 +414,7 @@ void GameData::loadModel(ModelID model) {
|
|||||||
auto sid = name.substr(specialPrefix.size());
|
auto sid = name.substr(specialPrefix.size());
|
||||||
unsigned short specialID = std::atoi(sid.c_str());
|
unsigned short specialID = std::atoi(sid.c_str());
|
||||||
name = engine->state->specialCharacters[specialID];
|
name = engine->state->specialCharacters[specialID];
|
||||||
/// @todo remove this from here
|
slotname = name;
|
||||||
loadTXD(name + ".txd");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -398,14 +422,19 @@ void GameData::loadModel(ModelID model) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
|
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
|
||||||
|
std::transform(slotname.begin(), slotname.end(), slotname.begin(),
|
||||||
|
::tolower);
|
||||||
|
|
||||||
|
/// @todo remove this from here
|
||||||
|
loadTXD(slotname + ".txd");
|
||||||
|
|
||||||
auto file = index.openFile(name + ".dff");
|
auto file = index.openFile(name + ".dff");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
logger->error("Data", "Failed to load model for " +
|
logger->error("Data", "Failed to load model for " +
|
||||||
std::to_string(model) + " [" + name + "]");
|
std::to_string(model) + " [" + name + "]");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LoaderDFF l;
|
auto m = dffLoader.loadFromMemory(file);
|
||||||
auto m = l.loadFromMemory(file);
|
|
||||||
if (!m) {
|
if (!m) {
|
||||||
logger->error("Data",
|
logger->error("Data",
|
||||||
"Error loading model file for " + std::to_string(model));
|
"Error loading model file for " + std::to_string(model));
|
||||||
|
@ -39,8 +39,10 @@ class GameData {
|
|||||||
private:
|
private:
|
||||||
std::string datpath;
|
std::string datpath;
|
||||||
std::string splash;
|
std::string splash;
|
||||||
|
std::string currenttextureslot;
|
||||||
|
|
||||||
Logger* logger;
|
Logger* logger;
|
||||||
|
LoaderDFF dffLoader;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* ctor
|
* ctor
|
||||||
@ -111,10 +113,16 @@ public:
|
|||||||
void loadLevelFile(const std::string& path);
|
void loadLevelFile(const std::string& path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to load a TXD, or does nothing if it has already been loaded
|
* Loads the txt slot if it is not already loaded and sets
|
||||||
|
* the current TXD slot
|
||||||
*/
|
*/
|
||||||
void loadTXD(const std::string& name);
|
void loadTXD(const std::string& name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a named texture archive from the game data
|
||||||
|
*/
|
||||||
|
TextureArchive loadTextureArchive(const std::string& name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts combined {name}_l{LOD} into name and lod.
|
* Converts combined {name}_l{LOD} into name and lod.
|
||||||
*/
|
*/
|
||||||
@ -155,9 +163,17 @@ public:
|
|||||||
|
|
||||||
void loadSplash(const std::string& name);
|
void loadSplash(const std::string& name);
|
||||||
|
|
||||||
TextureData::Handle findTexture(const std::string& name,
|
TextureData::Handle findSlotTexture(const std::string& slot,
|
||||||
const std::string& alpha = "") {
|
const std::string& texture) const {
|
||||||
return textures[{name, alpha}];
|
auto slotit = textureslots.find(slot);
|
||||||
|
if (slotit == textureslots.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto textureit = slotit->second.find(texture);
|
||||||
|
if (textureit == slotit->second.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return textureit->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileIndex index;
|
FileIndex index;
|
||||||
@ -222,9 +238,9 @@ public:
|
|||||||
WeatherLoader weatherLoader;
|
WeatherLoader weatherLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loaded textures (Textures are ID by name and alpha pairs)
|
* Texture slots, containing loaded textures.
|
||||||
*/
|
*/
|
||||||
std::map<std::pair<std::string, std::string>, TextureData::Handle> textures;
|
std::map<std::string, TextureArchive> textureslots;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Texture atlases.
|
* Texture atlases.
|
||||||
|
@ -158,18 +158,6 @@ InstanceObject* GameWorld::createInstance(const uint16_t id,
|
|||||||
data->loadModel(oi->id());
|
data->loadModel(oi->id());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string modelname = oi->name;
|
|
||||||
std::string texturename = oi->textureslot;
|
|
||||||
|
|
||||||
std::transform(std::begin(modelname), std::end(modelname),
|
|
||||||
std::begin(modelname), tolower);
|
|
||||||
std::transform(std::begin(texturename), std::end(texturename),
|
|
||||||
std::begin(texturename), tolower);
|
|
||||||
|
|
||||||
if (!texturename.empty()) {
|
|
||||||
data->loadTXD(texturename + ".txd");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for dynamic data.
|
// Check for dynamic data.
|
||||||
auto dyit = data->dynamicObjectData.find(oi->name);
|
auto dyit = data->dynamicObjectData.find(oi->name);
|
||||||
std::shared_ptr<DynamicObjectData> dydata;
|
std::shared_ptr<DynamicObjectData> dydata;
|
||||||
@ -177,7 +165,7 @@ InstanceObject* GameWorld::createInstance(const uint16_t id,
|
|||||||
dydata = dyit->second;
|
dydata = dyit->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modelname.empty()) {
|
if (oi->name.empty()) {
|
||||||
logger->warning(
|
logger->warning(
|
||||||
"World", "Instance with missing model: " + std::to_string(id));
|
"World", "Instance with missing model: " + std::to_string(id));
|
||||||
}
|
}
|
||||||
@ -243,15 +231,12 @@ CutsceneObject* GameWorld::createCutsceneObject(const uint16_t id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto clumpmodel = static_cast<ClumpModelInfo*>(modelinfo);
|
auto clumpmodel = static_cast<ClumpModelInfo*>(modelinfo);
|
||||||
std::string texturename;
|
|
||||||
|
|
||||||
if (!clumpmodel->isLoaded()) {
|
if (!clumpmodel->isLoaded()) {
|
||||||
data->loadModel(id);
|
data->loadModel(id);
|
||||||
}
|
}
|
||||||
auto model = clumpmodel->getModel();
|
auto model = clumpmodel->getModel();
|
||||||
|
|
||||||
texturename = modelinfo->textureslot;
|
|
||||||
|
|
||||||
if (id == 0) {
|
if (id == 0) {
|
||||||
auto playerobj = pedestrianPool.find(state->playerObject);
|
auto playerobj = pedestrianPool.find(state->playerObject);
|
||||||
if (playerobj) {
|
if (playerobj) {
|
||||||
@ -259,10 +244,6 @@ CutsceneObject* GameWorld::createCutsceneObject(const uint16_t id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!texturename.empty()) {
|
|
||||||
data->loadTXD(texturename + ".txd");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto instance = new CutsceneObject(this, pos, rot, model, modelinfo);
|
auto instance = new CutsceneObject(this, pos, rot, model, modelinfo);
|
||||||
|
|
||||||
cutscenePool.insert(instance);
|
cutscenePool.insert(instance);
|
||||||
@ -285,10 +266,6 @@ VehicleObject* GameWorld::createVehicle(const uint16_t id, const glm::vec3& pos,
|
|||||||
data->loadModel(id);
|
data->loadModel(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vti->textureslot.empty()) {
|
|
||||||
data->loadTXD(vti->textureslot + ".txd");
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::u8vec3 prim(255), sec(128);
|
glm::u8vec3 prim(255), sec(128);
|
||||||
auto palit = data->vehiclePalettes.find(
|
auto palit = data->vehiclePalettes.find(
|
||||||
vti->name); // modelname is conveniently lowercase (usually)
|
vti->name); // modelname is conveniently lowercase (usually)
|
||||||
@ -361,12 +338,6 @@ CharacterObject* GameWorld::createPedestrian(const uint16_t id,
|
|||||||
data->loadModel(id);
|
data->loadModel(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string texturename = pt->textureslot;
|
|
||||||
|
|
||||||
if (!texturename.empty()) {
|
|
||||||
data->loadTXD(texturename + ".txd");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ped = new CharacterObject(this, pos, rot, pt);
|
auto ped = new CharacterObject(this, pos, rot, pt);
|
||||||
ped->setGameObjectID(gid);
|
ped->setGameObjectID(gid);
|
||||||
new DefaultAIController(ped);
|
new DefaultAIController(ped);
|
||||||
@ -388,13 +359,12 @@ CharacterObject* GameWorld::createPlayer(const glm::vec3& pos,
|
|||||||
std::string modelname = "player";
|
std::string modelname = "player";
|
||||||
std::string texturename = "player";
|
std::string texturename = "player";
|
||||||
|
|
||||||
|
data->loadTXD(texturename + ".txd");
|
||||||
if (!pt->isLoaded()) {
|
if (!pt->isLoaded()) {
|
||||||
auto model = data->loadClump(modelname + ".dff");
|
auto model = data->loadClump(modelname + ".dff");
|
||||||
pt->setModel(model);
|
pt->setModel(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->loadTXD(texturename + ".txd");
|
|
||||||
|
|
||||||
auto ped = new CharacterObject(this, pos, rot, pt);
|
auto ped = new CharacterObject(this, pos, rot, pt);
|
||||||
ped->setGameObjectID(gid);
|
ped->setGameObjectID(gid);
|
||||||
ped->setLifetime(GameObject::PlayerLifetime);
|
ped->setLifetime(GameObject::PlayerLifetime);
|
||||||
@ -416,8 +386,6 @@ PickupObject* GameWorld::createPickup(const glm::vec3& pos, int id, int type) {
|
|||||||
data->loadModel(id);
|
data->loadModel(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->loadTXD(modelInfo->textureslot + ".txd");
|
|
||||||
|
|
||||||
PickupObject* pickup = nullptr;
|
PickupObject* pickup = nullptr;
|
||||||
auto pickuptype = (PickupObject::PickupType)type;
|
auto pickuptype = (PickupObject::PickupType)type;
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ PickupObject::PickupObject(GameWorld* world, const glm::vec3& position,
|
|||||||
m_corona->particle.direction = glm::vec3(0.f, 0.f, 1.f);
|
m_corona->particle.direction = glm::vec3(0.f, 0.f, 1.f);
|
||||||
m_corona->particle.orientation = VisualFX::ParticleData::Camera;
|
m_corona->particle.orientation = VisualFX::ParticleData::Camera;
|
||||||
m_corona->particle.colour = glm::vec4(1.0f, 0.3f, 0.3f, 0.3f);
|
m_corona->particle.colour = glm::vec4(1.0f, 0.3f, 0.3f, 0.3f);
|
||||||
m_corona->particle.texture = engine->data->findTexture("coronacircle");
|
m_corona->particle.texture = engine->data->findSlotTexture("particle", "coronacircle");
|
||||||
|
|
||||||
auto flags = behaviourFlags(m_type);
|
auto flags = behaviourFlags(m_type);
|
||||||
RW_UNUSED(flags);
|
RW_UNUSED(flags);
|
||||||
|
@ -71,7 +71,7 @@ void ProjectileObject::explode() {
|
|||||||
0.f});
|
0.f});
|
||||||
}
|
}
|
||||||
|
|
||||||
auto tex = engine->data->findTexture("explo02");
|
auto tex = engine->data->findSlotTexture("particle", "explo02");
|
||||||
|
|
||||||
auto explosion = engine->createEffect(VisualFX::Particle);
|
auto explosion = engine->createEffect(VisualFX::Particle);
|
||||||
explosion->particle.size = glm::vec2(exp_size);
|
explosion->particle.size = glm::vec2(exp_size);
|
||||||
|
@ -404,7 +404,7 @@ void GameRenderer::renderWorld(GameWorld* world, const ViewCamera& camera,
|
|||||||
GLuint splashTexName = 0;
|
GLuint splashTexName = 0;
|
||||||
auto fc = world->state->fadeColour;
|
auto fc = world->state->fadeColour;
|
||||||
if ((fc.r + fc.g + fc.b) == 0 && world->state->currentSplash.size() > 0) {
|
if ((fc.r + fc.g + fc.b) == 0 && world->state->currentSplash.size() > 0) {
|
||||||
auto splash = world->data->findTexture(world->state->currentSplash);
|
auto splash = world->data->findSlotTexture("generic", world->state->currentSplash);
|
||||||
if (splash) {
|
if (splash) {
|
||||||
splashTexName = splash->getName();
|
splashTexName = splash->getName();
|
||||||
}
|
}
|
||||||
@ -494,16 +494,6 @@ void GameRenderer::renderGeometry(Model* model, size_t g,
|
|||||||
|
|
||||||
if (mat.textures.size() > 0) {
|
if (mat.textures.size() > 0) {
|
||||||
auto tex = mat.textures[0].texture;
|
auto tex = mat.textures[0].texture;
|
||||||
if (!tex) {
|
|
||||||
auto& tC = mat.textures[0].name;
|
|
||||||
auto& tA = mat.textures[0].alphaName;
|
|
||||||
tex = data->findTexture(tC, tA);
|
|
||||||
if (!tex) {
|
|
||||||
// logger->warning("Renderer", "Missing texture: " + tC
|
|
||||||
// + " " + tA);
|
|
||||||
}
|
|
||||||
mat.textures[0].texture = tex;
|
|
||||||
}
|
|
||||||
if (tex) {
|
if (tex) {
|
||||||
dp.textures = {tex->getName()};
|
dp.textures = {tex->getName()};
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ void MapRenderer::draw(GameWorld* world, const MapInfo& mi) {
|
|||||||
for (int m = 0; m < MAP_BLOCK_SIZE; ++m) {
|
for (int m = 0; m < MAP_BLOCK_SIZE; ++m) {
|
||||||
std::string num = (m < 10 ? "0" : "");
|
std::string num = (m < 10 ? "0" : "");
|
||||||
std::string name = "radar" + num + std::to_string(m);
|
std::string name = "radar" + num + std::to_string(m);
|
||||||
auto texture = world->data->textures[{name, ""}];
|
auto texture = world->data->findSlotTexture(name, name);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture->getName());
|
glBindTexture(GL_TEXTURE_2D, texture->getName());
|
||||||
|
|
||||||
@ -140,7 +140,8 @@ void MapRenderer::draw(GameWorld* world, const MapInfo& mi) {
|
|||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
// We only need the outer ring if we're clipping.
|
// We only need the outer ring if we're clipping.
|
||||||
glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_ONE, GL_ZERO);
|
glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_ONE, GL_ZERO);
|
||||||
TextureData::Handle radarDisc = data->findTexture("radardisc");
|
TextureData::Handle radarDisc =
|
||||||
|
data->findSlotTexture("hud", "radardisc");
|
||||||
|
|
||||||
glm::mat4 model;
|
glm::mat4 model;
|
||||||
model = glm::translate(model, glm::vec3(mi.screenPosition, 0.0f));
|
model = glm::translate(model, glm::vec3(mi.screenPosition, 0.0f));
|
||||||
@ -257,7 +258,7 @@ void MapRenderer::prepareBlip(const glm::vec2& coord, const glm::mat4& view,
|
|||||||
|
|
||||||
GLuint tex = 0;
|
GLuint tex = 0;
|
||||||
if (!texture.empty()) {
|
if (!texture.empty()) {
|
||||||
auto sprite = data->findTexture(texture);
|
auto sprite = data->findSlotTexture("hud", texture);
|
||||||
tex = sprite->getName();
|
tex = sprite->getName();
|
||||||
}
|
}
|
||||||
renderer->setUniform(rectProg, "colour", colour);
|
renderer->setUniform(rectProg, "colour", colour);
|
||||||
|
@ -61,17 +61,6 @@ void ObjectRenderer::renderGeometry(Model* model, size_t g,
|
|||||||
|
|
||||||
if (mat.textures.size() > 0) {
|
if (mat.textures.size() > 0) {
|
||||||
auto tex = mat.textures[0].texture;
|
auto tex = mat.textures[0].texture;
|
||||||
if (!tex) {
|
|
||||||
auto& tC = mat.textures[0].name;
|
|
||||||
auto& tA = mat.textures[0].alphaName;
|
|
||||||
tex = m_world->data->findTexture(tC, tA);
|
|
||||||
if (!tex) {
|
|
||||||
// logger->warning("Renderer", "Missing texture: " + tC
|
|
||||||
// + " " + tA);
|
|
||||||
dp.textures = {m_errorTexture};
|
|
||||||
}
|
|
||||||
mat.textures[0].texture = tex;
|
|
||||||
}
|
|
||||||
if (tex) {
|
if (tex) {
|
||||||
if (tex->isTransparent()) {
|
if (tex->isTransparent()) {
|
||||||
isTransparent = true;
|
isTransparent = true;
|
||||||
|
@ -284,7 +284,7 @@ void TextRenderer::renderText(const TextRenderer::TextInfo& ti,
|
|||||||
Renderer::DrawParameters dp;
|
Renderer::DrawParameters dp;
|
||||||
dp.start = 0;
|
dp.start = 0;
|
||||||
dp.count = gb.getCount();
|
dp.count = gb.getCount();
|
||||||
auto ftexture = renderer->getData()->findTexture(fonts[ti.font]);
|
auto ftexture = renderer->getData()->findSlotTexture("fonts", fonts[ti.font]);
|
||||||
dp.textures = {ftexture->getName()};
|
dp.textures = {ftexture->getName()};
|
||||||
dp.depthWrite = false;
|
dp.depthWrite = false;
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ void WaterRenderer::setDataTexture(GLuint fbBinding, GLuint dataTex) {
|
|||||||
void WaterRenderer::render(GameRenderer* renderer, GameWorld* world) {
|
void WaterRenderer::render(GameRenderer* renderer, GameWorld* world) {
|
||||||
auto r = renderer->getRenderer();
|
auto r = renderer->getRenderer();
|
||||||
|
|
||||||
auto waterTex = world->data->findTexture("water_old");
|
auto waterTex = world->data->findSlotTexture("particle", "water_old");
|
||||||
RW_CHECK(waterTex != nullptr, "Water texture is null");
|
RW_CHECK(waterTex != nullptr, "Water texture is null");
|
||||||
if (waterTex == nullptr) {
|
if (waterTex == nullptr) {
|
||||||
// Can't render water if we don't have a texture.
|
// Can't render water if we don't have a texture.
|
||||||
|
@ -168,7 +168,7 @@ void drawPlayerInfo(PlayerController* player, GameWorld* world,
|
|||||||
}
|
}
|
||||||
|
|
||||||
TextureData::Handle itemTexture =
|
TextureData::Handle itemTexture =
|
||||||
render->getData()->findTexture(itemTextureName);
|
render->getData()->findSlotTexture("hud", itemTextureName);
|
||||||
RW_CHECK(itemTexture != nullptr, "Item has 0 texture");
|
RW_CHECK(itemTexture != nullptr, "Item has 0 texture");
|
||||||
if (itemTexture != nullptr) {
|
if (itemTexture != nullptr) {
|
||||||
RW_CHECK(itemTexture->getName() != 0, "Item has 0 texture");
|
RW_CHECK(itemTexture->getName() != 0, "Item has 0 texture");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <gl/gl_core_3_3.h>
|
#include <gl/gl_core_3_3.h>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@ -37,3 +38,4 @@ private:
|
|||||||
glm::ivec2 size;
|
glm::ivec2 size;
|
||||||
bool hasAlpha;
|
bool hasAlpha;
|
||||||
};
|
};
|
||||||
|
using TextureArchive = std::map<std::string, TextureData::Handle>;
|
||||||
|
@ -341,8 +341,10 @@ void LoaderDFF::readTexture(Model *model, const RWBStream &stream) {
|
|||||||
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
|
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
|
||||||
std::transform(alpha.begin(), alpha.end(), alpha.begin(), ::tolower);
|
std::transform(alpha.begin(), alpha.end(), alpha.begin(), ::tolower);
|
||||||
|
|
||||||
|
TextureData::Handle textureinst =
|
||||||
|
texturelookup ? texturelookup(name, alpha) : nullptr;
|
||||||
model->geometries.back()->materials.back().textures.push_back(
|
model->geometries.back()->materials.back().textures.push_back(
|
||||||
{name, alpha, nullptr});
|
{name, alpha, textureinst});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoaderDFF::readGeometryExtension(Model *model, const RWBStream &stream) {
|
void LoaderDFF::readGeometryExtension(Model *model, const RWBStream &stream) {
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
#ifndef _LOADERDFF_HPP_
|
#ifndef _LOADERDFF_HPP_
|
||||||
#define _LOADERDFF_HPP_
|
#define _LOADERDFF_HPP_
|
||||||
|
|
||||||
|
#include <gl/TextureData.hpp>
|
||||||
#include <loaders/RWBinaryStream.hpp>
|
#include <loaders/RWBinaryStream.hpp>
|
||||||
|
|
||||||
#include <platform/FileHandle.hpp>
|
#include <platform/FileHandle.hpp>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class Model;
|
class Model;
|
||||||
class GameData;
|
|
||||||
|
|
||||||
class DFFLoaderException {
|
class DFFLoaderException {
|
||||||
std::string _message;
|
std::string _message;
|
||||||
@ -48,7 +48,16 @@ class LoaderDFF {
|
|||||||
void readAtomic(Model* model, const RWBStream& stream);
|
void readAtomic(Model* model, const RWBStream& stream);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using TextureLookupCallback = std::function<TextureData::Handle(
|
||||||
|
const std::string&, const std::string&)>;
|
||||||
|
|
||||||
Model* loadFromMemory(FileHandle file);
|
Model* loadFromMemory(FileHandle file);
|
||||||
|
|
||||||
|
void setTextureLookupCallback(TextureLookupCallback tlc) {
|
||||||
|
texturelookup = tlc;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
TextureLookupCallback texturelookup;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -182,11 +182,7 @@ bool TextureLoader::loadFromMemory(FileHandle file,
|
|||||||
|
|
||||||
auto texture = createTexture(texNative, rootSection);
|
auto texture = createTexture(texNative, rootSection);
|
||||||
|
|
||||||
inTextures[{name, alpha}] = texture;
|
inTextures[name] = texture;
|
||||||
|
|
||||||
if (!alpha.empty()) {
|
|
||||||
inTextures[{name, ""}] = texture;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -11,8 +11,6 @@
|
|||||||
|
|
||||||
// This might suffice
|
// This might suffice
|
||||||
#include <gl/TextureData.hpp>
|
#include <gl/TextureData.hpp>
|
||||||
typedef std::map<std::pair<std::string, std::string>, TextureData::Handle>
|
|
||||||
TextureArchive;
|
|
||||||
|
|
||||||
class FileIndex;
|
class FileIndex;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user