EMI: render overworld actors using a straight coord system

This commit is contained in:
Dries Harnie 2012-04-13 19:45:33 +02:00
parent c27894e85e
commit d7ee515961
6 changed files with 76 additions and 29 deletions

View file

@ -1298,14 +1298,15 @@ void Actor::draw() {
g_driver->setShadowMode(); g_driver->setShadowMode();
if (g_driver->isHardwareAccelerated()) if (g_driver->isHardwareAccelerated())
g_driver->drawShadowPlanes(); 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(); costume->draw();
g_driver->finishActorDraw(); g_driver->finishActorDraw();
g_driver->clearShadowMode(); g_driver->clearShadowMode();
g_driver->setShadow(NULL); g_driver->setShadow(NULL);
} }
// normal draw actor // 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(); costume->draw();
g_driver->finishActorDraw(); g_driver->finishActorDraw();
} }
@ -1315,7 +1316,7 @@ void Actor::draw() {
x1 = y1 = 1000; x1 = y1 = 1000;
x2 = y2 = -1000; x2 = y2 = -1000;
if (!_costumeStack.empty()) { 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); _costumeStack.back()->getBoundingBox(&x1, &y1, &x2, &y2);
g_driver->finishActorDraw(); g_driver->finishActorDraw();
} }

View file

@ -113,7 +113,9 @@ public:
virtual void getBoundingBoxPos(const Mesh *mesh, int *x1, int *y1, int *x2, int *y2) = 0; 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, 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 finishActorDraw() = 0;
virtual void setShadow(Shadow *shadow) = 0; virtual void setShadow(Shadow *shadow) = 0;
virtual void drawShadowPlanes() = 0; virtual void drawShadowPlanes() = 0;

View file

