From d7ee5159619207f15e9d59eba72b51fda68d2def Mon Sep 17 00:00:00 2001 From: Dries Harnie Date: Fri, 13 Apr 2012 19:45:33 +0200 Subject: [PATCH] EMI: render overworld actors using a straight coord system --- engines/grim/actor.cpp | 7 +++--- engines/grim/gfx_base.h | 4 +++- engines/grim/gfx_opengl.cpp | 43 ++++++++++++++++++++++++++----------- engines/grim/gfx_opengl.h | 4 +++- engines/grim/gfx_tinygl.cpp | 43 +++++++++++++++++++++++++++---------- engines/grim/gfx_tinygl.h | 4 +++- 6 files changed, 76 insertions(+), 29 deletions(-) diff --git a/engines/grim/actor.cpp b/engines/grim/actor.cpp index 1aa40206fe1..0e0333f1f4c 100644 --- a/engines/grim/actor.cpp +++ b/engines/grim/actor.cpp @@ -1298,14 +1298,15 @@ void Actor::draw() { g_driver->setShadowMode(); if (g_driver->isHardwareAccelerated()) g_driver->drawShadowPlanes(); - g_driver->startActorDraw(absPos, _scale, _yaw, _pitch, _roll); + g_driver->startActorDraw(absPos, _scale, _yaw, _pitch, _roll, _inOverworld, _alphaMode != AlphaOff ? _global_alpha : 1.f); costume->draw(); g_driver->finishActorDraw(); g_driver->clearShadowMode(); g_driver->setShadow(NULL); } + // normal draw actor - g_driver->startActorDraw(absPos, _scale, _yaw, _pitch, _roll); + g_driver->startActorDraw(absPos, _scale, _yaw, _pitch, _roll, _inOverworld, _alphaMode != AlphaOff ? _global_alpha : 1.f); costume->draw(); g_driver->finishActorDraw(); } @@ -1315,7 +1316,7 @@ void Actor::draw() { x1 = y1 = 1000; x2 = y2 = -1000; if (!_costumeStack.empty()) { - g_driver->startActorDraw(absPos, _scale, _yaw, _pitch, _roll); + g_driver->startActorDraw(absPos, _scale, _yaw, _pitch, _roll, _inOverworld, 1.f); _costumeStack.back()->getBoundingBox(&x1, &y1, &x2, &y2); g_driver->finishActorDraw(); } diff --git a/engines/grim/gfx_base.h b/engines/grim/gfx_base.h index 41d6d5c212f..ef24a4eab9b 100644 --- a/engines/grim/gfx_base.h +++ b/engines/grim/gfx_base.h @@ -113,7 +113,9 @@ public: virtual void getBoundingBoxPos(const Mesh *mesh, int *x1, int *y1, int *x2, int *y2) = 0; virtual void startActorDraw(const Math::Vector3d &pos, float scale, const Math::Angle &yaw, - const Math::Angle &pitch, const Math::Angle &roll) = 0; + const Math::Angle &pitch, const Math::Angle &roll, const bool inOverworld, + const float alpha) = 0; + virtual void finishActorDraw() = 0; virtual void setShadow(Shadow *shadow) = 0; virtual void drawShadowPlanes() = 0; diff --git a/engines/grim/gfx_opengl.cpp b/engines/grim/gfx_opengl.cpp index 08f836025df..9b1d0ca4cb5 100644 --- a/engines/grim/gfx_opengl.cpp +++ b/engines/grim/gfx_opengl.cpp @@ -95,6 +95,7 @@ GfxOpenGL::GfxOpenGL() { g_driver = this; _storedDisplay = NULL; _emergFont = 0; + _alpha = 1.f; } GfxOpenGL::~GfxOpenGL() { @@ -375,7 +376,8 @@ void GfxOpenGL::getBoundingBoxPos(const Mesh *model, int *x1, int *y1, int *x2, } void GfxOpenGL::startActorDraw(const Math::Vector3d &pos, float scale, const Math::Angle &yaw, - const Math::Angle &pitch, const Math::Angle &roll) { + const Math::Angle &pitch, const Math::Angle &roll, const bool inOverworld, + const float alpha) { glEnable(GL_TEXTURE_2D); glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -393,22 +395,39 @@ void GfxOpenGL::startActorDraw(const Math::Vector3d &pos, float scale, const Mat glColor3f(_shadowColorR / 255.0f, _shadowColorG / 255.0f, _shadowColorB / 255.0f); glShadowProjection(_currentShadowArray->pos, shadowSector->getVertices()[0], shadowSector->getNormal(), _currentShadowArray->dontNegate); } - glTranslatef(pos.x(), pos.y(), pos.z()); - glScalef(scale, scale, scale); - // EMI uses Y axis as down-up, so we need to rotate differently. - if (g_grim->getGameType() == GType_MONKEY4) { - glRotatef(yaw.getDegrees(), 0, -1, 0); - glRotatef(pitch.getDegrees(), 1, 0, 0); - glRotatef(roll.getDegrees(), 0, 0, 1); + + if (alpha < 1.f) { + _alpha = alpha; + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + if (inOverworld) { + glLoadIdentity(); + glScalef(1.0, 1.0, -1.0); + glTranslatef(pos.x(), pos.y(), pos.z()); } else { - glRotatef(yaw.getDegrees(), 0, 0, 1); - glRotatef(pitch.getDegrees(), 1, 0, 0); - glRotatef(roll.getDegrees(), 0, 1, 0); + glTranslatef(pos.x(), pos.y(), pos.z()); + glScalef(scale, scale, scale); + // EMI uses Y axis as down-up, so we need to rotate differently. + if (g_grim->getGameType() == GType_MONKEY4) { + glRotatef(yaw.getDegrees(), 0, -1, 0); + glRotatef(pitch.getDegrees(), 1, 0, 0); + glRotatef(roll.getDegrees(), 0, 0, 1); + } else { + glRotatef(yaw.getDegrees(), 0, 0, 1); + glRotatef(pitch.getDegrees(), 1, 0, 0); + glRotatef(roll.getDegrees(), 0, 1, 0); + } } } void GfxOpenGL::finishActorDraw() { glPopMatrix(); + if (_alpha < 1.f) { + glDisable(GL_BLEND); + _alpha = 1.f; + } glDisable(GL_TEXTURE_2D); if (_currentShadowArray) { glEnable(GL_LIGHTING); @@ -501,7 +520,7 @@ void GfxOpenGL::drawEMIModelFace(const EMIModel* model, const EMIMeshFace* face) if (face->_hasTexture) { glTexCoord2f(model->_texVerts[index].getX(), model->_texVerts[index].getY()); } - glColor4ub(model->_colorMap[index].r,model->_colorMap[index].g,model->_colorMap[index].b,model->_colorMap[index].a); + glColor4ub(model->_colorMap[index].r,model->_colorMap[index].g,model->_colorMap[index].b,model->_colorMap[index].a * _alpha ); Math::Vector3d normal = model->_normals[index]; Math::Vector3d vertex = model->_drawVertices[index]; diff --git a/engines/grim/gfx_opengl.h b/engines/grim/gfx_opengl.h index 74676571380..96fcccf4113 100644 --- a/engines/grim/gfx_opengl.h +++ b/engines/grim/gfx_opengl.h @@ -62,7 +62,8 @@ public: void getBoundingBoxPos(const Mesh *model, int *x1, int *y1, int *x2, int *y2); void startActorDraw(const Math::Vector3d &pos, float scale, const Math::Angle &yaw, - const Math::Angle &pitch, const Math::Angle &roll); + const Math::Angle &pitch, const Math::Angle &roll, const bool inOverworld, + const float alpha); void finishActorDraw(); void setShadow(Shadow *shadow); void drawShadowPlanes(); @@ -136,6 +137,7 @@ private: bool _useDimShader; GLuint _dimFragProgram; GLint _maxLights; + float _alpha; }; } // end of namespace Grim diff --git a/engines/grim/gfx_tinygl.cpp b/engines/grim/gfx_tinygl.cpp index 98c2e42d66d..639ad42aa97 100644 --- a/engines/grim/gfx_tinygl.cpp +++ b/engines/grim/gfx_tinygl.cpp @@ -229,6 +229,7 @@ GfxTinyGL::GfxTinyGL() { g_driver = this; _zb = NULL; _storedDisplay = NULL; + _alpha = 1.f; } GfxTinyGL::~GfxTinyGL() { @@ -467,7 +468,8 @@ void GfxTinyGL::getBoundingBoxPos(const Mesh *model, int *x1, int *y1, int *x2, } void GfxTinyGL::startActorDraw(const Math::Vector3d &pos, float scale, const Math::Angle &yaw, - const Math::Angle &pitch, const Math::Angle &roll) { + const Math::Angle &pitch, const Math::Angle &roll, const bool inOverworld, + const float alpha) { tglEnable(TGL_TEXTURE_2D); tglMatrixMode(TGL_MODELVIEW); tglPushMatrix(); @@ -486,17 +488,30 @@ void GfxTinyGL::startActorDraw(const Math::Vector3d &pos, float scale, const Mat tglShadowProjection(_currentShadowArray->pos, shadowSector->getVertices()[0], shadowSector->getNormal(), _currentShadowArray->dontNegate); } - tglTranslatef(pos.x(), pos.y(), pos.z()); - tglScalef(scale, scale, scale); - // EMI uses Y axis as down-up, so we need to rotate differently. - if (g_grim->getGameType() == GType_MONKEY4) { - tglRotatef(yaw.getDegrees(), 0, -1, 0); - tglRotatef(pitch.getDegrees(), 1, 0, 0); - tglRotatef(roll.getDegrees(), 0, 0, 1); + // FIXME: TinyGL doesn't seem to support translucency. + if (alpha < 1.f) { + _alpha = alpha; +// tglEnable(TGL_BLEND); +// tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA); + } + + if (inOverworld) { + tglLoadIdentity(); + tglScalef(1.0, 1.0, -1.0); + tglTranslatef(pos.x(), pos.y(), pos.z()); } else { - tglRotatef(yaw.getDegrees(), 0, 0, 1); - tglRotatef(pitch.getDegrees(), 1, 0, 0); - tglRotatef(roll.getDegrees(), 0, 1, 0); + tglTranslatef(pos.x(), pos.y(), pos.z()); + tglScalef(scale, scale, scale); + // EMI uses Y axis as down-up, so we need to rotate differently. + if (g_grim->getGameType() == GType_MONKEY4) { + tglRotatef(yaw.getDegrees(), 0, -1, 0); + tglRotatef(pitch.getDegrees(), 1, 0, 0); + tglRotatef(roll.getDegrees(), 0, 0, 1); + } else { + tglRotatef(yaw.getDegrees(), 0, 0, 1); + tglRotatef(pitch.getDegrees(), 1, 0, 0); + tglRotatef(roll.getDegrees(), 0, 1, 0); + } } } @@ -505,6 +520,12 @@ void GfxTinyGL::finishActorDraw() { tglPopMatrix(); tglDisable(TGL_TEXTURE_2D); + // FIXME: TinyGL doesn't seem to support translucency. + if (_alpha < 1.f) { +// tglDisable(TGL_BLEND); + _alpha = 1.f; + } + if (_currentShadowArray) { tglSetShadowMaskBuf(NULL); }/* else { diff --git a/engines/grim/gfx_tinygl.h b/engines/grim/gfx_tinygl.h index 8afeab5bb1a..794ab91ab49 100644 --- a/engines/grim/gfx_tinygl.h +++ b/engines/grim/gfx_tinygl.h @@ -54,7 +54,8 @@ public: void getBoundingBoxPos(const Mesh *model, int *x1, int *y1, int *x2, int *y2); void startActorDraw(const Math::Vector3d &pos, float scale, const Math::Angle &yaw, - const Math::Angle &pitch, const Math::Angle &roll); + const Math::Angle &pitch, const Math::Angle &roll, const bool inOverworld, + const float alpha); void finishActorDraw(); void setShadow(Shadow *shadow); void drawShadowPlanes(); @@ -127,6 +128,7 @@ private: int _smushWidth; int _smushHeight; Graphics::PixelBuffer _storedDisplay; + float _alpha; void readPixels(int x, int y, int width, int height, uint8 *buffer); void blit(const Graphics::PixelFormat &format, BlitImage *blit, byte *dst, byte *src, int x, int y, int width, int height, bool trans);