mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-13 15:40:57 +00:00
GRIM: Every material image have its own properties, not shared in all the material.
This commit is contained in:
parent
c3470d9b16
commit
497dabe1b0
@ -33,7 +33,6 @@ class BitmapData;
|
||||
class Bitmap;
|
||||
class CMap;
|
||||
class Color;
|
||||
class MaterialData;
|
||||
class PrimitiveObject;
|
||||
class Font;
|
||||
class TextObject;
|
||||
@ -43,6 +42,7 @@ class Mesh;
|
||||
class MeshFace;
|
||||
class Sprite;
|
||||
class Light;
|
||||
class Texture;
|
||||
|
||||
enum colorFormat {
|
||||
BM_RGB565 = 1, // Grim Fandango
|
||||
@ -87,9 +87,9 @@ public:
|
||||
virtual void disableLights() = 0;
|
||||
virtual void setupLight(Light *light, int lightId) = 0;
|
||||
|
||||
virtual void createMaterial(MaterialData *material, const char *data, const CMap *cmap) = 0;
|
||||
virtual void selectMaterial(const Material *material) = 0;
|
||||
virtual void destroyMaterial(MaterialData *material) = 0;
|
||||
virtual void createMaterial(Texture *material, const char *data, const CMap *cmap) = 0;
|
||||
virtual void selectMaterial(const Texture *material) = 0;
|
||||
virtual void destroyMaterial(Texture *material) = 0;
|
||||
|
||||
virtual void createBitmap(BitmapData *bitmap) = 0;
|
||||
virtual void drawBitmap(const Bitmap *bitmap) = 0;
|
||||
@ -112,8 +112,8 @@ public:
|
||||
* the arguments specify the distance from the screen-edge to the first
|
||||
* non-iris pixel.
|
||||
*
|
||||
* @param x the width of the Iris
|
||||
* @param y the height of the Iris
|
||||
* @param x the width of the Iris
|
||||
* @param y the height of the Iris
|
||||
*/
|
||||
virtual void irisAroundRegion(int x, int y) = 0;
|
||||
|
||||
|
@ -960,53 +960,50 @@ void GfxOpenGL::drawTextObject(TextObject *text) {
|
||||
void GfxOpenGL::destroyTextObject(TextObject *text) {
|
||||
}
|
||||
|
||||
void GfxOpenGL::createMaterial(MaterialData *material, const char *data, const CMap *cmap) {
|
||||
material->_textures = new GLuint[material->_numImages];
|
||||
glGenTextures(material->_numImages, (GLuint *)material->_textures);
|
||||
void GfxOpenGL::createMaterial(Texture *material, const char *data, const CMap *cmap) {
|
||||
material->_texture = new GLuint[1];
|
||||
glGenTextures(1, (GLuint *)material->_texture);
|
||||
char *texdata = new char[material->_width * material->_height * 4];
|
||||
for (int i = 0; i < material->_numImages; i++) {
|
||||
char *texdatapos = texdata;
|
||||
for (int y = 0; y < material->_height; y++) {
|
||||
for (int x = 0; x < material->_width; x++) {
|
||||
uint8 col = *(uint8 *)(data);
|
||||
if (col == 0) {
|
||||
memset(texdatapos, 0, 4); // transparent
|
||||
if (!material->_hasAlpha) {
|
||||
texdatapos[3] = '\xff'; // fully opaque
|
||||
}
|
||||
} else {
|
||||
memcpy(texdatapos, cmap->_colors + 3 * (col), 3);
|
||||
char *texdatapos = texdata;
|
||||
for (int y = 0; y < material->_height; y++) {
|
||||
for (int x = 0; x < material->_width; x++) {
|
||||
uint8 col = *(uint8 *)(data);
|
||||
if (col == 0) {
|
||||
memset(texdatapos, 0, 4); // transparent
|
||||
if (!material->_hasAlpha) {
|
||||
texdatapos[3] = '\xff'; // fully opaque
|
||||
}
|
||||
texdatapos += 4;
|
||||
data++;
|
||||
} else {
|
||||
memcpy(texdatapos, cmap->_colors + 3 * (col), 3);
|
||||
texdatapos[3] = '\xff'; // fully opaque
|
||||
}
|
||||
texdatapos += 4;
|
||||
data++;
|
||||
}
|
||||
|
||||
GLuint *textures = (GLuint *)material->_textures;
|
||||
glBindTexture(GL_TEXTURE_2D, textures[i]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, material->_width, material->_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texdata);
|
||||
data += 24;
|
||||
}
|
||||
|
||||
GLuint *textures = (GLuint *)material->_texture;
|
||||
glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, material->_width, material->_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texdata);
|
||||
delete[] texdata;
|
||||
}
|
||||
|
||||
void GfxOpenGL::selectMaterial(const Material *material) {
|
||||
GLuint *textures = (GLuint *)material->getData()->_textures;
|
||||
glBindTexture(GL_TEXTURE_2D, textures[material->getCurrentImage()]);
|
||||
void GfxOpenGL::selectMaterial(const Texture *material) {
|
||||
GLuint *textures = (GLuint *)material->_texture;
|
||||
glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glScalef(1.0f / material->getData()->_width, 1.0f / material->getData()->_height, 1);
|
||||
glScalef(1.0f / material->_width, 1.0f / material->_height, 1);
|
||||
}
|
||||
|
||||
void GfxOpenGL::destroyMaterial(MaterialData *material) {
|
||||
GLuint *textures = (GLuint *)material->_textures;
|
||||
void GfxOpenGL::destroyMaterial(Texture *material) {
|
||||
GLuint *textures = (GLuint *)material->_texture;
|
||||
if (textures) {
|
||||
glDeleteTextures(material->_numImages, textures);
|
||||
glDeleteTextures(1, textures);
|
||||
delete[] textures;
|
||||
}
|
||||
}
|
||||
|
@ -83,9 +83,9 @@ public:
|
||||
void disableLights();
|
||||
void setupLight(Light *light, int lightId);
|
||||
|
||||
void createMaterial(MaterialData *material, const char *data, const CMap *cmap);
|
||||
void selectMaterial(const Material *material);
|
||||
void destroyMaterial(MaterialData *material);
|
||||
void createMaterial(Texture *material, const char *data, const CMap *cmap);
|
||||
void selectMaterial(const Texture *material);
|
||||
void destroyMaterial(Texture *material);
|
||||
|
||||
void createBitmap(BitmapData *bitmap);
|
||||
void drawBitmap(const Bitmap *bitmap);
|
||||
|
@ -803,54 +803,51 @@ void GfxTinyGL::destroyTextObject(TextObject *text) {
|
||||
}
|
||||
}
|
||||
|
||||
void GfxTinyGL::createMaterial(MaterialData *material, const char *data, const CMap *cmap) {
|
||||
material->_textures = new TGLuint[material->_numImages];
|
||||
tglGenTextures(material->_numImages, (TGLuint *)material->_textures);
|
||||
void GfxTinyGL::createMaterial(Texture *material, const char *data, const CMap *cmap) {
|
||||
material->_texture = new TGLuint[1];
|
||||
tglGenTextures(1, (TGLuint *)material->_texture);
|
||||
char *texdata = new char[material->_width * material->_height * 4];
|
||||
for (int i = 0; i < material->_numImages; i++) {
|
||||
char *texdatapos = texdata;
|
||||
for (int y = 0; y < material->_height; y++) {
|
||||
for (int x = 0; x < material->_width; x++) {
|
||||
uint8 col = *(uint8 *)(data);
|
||||
if (col == 0) {
|
||||
memset(texdatapos, 0, 4); // transparent
|
||||
if (!material->_hasAlpha) {
|
||||
texdatapos[3] = '\xff'; // fully opaque
|
||||
}
|
||||
} else {
|
||||
memcpy(texdatapos, cmap->_colors + 3 * (col), 3);
|
||||
char *texdatapos = texdata;
|
||||
for (int y = 0; y < material->_height; y++) {
|
||||
for (int x = 0; x < material->_width; x++) {
|
||||
uint8 col = *(uint8 *)(data);
|
||||
if (col == 0) {
|
||||
memset(texdatapos, 0, 4); // transparent
|
||||
if (!material->_hasAlpha) {
|
||||
texdatapos[3] = '\xff'; // fully opaque
|
||||
}
|
||||
texdatapos += 4;
|
||||
data++;
|
||||
} else {
|
||||
memcpy(texdatapos, cmap->_colors + 3 * (col), 3);
|
||||
texdatapos[3] = '\xff'; // fully opaque
|
||||
}
|
||||
texdatapos += 4;
|
||||
data++;
|
||||
}
|
||||
TGLuint *textures = (TGLuint *)material->_textures;
|
||||
tglBindTexture(TGL_TEXTURE_2D, textures[i]);
|
||||
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, TGL_RGBA, TGL_UNSIGNED_BYTE, texdata);
|
||||
data += 24;
|
||||
}
|
||||
TGLuint *textures = (TGLuint *)material->_texture;
|
||||
tglBindTexture(TGL_TEXTURE_2D, textures[0]);
|
||||
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, TGL_RGBA, TGL_UNSIGNED_BYTE, texdata);
|
||||
delete[] texdata;
|
||||
}
|
||||
|
||||
void GfxTinyGL::selectMaterial(const Material *material) {
|
||||
TGLuint *textures = (TGLuint *)material->getData()->_textures;
|
||||
tglBindTexture(TGL_TEXTURE_2D, textures[material->getCurrentImage()]);
|
||||
void GfxTinyGL::selectMaterial(const Texture *material) {
|
||||
TGLuint *textures = (TGLuint *)material->_texture;
|
||||
tglBindTexture(TGL_TEXTURE_2D, textures[0]);
|
||||
tglPushMatrix();
|
||||
tglMatrixMode(TGL_TEXTURE);
|
||||
tglLoadIdentity();
|
||||
tglScalef(1.0f / material->getData()->_width, 1.0f / material->getData()->_height, 1);
|
||||
tglScalef(1.0f / material->_width, 1.0f / material->_height, 1);
|
||||
tglMatrixMode(TGL_MODELVIEW);
|
||||
tglPopMatrix();
|
||||
}
|
||||
|
||||
void GfxTinyGL::destroyMaterial(MaterialData *material) {
|
||||
tglDeleteTextures(material->_numImages, (TGLuint *)material->_textures);
|
||||
delete[] (TGLuint *)material->_textures;
|
||||
void GfxTinyGL::destroyMaterial(Texture *material) {
|
||||
tglDeleteTextures(1, (TGLuint *)material->_texture);
|
||||
delete[] (TGLuint *)material->_texture;
|
||||
}
|
||||
|
||||
void GfxTinyGL::prepareSmushFrame(int width, int height, byte *bitmap) {
|
||||
|
@ -74,9 +74,9 @@ public:
|
||||
void disableLights();
|
||||
void setupLight(Light *light, int lightId);
|
||||
|
||||
void createMaterial(MaterialData *material, const char *data, const CMap *cmap);
|
||||
void selectMaterial(const Material *material);
|
||||
void destroyMaterial(MaterialData *material);
|
||||
void createMaterial(Texture *material, const char *data, const CMap *cmap);
|
||||
void selectMaterial(const Texture *material);
|
||||
void destroyMaterial(Texture *material);
|
||||
|
||||
void createBitmap(BitmapData *bitmap);
|
||||
void drawBitmap(const Bitmap *bitmap);
|
||||
|
@ -39,6 +39,7 @@ MaterialData::MaterialData(const Common::String &filename, const char *data, int
|
||||
error("invalid magic loading texture");
|
||||
|
||||
_numImages = READ_LE_UINT32(data + 12);
|
||||
_textures = new Texture[_numImages];
|
||||
/* Discovered by diffing orange.mat with pink.mat and blue.mat .
|
||||
* Actual meaning unknown, so I prefer to use it as an enum-ish
|
||||
* at the moment, to detect unexpected values.
|
||||
@ -48,19 +49,22 @@ MaterialData::MaterialData(const Common::String &filename, const char *data, int
|
||||
data += 16;
|
||||
else if (offset != 0)
|
||||
error("Unknown offset: %d", offset);
|
||||
_width = READ_LE_UINT32(data + 60 + _numImages * 40);
|
||||
_height = READ_LE_UINT32(data + 64 + _numImages * 40);
|
||||
_hasAlpha = READ_LE_UINT32(data + 68 + _numImages * 40);
|
||||
|
||||
if (_width == 0 || _height == 0) {
|
||||
if (gDebugLevel == DEBUG_WARN || gDebugLevel == DEBUG_ALL)
|
||||
warning("skip load texture: bad texture size (%dx%d) for texture %s", _width, _height, _fname.c_str());
|
||||
return;
|
||||
data += 60 + _numImages * 40;
|
||||
for (int i = 0; i < _numImages; ++i) {
|
||||
Texture *t = _textures + i;
|
||||
t->_width = READ_LE_UINT32(data);
|
||||
t->_height = READ_LE_UINT32(data + 4);
|
||||
t->_hasAlpha = READ_LE_UINT32(data + 8);
|
||||
if (t->_width == 0 || t->_height == 0) {
|
||||
if (gDebugLevel == DEBUG_WARN || gDebugLevel == DEBUG_ALL)
|
||||
warning("skip load texture: bad texture size (%dx%d) for texture %d of material %s",
|
||||
t->_width, t->_height, i, _fname.c_str());
|
||||
break;
|
||||
}
|
||||
g_driver->createMaterial(t, data + 24, cmap);
|
||||
data += 24 + t->_width * t->_height;
|
||||
}
|
||||
|
||||
data += 84 + _numImages * 40;
|
||||
|
||||
g_driver->createMaterial(this, data, cmap);
|
||||
}
|
||||
|
||||
MaterialData::~MaterialData() {
|
||||
@ -70,8 +74,12 @@ MaterialData::~MaterialData() {
|
||||
_materials = NULL;
|
||||
}
|
||||
|
||||
if (_width && _height)
|
||||
g_driver->destroyMaterial(this);
|
||||
for (int i = 0; i < _numImages; ++i) {
|
||||
Texture *t = _textures + i;
|
||||
if (t->_width && t->_height)
|
||||
g_driver->destroyMaterial(t);
|
||||
}
|
||||
delete[] _textures;
|
||||
}
|
||||
|
||||
MaterialData *MaterialData::getMaterialData(const Common::String &filename, const char *data, int len, CMap *cmap) {
|
||||
@ -112,8 +120,9 @@ void Material::reload(CMap *cmap) {
|
||||
}
|
||||
|
||||
void Material::select() const {
|
||||
if (_data->_width && _data->_height)
|
||||
g_driver->selectMaterial(this);
|
||||
Texture *t = _data->_textures + _currImage;
|
||||
if (t->_width && t->_height)
|
||||
g_driver->selectMaterial(t);
|
||||
}
|
||||
|
||||
Material::~Material() {
|
||||
|
@ -28,6 +28,14 @@
|
||||
|
||||
namespace Grim {
|
||||
|
||||
class Texture {
|
||||
public:
|
||||
int _width;
|
||||
int _height;
|
||||
bool _hasAlpha;
|
||||
void *_texture;
|
||||
};
|
||||
|
||||
class MaterialData {
|
||||
public:
|
||||
MaterialData(const Common::String &filename, const char *data, int len, CMap *cmap);
|
||||
@ -39,9 +47,7 @@ public:
|
||||
Common::String _fname;
|
||||
const ObjectPtr<CMap> _cmap;
|
||||
int _numImages;
|
||||
int _width, _height;
|
||||
bool _hasAlpha;
|
||||
void *_textures;
|
||||
Texture *_textures;
|
||||
int _refCount;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user