@ -95,6 +95,7 @@ GfxOpenGL::GfxOpenGL() {
g_driver = this; g_driver = this;
_storedDisplay = NULL; _storedDisplay = NULL;
_emergFont = 0; _emergFont = 0;
_alpha = 1.f;
} }
GfxOpenGL::~GfxOpenGL() { 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, 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); glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPushMatrix(); 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); glColor3f(_shadowColorR / 255.0f, _shadowColorG / 255.0f, _shadowColorB / 255.0f);
glShadowProjection(_currentShadowArray->pos, shadowSector->getVertices()[0], shadowSector->getNormal(), _currentShadowArray->dontNegate); glShadowProjection(_currentShadowArray->pos, shadowSector->getVertices()[0], shadowSector->getNormal(), _currentShadowArray->dontNegate);
} }
glTranslatef(pos.x(), pos.y(), pos.z());
glScalef(scale, scale, scale); if (alpha < 1.f) {
// EMI uses Y axis as down-up, so we need to rotate differently. _alpha = alpha;
if (g_grim->getGameType() == GType_MONKEY4) { glEnable(GL_BLEND);
glRotatef(yaw.getDegrees(), 0, -1, 0); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glRotatef(pitch.getDegrees(), 1, 0, 0); }
glRotatef(roll.getDegrees(), 0, 0, 1);
if (inOverworld) {
glLoadIdentity();
glScalef(1.0, 1.0, -1.0);
glTranslatef(pos.x(), pos.y(), pos.z());
} else { } else {
glRotatef(yaw.getDegrees(), 0, 0, 1); glTranslatef(pos.x(), pos.y(), pos.z());
glRotatef(pitch.getDegrees(), 1, 0, 0); glScalef(scale, scale, scale);
glRotatef(roll.getDegrees(), 0, 1, 0); // 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() { void GfxOpenGL::finishActorDraw() {
glPopMatrix(); glPopMatrix();
if (_alpha < 1.f) {
glDisable(GL_BLEND);
_alpha = 1.f;
}
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
if (_currentShadowArray) { if (_currentShadowArray) {
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
@ -501,7 +520,7 @@ void GfxOpenGL::drawEMIModelFace(const EMIModel* model, const EMIMeshFace* face)
if (face->_hasTexture) { if (face->_hasTexture) {
glTexCoord2f(model->_texVerts[index].getX(), model->_texVerts[index].getY()); 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 normal = model->_normals[index];
Math::Vector3d vertex = model->_drawVertices[index]; Math::Vector3d vertex = model->_drawVertices[index];

View file

@ -62,7 +62,8 @@ public:
void getBoundingBoxPos(const Mesh *model, int *x1, int *y1, int *x2, int *y2); 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, 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 finishActorDraw();
void setShadow(Shadow *shadow); void setShadow(Shadow *shadow);
void drawShadowPlanes(); void drawShadowPlanes();
@ -136,6 +137,7 @@ private:
bool _useDimShader; bool _useDimShader;
GLuint _dimFragProgram; GLuint _dimFragProgram;
GLint _maxLights; GLint _maxLights;
float _alpha;
}; };
} // end of namespace Grim } // end of namespace Grim

View file

@ -229,6 +229,7 @@ GfxTinyGL::GfxTinyGL() {
g_driver = this; g_driver = this;
_zb = NULL; _zb = NULL;
_storedDisplay = NULL; _storedDisplay = NULL;
_alpha = 1.f;
} }
GfxTinyGL::~GfxTinyGL() { 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, 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); tglEnable(TGL_TEXTURE_2D);
tglMatrixMode(TGL_MODELVIEW); tglMatrixMode(TGL_MODELVIEW);
tglPushMatrix(); 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); tglShadowProjection(_currentShadowArray->pos, shadowSector->getVertices()[0], shadowSector->getNormal(), _currentShadowArray->dontNegate);
} }
tglTranslatef(pos.x(), pos.y(), pos.z()); // FIXME: TinyGL doesn't seem to support translucency.
tglScalef(scale, scale, scale); if (alpha < 1.f) {
// EMI uses Y axis as down-up, so we need to rotate differently. _alpha = alpha;
if (g_grim->getGameType() == GType_MONKEY4) { // tglEnable(TGL_BLEND);
tglRotatef(yaw.getDegrees(), 0, -1, 0); // tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
tglRotatef(pitch.getDegrees(), 1, 0, 0); }
tglRotatef(roll.getDegrees(), 0, 0, 1);
if (inOverworld) {
tglLoadIdentity();
tglScalef(1.0, 1.0, -1.0);
tglTranslatef(pos.x(), pos.y(), pos.z());
} else { } else {
tglRotatef(yaw.getDegrees(), 0, 0, 1); tglTranslatef(pos.x(), pos.y(), pos.z());
tglRotatef(pitch.getDegrees(), 1, 0, 0); tglScalef(scale, scale, scale);
tglRotatef(roll.getDegrees(), 0, 1, 0); // 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(); tglPopMatrix();
tglDisable(TGL_TEXTURE_2D); tglDisable(TGL_TEXTURE_2D);
// FIXME: TinyGL doesn't seem to support translucency.
if (_alpha < 1.f) {
// tglDisable(TGL_BLEND);
_alpha = 1.f;
}
if (_currentShadowArray) { if (_currentShadowArray) {
tglSetShadowMaskBuf(NULL); tglSetShadowMaskBuf(NULL);
}/* else { }/* else {

View file

@ -54,7 +54,8 @@ public:
void getBoundingBoxPos(const Mesh *model, int *x1, int *y1, int *x2, int *y2); 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, 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 finishActorDraw();
void setShadow(Shadow *shadow); void setShadow(Shadow *shadow);
void drawShadowPlanes(); void drawShadowPlanes();
@ -127,6 +128,7 @@ private:
int _smushWidth; int _smushWidth;
int _smushHeight; int _smushHeight;
Graphics::PixelBuffer _storedDisplay; Graphics::PixelBuffer _storedDisplay;
float _alpha;
void readPixels(int x, int y, int width, int height, uint8 *buffer); 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); void blit(const Graphics::PixelFormat &format, BlitImage *blit, byte *dst, byte *src, int x, int y, int width, int height, bool trans);