refactor: Combine basic and skeletal vertex shaders

This commit is contained in:
Vsevolod Kremianskii 2020-09-29 08:47:05 +07:00
parent 8bc500e5c5
commit 9c856745e0
13 changed files with 87 additions and 114 deletions

View file

@ -128,7 +128,7 @@ void Console::render() const {
model = glm::scale(model, glm::vec3(_opts.width, height, 1.0f));
ShaderManager &shaders = Shaders;
shaders.activate(ShaderProgram::BasicDiffuse);
shaders.activate(ShaderProgram::ModelDiffuse);
shaders.setUniform("model", model);
shaders.setUniform("color", glm::vec3(0.0f));
shaders.setUniform("alpha", 0.5f);

View file

@ -56,7 +56,7 @@ void TargetOverlay::drawReticle(Texture &texture, const glm::vec3 &screenCoords)
transform = glm::scale(transform, glm::vec3(width, height, 1.0f));
ShaderManager &shaders = Shaders;
shaders.activate(ShaderProgram::BasicDiffuse);
shaders.activate(ShaderProgram::ModelDiffuse);
shaders.setUniform("model", transform);
shaders.setUniform("alpha", 1.0f);

View file

@ -213,7 +213,7 @@ void Control::render(const glm::ivec2 &offset, const string &textOverride) const
if (!_visible) return;
ShaderManager &shaders = Shaders;
shaders.activate(ShaderProgram::BasicDiffuse);
shaders.activate(ShaderProgram::ModelDiffuse);
shaders.setUniform("color", glm::vec3(1.0f));
shaders.setUniform("alpha", 1.0f);
@ -474,7 +474,7 @@ void Control::render3D(const glm::ivec2 &offset) const {
transform = glm::translate(transform, glm::vec3(_extent.left + offset.x, _extent.top + offset.y, 0.0f));
transform = glm::scale(transform, glm::vec3(_extent.width, _extent.height, 1.0f));
shaders.activate(ShaderProgram::BasicDiffuse);
shaders.activate(ShaderProgram::ModelDiffuse);
shaders.setUniform("model", transform);
shaders.setUniform("color", glm::vec3(1.0f));
shaders.setUniform("alpha", 1.0f);

View file

@ -36,7 +36,7 @@ void ImageButton::render(const glm::ivec2 &offset, const string &textOverride, c
if (!_visible) return;
ShaderManager &shaders = Shaders;
shaders.activate(ShaderProgram::BasicDiffuse);
shaders.activate(ShaderProgram::ModelDiffuse);
shaders.setUniform("color", glm::vec3(1.0f));
shaders.setUniform("alpha", 1.0f);

View file

@ -50,7 +50,7 @@ void ScrollBar::load(const GffStruct &gffs) {
void ScrollBar::render(const glm::ivec2 &offset, const string &textOverride) const {
if (!_dir.image) return;
Shaders.activate(ShaderProgram::BasicDiffuse);
Shaders.activate(ShaderProgram::ModelDiffuse);
Shaders.setUniform("color", glm::vec3(1.0f));
Shaders.setUniform("alpha", 1.0f);

View file

@ -234,7 +234,7 @@ void GUI::drawBackground() const {
glm::mat4 transform(glm::scale(glm::mat4(1.0f), glm::vec3(_gfxOpts.width, _gfxOpts.height, 1.0f)));
ShaderManager &shaders = Shaders;
shaders.activate(ShaderProgram::BasicDiffuse);
shaders.activate(ShaderProgram::ModelDiffuse);
shaders.setUniform("model", transform);
shaders.setUniform("color", glm::vec3(1.0f));
shaders.setUniform("alpha", 1.0f);

View file

@ -66,7 +66,7 @@ void AABBMesh::render(const AABB &aabb, const glm::mat4 &transform) const {
glm::mat4 transform2(transform * aabb.transform());
ShaderManager &shaders = Shaders;
shaders.activate(ShaderProgram::BasicWhite);
shaders.activate(ShaderProgram::ModelWhite);
shaders.setUniform("model", transform2);
shaders.setUniform("alpha", 1.0f);

View file

@ -62,7 +62,7 @@ CubeMesh::CubeMesh() {
void CubeMesh::render(const glm::mat4 &transform) const {
ShaderManager &shaders = Shaders;
shaders.activate(ShaderProgram::BasicWhite);
shaders.activate(ShaderProgram::ModelWhite);
shaders.setUniform("model", transform);
shaders.setUniform("alpha", 1.0f);

View file

@ -75,7 +75,7 @@ void MeshSceneNode::render() const {
shared_ptr<ModelNode::Skin> skin(_modelNode->skin());
const ModelSceneNode::AnimationState &animState = _model->animationState();
bool skeletal = skin && !animState.name.empty();
ShaderProgram program = getShaderProgram(*mesh, skeletal);
ShaderProgram program = getShaderProgram(*mesh);
ShaderManager &shaders = Shaders;
shaders.activate(program);
@ -97,6 +97,7 @@ void MeshSceneNode::render() const {
}
if (skeletal) {
shaders.setUniform("skeletalEnabled", true);
shaders.setUniform("absTransform", _modelNode->absoluteTransform());
shaders.setUniform("absTransformInv", _modelNode->absoluteTransformInverse());
@ -149,42 +150,35 @@ void MeshSceneNode::render() const {
if (_modelNode->isSelfIllumEnabled()) {
shaders.setUniform("selfIllumEnabled", false);
}
if (skeletal) {
shaders.setUniform("skeletalEnabled", false);
}
SceneNode::render();
}
ShaderProgram MeshSceneNode::getShaderProgram(const ModelMesh &mesh, bool skeletal) const {
ShaderProgram MeshSceneNode::getShaderProgram(const ModelMesh &mesh) const {
ShaderProgram program = ShaderProgram::None;
bool hasEnvmap = mesh.hasEnvmapTexture();
bool hasLightmap = mesh.hasLightmapTexture();
bool hasEnvmap = mesh.hasEnvmapTexture();
bool hasBumpyShiny = mesh.hasBumpyShinyTexture();
bool hasBumpmap = mesh.hasBumpmapTexture();
if (skeletal) {
if (hasEnvmap && !hasLightmap && !hasBumpyShiny && !hasBumpmap) {
program = ShaderProgram::SkeletalDiffuseEnvmap;
} else if (hasBumpyShiny && !hasEnvmap && !hasLightmap /* && !hasBumpmap */) {
program = ShaderProgram::SkeletalDiffuseBumpyShiny;
} else if (hasBumpmap && !hasEnvmap && !hasLightmap && !hasBumpyShiny) {
program = ShaderProgram::SkeletalDiffuseBumpmap;
} else if (!hasEnvmap && !hasLightmap && !hasBumpyShiny && !hasBumpmap) {
program = ShaderProgram::SkeletalDiffuse;
}
if (hasLightmap && !hasEnvmap && !hasBumpyShiny) {
program = ShaderProgram::ModelDiffuseLightmap;
} else if (hasLightmap && hasEnvmap && !hasBumpyShiny) {
program = ShaderProgram::ModelDiffuseLightmapEnvmap;
} else if (hasLightmap && !hasEnvmap && hasBumpyShiny) {
program = ShaderProgram::ModelDiffuseLightmapBumpyShiny;
} else if (!hasLightmap && hasEnvmap && !hasBumpyShiny) {
program = ShaderProgram::ModelDiffuseEnvmap;
} else if (!hasLightmap && !hasEnvmap && hasBumpyShiny) {
program = ShaderProgram::ModelDiffuseBumpyShiny;
} else if (!hasLightmap && !hasEnvmap && !hasBumpyShiny && hasBumpmap) {
program = ShaderProgram::ModelDiffuseBumpmap;
} else {
if (hasEnvmap && !hasLightmap && !hasBumpyShiny) {
program = ShaderProgram::BasicDiffuseEnvmap;
} else if (hasBumpyShiny && !hasEnvmap && !hasLightmap) {
program = ShaderProgram::BasicDiffuseBumpyShiny;
} else if (hasLightmap && !hasEnvmap && !hasBumpyShiny) {
program = ShaderProgram::BasicDiffuseLightmap;
} else if (hasEnvmap && hasLightmap && !hasBumpyShiny) {
program = ShaderProgram::BasicDiffuseLightmapEnvmap;
} else if (hasLightmap && hasBumpyShiny && !hasEnvmap) {
program = ShaderProgram::BasicDiffuseLightmapBumpyShiny;
} else if (!hasEnvmap && !hasLightmap && !hasBumpyShiny) {
program = ShaderProgram::BasicDiffuse;
}
program = ShaderProgram::ModelDiffuse;
}
if (program == ShaderProgram::None) {

View file

@ -50,7 +50,7 @@ private:
bool isTransparent() const;
ShaderProgram getShaderProgram(const ModelMesh &mesh, bool skeletal) const;
ShaderProgram getShaderProgram(const ModelMesh &mesh) const;
void updateAbsoluteTransform() override;
void updateCenter();
};

View file

@ -31,33 +31,7 @@ namespace reone {
namespace render {
static const GLchar kBasicVertexShader[] = R"END(
#version 330
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 texCoords;
layout(location = 3) in vec2 lightmapCoords;
out vec3 fragPosition;
out vec3 fragNormal;
out vec2 fragTexCoords;
out vec2 fragLightmapCoords;
void main() {
gl_Position = projection * view * model * vec4(position, 1);
fragPosition = vec3(model * vec4(position, 1));
fragNormal = mat3(transpose(inverse(model))) * normal;
fragTexCoords = texCoords;
fragLightmapCoords = lightmapCoords;
}
)END";
static const GLchar kSkeletalVertexShader[] = R"END(
static const GLchar kModelVertexShader[] = R"END(
#version 330
const int MAX_BONES = 128;
@ -65,6 +39,8 @@ const int MAX_BONES = 128;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
uniform bool skeletalEnabled;
uniform mat4 absTransform;
uniform mat4 absTransformInv;
uniform mat4 bones[MAX_BONES];
@ -72,36 +48,47 @@ uniform mat4 bones[MAX_BONES];
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 texCoords;
layout(location = 3) in vec2 lightmapCoords;
layout(location = 4) in vec4 boneWeights;
layout(location = 5) in vec4 boneIndices;
out vec3 fragPosition;
out vec3 fragNormal;
out vec2 fragTexCoords;
out vec2 fragLightmapCoords;
void main() {
float weight0 = boneWeights.x;
float weight1 = boneWeights.y;
float weight2 = boneWeights.z;
float weight3 = boneWeights.w;
vec3 newPosition = vec3(0.0);
int index0 = int(boneIndices.x);
int index1 = int(boneIndices.y);
int index2 = int(boneIndices.z);
int index3 = int(boneIndices.w);
if (skeletalEnabled) {
float weight0 = boneWeights.x;
float weight1 = boneWeights.y;
float weight2 = boneWeights.z;
float weight3 = boneWeights.w;
vec4 position4 = vec4(position, 1);
int index0 = int(boneIndices.x);
int index1 = int(boneIndices.y);
int index2 = int(boneIndices.z);
int index3 = int(boneIndices.w);
vec3 newPosition = vec3(0, 0, 0);
newPosition += weight0 * (absTransformInv * bones[index0] * absTransform * position4).xyz;
newPosition += weight1 * (absTransformInv * bones[index1] * absTransform * position4).xyz;
newPosition += weight2 * (absTransformInv * bones[index2] * absTransform * position4).xyz;
newPosition += weight3 * (absTransformInv * bones[index3] * absTransform * position4).xyz;
vec4 position4 = vec4(position, 1.0);
gl_Position = projection * view * model * vec4(newPosition, 1);
fragPosition = vec3(model * vec4(position, 1));
newPosition += weight0 * (absTransformInv * bones[index0] * absTransform * position4).xyz;
newPosition += weight1 * (absTransformInv * bones[index1] * absTransform * position4).xyz;
newPosition += weight2 * (absTransformInv * bones[index2] * absTransform * position4).xyz;
newPosition += weight3 * (absTransformInv * bones[index3] * absTransform * position4).xyz;
} else {
newPosition = position;
}
vec4 newPosition4 = vec4(newPosition, 1.0);
gl_Position = projection * view * model * newPosition4;
fragPosition = vec3(model * newPosition4);
fragNormal = mat3(transpose(inverse(model))) * normal;
fragTexCoords = texCoords;
fragLightmapCoords = lightmapCoords;
}
)END";
@ -118,7 +105,7 @@ layout(location = 2) in vec2 texCoords;
out vec2 fragTexCoords;
void main() {
gl_Position = projection * view * model * vec4(position, 1);
gl_Position = projection * view * model * vec4(position, 1.0);
fragTexCoords = texCoords;
}
)END";
@ -371,8 +358,7 @@ ShaderManager &ShaderManager::instance() {
}
void ShaderManager::initGL() {
initShader(ShaderName::VertexBasic, GL_VERTEX_SHADER, kBasicVertexShader);
initShader(ShaderName::VertexSkeletal, GL_VERTEX_SHADER, kSkeletalVertexShader);
initShader(ShaderName::VertexModel, GL_VERTEX_SHADER, kModelVertexShader);
initShader(ShaderName::VertexGUI, GL_VERTEX_SHADER, kGUIVertexShader);
initShader(ShaderName::FragmentWhite, GL_FRAGMENT_SHADER, kWhiteFragmentShader);
initShader(ShaderName::FragmentDiffuse, GL_FRAGMENT_SHADER, kDiffuseFragmentShader);
@ -385,18 +371,15 @@ void ShaderManager::initGL() {
initShader(ShaderName::FragmentDiffuseGaussianBlur, GL_FRAGMENT_SHADER, kGaussianBlurFragmentShader);
initShader(ShaderName::FragmentText, GL_FRAGMENT_SHADER, kTextFragmentShader);
initProgram(ShaderProgram::BasicWhite, ShaderName::VertexBasic, ShaderName::FragmentWhite);
initProgram(ShaderProgram::BasicDiffuse, ShaderName::VertexBasic, ShaderName::FragmentDiffuse);
initProgram(ShaderProgram::BasicDiffuseEnvmap, ShaderName::VertexBasic, ShaderName::FragmentDiffuseEnvmap);
initProgram(ShaderProgram::BasicDiffuseBumpyShiny, ShaderName::VertexBasic, ShaderName::FragmentDiffuseBumpyShiny);
initProgram(ShaderProgram::BasicDiffuseLightmap, ShaderName::VertexBasic, ShaderName::FragmentDiffuseLightmap);
initProgram(ShaderProgram::BasicDiffuseLightmapEnvmap, ShaderName::VertexBasic, ShaderName::FragmentDiffuseLightmapEnvmap);
initProgram(ShaderProgram::BasicDiffuseLightmapBumpyShiny, ShaderName::VertexBasic, ShaderName::FragmentDiffuseLightmapBumpyShiny);
initProgram(ShaderProgram::BasicDiffuseGaussianBlur, ShaderName::VertexBasic, ShaderName::FragmentDiffuseGaussianBlur);
initProgram(ShaderProgram::SkeletalDiffuse, ShaderName::VertexSkeletal, ShaderName::FragmentDiffuse);
initProgram(ShaderProgram::SkeletalDiffuseEnvmap, ShaderName::VertexSkeletal, ShaderName::FragmentDiffuseEnvmap);
initProgram(ShaderProgram::SkeletalDiffuseBumpyShiny, ShaderName::VertexSkeletal, ShaderName::FragmentDiffuseBumpyShiny);
initProgram(ShaderProgram::SkeletalDiffuseBumpmap, ShaderName::VertexSkeletal, ShaderName::FragmentDiffuseBumpmap);
initProgram(ShaderProgram::ModelWhite, ShaderName::VertexModel, ShaderName::FragmentWhite);
initProgram(ShaderProgram::ModelDiffuse, ShaderName::VertexModel, ShaderName::FragmentDiffuse);
initProgram(ShaderProgram::ModelDiffuseBumpmap, ShaderName::VertexModel, ShaderName::FragmentDiffuseBumpmap);
initProgram(ShaderProgram::ModelDiffuseBumpyShiny, ShaderName::VertexModel, ShaderName::FragmentDiffuseBumpyShiny);
initProgram(ShaderProgram::ModelDiffuseEnvmap, ShaderName::VertexModel, ShaderName::FragmentDiffuseEnvmap);
initProgram(ShaderProgram::ModelDiffuseGaussianBlur, ShaderName::VertexModel, ShaderName::FragmentDiffuseGaussianBlur);
initProgram(ShaderProgram::ModelDiffuseLightmap, ShaderName::VertexModel, ShaderName::FragmentDiffuseLightmap);
initProgram(ShaderProgram::ModelDiffuseLightmapEnvmap, ShaderName::VertexModel, ShaderName::FragmentDiffuseLightmapEnvmap);
initProgram(ShaderProgram::ModelDiffuseLightmapBumpyShiny, ShaderName::VertexModel, ShaderName::FragmentDiffuseLightmapBumpyShiny);
initProgram(ShaderProgram::GUIText, ShaderName::VertexGUI, ShaderName::FragmentText);
}

View file

@ -29,18 +29,15 @@ namespace render {
enum class ShaderProgram {
None,
BasicWhite,
BasicDiffuse,
BasicDiffuseEnvmap,
BasicDiffuseBumpyShiny,
BasicDiffuseLightmap,
BasicDiffuseLightmapEnvmap,
BasicDiffuseLightmapBumpyShiny,
BasicDiffuseGaussianBlur,
SkeletalDiffuse,
SkeletalDiffuseEnvmap,
SkeletalDiffuseBumpyShiny,
SkeletalDiffuseBumpmap,
ModelDiffuse,
ModelWhite,
ModelDiffuseBumpmap,
ModelDiffuseBumpyShiny,
ModelDiffuseEnvmap,
ModelDiffuseGaussianBlur,
ModelDiffuseLightmap,
ModelDiffuseLightmapBumpyShiny,
ModelDiffuseLightmapEnvmap,
GUIText
};
@ -68,18 +65,17 @@ public:
private:
enum class ShaderName {
VertexBasic,
VertexSkeletal,
VertexModel,
VertexGUI,
FragmentWhite,
FragmentDiffuse,
FragmentDiffuseEnvmap,
FragmentDiffuseBumpyShiny,
FragmentDiffuseLightmap,
FragmentDiffuseLightmapEnvmap,
FragmentDiffuseLightmapBumpyShiny,
FragmentDiffuseBumpmap,
FragmentDiffuseBumpyShiny,
FragmentDiffuseEnvmap,
FragmentDiffuseGaussianBlur,
FragmentDiffuseLightmap,
FragmentDiffuseLightmapBumpyShiny,
FragmentDiffuseLightmapEnvmap,
FragmentText
};

View file

@ -166,7 +166,7 @@ void RenderWindow::drawCursor() const {
transform = glm::scale(transform, glm::vec3(texture->width(), texture->height(), 1.0f));
ShaderManager &shaders = Shaders;
shaders.activate(ShaderProgram::BasicDiffuse);
shaders.activate(ShaderProgram::ModelDiffuse);
shaders.setUniform("model", transform);
shaders.setUniform("color", glm::vec3(1.0f));
shaders.setUniform("alpha", 1.0f);