GRIM/EMI: Refactor GfxBase::startActorDraw

This commit is contained in:
Dries Harnie 2013-12-04 14:26:44 +01:00 committed by Dries Harnie
parent fa9a866e54
commit b1a910c800
7 changed files with 35 additions and 26 deletions

View file

@ -1565,17 +1565,16 @@ void Actor::draw() {
}
// FIXME: if isAttached(), factor in the joint rotation as well.
Math::Vector3d absPos = getWorldPos();
const Math::Quaternion rot = getRotationQuat();
const Math::Vector3d &absPos = getWorldPos();
if (!_costumeStack.empty()) {
g_grim->getCurrSet()->setupLights(absPos);
if (g_grim->getGameType() == GType_GRIM) {
Costume *costume = _costumeStack.back();
drawCostume(costume, absPos, rot);
drawCostume(costume);
} else {
for (Common::List<Costume *>::iterator it = _costumeStack.begin(); it != _costumeStack.end(); ++it) {
Costume *costume = *it;
drawCostume(costume, absPos, rot);
drawCostume(costume);
}
}
}
@ -1585,7 +1584,7 @@ void Actor::draw() {
x1 = y1 = 1000;
x2 = y2 = -1000;
if (!_costumeStack.empty()) {
g_driver->startActorDraw(absPos, _scale, rot, _inOverworld, 1.f, false);
g_driver->startActorDraw(this);
_costumeStack.back()->getBoundingBox(&x1, &y1, &x2, &y2);
g_driver->finishActorDraw();
}
@ -1607,9 +1606,7 @@ void Actor::draw() {
_drawnToClean = false;
}
void Actor::drawCostume(Costume *costume, const Math::Vector3d &absPos, const Math::Quaternion &rot) {
const float alpha = _alphaMode != AlphaOff ? _globalAlpha : 1.f;
const bool depthOnly = getSortOrder() >= 100;
void Actor::drawCostume(Costume *costume) {
for (int l = 0; l < MAX_SHADOWS; l++) {
if (!shouldDrawShadow(l))
continue;
@ -1617,7 +1614,7 @@ void Actor::drawCostume(Costume *costume, const Math::Vector3d &absPos, const Ma
g_driver->setShadowMode();
if (g_driver->isHardwareAccelerated())
g_driver->drawShadowPlanes();
g_driver->startActorDraw(absPos, _scale, rot, _inOverworld, alpha, depthOnly);
g_driver->startActorDraw(this);
costume->draw();
g_driver->finishActorDraw();
g_driver->clearShadowMode();
@ -1627,7 +1624,7 @@ void Actor::drawCostume(Costume *costume, const Math::Vector3d &absPos, const Ma
bool isShadowCostume = costume->getFilename().equals("fx/dumbshadow.cos");
if (!isShadowCostume || (isShadowCostume && _costumeStack.size() > 1 && _shadowActive)) {
// normal draw actor
g_driver->startActorDraw(absPos, _scale, rot, _inOverworld, alpha, depthOnly);
g_driver->startActorDraw(this);
costume->draw();
g_driver->finishActorDraw();
}

View file

@ -536,7 +536,7 @@ private:
bool shouldDrawShadow(int shadowId);
void stopTalking();
bool stopMumbleChore();
void drawCostume(Costume *costume, const Math::Vector3d &absPos, const Math::Quaternion &rot);
void drawCostume(Costume *costume);
/**
* Given a start point and a destination this function returns a position
* that doesn't collide with any actor.

View file

@ -37,6 +37,7 @@ namespace Graphics {
namespace Grim {
struct Shadow;
class Actor;
class SaveGame;
class BitmapData;
class Bitmap;
@ -114,9 +115,7 @@ public:
virtual void flipBuffer() = 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::Quaternion &quat,
const bool inOverworld, const float alpha, const bool depthOnly) = 0;
virtual void startActorDraw(const Actor *act) = 0;
virtual void finishActorDraw() = 0;
virtual void setShadow(Shadow *shadow) = 0;
virtual void drawShadowPlanes() = 0;

View file

@ -379,8 +379,8 @@ void GfxOpenGL::getBoundingBoxPos(const Mesh *model, int *x1, int *y1, int *x2,
*y2 = (int)bottom;
}
void GfxOpenGL::startActorDraw(const Math::Vector3d &pos, float scale, const Math::Quaternion &quat,
const bool inOverworld, const float alpha, const bool depthOnly) {
void GfxOpenGL::startActorDraw(const Actor *actor) {
_currentActor = actor;
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
@ -401,13 +401,18 @@ void GfxOpenGL::startActorDraw(const Math::Vector3d &pos, float scale, const Mat
glShadowProjection(_currentShadowArray->pos, shadowSector->getVertices()[0], shadowSector->getNormal(), _currentShadowArray->dontNegate);
}
const float alpha = actor->getEffectiveAlpha();
if (alpha < 1.f) {
_alpha = alpha;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
if (inOverworld) {
const Math::Vector3d &pos = actor->getWorldPos();
const Math::Quaternion &quat = actor->getRotationQuat();
const float &scale = actor->getScale();
if (actor->isInOverworld()) {
// At distance 3.2, a 6.4x4.8 actor fills the screen.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@ -431,7 +436,7 @@ void GfxOpenGL::startActorDraw(const Math::Vector3d &pos, float scale, const Mat
glMultMatrixf(quat.toMatrix().getData());
}
if (depthOnly) {
if (actor->getSortOrder() >= 100) {
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_TRUE);
}
@ -454,6 +459,7 @@ void GfxOpenGL::finishActorDraw() {
glDisable(GL_POLYGON_OFFSET_FILL);
}
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
_currentActor = NULL;
}
void GfxOpenGL::setShadow(Shadow *shadow) {

View file

@ -61,8 +61,7 @@ public:
void getBoundingBoxPos(const Mesh *model, int *x1, int *y1, int *x2, int *y2);
void startActorDraw(const Math::Vector3d &pos, float scale, const Math::Quaternion &quat,
const bool inOverworld, const float alpha, const bool depthOnly);
void startActorDraw(const Actor *actor);
void finishActorDraw();
void setShadow(Shadow *shadow);
void drawShadowPlanes();
@ -137,6 +136,7 @@ private:
GLuint _dimFragProgram;
GLint _maxLights;
float _alpha;
const Actor *_currentActor;
};
} // end of namespace Grim

View file

@ -512,8 +512,8 @@ void GfxTinyGL::getBoundingBoxPos(const Mesh *model, int *x1, int *y1, int *x2,
}*/
}
void GfxTinyGL::startActorDraw(const Math::Vector3d &pos, float scale, const Math::Quaternion &quat,
const bool inOverworld, const float alpha, const bool depthOnly) {
void GfxTinyGL::startActorDraw(const Actor *actor) {
_currentActor = actor;
tglEnable(TGL_TEXTURE_2D);
tglMatrixMode(TGL_PROJECTION);
tglPushMatrix();
@ -535,13 +535,18 @@ void GfxTinyGL::startActorDraw(const Math::Vector3d &pos, float scale, const Mat
}
// FIXME: TinyGL doesn't seem to support translucency.
const float alpha = actor->getEffectiveAlpha();
if (alpha < 1.f) {
_alpha = alpha;
// tglEnable(TGL_BLEND);
// tglBlendFunc(TGL_SRC_ALPHA, TGL_ONE_MINUS_SRC_ALPHA);
}
if (inOverworld) {
const Math::Vector3d &pos = actor->getWorldPos();
const Math::Quaternion &quat = actor->getRotationQuat();
const float &scale = actor->getScale();
if (actor->isInOverworld()) {
tglMatrixMode(TGL_PROJECTION);
tglLoadIdentity();
float right = 1;
@ -564,8 +569,9 @@ void GfxTinyGL::startActorDraw(const Math::Vector3d &pos, float scale, const Mat
tglMultMatrixf(quat.toMatrix().getData());
}
if (depthOnly)
if (actor->getSortOrder() >= 100) {
tglColorMask(false, false, false, false);
}
}
void GfxTinyGL::finishActorDraw() {
@ -602,6 +608,7 @@ void GfxTinyGL::finishActorDraw() {
}*/
tglColorMask(TGL_TRUE, TGL_TRUE, TGL_TRUE, TGL_TRUE);
_currentActor = NULL;
}
void GfxTinyGL::drawShadowPlanes() {

View file

@ -57,8 +57,7 @@ public:
void getBoundingBoxPos(const Mesh *model, int *x1, int *y1, int *x2, int *y2);
void startActorDraw(const Math::Vector3d &pos, float scale, const Math::Quaternion &quat,
const bool inOverworld, const float alpha, const bool depthOnly);
void startActorDraw(const Actor *actor);
void finishActorDraw();
void setShadow(Shadow *shadow);
void drawShadowPlanes();
@ -137,6 +136,7 @@ private:
float _alpha;
Common::HashMap<int, TinyGL::Buffer *> _buffers;
uint _bufferId;
const Actor *_currentActor;
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);