mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-26 20:59:00 +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/emi_actor.fragment FILE "engines/grim/shaders/emi_actor.fragment"
|
||||
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.vertex FILE "engines/grim/shaders/emi_background.vertex"
|
||||
shaders/emi_dimplane.fragment FILE "engines/grim/shaders/emi_dimplane.fragment"
|
||||
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.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.vertex FILE "engines/grim/shaders/grim_background.vertex"
|
||||
shaders/grim_primitive.fragment FILE "engines/grim/shaders/grim_primitive.fragment"
|
||||
|
@ -117,6 +117,7 @@ struct FontUserData {
|
||||
|
||||
struct EMIModelUserData {
|
||||
OpenGL::ShaderGL *_shader;
|
||||
OpenGL::ShaderGL *_shaderLights;
|
||||
uint32 _texCoordsVBO;
|
||||
uint32 _colorMapVBO;
|
||||
uint32 _verticesVBO;
|
||||
@ -125,6 +126,7 @@ struct EMIModelUserData {
|
||||
|
||||
struct ModelUserData {
|
||||
OpenGL::ShaderGL *_shader;
|
||||
OpenGL::ShaderGL *_shaderLights;
|
||||
uint32 _meshInfoVBO;
|
||||
};
|
||||
|
||||
@ -220,6 +222,7 @@ GfxOpenGLS::GfxOpenGLS() {
|
||||
_textProgram = nullptr;
|
||||
_emergProgram = nullptr;
|
||||
_actorProgram = nullptr;
|
||||
_actorLightsProgram = nullptr;
|
||||
_spriteProgram = nullptr;
|
||||
_primitiveProgram = nullptr;
|
||||
_irisProgram = nullptr;
|
||||
@ -244,6 +247,7 @@ GfxOpenGLS::~GfxOpenGLS() {
|
||||
delete _textProgram;
|
||||
delete _emergProgram;
|
||||
delete _actorProgram;
|
||||
delete _actorLightsProgram;
|
||||
delete _spriteProgram;
|
||||
delete _primitiveProgram;
|
||||
delete _irisProgram;
|
||||
@ -375,7 +379,8 @@ void GfxOpenGLS::setupShaders() {
|
||||
|
||||
static const char* actorAttributes[] = {"position", "texcoord", "color", "normal", NULL};
|
||||
_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 };
|
||||
_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) {
|
||||
_currentActor = actor;
|
||||
_actorProgram->use();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
const Math::Vector3d &pos = actor->getWorldPos();
|
||||
@ -660,6 +664,8 @@ void GfxOpenGLS::startActorDraw(const Actor *actor) {
|
||||
Math::Matrix4 viewMatrix = _viewMatrix;
|
||||
viewMatrix.transpose();
|
||||
|
||||
OpenGL::ShaderGL *shaders[] = { _spriteProgram, _actorProgram, _actorLightsProgram };
|
||||
|
||||
if (g_grim->getGameType() == GType_MONKEY4) {
|
||||
glEnable(GL_CULL_FACE);
|
||||
glFrontFace(GL_CW);
|
||||
@ -676,48 +682,25 @@ void GfxOpenGLS::startActorDraw(const Actor *actor) {
|
||||
normalMatrix.invertAffineOrthonormal();
|
||||
modelMatrix.transpose();
|
||||
|
||||
_actorProgram->setUniform("modelMatrix", modelMatrix);
|
||||
if (actor->isInOverworld()) {
|
||||
_actorProgram->setUniform("viewMatrix", viewMatrix);
|
||||
_actorProgram->setUniform("projMatrix", _overworldProjMatrix);
|
||||
_actorProgram->setUniform("cameraPos", Math::Vector3d(0,0,0));
|
||||
} else {
|
||||
_actorProgram->setUniform("viewMatrix", viewRot);
|
||||
_actorProgram->setUniform("projMatrix", _projMatrix);
|
||||
_actorProgram->setUniform("cameraPos", _currentPos);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
shaders[i]->use();
|
||||
shaders[i]->setUniform("modelMatrix", modelMatrix);
|
||||
if (actor->isInOverworld()) {
|
||||
shaders[i]->setUniform("viewMatrix", viewMatrix);
|
||||
shaders[i]->setUniform("projMatrix", _overworldProjMatrix);
|
||||
shaders[i]->setUniform("cameraPos", Math::Vector3d(0,0,0));
|
||||
} else {
|
||||
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 {
|
||||
Math::Matrix4 modelMatrix = quat.toMatrix();
|
||||
bool hasZBuffer = g_grim->getCurrSet()->getCurrSetup()->_bkgndZBm;
|
||||
@ -728,16 +711,19 @@ void GfxOpenGLS::startActorDraw(const Actor *actor) {
|
||||
modelMatrix.setPosition(pos);
|
||||
modelMatrix.transpose();
|
||||
|
||||
_actorProgram->setUniform("modelMatrix", modelMatrix);
|
||||
_actorProgram->setUniform("viewMatrix", _viewMatrix);
|
||||
_actorProgram->setUniform("projMatrix", _projMatrix);
|
||||
_actorProgram->setUniform("extraMatrix", extraMatrix);
|
||||
_actorProgram->setUniform("tex", 0);
|
||||
_actorProgram->setUniform("texZBuf", 1);
|
||||
_actorProgram->setUniform("hasZBuffer", hasZBuffer);
|
||||
_actorProgram->setUniform("texcropZBuf", _zBufTexCrop);
|
||||
_actorProgram->setUniform("screenSize", Math::Vector2d(_screenWidth, _screenHeight));
|
||||
_actorProgram->setUniform1f("alphaRef", 0.5f);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
shaders[i]->use();
|
||||
shaders[i]->setUniform("modelMatrix", modelMatrix);
|
||||
shaders[i]->setUniform("viewMatrix", _viewMatrix);
|
||||
shaders[i]->setUniform("projMatrix", _projMatrix);
|
||||
shaders[i]->setUniform("extraMatrix", extraMatrix);
|
||||
shaders[i]->setUniform("tex", 0);
|
||||
shaders[i]->setUniform("texZBuf", 1);
|
||||
shaders[i]->setUniform("hasZBuffer", hasZBuffer);
|
||||
shaders[i]->setUniform("texcropZBuf", _zBufTexCrop);
|
||||
shaders[i]->setUniform("screenSize", Math::Vector2d(_screenWidth, _screenHeight));
|
||||
shaders[i]->setUniform1f("alphaRef", 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
if (_currentShadowArray) {
|
||||
@ -752,43 +738,48 @@ void GfxOpenGLS::startActorDraw(const Actor *actor) {
|
||||
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);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
shaders[i]->use();
|
||||
shaders[i]->setUniform("shadow._active", true);
|
||||
shaders[i]->setUniform("shadow._color", color);
|
||||
shaders[i]->setUniform("shadow._light", _currentShadowArray->pos);
|
||||
shaders[i]->setUniform("shadow._point", shadowSector->getVertices()[0]);
|
||||
shaders[i]->setUniform("shadow._normal", normal);
|
||||
}
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
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);
|
||||
_actorProgram->setUniform("hasAmbient", _hasAmbientLight);
|
||||
_actorLightsProgram->setUniform("hasAmbient", _hasAmbientLight);
|
||||
if (_lightsEnabled) {
|
||||
for (int i = 0; i < _maxLights; ++i) {
|
||||
const GLSLight &l = _lights[i];
|
||||
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;
|
||||
direction.w() = 0.0;
|
||||
viewMatrix.transformVector(&direction);
|
||||
direction.w() = l._direction.w();
|
||||
|
||||
uniform = Common::String::format("lights[%u]._direction", i);
|
||||
_actorProgram->setUniform(uniform.c_str(), direction);
|
||||
uniform = Common::String::format("lightsDirection[%u]", i);
|
||||
_actorLightsProgram->setUniform(uniform.c_str(), direction);
|
||||
|
||||
uniform = Common::String::format("lights[%u]._color", i);
|
||||
_actorProgram->setUniform(uniform.c_str(), l._color);
|
||||
uniform = Common::String::format("lightsColor[%u]", i);
|
||||
_actorLightsProgram->setUniform(uniform.c_str(), l._color);
|
||||
|
||||
uniform = Common::String::format("lights[%u]._params", i);
|
||||
_actorProgram->setUniform(uniform.c_str(), l._params);
|
||||
uniform = Common::String::format("lightsParams[%u]", i);
|
||||
_actorLightsProgram->setUniform(uniform.c_str(), l._params);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -950,13 +941,17 @@ void GfxOpenGLS::drawEMIModelFace(const EMIModel* model, const EMIMeshFace* face
|
||||
face->_flags & EMIMeshFace::kUnknownBlend)
|
||||
glEnable(GL_BLEND);
|
||||
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;
|
||||
mud->_shader->setUniform("textured", textured ? GL_TRUE : GL_FALSE);
|
||||
mud->_shader->setUniform("lightsEnabled", (face->_flags & EMIMeshFace::kNoLighting) ? false : _lightsEnabled);
|
||||
mud->_shader->setUniform("swapRandB", _selectedTexture->_colorFormat == BM_BGRA || _selectedTexture->_colorFormat == BM_BGR888);
|
||||
mud->_shader->setUniform("useVertexAlpha", _selectedTexture->_colorFormat == BM_BGRA);
|
||||
mud->_shader->setUniform1f("meshAlpha", (model->_meshAlphaMode == Actor::AlphaReplace) ? model->_meshAlpha : 1.0f);
|
||||
actorShader->setUniform("textured", textured ? GL_TRUE : GL_FALSE);
|
||||
actorShader->setUniform("swapRandB", _selectedTexture->_colorFormat == BM_BGRA || _selectedTexture->_colorFormat == BM_BGR888);
|
||||
actorShader->setUniform("useVertexAlpha", _selectedTexture->_colorFormat == BM_BGRA);
|
||||
actorShader->setUniform1f("meshAlpha", (model->_meshAlphaMode == Actor::AlphaReplace) ? model->_meshAlpha : 1.0f);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, face->_indicesEBO);
|
||||
|
||||
@ -968,11 +963,14 @@ void GfxOpenGLS::drawMesh(const Mesh *mesh) {
|
||||
const ModelUserData *mud = (const ModelUserData *)mesh->_userData;
|
||||
if (!mud)
|
||||
return;
|
||||
OpenGL::ShaderGL *actorShader = mud->_shader;
|
||||
OpenGL::ShaderGL *actorShader;
|
||||
if (_lightsEnabled && !isShadowModeActive())
|
||||
actorShader = mud->_shaderLights;
|
||||
else
|
||||
actorShader = mud->_shader;
|
||||
|
||||
actorShader->use();
|
||||
actorShader->setUniform("extraMatrix", _matrixStack.top());
|
||||
actorShader->setUniform("lightsEnabled", _lightsEnabled && !isShadowModeActive());
|
||||
|
||||
const Material *curMaterial = NULL;
|
||||
for (int i = 0; i < mesh->_numFaces;) {
|
||||
@ -1056,8 +1054,6 @@ void GfxOpenGLS::drawSprite(const Sprite *sprite) {
|
||||
_spriteProgram->setUniform("extraMatrix", extraMatrix);
|
||||
_spriteProgram->setUniform("textured", GL_TRUE);
|
||||
_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) {
|
||||
_spriteProgram->setUniform1f("alphaRef", 0.5f);
|
||||
} 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);
|
||||
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) {
|
||||
EMIMeshFace * face = &model->_faces[i];
|
||||
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);
|
||||
|
||||
OpenGL::ShaderGL *shader = _actorProgram->clone();
|
||||
mud->_shader = shader;
|
||||
shader->enableVertexAttribute("position", mud->_meshInfoVBO, 3, GL_FLOAT, GL_FALSE, sizeof(GrimVertex), 0);
|
||||
shader->enableVertexAttribute("texcoord", mud->_meshInfoVBO, 2, GL_FLOAT, GL_FALSE, sizeof(GrimVertex), 3 * sizeof(float));
|
||||
shader->enableVertexAttribute("normal", mud->_meshInfoVBO, 3, GL_FLOAT, GL_FALSE, sizeof(GrimVertex), 5 * sizeof(float));
|
||||
shader->disableVertexAttribute("color", Math::Vector4d(1.f, 1.f, 1.f, 1.f));
|
||||
OpenGL::ShaderGL *actorShader = _actorProgram->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->_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) {
|
||||
|
@ -225,6 +225,7 @@ private:
|
||||
|
||||
OpenGL::ShaderGL* _backgroundProgram;
|
||||
OpenGL::ShaderGL* _actorProgram;
|
||||
OpenGL::ShaderGL* _actorLightsProgram;
|
||||
OpenGL::ShaderGL* _spriteProgram;
|
||||
OpenGL::ShaderGL* _dimProgram;
|
||||
OpenGL::ShaderGL* _dimPlaneProgram;
|
||||
|
@ -10,20 +10,8 @@ uniform highp mat4 extraMatrix;
|
||||
uniform highp mat4 normalMatrix;
|
||||
uniform highp vec3 cameraPos;
|
||||
uniform bool textured;
|
||||
uniform bool isBillboard;
|
||||
uniform bool useVertexAlpha;
|
||||
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 {
|
||||
bool _active;
|
||||
@ -41,34 +29,23 @@ out vec4 Color;
|
||||
void main()
|
||||
{
|
||||
vec4 pos = vec4(position, 1.0);
|
||||
if (isBillboard) {
|
||||
vec4 offset = modelMatrix * vec4(0.0, 0.0, 0.0, 1.0);
|
||||
offset -= vec4(cameraPos * offset.w, 0.0);
|
||||
offset = viewMatrix * offset;
|
||||
pos = modelMatrix * pos;
|
||||
|
||||
pos = extraMatrix * pos;
|
||||
pos += vec4(offset.xyz * pos.w, 0.0);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
// 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 -= vec4(cameraPos * pos.w, 0.0);
|
||||
pos = viewMatrix * pos;
|
||||
pos /= pos.w;
|
||||
pos.z *= -1.0;
|
||||
|
||||
vec4 projectedPos = projMatrix * pos;
|
||||
if (isBillboard)
|
||||
projectedPos.z = ROUND(projectedPos.z);
|
||||
|
||||
gl_Position = projectedPos;
|
||||
|
||||
@ -86,49 +63,4 @@ void main()
|
||||
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 highp vec2 texScale;
|
||||
|
||||
struct Light {
|
||||
vec4 _position;
|
||||
vec4 _direction;
|
||||
vec4 _color;
|
||||
vec4 _params;
|
||||
};
|
||||
const int maxLights = 8;
|
||||
uniform Light lights[maxLights];
|
||||
|
||||
struct shadow_info {
|
||||
bool _active;
|
||||
vec3 _color;
|
||||
@ -65,38 +56,4 @@ void main()
|
||||
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