1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-11 15:45:05 +02:00

#16 matrix array in the shader (for entities), do not recalc joints more than one time per Game::render (in multipass case)

This commit is contained in:
XProger
2016-12-22 00:06:13 +03:00
parent b6f50a674e
commit 69e4f8e962
6 changed files with 43 additions and 15 deletions

View File

@@ -23,6 +23,9 @@ struct Controller {
int *meshes;
int mCount;
mat4 *joints;
int frameIndex;
struct ActionCommand {
int emitter;
TR::Action action;
@@ -36,12 +39,16 @@ struct Controller {
Controller(TR::Level *level, int entity) : level(level), entity(entity), animation(level, getModel()), state(animation.state), meshes(NULL), mCount(0), actionCommand(NULL) {
TR::Entity &e = getEntity();
pos = vec3((float)e.x, (float)e.y, (float)e.z);
angle = vec3(0.0f, e.rotation, 0.0f);
pos = vec3((float)e.x, (float)e.y, (float)e.z);
angle = vec3(0.0f, e.rotation, 0.0f);
TR::Model *m = getModel();
joints = m ? new mat4[m->mCount] : NULL;
frameIndex = -1;
}
virtual ~Controller() {
delete[] meshes;
delete[] joints;
}
void initMeshOverrides() {
@@ -395,11 +402,9 @@ struct Controller {
updateAnimation(true);
}
void renderMesh(const mat4 &matrix, MeshBuilder *mesh, uint32 offsetIndex) {
void renderMesh(MeshBuilder *mesh, uint32 offsetIndex) {
MeshBuilder::MeshInfo *mInfo = mesh->meshMap[offsetIndex];
if (!mInfo) return; // invisible mesh (offsetIndex > 0 && level.meshOffsets[offsetIndex] == 0) camera target entity etc.
Core::active.shader->setParam(uModel, matrix);
mesh->renderMesh(mInfo);
}
@@ -438,14 +443,19 @@ struct Controller {
TR::Entity &entity = getEntity();
TR::Model *model = getModel();
ASSERT(model);
entity.flags.rendered = true;
mat4 joints[32]; // TODO: UBO heap
ASSERT(model->mCount <= 32);
if (Core::frameIndex != frameIndex)
animation.getJoints(matrix, -1, true, joints);
Core::active.shader->setParam(uModel, joints[0], model->mCount);
animation.getJoints(matrix, -1, true, joints);
for (int i = 0; i < model->mCount; i++)
renderMesh(joints[i], mesh, meshes ? meshes[i] : (model->mStart + i));
renderMesh(mesh, meshes ? meshes[i] : (model->mStart + i));
frameIndex = Core::frameIndex;
/* // blob shadow
if (TR::castShadow(entity.type)) {

View File

@@ -132,6 +132,7 @@ struct Texture;
namespace Core {
int width, height;
int frameIndex;
float deltaTime;
mat4 mView, mProj, mViewProj, mViewInv, mModel, mLightProj;
vec3 viewPos;
@@ -252,6 +253,8 @@ namespace Core {
for (int i = 0; i < MAX_LIGHTS; i++)
lightColor[i] = vec4(0, 0, 0, 1);
frameIndex = 0;
}
void free() {

View File

@@ -44,6 +44,7 @@ namespace Game {
void render() {
level->render();
Core::frameIndex++;
}
}

View File

@@ -1761,7 +1761,8 @@ struct Lara : Character {
m.translate(offset);
Core::active.shader->setParam(uColor, vec4(lum, lum, lum, alpha));
renderMesh(m, mesh, level->extra.muzzleFlash->mStart);
Core::active.shader->setParam(uModel, m);
renderMesh(mesh, level->extra.muzzleFlash->mStart);
}
virtual void render(Frustum *frustum, MeshBuilder *mesh) {

View File

@@ -323,6 +323,17 @@ struct MeshBuilder {
if (info.offset == level.meshOffsets[j])
meshMap[j] = &info;
int16 joint = 0;
for (int j = 0; j < level.modelsCount; j++) {
TR::Model &m = level.models[j];
for (int k = m.mStart; k < m.mStart + m.mCount; k++) {
if (mesh.offset == level.meshOffsets[k]) {
joint = k - m.mStart;
break;
}
}
}
int vStart = vCount;
for (int j = 0; j < mesh.rCount; j++) {
TR::Rectangle &f = mesh.rectangles[j];
@@ -335,7 +346,7 @@ struct MeshBuilder {
for (int k = 0; k < 4; k++) {
TR::Mesh::Vertex &v = mesh.vertices[f.vertices[k]];
vertices[vCount].coord = v.coord;
vertices[vCount].coord = { v.coord.x, v.coord.y, v.coord.z, joint };
vertices[vCount].normal = v.normal;
vertices[vCount].color = { c.r, c.g, c.b, intensity(v.coord.w) };
@@ -354,7 +365,7 @@ struct MeshBuilder {
for (int k = 0; k < 3; k++) {
TR::Mesh::Vertex &v = mesh.vertices[f.vertices[k]];
vertices[vCount].coord = v.coord;
vertices[vCount].coord = { v.coord.x, v.coord.y, v.coord.z, joint };
vertices[vCount].normal = v.normal;
vertices[vCount].color = { c.r, c.g, c.b, intensity(v.coord.w) };

View File

@@ -26,7 +26,7 @@ uniform int uType;
#ifdef VERTEX
uniform mat4 uViewProj;
uniform mat4 uModel;
uniform mat4 uModel[32];
#ifndef PASS_AMBIENT
uniform mat4 uViewInv;
@@ -54,7 +54,9 @@ uniform int uType;
#define TEXCOORD_SCALE (1.0 / 32767.0)
void main() {
vec4 coord = uModel * vec4(aCoord.xyz, 1.0);
mat4 rJoint = uModel[int(aCoord.w)];
vec4 coord = rJoint * vec4(aCoord.xyz, 1.0);
#ifdef PASS_COMPOSE
if (uType != TYPE_SPRITE) {
@@ -65,7 +67,7 @@ uniform int uType;
vec2 offset = uAnimTexOffsets[int(range.x + f)]; // texCoord offset from first frame
vTexCoord = (aTexCoord.xy + offset) * TEXCOORD_SCALE; // first frame + offset * isAnimated
vNormal = vec4((uModel * vec4(aNormal.xyz, 0.0)).xyz, aNormal.w);
vNormal = vec4((rJoint * vec4(aNormal.xyz, 0.0)).xyz, aNormal.w);
} else {
coord.xyz += uViewInv[0].xyz * aTexCoord.z - uViewInv[1].xyz * aTexCoord.w;
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;