EMI: Add support for clamping sprite textures and repeating other textures.

This commit is contained in:
Joseph Jezak 2014-06-17 21:58:21 -04:00
parent 29ddd3b3e9
commit df3d63fc24
18 changed files with 40 additions and 28 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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');
}

View file

@ -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) {

View file

@ -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;

View file

@ -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 {

View file

@ -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;

View file

@ -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 {

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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");
}

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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;

View file

@ -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);

View file

@ -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;