GRAPHICS: Add shadow mode to grim actors [OpenGLS]

This commit is contained in:
Dries Harnie 2014-01-22 23:43:10 +01:00
parent 6c8a35e53b
commit ca20357bd5
2 changed files with 44 additions and 1 deletions

View file

@ -456,6 +456,26 @@ void GfxOpenGLS::startActorDraw(const Actor *actor) {
_actorProgram->setUniform("texcropZBuf", _zBufTexCrop); _actorProgram->setUniform("texcropZBuf", _zBufTexCrop);
_actorProgram->setUniform("screenSize", Math::Vector2d(_screenWidth, _screenHeight)); _actorProgram->setUniform("screenSize", Math::Vector2d(_screenWidth, _screenHeight));
if (_currentShadowArray) {
const Sector *shadowSector = _currentShadowArray->planeList.front().sector;
const Math::Vector3d color = Math::Vector3d(_shadowColorR, _shadowColorG, _shadowColorB) / 255.f;
Math::Vector3d normal = shadowSector->getNormal();
if (!_currentShadowArray->dontNegate)
normal = -normal;
_actorProgram->setUniform("shadow._active", true);
_actorProgram->setUniform("shadow._color", color);
_actorProgram->setUniform("shadow._light", _currentShadowArray->pos);
_actorProgram->setUniform("shadow._point", shadowSector->getVertices()[0]);
_actorProgram->setUniform("shadow._normal", normal);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glEnable(GL_POLYGON_OFFSET_FILL);
} else {
_actorProgram->setUniform("shadow._active", false);
}
_actorProgram->setUniform("lightsEnabled", _lightsEnabled); _actorProgram->setUniform("lightsEnabled", _lightsEnabled);
if (_lightsEnabled) { if (_lightsEnabled) {
for (int i = 0; i < _maxLights; ++i) { for (int i = 0; i < _maxLights; ++i) {
@ -482,6 +502,7 @@ void GfxOpenGLS::startActorDraw(const Actor *actor) {
void GfxOpenGLS::finishActorDraw() { void GfxOpenGLS::finishActorDraw() {
_currentActor = NULL; _currentActor = NULL;
glDisable(GL_POLYGON_OFFSET_FILL);
} }
void GfxOpenGLS::setShadow(Shadow *shadow) { void GfxOpenGLS::setShadow(Shadow *shadow) {
@ -654,7 +675,8 @@ void GfxOpenGLS::drawMesh(const Mesh *mesh) {
faces += 3 * (mesh->_faces[i]._numVertices - 2); faces += 3 * (mesh->_faces[i]._numVertices - 2);
} }
actorShader->setUniform("textured", face->_texVertices ? GL_TRUE : GL_FALSE); bool textured = face->_texVertices && ! _currentShadowArray;
actorShader->setUniform("textured", textured ? GL_TRUE : GL_FALSE);
actorShader->setUniform("texScale", Math::Vector2d(_selectedTexture->_width, _selectedTexture->_height)); actorShader->setUniform("texScale", Math::Vector2d(_selectedTexture->_width, _selectedTexture->_height));
glDrawArrays(GL_TRIANGLES, *(int *)face->_userData, faces); glDrawArrays(GL_TRIANGLES, *(int *)face->_userData, faces);

View file

@ -4,6 +4,14 @@ struct light {
vec4 _color; vec4 _color;
}; };
struct shadow_info {
bool _active;
vec3 _color;
vec3 _light;
vec3 _point;
vec3 _normal;
};
const int maxLights = 8; const int maxLights = 8;
const float DIFFUSE_FACTOR = 0.8; const float DIFFUSE_FACTOR = 0.8;
@ -19,6 +27,7 @@ uniform highp mat4 extraMatrix;
uniform highp vec2 texScale; uniform highp vec2 texScale;
uniform bool textured; uniform bool textured;
uniform light lights[maxLights]; uniform light lights[maxLights];
uniform shadow_info shadow;
uniform bool lightsEnabled; uniform bool lightsEnabled;
out vec2 Texcoord; out vec2 Texcoord;
@ -32,6 +41,15 @@ void main()
extraMatrix * extraMatrix *
pos; pos;
// See http://en.wikipedia.org/wiki/Line-plane_intersection
if (shadow._active) {
pos /= pos.w;
vec3 l = pos.xyz - shadow._light;
float d = dot(shadow._point - shadow._light, shadow._normal) / dot(l, shadow._normal);
vec3 p = shadow._light + d * l;
pos = vec4(p, 1.0);
}
gl_Position = projMatrix * viewMatrix * pos; gl_Position = projMatrix * viewMatrix * pos;
if (textured) { if (textured) {
@ -69,5 +87,8 @@ void main()
Color = color * vec4(light, 1.0); Color = color * vec4(light, 1.0);
} else */ { } else */ {
Color = color; Color = color;
if (shadow._active) {
Color = vec4(shadow._color, 1.0);
}
} }
} }