EMI: Add support for clamping sprite textures and repeating other textures.
This commit is contained in:
parent
29ddd3b3e9
commit
df3d63fc24
18 changed files with 40 additions and 28 deletions
|
@ -284,10 +284,10 @@ Material *EMICostume::findMaterial(const Common::String &name) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Material *EMICostume::loadMaterial(const Common::String &name) {
|
||||
Material *EMICostume::loadMaterial(const Common::String &name, bool clamp) {
|
||||
Material *mat = findMaterial(name);
|
||||
if (!mat) {
|
||||
mat = g_resourceloader->loadMaterial(name.c_str(), nullptr);
|
||||
mat = g_resourceloader->loadMaterial(name.c_str(), nullptr, clamp);
|
||||
_materials.push_back(mat);
|
||||
}
|
||||
return mat;
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
void saveState(SaveGame *state) const override;
|
||||
bool restoreState(SaveGame *state) override;
|
||||
|
||||
Material *loadMaterial(const Common::String &name);
|
||||
Material *loadMaterial(const Common::String &name, bool clamp);
|
||||
Material *findMaterial(const Common::String &name);
|
||||
|
||||
void setWearChoreActive(bool isActive);
|
||||
|
|
|
@ -249,7 +249,7 @@ void EMIModel::prepareTextures() {
|
|||
for (uint32 i = 0; i < _numTextures; i++) {
|
||||
// HACK: As we dont know what specialty-textures are yet, we skip loading them
|
||||
if (!_texNames[i].contains("specialty"))
|
||||
_mats[i] = _costume->loadMaterial(_texNames[i]);
|
||||
_mats[i] = _costume->loadMaterial(_texNames[i], false);
|
||||
else
|
||||
_mats[i] = g_driver->getSpecialtyTexture(_texNames[i][9] - '0');
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ void SpecialtyMaterial::create(const char *data, int width, int height) {
|
|||
_texture->_height = height;
|
||||
_texture->_bpp = 4;
|
||||
_texture->_colorFormat = BM_RGBA;
|
||||
g_driver->createMaterial(_texture, data, nullptr);
|
||||
g_driver->createMaterial(_texture, data, nullptr, false);
|
||||
}
|
||||
|
||||
Math::Matrix4 GfxBase::makeLookMatrix(const Math::Vector3d& pos, const Math::Vector3d& interest, const Math::Vector3d& up) {
|
||||
|
|
|
@ -147,7 +147,7 @@ public:
|
|||
virtual void setupLight(Light *light, int lightId) = 0;
|
||||
virtual void turnOffLight(int lightId) = 0;
|
||||
|
||||
virtual void createMaterial(Texture *material, const char *data, const CMap *cmap) = 0;
|
||||
virtual void createMaterial(Texture *material, const char *data, const CMap *cmap, bool clamp) = 0;
|
||||
virtual void selectMaterial(const Texture *material) = 0;
|
||||
virtual void destroyMaterial(Texture *material) = 0;
|
||||
|
||||
|
|
|
@ -1293,7 +1293,7 @@ void GfxOpenGL::drawTextObject(const TextObject *text) {
|
|||
void GfxOpenGL::destroyTextObject(TextObject *text) {
|
||||
}
|
||||
|
||||
void GfxOpenGL::createMaterial(Texture *material, const char *data, const CMap *cmap) {
|
||||
void GfxOpenGL::createMaterial(Texture *material, const char *data, const CMap *cmap, bool clamp) {
|
||||
material->_texture = new GLuint[1];
|
||||
glGenTextures(1, (GLuint *)material->_texture);
|
||||
char *texdata = new char[material->_width * material->_height * 4];
|
||||
|
@ -1337,7 +1337,7 @@ void GfxOpenGL::createMaterial(Texture *material, const char *data, const CMap *
|
|||
glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||
|
||||
//Remove darkened lines in EMI intro
|
||||
if (g_grim->getGameType() == GType_MONKEY4) {
|
||||
if (g_grim->getGameType() == GType_MONKEY4 && clamp) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
} else {
|
||||
|
|
|
@ -87,7 +87,7 @@ public:
|
|||
void setupLight(Light *light, int lightId) override;
|
||||
void turnOffLight(int lightId) override;
|
||||
|
||||
void createMaterial(Texture *material, const char *data, const CMap *cmap) override;
|
||||
void createMaterial(Texture *material, const char *data, const CMap *cmap, bool clamp) override;
|
||||
void selectMaterial(const Texture *material) override;
|
||||
void destroyMaterial(Texture *material) override;
|
||||
|
||||
|
|
|
@ -873,7 +873,7 @@ void GfxOpenGLS::turnOffLight(int lightId) {
|
|||
}
|
||||
|
||||
|
||||
void GfxOpenGLS::createMaterial(Texture *material, const char *data, const CMap *cmap) {
|
||||
void GfxOpenGLS::createMaterial(Texture *material, const char *data, const CMap *cmap, bool clamp) {
|
||||
material->_texture = new GLuint[1];
|
||||
glGenTextures(1, (GLuint *)material->_texture);
|
||||
char *texdata = new char[material->_width * material->_height * 4];
|
||||
|
@ -927,7 +927,7 @@ void GfxOpenGLS::createMaterial(Texture *material, const char *data, const CMap
|
|||
glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||
|
||||
//Remove darkened lines in EMI intro
|
||||
if (g_grim->getGameType() == GType_MONKEY4) {
|
||||
if (g_grim->getGameType() == GType_MONKEY4 && clamp) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
} else {
|
||||
|
|
|
@ -90,7 +90,7 @@ public:
|
|||
virtual void setupLight(Light *light, int lightId);
|
||||
virtual void turnOffLight(int lightId);
|
||||
|
||||
virtual void createMaterial(Texture *material, const char *data, const CMap *cmap);
|
||||
virtual void createMaterial(Texture *material, const char *data, const CMap *cmap, bool clamp);
|
||||
virtual void selectMaterial(const Texture *material);
|
||||
virtual void destroyMaterial(Texture *material);
|
||||
|
||||
|
|
|
@ -1241,7 +1241,7 @@ void GfxTinyGL::destroyTextObject(TextObject *text) {
|
|||
}
|
||||
}
|
||||
|
||||
void GfxTinyGL::createMaterial(Texture *material, const char *data, const CMap *cmap) {
|
||||
void GfxTinyGL::createMaterial(Texture *material, const char *data, const CMap *cmap, bool clamp) {
|
||||
material->_texture = new TGLuint[1];
|
||||
tglGenTextures(1, (TGLuint *)material->_texture);
|
||||
char *texdata = new char[material->_width * material->_height * 4];
|
||||
|
@ -1282,8 +1282,17 @@ void GfxTinyGL::createMaterial(Texture *material, const char *data, const CMap *
|
|||
|
||||
TGLuint *textures = (TGLuint *)material->_texture;
|
||||
tglBindTexture(TGL_TEXTURE_2D, textures[0]);
|
||||
|
||||
// FIXME: TinyGL only supports TGL_REPEAT
|
||||
// Remove darkened lines in EMI intro
|
||||
// if (g_grim->getGameType() == GType_MONKEY4 && clamp) {
|
||||
// tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_S, TGL_CLAMP);
|
||||
// tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_T, TGL_CLAMP);
|
||||
// } else {
|
||||
tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_S, TGL_REPEAT);
|
||||
tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_T, TGL_REPEAT);
|
||||
// }
|
||||
|
||||
tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MAG_FILTER, TGL_LINEAR);
|
||||
tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MIN_FILTER, TGL_LINEAR);
|
||||
tglTexImage2D(TGL_TEXTURE_2D, 0, 3, material->_width, material->_height, 0, format, TGL_UNSIGNED_BYTE, texdata);
|
||||
|
|
|
@ -83,7 +83,7 @@ public:
|
|||
void setupLight(Light *light, int lightId);
|
||||
void turnOffLight(int lightId);
|
||||
|
||||
void createMaterial(Texture *material, const char *data, const CMap *cmap);
|
||||
void createMaterial(Texture *material, const char *data, const CMap *cmap, bool clamp);
|
||||
void selectMaterial(const Texture *material);
|
||||
void destroyMaterial(Texture *material);
|
||||
|
||||
|
|
|
@ -413,7 +413,8 @@ void GrimEngine::handleDebugLoadResource() {
|
|||
} else if (strstr(buf, ".mat")) {
|
||||
CMap *cmap = g_resourceloader->loadColormap("item.cmp");
|
||||
warning("Default colormap applied to resources loaded in this fashion");
|
||||
resource = (void *)g_resourceloader->loadMaterial(buf, cmap);
|
||||
// Default to repeating the texture as in GRIM
|
||||
resource = (void *)g_resourceloader->loadMaterial(buf, cmap, false);
|
||||
} else {
|
||||
warning("Resource type not understood");
|
||||
}
|
||||
|
|
|
@ -200,9 +200,10 @@ MaterialData *MaterialData::getMaterialData(const Common::String &filename, Comm
|
|||
return m;
|
||||
}
|
||||
|
||||
Material::Material(const Common::String &filename, Common::SeekableReadStream *data, CMap *cmap) :
|
||||
Material::Material(const Common::String &filename, Common::SeekableReadStream *data, CMap *cmap, bool clamp) :
|
||||
Object(), _currImage(0) {
|
||||
_data = MaterialData::getMaterialData(filename, data, cmap);
|
||||
_clampTexture = clamp;
|
||||
}
|
||||
|
||||
Material::Material() :
|
||||
|
@ -216,7 +217,7 @@ void Material::reload(CMap *cmap) {
|
|||
delete _data;
|
||||
}
|
||||
|
||||
Material *m = g_resourceloader->loadMaterial(fname, cmap);
|
||||
Material *m = g_resourceloader->loadMaterial(fname, cmap, _clampTexture);
|
||||
// Steal the data from the new material and discard it.
|
||||
_data = m->_data;
|
||||
++_data->_refCount;
|
||||
|
@ -227,7 +228,7 @@ void Material::select() const {
|
|||
Texture *t = _data->_textures + _currImage;
|
||||
if (t->_width && t->_height) {
|
||||
if (!t->_texture) {
|
||||
g_driver->createMaterial(t, t->_data, _data->_cmap);
|
||||
g_driver->createMaterial(t, t->_data, _data->_cmap, _clampTexture);
|
||||
delete[] t->_data;
|
||||
t->_data = nullptr;
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ private:
|
|||
class Material : public Object {
|
||||
public:
|
||||
// Load a texture from the given data.
|
||||
Material(const Common::String &filename, Common::SeekableReadStream *data, CMap *cmap);
|
||||
Material(const Common::String &filename, Common::SeekableReadStream *data, CMap *cmap, bool clamp);
|
||||
|
||||
void reload(CMap *cmap);
|
||||
// Load this texture into the GL context
|
||||
|
@ -85,6 +85,7 @@ protected:
|
|||
private:
|
||||
MaterialData *_data;
|
||||
int _currImage;
|
||||
bool _clampTexture;
|
||||
};
|
||||
|
||||
} // end of namespace Grim
|
||||
|
|
|
@ -246,7 +246,7 @@ void Model::loadMaterial(int index, CMap *cmap) {
|
|||
if (mat && cmap->getFilename() == _cmap->getFilename()) {
|
||||
_materials[index] = mat;
|
||||
} else {
|
||||
_materials[index] = g_resourceloader->loadMaterial(_materialNames[index], cmap);
|
||||
_materials[index] = g_resourceloader->loadMaterial(_materialNames[index], cmap, false);
|
||||
}
|
||||
_materialsShared[index] = false;
|
||||
}
|
||||
|
|
|
@ -401,7 +401,7 @@ LipSync *ResourceLoader::loadLipSync(const Common::String &filename) {
|
|||
return result;
|
||||
}
|
||||
|
||||
Material *ResourceLoader::loadMaterial(const Common::String &filename, CMap *c) {
|
||||
Material *ResourceLoader::loadMaterial(const Common::String &filename, CMap *c, bool clamp) {
|
||||
Common::String fname = fixFilename(filename, false);
|
||||
fname.toLowercase();
|
||||
Common::SeekableReadStream *stream;
|
||||
|
@ -413,13 +413,13 @@ Material *ResourceLoader::loadMaterial(const Common::String &filename, CMap *c)
|
|||
if (g_grim->getGameType() == GType_MONKEY4 && g_grim->getGameFlags() & ADGF_DEMO) {
|
||||
const Common::String replacement("fx/candle.sprb");
|
||||
warning("Could not find material %s, using %s instead", filename.c_str(), replacement.c_str());
|
||||
return loadMaterial(replacement, nullptr);
|
||||
return loadMaterial(replacement, nullptr, clamp);
|
||||
} else {
|
||||
error("Could not find material %s", filename.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
Material *result = new Material(fname, stream, c);
|
||||
Material *result = new Material(fname, stream, c, clamp);
|
||||
delete stream;
|
||||
|
||||
return result;
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
Costume *loadCostume(const Common::String &fname, Costume *prevCost);
|
||||
Font *loadFont(const Common::String &fname);
|
||||
KeyframeAnim *loadKeyframe(const Common::String &fname);
|
||||
Material *loadMaterial(const Common::String &fname, CMap *c);
|
||||
Material *loadMaterial(const Common::String &fname, CMap *c, bool clamp);
|
||||
Model *loadModel(const Common::String &fname, CMap *c, Model *parent = NULL);
|
||||
EMIModel *loadModelEMI(const Common::String &fname, EMICostume *costume);
|
||||
LipSync *loadLipSync(const Common::String &fname);
|
||||
|
|
|
@ -46,7 +46,7 @@ void Sprite::draw() const {
|
|||
void Sprite::loadGrim(const Common::String &name, const char *comma, CMap *cmap) {
|
||||
int width, height, x, y, z;
|
||||
sscanf(comma, ",%d,%d,%d,%d,%d", &width, &height, &x, &y, &z);
|
||||
_material = g_resourceloader->loadMaterial(name, cmap);
|
||||
_material = g_resourceloader->loadMaterial(name, cmap, true);
|
||||
_width = (float)width / 100.0f;
|
||||
_height = (float)height / 100.0f;
|
||||
_pos.set((float)x / 100.0f, (float)y / 100.0f, (float)z / 100.0f);
|
||||
|
@ -73,7 +73,7 @@ void Sprite::loadBinary(Common::SeekableReadStream *stream, EMICostume *costume)
|
|||
offX = get_float(data + 8);
|
||||
offY = get_float(data + 12);
|
||||
|
||||
_material = costume->loadMaterial(texname);
|
||||
_material = costume->loadMaterial(texname, true);
|
||||
_width = width;
|
||||
_height = height;
|
||||
_next = nullptr;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue