GPU skinning refactoring
This commit is contained in:
1 parent
83cceecccd
commit
2ef2e456f7
4 files changed
+161
-138
No files matched your search
+50
-120
@@ -27,9 +27,6 @@ void Character::loadBinaryAnimation(AnimationState state, const std::string& fil
|
||||
data.totalFrames = 1;
|
||||
}
|
||||
}
|
||||
/*void Character::setTexture(std::shared_ptr<Texture> tex) {
|
||||
texture = tex;
|
||||
}*/
|
||||
|
||||
void Character::setTarget(const Eigen::Vector3f& target,
|
||||
std::function<void()> onArrived) {
|
||||
@@ -259,7 +256,7 @@ void Character::update(int64_t deltaMs) {
|
||||
|
||||
if (static_cast<int>(anim.currentFrame) != anim.lastFrame) {
|
||||
if (useGpuSkinning) {
|
||||
anim.model.ComputeSkinningMatrices(static_cast<int>(anim.currentFrame), anim.skinningMatrices);
|
||||
anim.gpuSkinningShaderData.ComputeSkinningMatrices(anim.model.startBones, anim.model.animations[0].keyFrames, static_cast<int>(anim.currentFrame));
|
||||
} else {
|
||||
anim.model.Interpolate(static_cast<int>(anim.currentFrame));
|
||||
}
|
||||
@@ -310,14 +307,15 @@ void Character::drawGpuSkinning(Renderer& renderer) {
|
||||
}
|
||||
|
||||
auto& anim = it->second;
|
||||
anim.prepareGpuSkinningVBOs();
|
||||
anim.gpuSkinningShaderData.prepareGpuSkinningVBOs(anim.model);
|
||||
|
||||
if (anim.skinningMatrices.empty())
|
||||
if (anim.gpuSkinningShaderData.skinningMatrices.empty())
|
||||
{
|
||||
if (anim.model.animations.empty() || anim.model.animations[0].keyFrames.empty()) return;
|
||||
anim.model.ComputeSkinningMatrices(
|
||||
anim.model.animations[0].keyFrames[0].frame, anim.skinningMatrices);
|
||||
if (anim.skinningMatrices.empty()) return;
|
||||
|
||||
anim.gpuSkinningShaderData.ComputeSkinningMatrices(anim.model.startBones, anim.model.animations[0].keyFrames, static_cast<int>(anim.currentFrame));
|
||||
|
||||
if (anim.gpuSkinningShaderData.skinningMatrices.empty()) return;
|
||||
}
|
||||
static const std::string skinningShaderName = "skinning";
|
||||
static const std::string boneMatricesUniform = "uBoneMatrices[0]";
|
||||
@@ -337,51 +335,56 @@ void Character::drawGpuSkinning(Renderer& renderer) {
|
||||
|
||||
// Upload bone skinning matrices
|
||||
renderer.RenderUniformMatrix4fvArray(boneMatricesUniform,
|
||||
static_cast<int>(anim.skinningMatrices.size()), false,
|
||||
anim.skinningMatrices[0].data());
|
||||
static_cast<int>(anim.gpuSkinningShaderData.skinningMatrices.size()), false,
|
||||
anim.gpuSkinningShaderData.skinningMatrices[0].data());
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture->getTexID());
|
||||
|
||||
// Bind VAO (desktop only)
|
||||
#ifndef EMSCRIPTEN
|
||||
#ifndef __ANDROID__
|
||||
if (anim.bindPoseMutable.vao) {
|
||||
glBindVertexArray(anim.bindPoseMutable.vao->getBuffer());
|
||||
if (anim.gpuSkinningShaderData.bindPoseMutable.vao) {
|
||||
glBindVertexArray(anim.gpuSkinningShaderData.bindPoseMutable.vao->getBuffer());
|
||||
renderer.shaderManager.EnableVertexAttribArrays();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Bind position and texcoord VBOs
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.bindPoseMutable.positionVBO->getBuffer());
|
||||
renderer.VertexAttribPointer3fv("vPosition", 0, NULL);
|
||||
|
||||
if (anim.bindPoseMutable.texCoordVBO) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.bindPoseMutable.texCoordVBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("vTexCoord", 0, NULL);
|
||||
}
|
||||
|
||||
// Bind bone index VBOs
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneIndices0VBO->getBuffer());
|
||||
renderer.VertexAttribPointer4fv("aBoneIndices0", 0, NULL);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneIndices1VBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("aBoneIndices1", 0, NULL);
|
||||
|
||||
// Bind bone weight VBOs
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneWeights0VBO->getBuffer());
|
||||
renderer.VertexAttribPointer4fv("aBoneWeights0", 0, NULL);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneWeights1VBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("aBoneWeights1", 0, NULL);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(anim.bindPoseMutable.data.PositionData.size()));
|
||||
|
||||
anim.gpuSkinningShaderData.RenderVBO(renderer);
|
||||
|
||||
renderer.PopMatrix();
|
||||
renderer.PopProjectionMatrix();
|
||||
renderer.shaderManager.PopShader();
|
||||
}
|
||||
|
||||
bool Character::prepareGpuSkinning()
|
||||
{
|
||||
AnimationState drawState = resolveActiveState();
|
||||
auto it = animations.find(drawState);
|
||||
if (it == animations.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& anim = it->second;
|
||||
anim.gpuSkinningShaderData.prepareGpuSkinningVBOs(anim.model);
|
||||
if (anim.gpuSkinningShaderData.skinningMatrices.empty()) {
|
||||
if (anim.model.animations.empty() || anim.model.animations[0].keyFrames.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
anim.gpuSkinningShaderData.ComputeSkinningMatrices(anim.model.startBones, anim.model.animations[0].keyFrames, static_cast<int>(anim.currentFrame));
|
||||
|
||||
if (anim.gpuSkinningShaderData.skinningMatrices.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ==================== Shadow depth pass ====================
|
||||
|
||||
void Character::drawShadowDepth(Renderer& renderer) {
|
||||
@@ -418,14 +421,7 @@ void Character::drawShadowDepthGpuSkinning(Renderer& renderer) {
|
||||
auto it = animations.find(drawState);
|
||||
if (it == animations.end()) return;
|
||||
|
||||
auto& anim = it->second;
|
||||
anim.prepareGpuSkinningVBOs();
|
||||
if (anim.skinningMatrices.empty()) {
|
||||
if (anim.model.animations.empty() || anim.model.animations[0].keyFrames.empty()) return;
|
||||
anim.model.ComputeSkinningMatrices(
|
||||
anim.model.animations[0].keyFrames[0].frame, anim.skinningMatrices);
|
||||
if (anim.skinningMatrices.empty()) return;
|
||||
}
|
||||
if (!prepareGpuSkinning()) return;
|
||||
|
||||
static const std::string shadowSkinningShader = "shadow_depth_skinning";
|
||||
static const std::string boneMatricesUniform = "uBoneMatrices[0]";
|
||||
@@ -440,36 +436,10 @@ void Character::drawShadowDepthGpuSkinning(Renderer& renderer) {
|
||||
renderer.RotateMatrix(modelCorrectionRotation.toRotationMatrix());
|
||||
|
||||
renderer.RenderUniformMatrix4fvArray(boneMatricesUniform,
|
||||
static_cast<int>(anim.skinningMatrices.size()), false,
|
||||
anim.skinningMatrices[0].data());
|
||||
|
||||
#ifndef EMSCRIPTEN
|
||||
#ifndef __ANDROID__
|
||||
if (anim.bindPoseMutable.vao) {
|
||||
glBindVertexArray(anim.bindPoseMutable.vao->getBuffer());
|
||||
renderer.shaderManager.EnableVertexAttribArrays();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.bindPoseMutable.positionVBO->getBuffer());
|
||||
renderer.VertexAttribPointer3fv("vPosition", 0, NULL);
|
||||
|
||||
if (anim.bindPoseMutable.texCoordVBO) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.bindPoseMutable.texCoordVBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("vTexCoord", 0, NULL);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneIndices0VBO->getBuffer());
|
||||
renderer.VertexAttribPointer4fv("aBoneIndices0", 0, NULL);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneIndices1VBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("aBoneIndices1", 0, NULL);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneWeights0VBO->getBuffer());
|
||||
renderer.VertexAttribPointer4fv("aBoneWeights0", 0, NULL);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneWeights1VBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("aBoneWeights1", 0, NULL);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(anim.bindPoseMutable.data.PositionData.size()));
|
||||
static_cast<int>(it->second.gpuSkinningShaderData.skinningMatrices.size()), false,
|
||||
it->second.gpuSkinningShaderData.skinningMatrices[0].data());
|
||||
|
||||
it->second.gpuSkinningShaderData.RenderVBO(renderer);
|
||||
|
||||
renderer.PopMatrix();
|
||||
renderer.shaderManager.PopShader();
|
||||
@@ -528,15 +498,7 @@ void Character::drawGpuSkinningWithShadow(Renderer& renderer, const Eigen::Matri
|
||||
auto it = animations.find(drawState);
|
||||
if (it == animations.end() || !texture) return;
|
||||
|
||||
auto& anim = it->second;
|
||||
anim.prepareGpuSkinningVBOs();
|
||||
|
||||
if (anim.skinningMatrices.empty()) {
|
||||
if (anim.model.animations.empty() || anim.model.animations[0].keyFrames.empty()) return;
|
||||
anim.model.ComputeSkinningMatrices(
|
||||
anim.model.animations[0].keyFrames[0].frame, anim.skinningMatrices);
|
||||
if (anim.skinningMatrices.empty()) return;
|
||||
}
|
||||
if (!prepareGpuSkinning()) return;
|
||||
|
||||
static const std::string skinningShadowShader = "skinning_shadow";
|
||||
static const std::string boneMatricesUniform = "uBoneMatrices[0]";
|
||||
@@ -562,44 +524,12 @@ void Character::drawGpuSkinningWithShadow(Renderer& renderer, const Eigen::Matri
|
||||
renderer.RotateMatrix(modelCorrectionRotation.toRotationMatrix());
|
||||
|
||||
renderer.RenderUniformMatrix4fvArray(boneMatricesUniform,
|
||||
static_cast<int>(anim.skinningMatrices.size()), false,
|
||||
anim.skinningMatrices[0].data());
|
||||
static_cast<int>(it->second.gpuSkinningShaderData.skinningMatrices.size()), false,
|
||||
it->second.gpuSkinningShaderData.skinningMatrices[0].data());
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture->getTexID());
|
||||
|
||||
#ifndef EMSCRIPTEN
|
||||
#ifndef __ANDROID__
|
||||
if (anim.bindPoseMutable.vao) {
|
||||
glBindVertexArray(anim.bindPoseMutable.vao->getBuffer());
|
||||
renderer.shaderManager.EnableVertexAttribArrays();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.bindPoseMutable.positionVBO->getBuffer());
|
||||
renderer.VertexAttribPointer3fv("vPosition", 0, NULL);
|
||||
|
||||
if (anim.bindPoseMutable.texCoordVBO) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.bindPoseMutable.texCoordVBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("vTexCoord", 0, NULL);
|
||||
}
|
||||
|
||||
// Bind normals for diffuse lighting (skinning_shadow shader skins them)
|
||||
if (anim.bindPoseMutable.normalVBO) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.bindPoseMutable.normalVBO->getBuffer());
|
||||
renderer.VertexAttribPointer3fv("vNormal", 0, NULL);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneIndices0VBO->getBuffer());
|
||||
renderer.VertexAttribPointer4fv("aBoneIndices0", 0, NULL);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneIndices1VBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("aBoneIndices1", 0, NULL);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneWeights0VBO->getBuffer());
|
||||
renderer.VertexAttribPointer4fv("aBoneWeights0", 0, NULL);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, anim.boneWeights1VBO->getBuffer());
|
||||
renderer.VertexAttribPointer2fv("aBoneWeights1", 0, NULL);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(anim.bindPoseMutable.data.PositionData.size()));
|
||||
it->second.gpuSkinningShaderData.RenderVBO(renderer);
|
||||
|
||||
renderer.PopMatrix();
|
||||
renderer.PopProjectionMatrix();
|
||||
|
||||
Reference in new issue
Block a user