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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Material *EMICostume::loadMaterial(const Common::String &name) {
|
Material *EMICostume::loadMaterial(const Common::String &name, bool clamp) {
|
||||||
Material *mat = findMaterial(name);
|
Material *mat = findMaterial(name);
|
||||||
if (!mat) {
|
if (!mat) {
|
||||||
mat = g_resourceloader->loadMaterial(name.c_str(), nullptr);
|
mat = g_resourceloader->loadMaterial(name.c_str(), nullptr, clamp);
|
||||||
_materials.push_back(mat);
|
_materials.push_back(mat);
|
||||||
}
|
}
|
||||||
return mat;
|
return mat;
|
||||||
|
|
|
@ -52,7 +52,7 @@ public:
|
||||||
void saveState(SaveGame *state) const override;
|
void saveState(SaveGame *state) const override;
|
||||||
bool restoreState(SaveGame *state) 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);
|
Material *findMaterial(const Common::String &name);
|
||||||
|
|
||||||
void setWearChoreActive(bool isActive);
|
void setWearChoreActive(bool isActive);
|
||||||
|
|
|
@ -249,7 +249,7 @@ void EMIModel::prepareTextures() {
|
||||||
for (uint32 i = 0; i < _numTextures; i++) {
|
for (uint32 i = 0; i < _numTextures; i++) {
|
||||||
// HACK: As we dont know what specialty-textures are yet, we skip loading them
|
// HACK: As we dont know what specialty-textures are yet, we skip loading them
|
||||||
if (!_texNames[i].contains("specialty"))
|
if (!_texNames[i].contains("specialty"))
|
||||||
_mats[i] = _costume->loadMaterial(_texNames[i]);
|
_mats[i] = _costume->loadMaterial(_texNames[i], false);
|
||||||
else
|
else
|
||||||
_mats[i] = g_driver->getSpecialtyTexture(_texNames[i][9] - '0');
|
_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->_height = height;
|
||||||
_texture->_bpp = 4;
|
_texture->_bpp = 4;
|
||||||
_texture->_colorFormat = BM_RGBA;
|
_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) {
|
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 setupLight(Light *light, int lightId) = 0;
|
||||||
virtual void turnOffLight(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 selectMaterial(const Texture *material) = 0;
|
||||||
virtual void destroyMaterial(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::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];
|
material->_texture = new GLuint[1];
|
||||||
glGenTextures(1, (GLuint *)material->_texture);
|
glGenTextures(1, (GLuint *)material->_texture);
|
||||||
char *texdata = new char[material->_width * material->_height * 4];
|
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]);
|
glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||||
|
|
||||||
//Remove darkened lines in EMI intro
|
//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_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -87,7 +87,7 @@ public:
|
||||||
void setupLight(Light *light, int lightId) override;
|
void setupLight(Light *light, int lightId) override;
|
||||||
void turnOffLight(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 selectMaterial(const Texture *material) override;
|
||||||
void destroyMaterial(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];
|
material->_texture = new GLuint[1];
|
||||||
glGenTextures(1, (GLuint *)material->_texture);
|
glGenTextures(1, (GLuint *)material->_texture);
|
||||||
char *texdata = new char[material->_width * material->_height * 4];
|
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]);
|
glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||||
|
|
||||||
//Remove darkened lines in EMI intro
|
//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_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -90,7 +90,7 @@ public:
|
||||||
virtual void setupLight(Light *light, int lightId);
|
virtual void setupLight(Light *light, int lightId);
|
||||||
virtual void turnOffLight(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 selectMaterial(const Texture *material);
|
||||||
virtual void destroyMaterial(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];
|
material->_texture = new TGLuint[1];
|
||||||
tglGenTextures(1, (TGLuint *)material->_texture);
|
tglGenTextures(1, (TGLuint *)material->_texture);
|
||||||
char *texdata = new char[material->_width * material->_height * 4];
|
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;
|
TGLuint *textures = (TGLuint *)material->_texture;
|
||||||
tglBindTexture(TGL_TEXTURE_2D, textures[0]);
|
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_S, TGL_REPEAT);
|
||||||
tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_T, 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_MAG_FILTER, TGL_LINEAR);
|
||||||
tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MIN_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);
|
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 setupLight(Light *light, int lightId);
|
||||||
void turnOffLight(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 selectMaterial(const Texture *material);
|
||||||
void destroyMaterial(Texture *material);
|
void destroyMaterial(Texture *material);
|
||||||
|
|
||||||
|
|
|
@ -413,7 +413,8 @@ void GrimEngine::handleDebugLoadResource() {
|
||||||
} else if (strstr(buf, ".mat")) {
|
} else if (strstr(buf, ".mat")) {
|
||||||
CMap *cmap = g_resourceloader->loadColormap("item.cmp");
|
CMap *cmap = g_resourceloader->loadColormap("item.cmp");
|
||||||
warning("Default colormap applied to resources loaded in this fashion");
|
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 {
|
} else {
|
||||||
warning("Resource type not understood");
|
warning("Resource type not understood");
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,9 +200,10 @@ MaterialData *MaterialData::getMaterialData(const Common::String &filename, Comm
|
||||||
return m;
|
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) {
|
Object(), _currImage(0) {
|
||||||
_data = MaterialData::getMaterialData(filename, data, cmap);
|
_data = MaterialData::getMaterialData(filename, data, cmap);
|
||||||
|
_clampTexture = clamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
Material::Material() :
|
Material::Material() :
|
||||||
|
@ -216,7 +217,7 @@ void Material::reload(CMap *cmap) {
|
||||||
delete _data;
|
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.
|
// Steal the data from the new material and discard it.
|
||||||
_data = m->_data;
|
_data = m->_data;
|
||||||
++_data->_refCount;
|
++_data->_refCount;
|
||||||
|
@ -227,7 +228,7 @@ void Material::select() const {
|
||||||
Texture *t = _data->_textures + _currImage;
|
Texture *t = _data->_textures + _currImage;
|
||||||
if (t->_width && t->_height) {
|
if (t->_width && t->_height) {
|
||||||
if (!t->_texture) {
|
if (!t->_texture) {
|
||||||
g_driver->createMaterial(t, t->_data, _data->_cmap);
|
g_driver->createMaterial(t, t->_data, _data->_cmap, _clampTexture);
|
||||||
delete[] t->_data;
|
delete[] t->_data;
|
||||||
t->_data = nullptr;
|
t->_data = nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ private:
|
||||||
class Material : public Object {
|
class Material : public Object {
|
||||||
public:
|
public:
|
||||||
// Load a texture from the given data.
|
// 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);
|
void reload(CMap *cmap);
|
||||||
// Load this texture into the GL context
|
// Load this texture into the GL context
|
||||||
|
@ -85,6 +85,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
MaterialData *_data;
|
MaterialData *_data;
|
||||||
int _currImage;
|
int _currImage;
|
||||||
|
bool _clampTexture;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Grim
|
} // end of namespace Grim
|
||||||
|
|
|
@ -246,7 +246,7 @@ void Model::loadMaterial(int index, CMap *cmap) {
|
||||||
if (mat && cmap->getFilename() == _cmap->getFilename()) {
|
if (mat && cmap->getFilename() == _cmap->getFilename()) {
|
||||||
_materials[index] = mat;
|
_materials[index] = mat;
|
||||||
} else {
|
} else {
|
||||||
_materials[index] = g_resourceloader->loadMaterial(_materialNames[index], cmap);
|
_materials[index] = g_resourceloader->loadMaterial(_materialNames[index], cmap, false);
|
||||||
}
|
}
|
||||||
_materialsShared[index] = false;
|
_materialsShared[index] = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -401,7 +401,7 @@ LipSync *ResourceLoader::loadLipSync(const Common::String &filename) {
|
||||||
return result;
|
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);
|
Common::String fname = fixFilename(filename, false);
|
||||||
fname.toLowercase();
|
fname.toLowercase();
|
||||||
Common::SeekableReadStream *stream;
|
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) {
|
if (g_grim->getGameType() == GType_MONKEY4 && g_grim->getGameFlags() & ADGF_DEMO) {
|
||||||
const Common::String replacement("fx/candle.sprb");
|
const Common::String replacement("fx/candle.sprb");
|
||||||
warning("Could not find material %s, using %s instead", filename.c_str(), replacement.c_str());
|
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 {
|
} else {
|
||||||
error("Could not find material %s", filename.c_str());
|
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;
|
delete stream;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -63,7 +63,7 @@ public:
|
||||||
Costume *loadCostume(const Common::String &fname, Costume *prevCost);
|
Costume *loadCostume(const Common::String &fname, Costume *prevCost);
|
||||||
Font *loadFont(const Common::String &fname);
|
Font *loadFont(const Common::String &fname);
|
||||||
KeyframeAnim *loadKeyframe(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);
|
Model *loadModel(const Common::String &fname, CMap *c, Model *parent = NULL);
|
||||||
EMIModel *loadModelEMI(const Common::String &fname, EMICostume *costume);
|
EMIModel *loadModelEMI(const Common::String &fname, EMICostume *costume);
|
||||||
LipSync *loadLipSync(const Common::String &fname);
|
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) {
|
void Sprite::loadGrim(const Common::String &name, const char *comma, CMap *cmap) {
|
||||||
int width, height, x, y, z;
|
int width, height, x, y, z;
|
||||||
sscanf(comma, ",%d,%d,%d,%d,%d", &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;
|
_width = (float)width / 100.0f;
|
||||||
_height = (float)height / 100.0f;
|
_height = (float)height / 100.0f;
|
||||||
_pos.set((float)x / 100.0f, (float)y / 100.0f, (float)z / 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);
|
offX = get_float(data + 8);
|
||||||
offY = get_float(data + 12);
|
offY = get_float(data + 12);
|
||||||
|
|
||||||
_material = costume->loadMaterial(texname);
|
_material = costume->loadMaterial(texname, true);
|
||||||
_width = width;
|
_width = width;
|
||||||
_height = height;
|
_height = height;
|
||||||
_next = nullptr;
|
_next = nullptr;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue