mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-27 05:32:45 +00:00
GRIM: Simplify shaders for Raspberry PI (#2618)
* GRIM: Simplify shaders for Raspberry PI
This commit is contained in:
parent
cb2ae8f844
commit
d76faf125c
@ -113,12 +113,18 @@ shaders/grim_emerg.fragment FILE "engines/grim/shaders/grim_emerg.fr
|
|||||||
shaders/grim_emerg.vertex FILE "engines/grim/shaders/grim_emerg.vertex"
|
shaders/grim_emerg.vertex FILE "engines/grim/shaders/grim_emerg.vertex"
|
||||||
shaders/emi_actor.fragment FILE "engines/grim/shaders/emi_actor.fragment"
|
shaders/emi_actor.fragment FILE "engines/grim/shaders/emi_actor.fragment"
|
||||||
shaders/emi_actor.vertex FILE "engines/grim/shaders/emi_actor.vertex"
|
shaders/emi_actor.vertex FILE "engines/grim/shaders/emi_actor.vertex"
|
||||||
|
shaders/emi_actorlights.fragment FILE "engines/grim/shaders/emi_actorlights.fragment"
|
||||||
|
shaders/emi_actorlights.vertex FILE "engines/grim/shaders/emi_actorlights.vertex"
|
||||||
shaders/emi_background.fragment FILE "engines/grim/shaders/emi_background.fragment"
|
shaders/emi_background.fragment FILE "engines/grim/shaders/emi_background.fragment"
|
||||||
shaders/emi_background.vertex FILE "engines/grim/shaders/emi_background.vertex"
|
shaders/emi_background.vertex FILE "engines/grim/shaders/emi_background.vertex"
|
||||||
shaders/emi_dimplane.fragment FILE "engines/grim/shaders/emi_dimplane.fragment"
|
shaders/emi_dimplane.fragment FILE "engines/grim/shaders/emi_dimplane.fragment"
|
||||||
shaders/emi_dimplane.vertex FILE "engines/grim/shaders/emi_dimplane.vertex"
|
shaders/emi_dimplane.vertex FILE "engines/grim/shaders/emi_dimplane.vertex"
|
||||||
|
shaders/emi_sprite.fragment FILE "engines/grim/shaders/emi_sprite.fragment"
|
||||||
|
shaders/emi_sprite.vertex FILE "engines/grim/shaders/emi_sprite.vertex"
|
||||||
shaders/grim_actor.fragment FILE "engines/grim/shaders/grim_actor.fragment"
|
shaders/grim_actor.fragment FILE "engines/grim/shaders/grim_actor.fragment"
|
||||||
shaders/grim_actor.vertex FILE "engines/grim/shaders/grim_actor.vertex"
|
shaders/grim_actor.vertex FILE "engines/grim/shaders/grim_actor.vertex"
|
||||||
|
shaders/grim_actorlights.fragment FILE "engines/grim/shaders/grim_actorlights.fragment"
|
||||||
|
shaders/grim_actorlights.vertex FILE "engines/grim/shaders/grim_actorlights.vertex"
|
||||||
shaders/grim_background.fragment FILE "engines/grim/shaders/grim_background.fragment"
|
shaders/grim_background.fragment FILE "engines/grim/shaders/grim_background.fragment"
|
||||||
shaders/grim_background.vertex FILE "engines/grim/shaders/grim_background.vertex"
|
shaders/grim_background.vertex FILE "engines/grim/shaders/grim_background.vertex"
|
||||||
shaders/grim_primitive.fragment FILE "engines/grim/shaders/grim_primitive.fragment"
|
shaders/grim_primitive.fragment FILE "engines/grim/shaders/grim_primitive.fragment"
|
||||||
|
@ -117,6 +117,7 @@ struct FontUserData {
|
|||||||
|
|
||||||
struct EMIModelUserData {
|
struct EMIModelUserData {
|
||||||
OpenGL::ShaderGL *_shader;
|
OpenGL::ShaderGL *_shader;
|
||||||
|
OpenGL::ShaderGL *_shaderLights;
|
||||||
uint32 _texCoordsVBO;
|
uint32 _texCoordsVBO;
|
||||||
uint32 _colorMapVBO;
|
uint32 _colorMapVBO;
|
||||||
uint32 _verticesVBO;
|
uint32 _verticesVBO;
|
||||||
@ -125,6 +126,7 @@ struct EMIModelUserData {
|
|||||||
|
|
||||||
struct ModelUserData {
|
struct ModelUserData {
|
||||||
OpenGL::ShaderGL *_shader;
|
OpenGL::ShaderGL *_shader;
|
||||||
|
OpenGL::ShaderGL *_shaderLights;
|
||||||
uint32 _meshInfoVBO;
|
uint32 _meshInfoVBO;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -220,6 +222,7 @@ GfxOpenGLS::GfxOpenGLS() {
|
|||||||
_textProgram = nullptr;
|
_textProgram = nullptr;
|
||||||
_emergProgram = nullptr;
|
_emergProgram = nullptr;
|
||||||
_actorProgram = nullptr;
|
_actorProgram = nullptr;
|
||||||
|
_actorLightsProgram = nullptr;
|
||||||
_spriteProgram = nullptr;
|
_spriteProgram = nullptr;
|
||||||
_primitiveProgram = nullptr;
|
_primitiveProgram = nullptr;
|
||||||
_irisProgram = nullptr;
|
_irisProgram = nullptr;
|
||||||
@ -244,6 +247,7 @@ GfxOpenGLS::~GfxOpenGLS() {
|
|||||||
delete _textProgram;
|
delete _textProgram;
|
||||||
delete _emergProgram;
|
delete _emergProgram;
|
||||||
delete _actorProgram;
|
delete _actorProgram;
|
||||||
|
delete _actorLightsProgram;
|
||||||
delete _spriteProgram;
|
delete _spriteProgram;
|
||||||
delete _primitiveProgram;
|
delete _primitiveProgram;
|
||||||
delete _irisProgram;
|
delete _irisProgram;
|
||||||
@ -375,7 +379,8 @@ void GfxOpenGLS::setupShaders() {
|
|||||||
|
|
||||||
static const char* actorAttributes[] = {"position", "texcoord", "color", "normal", NULL};
|
static const char* actorAttributes[] = {"position", "texcoord", "color", "normal", NULL};
|
||||||
_actorProgram = OpenGL::ShaderGL::fromFiles(isEMI ? "emi_actor" : "grim_actor", actorAttributes);
|
_actorProgram = OpenGL::ShaderGL::fromFiles(isEMI ? "emi_actor" : "grim_actor", actorAttributes);
|
||||||
_spriteProgram = OpenGL::ShaderGL::fromFiles(isEMI ? "emi_actor" : "grim_actor", actorAttributes);
|
_actorLightsProgram = OpenGL::ShaderGL::fromFiles(isEMI ? "emi_actorlights" : "grim_actorlights", actorAttributes);
|
||||||
|
_spriteProgram = OpenGL::ShaderGL::fromFiles(isEMI ? "emi_sprite" : "grim_actor", actorAttributes);
|
||||||
|
|
||||||
static const char* primAttributes[] = { "position", NULL };
|
static const char* primAttributes[] = { "position", NULL };
|
||||||
_shadowPlaneProgram = OpenGL::ShaderGL::fromFiles("grim_shadowplane", primAttributes);
|
_shadowPlaneProgram = OpenGL::ShaderGL::fromFiles("grim_shadowplane", primAttributes);
|
||||||
@ -650,7 +655,6 @@ void GfxOpenGLS::getActorScreenBBox(const Actor *actor, Common::Point &p1, Commo
|
|||||||
|
|
||||||
void GfxOpenGLS::startActorDraw(const Actor *actor) {
|
void GfxOpenGLS::startActorDraw(const Actor *actor) {
|
||||||
_currentActor = actor;
|
_currentActor = actor;
|
||||||
_actorProgram->use();
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
const Math::Vector3d &pos = actor->getWorldPos();
|
const Math::Vector3d &pos = actor->getWorldPos();
|
||||||
@ -660,6 +664,8 @@ void GfxOpenGLS::startActorDraw(const Actor *actor) {
|
|||||||
Math::Matrix4 viewMatrix = _viewMatrix;
|
Math::Matrix4 viewMatrix = _viewMatrix;
|
||||||
viewMatrix.transpose();
|
viewMatrix.transpose();
|
||||||
|
|
||||||
|
OpenGL::ShaderGL *shaders[] = { _spriteProgram, _actorProgram, _actorLightsProgram };
|
||||||
|
|
||||||
if (g_grim->getGameType() == GType_MONKEY4) {
|
if (g_grim->getGameType() == GType_MONKEY4) {
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glFrontFace(GL_CW);
|
glFrontFace(GL_CW);
|
||||||
@ -676,48 +682,25 @@ void GfxOpenGLS::startActorDraw(const Actor *actor) {
|
|||||||
normalMatrix.invertAffineOrthonormal();
|
normalMatrix.invertAffineOrthonormal();
|
||||||
modelMatrix.transpose();
|
modelMatrix.transpose();
|
||||||
|
|
||||||
_actorProgram->setUniform("modelMatrix", modelMatrix);
|
for (int i = 0; i < 3; i++) {
|
||||||
if (actor->isInOverworld()) {
|
shaders[i]->use();
|
||||||
_actorProgram->setUniform("viewMatrix", viewMatrix);
|
shaders[i]->setUniform("modelMatrix", modelMatrix);
|
||||||
_actorProgram->setUniform("projMatrix", _overworldProjMatrix);
|
if (actor->isInOverworld()) {
|
||||||
_actorProgram->setUniform("cameraPos", Math::Vector3d(0,0,0));
|
shaders[i]->setUniform("viewMatrix", viewMatrix);
|
||||||
} else {
|
shaders[i]->setUniform("projMatrix", _overworldProjMatrix);
|
||||||
_actorProgram->setUniform("viewMatrix", viewRot);
|
shaders[i]->setUniform("cameraPos", Math::Vector3d(0,0,0));
|
||||||
_actorProgram->setUniform("projMatrix", _projMatrix);
|
} else {
|
||||||
_actorProgram->setUniform("cameraPos", _currentPos);
|
shaders[i]->setUniform("viewMatrix", viewRot);
|
||||||
|
shaders[i]->setUniform("projMatrix", _projMatrix);
|
||||||
|
shaders[i]->setUniform("cameraPos", _currentPos);
|
||||||
|
}
|
||||||
|
shaders[i]->setUniform("normalMatrix", normalMatrix);
|
||||||
|
|
||||||
|
shaders[i]->setUniform("useVertexAlpha", GL_FALSE);
|
||||||
|
shaders[i]->setUniform("uniformColor", color);
|
||||||
|
shaders[i]->setUniform1f("alphaRef", 0.0f);
|
||||||
|
shaders[i]->setUniform1f("meshAlpha", 1.0f);
|
||||||
}
|
}
|
||||||
_actorProgram->setUniform("normalMatrix", normalMatrix);
|
|
||||||
|
|
||||||
_actorProgram->setUniform("isBillboard", GL_FALSE);
|
|
||||||
_actorProgram->setUniform("useVertexAlpha", GL_FALSE);
|
|
||||||
_actorProgram->setUniform("uniformColor", color);
|
|
||||||
_actorProgram->setUniform1f("alphaRef", 0.0f);
|
|
||||||
_actorProgram->setUniform1f("meshAlpha", 1.0f);
|
|
||||||
|
|
||||||
// set the uniform parameter for _spriteProgram
|
|
||||||
// since they are needed by emi_actor.{fragment,vertex}
|
|
||||||
// in drawSprite()
|
|
||||||
_spriteProgram->use();
|
|
||||||
_spriteProgram->setUniform("modelMatrix", modelMatrix);
|
|
||||||
if (actor->isInOverworld()) {
|
|
||||||
_spriteProgram->setUniform("viewMatrix", viewMatrix);
|
|
||||||
_spriteProgram->setUniform("projMatrix", _overworldProjMatrix);
|
|
||||||
_spriteProgram->setUniform("cameraPos", Math::Vector3d(0,0,0));
|
|
||||||
} else {
|
|
||||||
_spriteProgram->setUniform("viewMatrix", viewRot);
|
|
||||||
_spriteProgram->setUniform("projMatrix", _projMatrix);
|
|
||||||
_spriteProgram->setUniform("cameraPos", _currentPos);
|
|
||||||
}
|
|
||||||
_spriteProgram->setUniform("normalMatrix", normalMatrix);
|
|
||||||
|
|
||||||
_spriteProgram->setUniform("actorPos", pos);
|
|
||||||
_spriteProgram->setUniform("isBillboard", GL_FALSE);
|
|
||||||
_spriteProgram->setUniform("useVertexAlpha", GL_FALSE);
|
|
||||||
_spriteProgram->setUniform("uniformColor", color);
|
|
||||||
_spriteProgram->setUniform1f("alphaRef", 0.0f);
|
|
||||||
_spriteProgram->setUniform1f("meshAlpha", 1.0f);
|
|
||||||
|
|
||||||
_actorProgram->use();
|
|
||||||
} else {
|
} else {
|
||||||
Math::Matrix4 modelMatrix = quat.toMatrix();
|
Math::Matrix4 modelMatrix = quat.toMatrix();
|
||||||
bool hasZBuffer = g_grim->getCurrSet()->getCurrSetup()->_bkgndZBm;
|
bool hasZBuffer = g_grim->getCurrSet()->getCurrSetup()->_bkgndZBm;
|
||||||
@ -728,16 +711,19 @@ void GfxOpenGLS::startActorDraw(const Actor *actor) {
|
|||||||
modelMatrix.setPosition(pos);
|
modelMatrix.setPosition(pos);
|
||||||
modelMatrix.transpose();
|
modelMatrix.transpose();
|
||||||
|
|
||||||
_actorProgram->setUniform("modelMatrix", modelMatrix);
|
for (int i = 0; i < 3; i++) {
|
||||||
_actorProgram->setUniform("viewMatrix", _viewMatrix);
|
shaders[i]->use();
|
||||||
_actorProgram->setUniform("projMatrix", _projMatrix);
|
shaders[i]->setUniform("modelMatrix", modelMatrix);
|
||||||
_actorProgram->setUniform("extraMatrix", extraMatrix);
|
shaders[i]->setUniform("viewMatrix", _viewMatrix);
|
||||||
_actorProgram->setUniform("tex", 0);
|
shaders[i]->setUniform("projMatrix", _projMatrix);
|
||||||
_actorProgram->setUniform("texZBuf", 1);
|
shaders[i]->setUniform("extraMatrix", extraMatrix);
|
||||||
_actorProgram->setUniform("hasZBuffer", hasZBuffer);
|
shaders[i]->setUniform("tex", 0);
|
||||||
_actorProgram->setUniform("texcropZBuf", _zBufTexCrop);
|
shaders[i]->setUniform("texZBuf", 1);
|
||||||
_actorProgram->setUniform("screenSize", Math::Vector2d(_screenWidth, _screenHeight));
|
shaders[i]->setUniform("hasZBuffer", hasZBuffer);
|
||||||
_actorProgram->setUniform1f("alphaRef", 0.5f);
|
shaders[i]->setUniform("texcropZBuf", _zBufTexCrop);
|
||||||
|
shaders[i]->setUniform("screenSize", Math::Vector2d(_screenWidth, _screenHeight));
|
||||||
|
shaders[i]->setUniform1f("alphaRef", 0.5f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_currentShadowArray) {
|
if (_currentShadowArray) {
|
||||||
@ -752,43 +738,48 @@ void GfxOpenGLS::startActorDraw(const Actor *actor) {
|
|||||||
if (!_currentShadowArray->dontNegate)
|
if (!_currentShadowArray->dontNegate)
|
||||||
normal = -normal;
|
normal = -normal;
|
||||||
|
|
||||||
_actorProgram->setUniform("shadow._active", true);
|
for (int i = 0; i < 3; i++) {
|
||||||
_actorProgram->setUniform("shadow._color", color);
|
shaders[i]->use();
|
||||||
_actorProgram->setUniform("shadow._light", _currentShadowArray->pos);
|
shaders[i]->setUniform("shadow._active", true);
|
||||||
_actorProgram->setUniform("shadow._point", shadowSector->getVertices()[0]);
|
shaders[i]->setUniform("shadow._color", color);
|
||||||
_actorProgram->setUniform("shadow._normal", normal);
|
shaders[i]->setUniform("shadow._light", _currentShadowArray->pos);
|
||||||
|
shaders[i]->setUniform("shadow._point", shadowSector->getVertices()[0]);
|
||||||
|
shaders[i]->setUniform("shadow._normal", normal);
|
||||||
|
}
|
||||||
|
|
||||||
glDepthMask(GL_FALSE);
|
glDepthMask(GL_FALSE);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_actorProgram->setUniform("shadow._active", false);
|
for (int i = 0; i < 3; i++) {
|
||||||
|
shaders[i]->use();
|
||||||
|
shaders[i]->setUniform("shadow._active", false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_actorProgram->setUniform("lightsEnabled", _lightsEnabled);
|
_actorLightsProgram->setUniform("hasAmbient", _hasAmbientLight);
|
||||||
_actorProgram->setUniform("hasAmbient", _hasAmbientLight);
|
|
||||||
if (_lightsEnabled) {
|
if (_lightsEnabled) {
|
||||||
for (int i = 0; i < _maxLights; ++i) {
|
for (int i = 0; i < _maxLights; ++i) {
|
||||||
const GLSLight &l = _lights[i];
|
const GLSLight &l = _lights[i];
|
||||||
Common::String uniform;
|
Common::String uniform;
|
||||||
uniform = Common::String::format("lights[%u]._position", i);
|
uniform = Common::String::format("lightsPosition[%u]", i);
|
||||||
|
|
||||||
_actorProgram->setUniform(uniform.c_str(), viewMatrix * l._position);
|
_actorLightsProgram->setUniform(uniform.c_str(), viewMatrix * l._position);
|
||||||
|
|
||||||
Math::Vector4d direction = l._direction;
|
Math::Vector4d direction = l._direction;
|
||||||
direction.w() = 0.0;
|
direction.w() = 0.0;
|
||||||
viewMatrix.transformVector(&direction);
|
viewMatrix.transformVector(&direction);
|
||||||
direction.w() = l._direction.w();
|
direction.w() = l._direction.w();
|
||||||
|
|
||||||
uniform = Common::String::format("lights[%u]._direction", i);
|
uniform = Common::String::format("lightsDirection[%u]", i);
|
||||||
_actorProgram->setUniform(uniform.c_str(), direction);
|
_actorLightsProgram->setUniform(uniform.c_str(), direction);
|
||||||
|
|
||||||
uniform = Common::String::format("lights[%u]._color", i);
|
uniform = Common::String::format("lightsColor[%u]", i);
|
||||||
_actorProgram->setUniform(uniform.c_str(), l._color);
|
_actorLightsProgram->setUniform(uniform.c_str(), l._color);
|
||||||
|
|
||||||
uniform = Common::String::format("lights[%u]._params", i);
|
uniform = Common::String::format("lightsParams[%u]", i);
|
||||||
_actorProgram->setUniform(uniform.c_str(), l._params);
|
_actorLightsProgram->setUniform(uniform.c_str(), l._params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -950,13 +941,17 @@ void GfxOpenGLS::drawEMIModelFace(const EMIModel* model, const EMIMeshFace* face
|
|||||||
face->_flags & EMIMeshFace::kUnknownBlend)
|
face->_flags & EMIMeshFace::kUnknownBlend)
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
const EMIModelUserData *mud = (const EMIModelUserData *)model->_userData;
|
const EMIModelUserData *mud = (const EMIModelUserData *)model->_userData;
|
||||||
mud->_shader->use();
|
OpenGL::ShaderGL *actorShader;
|
||||||
|
if ((face->_flags & EMIMeshFace::kNoLighting) ? false : _lightsEnabled)
|
||||||
|
actorShader = mud->_shaderLights;
|
||||||
|
else
|
||||||
|
actorShader = mud->_shader;
|
||||||
|
actorShader->use();
|
||||||
bool textured = face->_hasTexture && !_currentShadowArray;
|
bool textured = face->_hasTexture && !_currentShadowArray;
|
||||||
mud->_shader->setUniform("textured", textured ? GL_TRUE : GL_FALSE);
|
actorShader->setUniform("textured", textured ? GL_TRUE : GL_FALSE);
|
||||||
mud->_shader->setUniform("lightsEnabled", (face->_flags & EMIMeshFace::kNoLighting) ? false : _lightsEnabled);
|
actorShader->setUniform("swapRandB", _selectedTexture->_colorFormat == BM_BGRA || _selectedTexture->_colorFormat == BM_BGR888);
|
||||||
mud->_shader->setUniform("swapRandB", _selectedTexture->_colorFormat == BM_BGRA || _selectedTexture->_colorFormat == BM_BGR888);
|
actorShader->setUniform("useVertexAlpha", _selectedTexture->_colorFormat == BM_BGRA);
|
||||||
mud->_shader->setUniform("useVertexAlpha", _selectedTexture->_colorFormat == BM_BGRA);
|
actorShader->setUniform1f("meshAlpha", (model->_meshAlphaMode == Actor::AlphaReplace) ? model->_meshAlpha : 1.0f);
|
||||||
mud->_shader->setUniform1f("meshAlpha", (model->_meshAlphaMode == Actor::AlphaReplace) ? model->_meshAlpha : 1.0f);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, face->_indicesEBO);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, face->_indicesEBO);
|
||||||
|
|
||||||
@ -968,11 +963,14 @@ void GfxOpenGLS::drawMesh(const Mesh *mesh) {
|
|||||||
const ModelUserData *mud = (const ModelUserData *)mesh->_userData;
|
const ModelUserData *mud = (const ModelUserData *)mesh->_userData;
|
||||||
if (!mud)
|
if (!mud)
|
||||||
return;
|
return;
|
||||||
OpenGL::ShaderGL *actorShader = mud->_shader;
|
OpenGL::ShaderGL *actorShader;
|
||||||
|
if (_lightsEnabled && !isShadowModeActive())
|
||||||
|
actorShader = mud->_shaderLights;
|
||||||
|
else
|
||||||
|
actorShader = mud->_shader;
|
||||||
|
|
||||||
actorShader->use();
|
actorShader->use();
|
||||||
actorShader->setUniform("extraMatrix", _matrixStack.top());
|
actorShader->setUniform("extraMatrix", _matrixStack.top());
|
||||||
actorShader->setUniform("lightsEnabled", _lightsEnabled && !isShadowModeActive());
|
|
||||||
|
|
||||||
const Material *curMaterial = NULL;
|
const Material *curMaterial = NULL;
|
||||||
for (int i = 0; i < mesh->_numFaces;) {
|
for (int i = 0; i < mesh->_numFaces;) {
|
||||||
@ -1056,8 +1054,6 @@ void GfxOpenGLS::drawSprite(const Sprite *sprite) {
|
|||||||
_spriteProgram->setUniform("extraMatrix", extraMatrix);
|
_spriteProgram->setUniform("extraMatrix", extraMatrix);
|
||||||
_spriteProgram->setUniform("textured", GL_TRUE);
|
_spriteProgram->setUniform("textured", GL_TRUE);
|
||||||
_spriteProgram->setUniform("swapRandB", _selectedTexture->_colorFormat == BM_BGRA || _selectedTexture->_colorFormat == BM_BGR888);
|
_spriteProgram->setUniform("swapRandB", _selectedTexture->_colorFormat == BM_BGRA || _selectedTexture->_colorFormat == BM_BGR888);
|
||||||
_spriteProgram->setUniform("isBillboard", GL_TRUE);
|
|
||||||
_spriteProgram->setUniform("lightsEnabled", false);
|
|
||||||
if (g_grim->getGameType() == GType_GRIM) {
|
if (g_grim->getGameType() == GType_GRIM) {
|
||||||
_spriteProgram->setUniform1f("alphaRef", 0.5f);
|
_spriteProgram->setUniform1f("alphaRef", 0.5f);
|
||||||
} else if (sprite->_flags2 & Sprite::AlphaTest) {
|
} else if (sprite->_flags2 & Sprite::AlphaTest) {
|
||||||
@ -2013,6 +2009,13 @@ void GfxOpenGLS::createEMIModel(EMIModel *model) {
|
|||||||
actorShader->enableVertexAttribute("color", mud->_colorMapVBO, 4, GL_UNSIGNED_BYTE, GL_TRUE, 4 * sizeof(byte), 0);
|
actorShader->enableVertexAttribute("color", mud->_colorMapVBO, 4, GL_UNSIGNED_BYTE, GL_TRUE, 4 * sizeof(byte), 0);
|
||||||
mud->_shader = actorShader;
|
mud->_shader = actorShader;
|
||||||
|
|
||||||
|
actorShader = _actorLightsProgram->clone();
|
||||||
|
actorShader->enableVertexAttribute("position", mud->_verticesVBO, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
|
||||||
|
actorShader->enableVertexAttribute("normal", mud->_normalsVBO, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
|
||||||
|
actorShader->enableVertexAttribute("texcoord", mud->_texCoordsVBO, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0);
|
||||||
|
actorShader->enableVertexAttribute("color", mud->_colorMapVBO, 4, GL_UNSIGNED_BYTE, GL_TRUE, 4 * sizeof(byte), 0);
|
||||||
|
mud->_shaderLights = actorShader;
|
||||||
|
|
||||||
for (uint32 i = 0; i < model->_numFaces; ++i) {
|
for (uint32 i = 0; i < model->_numFaces; ++i) {
|
||||||
EMIMeshFace * face = &model->_faces[i];
|
EMIMeshFace * face = &model->_faces[i];
|
||||||
face->_indicesEBO = OpenGL::ShaderGL::createBuffer(GL_ELEMENT_ARRAY_BUFFER, face->_faceLength * 3 * sizeof(uint16), face->_indexes, GL_STATIC_DRAW);
|
face->_indicesEBO = OpenGL::ShaderGL::createBuffer(GL_ELEMENT_ARRAY_BUFFER, face->_faceLength * 3 * sizeof(uint16), face->_indexes, GL_STATIC_DRAW);
|
||||||
@ -2080,12 +2083,19 @@ void GfxOpenGLS::createMesh(Mesh *mesh) {
|
|||||||
|
|
||||||
mud->_meshInfoVBO = OpenGL::ShaderGL::createBuffer(GL_ARRAY_BUFFER, meshInfo.size() * sizeof(GrimVertex), &meshInfo[0], GL_STATIC_DRAW);
|
mud->_meshInfoVBO = OpenGL::ShaderGL::createBuffer(GL_ARRAY_BUFFER, meshInfo.size() * sizeof(GrimVertex), &meshInfo[0], GL_STATIC_DRAW);
|
||||||
|
|
||||||
OpenGL::ShaderGL *shader = _actorProgram->clone();
|
OpenGL::ShaderGL *actorShader = _actorProgram->clone();
|
||||||
mud->_shader = shader;
|
actorShader->enableVertexAttribute("position", mud->_meshInfoVBO, 3, GL_FLOAT, GL_FALSE, sizeof(GrimVertex), 0);
|
||||||
shader->enableVertexAttribute("position", mud->_meshInfoVBO, 3, GL_FLOAT, GL_FALSE, sizeof(GrimVertex), 0);
|
actorShader->enableVertexAttribute("texcoord", mud->_meshInfoVBO, 2, GL_FLOAT, GL_FALSE, sizeof(GrimVertex), 3 * sizeof(float));
|
||||||
shader->enableVertexAttribute("texcoord", mud->_meshInfoVBO, 2, GL_FLOAT, GL_FALSE, sizeof(GrimVertex), 3 * sizeof(float));
|
actorShader->enableVertexAttribute("normal", mud->_meshInfoVBO, 3, GL_FLOAT, GL_FALSE, sizeof(GrimVertex), 5 * sizeof(float));
|
||||||
shader->enableVertexAttribute("normal", mud->_meshInfoVBO, 3, GL_FLOAT, GL_FALSE, sizeof(GrimVertex), 5 * sizeof(float));
|
actorShader->disableVertexAttribute("color", Math::Vector4d(1.f, 1.f, 1.f, 1.f));
|
||||||
shader->disableVertexAttribute("color", Math::Vector4d(1.f, 1.f, 1.f, 1.f));
|
mud->_shader = actorShader;
|
||||||
|
|
||||||
|
actorShader = _actorLightsProgram->clone();
|
||||||
|
actorShader->enableVertexAttribute("position", mud->_meshInfoVBO, 3, GL_FLOAT, GL_FALSE, sizeof(GrimVertex), 0);
|
||||||
|
actorShader->enableVertexAttribute("texcoord", mud->_meshInfoVBO, 2, GL_FLOAT, GL_FALSE, sizeof(GrimVertex), 3 * sizeof(float));
|
||||||
|
actorShader->enableVertexAttribute("normal", mud->_meshInfoVBO, 3, GL_FLOAT, GL_FALSE, sizeof(GrimVertex), 5 * sizeof(float));
|
||||||
|
actorShader->disableVertexAttribute("color", Math::Vector4d(1.f, 1.f, 1.f, 1.f));
|
||||||
|
mud->_shaderLights = actorShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GfxOpenGLS::destroyMesh(const Mesh *mesh) {
|
void GfxOpenGLS::destroyMesh(const Mesh *mesh) {
|
||||||
|
@ -225,6 +225,7 @@ private:
|
|||||||
|
|
||||||
OpenGL::ShaderGL* _backgroundProgram;
|
OpenGL::ShaderGL* _backgroundProgram;
|
||||||
OpenGL::ShaderGL* _actorProgram;
|
OpenGL::ShaderGL* _actorProgram;
|
||||||
|
OpenGL::ShaderGL* _actorLightsProgram;
|
||||||
OpenGL::ShaderGL* _spriteProgram;
|
OpenGL::ShaderGL* _spriteProgram;
|
||||||
OpenGL::ShaderGL* _dimProgram;
|
OpenGL::ShaderGL* _dimProgram;
|
||||||
OpenGL::ShaderGL* _dimPlaneProgram;
|
OpenGL::ShaderGL* _dimPlaneProgram;
|
||||||
|
@ -10,20 +10,8 @@ uniform highp mat4 extraMatrix;
|
|||||||
uniform highp mat4 normalMatrix;
|
uniform highp mat4 normalMatrix;
|
||||||
uniform highp vec3 cameraPos;
|
uniform highp vec3 cameraPos;
|
||||||
uniform bool textured;
|
uniform bool textured;
|
||||||
uniform bool isBillboard;
|
|
||||||
uniform bool useVertexAlpha;
|
uniform bool useVertexAlpha;
|
||||||
uniform vec4 uniformColor;
|
uniform vec4 uniformColor;
|
||||||
uniform bool lightsEnabled;
|
|
||||||
uniform bool hasAmbient;
|
|
||||||
|
|
||||||
struct Light {
|
|
||||||
vec4 _position;
|
|
||||||
vec4 _direction;
|
|
||||||
vec4 _color;
|
|
||||||
vec4 _params;
|
|
||||||
};
|
|
||||||
const int maxLights = 8;
|
|
||||||
uniform Light lights[maxLights];
|
|
||||||
|
|
||||||
struct shadow_info {
|
struct shadow_info {
|
||||||
bool _active;
|
bool _active;
|
||||||
@ -41,34 +29,23 @@ out vec4 Color;
|
|||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 pos = vec4(position, 1.0);
|
vec4 pos = vec4(position, 1.0);
|
||||||
if (isBillboard) {
|
pos = modelMatrix * pos;
|
||||||
vec4 offset = modelMatrix * vec4(0.0, 0.0, 0.0, 1.0);
|
|
||||||
offset -= vec4(cameraPos * offset.w, 0.0);
|
|
||||||
offset = viewMatrix * offset;
|
|
||||||
|
|
||||||
pos = extraMatrix * pos;
|
// See http://en.wikipedia.org/wiki/Line-plane_intersection
|
||||||
pos += vec4(offset.xyz * pos.w, 0.0);
|
if (shadow._active) {
|
||||||
} else {
|
pos /= pos.w;
|
||||||
pos = modelMatrix * pos;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
// See http://en.wikipedia.org/wiki/Line-plane_intersection
|
pos -= vec4(cameraPos * pos.w, 0.0);
|
||||||
if (shadow._active) {
|
pos = viewMatrix * pos;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
pos -= vec4(cameraPos * pos.w, 0.0);
|
|
||||||
pos = viewMatrix * pos;
|
|
||||||
}
|
|
||||||
pos /= pos.w;
|
pos /= pos.w;
|
||||||
pos.z *= -1.0;
|
pos.z *= -1.0;
|
||||||
|
|
||||||
vec4 projectedPos = projMatrix * pos;
|
vec4 projectedPos = projMatrix * pos;
|
||||||
if (isBillboard)
|
|
||||||
projectedPos.z = ROUND(projectedPos.z);
|
|
||||||
|
|
||||||
gl_Position = projectedPos;
|
gl_Position = projectedPos;
|
||||||
|
|
||||||
@ -86,49 +63,4 @@ void main()
|
|||||||
Texcoord = vec2(0.0, 0.0);
|
Texcoord = vec2(0.0, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lightsEnabled) {
|
|
||||||
vec3 light = vec3(0.0, 0.0, 0.0);
|
|
||||||
vec3 normalEye = normalize((normalMatrix * vec4(normal, 1.0)).xyz);
|
|
||||||
|
|
||||||
for (int i = 0; i < maxLights; ++i) {
|
|
||||||
float intensity = lights[i]._color.w;
|
|
||||||
float light_type = lights[i]._position.w;
|
|
||||||
if (light_type >= 0.0) { // Not ambient
|
|
||||||
vec3 vertexToLight;
|
|
||||||
if (light_type > 0.0) { // positional light
|
|
||||||
float falloffNear = lights[i]._params.x;
|
|
||||||
float falloffFar = max(falloffNear, lights[i]._params.y);
|
|
||||||
vertexToLight = lights[i]._position.xyz - pos.xyz;
|
|
||||||
float dist = length(vertexToLight);
|
|
||||||
if (falloffFar == falloffNear) {
|
|
||||||
intensity = 0.0;
|
|
||||||
} else {
|
|
||||||
intensity *= clamp(1.0 - (dist - falloffNear) / (falloffFar - falloffNear), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
if (lights[i]._direction.w > -1.0) { // Spotlight
|
|
||||||
// See DirectX spotlight documentation
|
|
||||||
float cosAngle = -dot(normalize(vertexToLight), normalize(lights[i]._direction.xyz)); // rho
|
|
||||||
float cosPenumbra = clamp(lights[i]._params.w, 0.0, 1.0); // cos(theta / 2)
|
|
||||||
float cosUmbra = clamp(lights[i]._params.z, 0.0, cosPenumbra); // cos(phi / 2)
|
|
||||||
if (cosAngle <= cosPenumbra) {
|
|
||||||
if (cosAngle < cosUmbra || cosPenumbra == cosUmbra) {
|
|
||||||
intensity = 0.0;
|
|
||||||
} else {
|
|
||||||
intensity *= (cosAngle - cosUmbra) / (cosPenumbra - cosUmbra);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { // directional light
|
|
||||||
vertexToLight = -lights[i]._position.xyz;
|
|
||||||
}
|
|
||||||
intensity *= max(0.0, dot(normalEye, normalize(vertexToLight)));
|
|
||||||
}
|
|
||||||
light += lights[i]._color.xyz * intensity;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasAmbient)
|
|
||||||
light += vec3(0.5, 0.5, 0.5);
|
|
||||||
light /= max(1.0, max(max(light.x, light.y), light.z));
|
|
||||||
Color *= vec4(light, 1.0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
26
engines/grim/shaders/emi_actorlights.fragment
Normal file
26
engines/grim/shaders/emi_actorlights.fragment
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
in vec2 Texcoord;
|
||||||
|
in vec4 Color;
|
||||||
|
|
||||||
|
uniform sampler2D tex;
|
||||||
|
uniform bool textured;
|
||||||
|
uniform bool swapRandB;
|
||||||
|
uniform float alphaRef;
|
||||||
|
uniform float meshAlpha;
|
||||||
|
|
||||||
|
OUTPUT
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
outColor = Color;
|
||||||
|
if (textured) {
|
||||||
|
vec4 texColor = texture(tex, Texcoord);
|
||||||
|
#ifdef GL_ES
|
||||||
|
if (swapRandB)
|
||||||
|
texColor.rb = texColor.br;
|
||||||
|
#endif
|
||||||
|
outColor.rgba *= texColor.rgba;
|
||||||
|
outColor.a *= meshAlpha;
|
||||||
|
if (outColor.a < alphaRef)
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
}
|
116
engines/grim/shaders/emi_actorlights.vertex
Normal file
116
engines/grim/shaders/emi_actorlights.vertex
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
in vec3 position;
|
||||||
|
in vec2 texcoord;
|
||||||
|
in vec4 color;
|
||||||
|
in vec3 normal;
|
||||||
|
|
||||||
|
uniform highp mat4 modelMatrix;
|
||||||
|
uniform highp mat4 viewMatrix;
|
||||||
|
uniform highp mat4 projMatrix;
|
||||||
|
uniform highp mat4 extraMatrix;
|
||||||
|
uniform highp mat4 normalMatrix;
|
||||||
|
uniform highp vec3 cameraPos;
|
||||||
|
uniform bool textured;
|
||||||
|
uniform bool useVertexAlpha;
|
||||||
|
uniform vec4 uniformColor;
|
||||||
|
uniform bool hasAmbient;
|
||||||
|
|
||||||
|
const int maxLights = 8;
|
||||||
|
uniform vec4 lightsPosition[maxLights];
|
||||||
|
uniform vec4 lightsDirection[maxLights];
|
||||||
|
uniform vec4 lightsColor[maxLights];
|
||||||
|
uniform vec4 lightsParams[maxLights];
|
||||||
|
|
||||||
|
struct shadow_info {
|
||||||
|
bool _active;
|
||||||
|
vec3 _color;
|
||||||
|
vec3 _light;
|
||||||
|
vec3 _point;
|
||||||
|
vec3 _normal;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform shadow_info shadow;
|
||||||
|
|
||||||
|
out vec2 Texcoord;
|
||||||
|
out vec4 Color;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 pos = vec4(position, 1.0);
|
||||||
|
pos = modelMatrix * 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
pos -= vec4(cameraPos * pos.w, 0.0);
|
||||||
|
pos = viewMatrix * pos;
|
||||||
|
pos /= pos.w;
|
||||||
|
pos.z *= -1.0;
|
||||||
|
|
||||||
|
vec4 projectedPos = projMatrix * pos;
|
||||||
|
|
||||||
|
gl_Position = projectedPos;
|
||||||
|
|
||||||
|
if (shadow._active) {
|
||||||
|
Color = vec4(shadow._color, 1.0);
|
||||||
|
} else {
|
||||||
|
Color = color;
|
||||||
|
}
|
||||||
|
if (!useVertexAlpha)
|
||||||
|
Color.a = 1.0;
|
||||||
|
Color *= uniformColor;
|
||||||
|
if (textured) {
|
||||||
|
Texcoord = texcoord;
|
||||||
|
} else {
|
||||||
|
Texcoord = vec2(0.0, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 light = vec3(0.0, 0.0, 0.0);
|
||||||
|
vec3 normalEye = normalize((normalMatrix * vec4(normal, 1.0)).xyz);
|
||||||
|
|
||||||
|
for (int i = 0; i < maxLights; ++i) {
|
||||||
|
float intensity = lightsColor[i].w;
|
||||||
|
float light_type = lightsPosition[i].w;
|
||||||
|
if (light_type >= 0.0) { // Not ambient
|
||||||
|
vec3 vertexToLight;
|
||||||
|
if (light_type > 0.0) { // positional light
|
||||||
|
float falloffNear = lightsParams[i].x;
|
||||||
|
float falloffFar = max(falloffNear, lightsParams[i].y);
|
||||||
|
vertexToLight = lightsPosition[i].xyz - pos.xyz;
|
||||||
|
float dist = length(vertexToLight);
|
||||||
|
if (falloffFar == falloffNear) {
|
||||||
|
intensity = 0.0;
|
||||||
|
} else {
|
||||||
|
intensity *= clamp(1.0 - (dist - falloffNear) / (falloffFar - falloffNear), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
if (lightsDirection[i].w > -1.0) { // Spotlight
|
||||||
|
// See DirectX spotlight documentation
|
||||||
|
float cosAngle = -dot(normalize(vertexToLight), normalize(lightsDirection[i].xyz)); // rho
|
||||||
|
float cosPenumbra = clamp(lightsParams[i].w, 0.0, 1.0); // cos(theta / 2)
|
||||||
|
float cosUmbra = clamp(lightsParams[i].z, 0.0, cosPenumbra); // cos(phi / 2)
|
||||||
|
if (cosAngle <= cosPenumbra) {
|
||||||
|
if (cosAngle < cosUmbra || cosPenumbra == cosUmbra) {
|
||||||
|
intensity = 0.0;
|
||||||
|
} else {
|
||||||
|
intensity *= (cosAngle - cosUmbra) / (cosPenumbra - cosUmbra);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // directional light
|
||||||
|
vertexToLight = -lightsPosition[i].xyz;
|
||||||
|
}
|
||||||
|
intensity *= max(0.0, dot(normalEye, normalize(vertexToLight)));
|
||||||
|
}
|
||||||
|
light += lightsColor[i].xyz * intensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAmbient)
|
||||||
|
light += vec3(0.5, 0.5, 0.5);
|
||||||
|
light /= max(1.0, max(max(light.x, light.y), light.z));
|
||||||
|
Color *= vec4(light, 1.0);
|
||||||
|
}
|
26
engines/grim/shaders/emi_sprite.fragment
Normal file
26
engines/grim/shaders/emi_sprite.fragment
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
in vec2 Texcoord;
|
||||||
|
in vec4 Color;
|
||||||
|
|
||||||
|
uniform sampler2D tex;
|
||||||
|
uniform bool textured;
|
||||||
|
uniform bool swapRandB;
|
||||||
|
uniform float alphaRef;
|
||||||
|
uniform float meshAlpha;
|
||||||
|
|
||||||
|
OUTPUT
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
outColor = Color;
|
||||||
|
if (textured) {
|
||||||
|
vec4 texColor = texture(tex, Texcoord);
|
||||||
|
#ifdef GL_ES
|
||||||
|
if (swapRandB)
|
||||||
|
texColor.rb = texColor.br;
|
||||||
|
#endif
|
||||||
|
outColor.rgba *= texColor.rgba;
|
||||||
|
outColor.a *= meshAlpha;
|
||||||
|
if (outColor.a < alphaRef)
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
}
|
60
engines/grim/shaders/emi_sprite.vertex
Normal file
60
engines/grim/shaders/emi_sprite.vertex
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
in vec3 position;
|
||||||
|
in vec2 texcoord;
|
||||||
|
in vec4 color;
|
||||||
|
in vec3 normal;
|
||||||
|
|
||||||
|
uniform highp mat4 modelMatrix;
|
||||||
|
uniform highp mat4 viewMatrix;
|
||||||
|
uniform highp mat4 projMatrix;
|
||||||
|
uniform highp mat4 extraMatrix;
|
||||||
|
uniform highp mat4 normalMatrix;
|
||||||
|
uniform highp vec3 cameraPos;
|
||||||
|
uniform bool textured;
|
||||||
|
uniform bool useVertexAlpha;
|
||||||
|
uniform vec4 uniformColor;
|
||||||
|
|
||||||
|
struct shadow_info {
|
||||||
|
bool _active;
|
||||||
|
vec3 _color;
|
||||||
|
vec3 _light;
|
||||||
|
vec3 _point;
|
||||||
|
vec3 _normal;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform shadow_info shadow;
|
||||||
|
|
||||||
|
out vec2 Texcoord;
|
||||||
|
out vec4 Color;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 pos = vec4(position, 1.0);
|
||||||
|
vec4 offset = modelMatrix * vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
offset -= vec4(cameraPos * offset.w, 0.0);
|
||||||
|
offset = viewMatrix * offset;
|
||||||
|
|
||||||
|
pos = extraMatrix * pos;
|
||||||
|
pos += vec4(offset.xyz * pos.w, 0.0);
|
||||||
|
pos /= pos.w;
|
||||||
|
pos.z *= -1.0;
|
||||||
|
|
||||||
|
vec4 projectedPos = projMatrix * pos;
|
||||||
|
projectedPos.z = ROUND(projectedPos.z);
|
||||||
|
|
||||||
|
gl_Position = projectedPos;
|
||||||
|
|
||||||
|
if (shadow._active) {
|
||||||
|
Color = vec4(shadow._color, 1.0);
|
||||||
|
} else {
|
||||||
|
Color = color;
|
||||||
|
}
|
||||||
|
if (!useVertexAlpha)
|
||||||
|
Color.a = 1.0;
|
||||||
|
Color *= uniformColor;
|
||||||
|
if (textured) {
|
||||||
|
Texcoord = texcoord;
|
||||||
|
} else {
|
||||||
|
Texcoord = vec2(0.0, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -15,15 +15,6 @@ uniform bool textured;
|
|||||||
uniform bool lightsEnabled;
|
uniform bool lightsEnabled;
|
||||||
uniform highp vec2 texScale;
|
uniform highp vec2 texScale;
|
||||||
|
|
||||||
struct Light {
|
|
||||||
vec4 _position;
|
|
||||||
vec4 _direction;
|
|
||||||
vec4 _color;
|
|
||||||
vec4 _params;
|
|
||||||
};
|
|
||||||
const int maxLights = 8;
|
|
||||||
uniform Light lights[maxLights];
|
|
||||||
|
|
||||||
struct shadow_info {
|
struct shadow_info {
|
||||||
bool _active;
|
bool _active;
|
||||||
vec3 _color;
|
vec3 _color;
|
||||||
@ -65,38 +56,4 @@ void main()
|
|||||||
Texcoord = vec2(0.0, 0.0);
|
Texcoord = vec2(0.0, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lightsEnabled) {
|
|
||||||
vec3 light = vec3(0.0, 0.0, 0.0);
|
|
||||||
vec3 normalEye = normalize((viewMatrix * (modelMatrix * extraMatrix * vec4(normal, 0.0))).xyz);
|
|
||||||
|
|
||||||
for (int i = 0; i < maxLights; ++i) {
|
|
||||||
float intensity = lights[i]._color.w;
|
|
||||||
float light_type = lights[i]._position.w;
|
|
||||||
if (light_type >= 0.0) { // Not ambient
|
|
||||||
vec3 vertexToLight = lights[i]._position.xyz;
|
|
||||||
if (light_type > 0.0) { // positional light
|
|
||||||
vertexToLight -= positionView.xyz;
|
|
||||||
float dist = length(vertexToLight);
|
|
||||||
intensity /= CONSTANT_ATTENUATION + dist * (LINEAR_ATTENUATION + dist * QUADRATIC_ATTENUATION);
|
|
||||||
if (lights[i]._direction.w > -1.0) { // Spotlight
|
|
||||||
// See DirectX spotlight documentation
|
|
||||||
float cosAngle = -dot(normalize(vertexToLight), normalize(lights[i]._direction.xyz)); // rho
|
|
||||||
float cosPenumbra = clamp(lights[i]._params.w, 0.0, 1.0); // cos(theta / 2)
|
|
||||||
float cosUmbra = clamp(lights[i]._params.z, 0.0, cosPenumbra); // cos(phi / 2)
|
|
||||||
if (cosAngle <= cosPenumbra) {
|
|
||||||
if (cosAngle < cosUmbra || cosPenumbra == cosUmbra) {
|
|
||||||
intensity = 0.0;
|
|
||||||
} else {
|
|
||||||
intensity *= (cosAngle - cosUmbra) / (cosPenumbra - cosUmbra);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
intensity *= max(0.0, dot(normalEye, normalize(vertexToLight)));
|
|
||||||
}
|
|
||||||
light += lights[i]._color.xyz * intensity;
|
|
||||||
}
|
|
||||||
light /= max(1.0, max(max(light.x, light.y), light.z));
|
|
||||||
Color *= vec4(light, 1.0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
47
engines/grim/shaders/grim_actorlights.fragment
Normal file
47
engines/grim/shaders/grim_actorlights.fragment
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
in vec2 Texcoord;
|
||||||
|
in vec4 Color;
|
||||||
|
|
||||||
|
uniform sampler2D tex;
|
||||||
|
uniform sampler2D texZBuf;
|
||||||
|
uniform bool textured;
|
||||||
|
uniform bool hasZBuffer;
|
||||||
|
uniform vec2 texcropZBuf;
|
||||||
|
uniform vec2 screenSize;
|
||||||
|
uniform float alphaRef;
|
||||||
|
|
||||||
|
//#define SGSPLUS_FIX
|
||||||
|
#ifndef SGSPLUS_FIX
|
||||||
|
const float offsetY = 0.0;
|
||||||
|
#else
|
||||||
|
// fix for bugged Samsung Galaxy S plus driver
|
||||||
|
const float offsetY = 32.0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
OUTPUT
|
||||||
|
|
||||||
|
void checkZBuffer()
|
||||||
|
{
|
||||||
|
#ifndef SGSPLUS_FIX
|
||||||
|
vec2 zCoord = vec2((gl_FragCoord.x-0.5)/screenSize.x, 1.0-(gl_FragCoord.y-offsetY-0.5)/screenSize.y);
|
||||||
|
#else
|
||||||
|
vec2 zCoord = vec2((gl_FragCoord.x-0.5)/screenSize.x, (gl_FragCoord.y-offsetY-0.5)/screenSize.y);
|
||||||
|
#endif
|
||||||
|
vec2 sampled = texture(texZBuf, zCoord * texcropZBuf).ra;
|
||||||
|
float sceneZ = sampled.y + sampled.x / 256.0;
|
||||||
|
|
||||||
|
if (gl_FragCoord.z * 1.0039 > sceneZ)
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
if (hasZBuffer)
|
||||||
|
checkZBuffer();
|
||||||
|
outColor = Color;
|
||||||
|
if (textured) {
|
||||||
|
outColor *= texture(tex, Texcoord);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outColor.a < alphaRef)
|
||||||
|
discard;
|
||||||
|
}
|
97
engines/grim/shaders/grim_actorlights.vertex
Normal file
97
engines/grim/shaders/grim_actorlights.vertex
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
const float CONSTANT_ATTENUATION = 1.0;
|
||||||
|
const float LINEAR_ATTENUATION = 0.0;
|
||||||
|
const float QUADRATIC_ATTENUATION = 1.0;
|
||||||
|
|
||||||
|
in vec3 position;
|
||||||
|
in vec2 texcoord;
|
||||||
|
in vec4 color;
|
||||||
|
in vec3 normal;
|
||||||
|
|
||||||
|
uniform highp mat4 modelMatrix;
|
||||||
|
uniform highp mat4 viewMatrix;
|
||||||
|
uniform highp mat4 projMatrix;
|
||||||
|
uniform highp mat4 extraMatrix;
|
||||||
|
uniform bool textured;
|
||||||
|
uniform bool lightsEnabled;
|
||||||
|
uniform highp vec2 texScale;
|
||||||
|
|
||||||
|
const int maxLights = 8;
|
||||||
|
uniform vec4 lightsPosition[maxLights];
|
||||||
|
uniform vec4 lightsDirection[maxLights];
|
||||||
|
uniform vec4 lightsColor[maxLights];
|
||||||
|
uniform vec4 lightsParams[maxLights];
|
||||||
|
|
||||||
|
struct shadow_info {
|
||||||
|
bool _active;
|
||||||
|
vec3 _color;
|
||||||
|
vec3 _light;
|
||||||
|
vec3 _point;
|
||||||
|
vec3 _normal;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform shadow_info shadow;
|
||||||
|
|
||||||
|
out vec2 Texcoord;
|
||||||
|
out vec4 Color;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 pos = modelMatrix * extraMatrix * vec4(position, 1.0);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 positionView = viewMatrix * pos;
|
||||||
|
gl_Position = projMatrix * positionView;
|
||||||
|
|
||||||
|
if (shadow._active) {
|
||||||
|
Color = vec4(shadow._color, 1.0);
|
||||||
|
} else {
|
||||||
|
Color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textured) {
|
||||||
|
Texcoord = vec2(0.0, 1.0) + (texcoord / texScale);
|
||||||
|
} else {
|
||||||
|
Texcoord = vec2(0.0, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 light = vec3(0.0, 0.0, 0.0);
|
||||||
|
vec3 normalEye = normalize((viewMatrix * (modelMatrix * extraMatrix * vec4(normal, 0.0))).xyz);
|
||||||
|
|
||||||
|
for (int i = 0; i < maxLights; ++i) {
|
||||||
|
float intensity = lightsColor[i].w;
|
||||||
|
float light_type = lightsPosition[i].w;
|
||||||
|
if (light_type >= 0.0) { // Not ambient
|
||||||
|
vec3 vertexToLight = lightsPosition[i].xyz;
|
||||||
|
if (light_type > 0.0) { // positional light
|
||||||
|
vertexToLight -= positionView.xyz;
|
||||||
|
float dist = length(vertexToLight);
|
||||||
|
intensity /= CONSTANT_ATTENUATION + dist * (LINEAR_ATTENUATION + dist * QUADRATIC_ATTENUATION);
|
||||||
|
if (lightsDirection[i].w > -1.0) { // Spotlight
|
||||||
|
// See DirectX spotlight documentation
|
||||||
|
float cosAngle = -dot(normalize(vertexToLight), normalize(lightsDirection[i].xyz)); // rho
|
||||||
|
float cosPenumbra = clamp(lightsParams[i].w, 0.0, 1.0); // cos(theta / 2)
|
||||||
|
float cosUmbra = clamp(lightsParams[i].z, 0.0, cosPenumbra); // cos(phi / 2)
|
||||||
|
if (cosAngle <= cosPenumbra) {
|
||||||
|
if (cosAngle < cosUmbra || cosPenumbra == cosUmbra) {
|
||||||
|
intensity = 0.0;
|
||||||
|
} else {
|
||||||
|
intensity *= (cosAngle - cosUmbra) / (cosPenumbra - cosUmbra);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intensity *= max(0.0, dot(normalEye, normalize(vertexToLight)));
|
||||||
|
}
|
||||||
|
light += lightsColor[i].xyz * intensity;
|
||||||
|
}
|
||||||
|
light /= max(1.0, max(max(light.x, light.y), light.z));
|
||||||
|
Color *= vec4(light, 1.0);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user