mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 22:28:10 +00:00
STARK: Project a black shadow from above
This commit is contained in:
parent
8e9c5580ac
commit
891375d509
@ -63,6 +63,8 @@ shaders/stark_surface.fragment FILE "engines/stark/shaders/stark_surface.fr
|
||||
shaders/stark_surface.vertex FILE "engines/stark/shaders/stark_surface.vertex"
|
||||
shaders/stark_fade.fragment FILE "engines/stark/shaders/stark_fade.fragment"
|
||||
shaders/stark_fade.vertex FILE "engines/stark/shaders/stark_fade.vertex"
|
||||
shaders/stark_shadow.fragment FILE "engines/stark/shaders/stark_shadow.fragment"
|
||||
shaders/stark_shadow.vertex FILE "engines/stark/shaders/stark_shadow.vertex"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -63,6 +63,8 @@ shaders/stark_surface.fragment FILE "engines/stark/shaders/stark_surface.fr
|
||||
shaders/stark_surface.vertex FILE "engines/stark/shaders/stark_surface.vertex"
|
||||
shaders/stark_fade.fragment FILE "engines/stark/shaders/stark_fade.fragment"
|
||||
shaders/stark_fade.vertex FILE "engines/stark/shaders/stark_fade.vertex"
|
||||
shaders/stark_shadow.fragment FILE "engines/stark/shaders/stark_shadow.fragment"
|
||||
shaders/stark_shadow.vertex FILE "engines/stark/shaders/stark_shadow.vertex"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -61,6 +61,7 @@ OpenGLSDriver::OpenGLSDriver() :
|
||||
_surfaceShader(nullptr),
|
||||
_actorShader(nullptr),
|
||||
_fadeShader(nullptr),
|
||||
_shadowShader(nullptr),
|
||||
_surfaceVBO(0),
|
||||
_fadeVBO(0) {
|
||||
}
|
||||
@ -71,6 +72,7 @@ OpenGLSDriver::~OpenGLSDriver() {
|
||||
delete _surfaceShader;
|
||||
delete _actorShader;
|
||||
delete _fadeShader;
|
||||
delete _shadowShader;
|
||||
}
|
||||
|
||||
void OpenGLSDriver::init() {
|
||||
@ -85,6 +87,9 @@ void OpenGLSDriver::init() {
|
||||
static const char* actorAttributes[] = { "position1", "position2", "bone1", "bone2", "boneWeight", "normal", "texcoord", nullptr };
|
||||
_actorShader = OpenGL::Shader::fromFiles("stark_actor", actorAttributes);
|
||||
|
||||
static const char* shadowAttributes[] = { "position1", "position2", "bone1", "bone2", "boneWeight", nullptr };
|
||||
_shadowShader = OpenGL::Shader::fromFiles("stark_shadow", shadowAttributes);
|
||||
|
||||
static const char* fadeAttributes[] = { "position", nullptr };
|
||||
_fadeShader = OpenGL::Shader::fromFiles("stark_fade", fadeAttributes);
|
||||
_fadeVBO = OpenGL::Shader::createBuffer(GL_ARRAY_BUFFER, sizeof(fadeVertices), fadeVertices);
|
||||
@ -201,6 +206,10 @@ OpenGL::Shader *OpenGLSDriver::createFadeShaderInstance() {
|
||||
return _fadeShader->clone();
|
||||
}
|
||||
|
||||
OpenGL::Shader *OpenGLSDriver::createShadowShaderInstance() {
|
||||
return _shadowShader->clone();
|
||||
}
|
||||
|
||||
Graphics::Surface *OpenGLSDriver::getViewportScreenshot() const {
|
||||
Graphics::Surface *s = new Graphics::Surface();
|
||||
s->create(_viewport.width(), _viewport.height(), getRGBAPixelFormat());
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
#include "common/system.h"
|
||||
|
||||
//#define USE_GLES2
|
||||
|
||||
#if defined(USE_GLES2) || defined(USE_OPENGL_SHADERS)
|
||||
|
||||
#include "engines/stark/gfx/driver.h"
|
||||
@ -58,6 +60,7 @@ public:
|
||||
OpenGL::Shader *createActorShaderInstance();
|
||||
OpenGL::Shader *createSurfaceShaderInstance();
|
||||
OpenGL::Shader *createFadeShaderInstance();
|
||||
OpenGL::Shader *createShadowShaderInstance();
|
||||
|
||||
void start2DMode();
|
||||
void end2DMode();
|
||||
@ -75,6 +78,7 @@ private:
|
||||
OpenGL::Shader *_surfaceShader;
|
||||
OpenGL::Shader *_actorShader;
|
||||
OpenGL::Shader *_fadeShader;
|
||||
OpenGL::Shader *_shadowShader;
|
||||
uint32 _surfaceVBO;
|
||||
uint32 _fadeVBO;
|
||||
};
|
||||
|
@ -39,12 +39,14 @@ OpenGLSActorRenderer::OpenGLSActorRenderer(OpenGLSDriver *gfx) :
|
||||
_gfx(gfx),
|
||||
_faceVBO(0) {
|
||||
_shader = _gfx->createActorShaderInstance();
|
||||
_shadowShader = _gfx->createShadowShaderInstance();
|
||||
}
|
||||
|
||||
OpenGLSActorRenderer::~OpenGLSActorRenderer() {
|
||||
clearVertices();
|
||||
|
||||
delete _shader;
|
||||
delete _shadowShader;
|
||||
}
|
||||
|
||||
void OpenGLSActorRenderer::render(const Math::Vector3d &position, float direction, const LightEntryArray &lights) {
|
||||
@ -86,8 +88,8 @@ void OpenGLSActorRenderer::render(const Math::Vector3d &position, float directio
|
||||
_shader->setUniform("modelViewMatrix", modelViewMatrix);
|
||||
_shader->setUniform("projectionMatrix", projectionMatrix);
|
||||
_shader->setUniform("normalMatrix", normalMatrix.getRotation());
|
||||
setBoneRotationArrayUniform("boneRotation");
|
||||
setBonePositionArrayUniform("bonePosition");
|
||||
setBoneRotationArrayUniform(_shader, "boneRotation");
|
||||
setBonePositionArrayUniform(_shader, "bonePosition");
|
||||
setLightArrayUniform("lights", lights);
|
||||
|
||||
Common::Array<Face *> faces = _model->getFaces();
|
||||
@ -112,6 +114,28 @@ void OpenGLSActorRenderer::render(const Math::Vector3d &position, float directio
|
||||
}
|
||||
|
||||
_shader->unbind();
|
||||
|
||||
// Shadow
|
||||
_shadowShader->enableVertexAttribute("position1", _faceVBO, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), 0);
|
||||
_shadowShader->enableVertexAttribute("position2", _faceVBO, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), 12);
|
||||
_shadowShader->enableVertexAttribute("bone1", _faceVBO, 1, GL_FLOAT, GL_FALSE, 14 * sizeof(float), 24);
|
||||
_shadowShader->enableVertexAttribute("bone2", _faceVBO, 1, GL_FLOAT, GL_FALSE, 14 * sizeof(float), 28);
|
||||
_shadowShader->enableVertexAttribute("boneWeight", _faceVBO, 1, GL_FLOAT, GL_FALSE, 14 * sizeof(float), 32);
|
||||
_shadowShader->use(true);
|
||||
|
||||
_shadowShader->setUniform("modelViewMatrix", modelViewMatrix);
|
||||
_shadowShader->setUniform("projectionMatrix", projectionMatrix);
|
||||
setBoneRotationArrayUniform(_shadowShader, "boneRotation");
|
||||
setBonePositionArrayUniform(_shadowShader, "bonePosition");
|
||||
|
||||
for (Common::Array<Face *>::const_iterator face = faces.begin(); face != faces.end(); ++face) {
|
||||
GLuint ebo = _faceEBO[*face];
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||
glDrawElements(GL_TRIANGLES, (*face)->vertexIndices.size(), GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
_shadowShader->unbind();
|
||||
}
|
||||
|
||||
void OpenGLSActorRenderer::clearVertices() {
|
||||
@ -173,10 +197,10 @@ uint32 OpenGLSActorRenderer::createFaceEBO(const Face *face) {
|
||||
return OpenGL::Shader::createBuffer(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32) * face->vertexIndices.size(), &face->vertexIndices[0]);
|
||||
}
|
||||
|
||||
void OpenGLSActorRenderer::setBonePositionArrayUniform(const char *uniform) {
|
||||
void OpenGLSActorRenderer::setBonePositionArrayUniform(OpenGL::Shader *shader, const char *uniform) {
|
||||
const Common::Array<BoneNode *> &bones = _model->getBones();
|
||||
|
||||
GLint pos = _shader->getUniformLocation(uniform);
|
||||
GLint pos = shader->getUniformLocation(uniform);
|
||||
if (pos == -1) {
|
||||
error("No uniform named '%s'", uniform);
|
||||
}
|
||||
@ -194,10 +218,10 @@ void OpenGLSActorRenderer::setBonePositionArrayUniform(const char *uniform) {
|
||||
delete[] positions;
|
||||
}
|
||||
|
||||
void OpenGLSActorRenderer::setBoneRotationArrayUniform(const char *uniform) {
|
||||
void OpenGLSActorRenderer::setBoneRotationArrayUniform(OpenGL::Shader *shader, const char *uniform) {
|
||||
const Common::Array<BoneNode *> &bones = _model->getBones();
|
||||
|
||||
GLint rot = _shader->getUniformLocation(uniform);
|
||||
GLint rot = shader->getUniformLocation(uniform);
|
||||
if (rot == -1) {
|
||||
error("No uniform named '%s'", uniform);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ protected:
|
||||
typedef Common::HashMap<Face *, uint32> FaceBufferMap;
|
||||
|
||||
OpenGLSDriver *_gfx;
|
||||
OpenGL::Shader *_shader;
|
||||
OpenGL::Shader *_shader, *_shadowShader;
|
||||
|
||||
uint32 _faceVBO;
|
||||
FaceBufferMap _faceEBO;
|
||||
@ -58,8 +58,8 @@ protected:
|
||||
void uploadVertices();
|
||||
uint32 createModelVBO(const Model *model);
|
||||
uint32 createFaceEBO(const Face *face);
|
||||
void setBonePositionArrayUniform(const char *uniform);
|
||||
void setBoneRotationArrayUniform(const char *uniform);
|
||||
void setBonePositionArrayUniform(OpenGL::Shader *shader, const char *uniform);
|
||||
void setBoneRotationArrayUniform(OpenGL::Shader *shader, const char *uniform);
|
||||
void setLightArrayUniform(const char *uniform, const LightEntryArray &lights);
|
||||
};
|
||||
|
||||
|
5
engines/stark/shaders/stark_shadow.fragment
Normal file
5
engines/stark/shaders/stark_shadow.fragment
Normal file
@ -0,0 +1,5 @@
|
||||
OUTPUT
|
||||
|
||||
void main() {
|
||||
outColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
24
engines/stark/shaders/stark_shadow.vertex
Normal file
24
engines/stark/shaders/stark_shadow.vertex
Normal file
@ -0,0 +1,24 @@
|
||||
in vec3 position1;
|
||||
in vec3 position2;
|
||||
in float bone1;
|
||||
in float bone2;
|
||||
in float boneWeight;
|
||||
|
||||
const int maxBones = 70;
|
||||
|
||||
uniform mat4 modelViewMatrix;
|
||||
uniform mat4 projectionMatrix;
|
||||
uniform vec4 boneRotation[maxBones];
|
||||
uniform vec3 bonePosition[maxBones];
|
||||
|
||||
vec3 qrot(vec4 q, vec3 v) {
|
||||
return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec3 b1 = qrot(boneRotation[int(bone1)], position1) + bonePosition[int(bone1)];
|
||||
vec3 b2 = qrot(boneRotation[int(bone2)], position2) + bonePosition[int(bone2)];
|
||||
vec3 modelPosition = mix(b2, b1, boneWeight);
|
||||
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4(modelPosition.x, 0.0, modelPosition.z, 1.0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user