1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-13 00:24:24 +02:00

#23 reduce number of VAOs

This commit is contained in:
XProger
2017-08-15 05:43:42 +03:00
parent 2a9e6f2cb4
commit f23f481b29
3 changed files with 97 additions and 84 deletions

View File

@@ -118,7 +118,7 @@ struct ShaderCache {
}
}
const char *passNames[] = { "COMPOSE", "SHADOW", "AMBIENT", "WATER", "FILTER", "VOLUME", "GUI" };
const char *passNames[] = { "COMPOSE", "SHADOW", "AMBIENT", "WATER", "FILTER", "GUI" };
const char *src = NULL;
const char *typ = NULL;
switch (pass) {

View File

@@ -16,7 +16,7 @@ struct MeshRange {
int vStart;
int aIndex;
MeshRange() : aIndex(-1) {}
MeshRange() : iStart(0), iCount(0), vStart(0), aIndex(-1) {}
void setup() const {
glEnableVertexAttribArray(aCoord);
@@ -224,14 +224,8 @@ struct MeshBuilder {
vCount += mesh.rCount * 4 + mesh.tCount * 3;
}
RoomRange &range = rooms[i];
range.sprites.vStart = vCount;
range.sprites.iStart = iCount;
iCount += d.sCount * 6;
vCount += d.sCount * 4;
range.sprites.iCount = iCount - range.sprites.iStart;
ASSERT(vCount - range.sprites.vStart < 0xFFFF);
}
// get models info
@@ -251,39 +245,24 @@ struct MeshBuilder {
// get size of mesh for sprite sequences
sequences = new MeshRange[level.spriteSequencesCount];
for (int i = 0; i < level.spriteSequencesCount; i++) {
sequences[i].vStart = vCount;
sequences[i].iStart = iCount;
sequences[i].iCount = level.spriteSequences[i].sCount * 6;
iCount += level.spriteSequences[i].sCount * 6;
vCount += level.spriteSequences[i].sCount * 4;
}
// shadow blob mesh (8 triangles, 8 vertices)
shadowBlob.vStart = vCount;
shadowBlob.iStart = iCount;
shadowBlob.iCount = 8 * 3 * 3;
iCount += shadowBlob.iCount;
iCount += 8 * 3 * 3;
vCount += 8 * 2 + 1;
// quad (post effect filter)
quad.vStart = vCount;
quad.iStart = iCount;
quad.iCount = 2 * 3;
iCount += quad.iCount;
iCount += 2 * 3;
vCount += 4;
// circle
circle.vStart = vCount;
circle.iStart = iCount;
circle.iCount = CIRCLE_SEGS * 3;
iCount += circle.iCount;
iCount += CIRCLE_SEGS * 3;
vCount += CIRCLE_SEGS + 1;
// detailed plane
plane.vStart = vCount;
plane.iStart = iCount;
plane.iCount = PLANE_DETAIL * 2 * PLANE_DETAIL * 2 * (2 * 3);
iCount += plane.iCount;
iCount += PLANE_DETAIL * 2 * PLANE_DETAIL * 2 * (2 * 3);
vCount += (PLANE_DETAIL * 2 + 1) * (PLANE_DETAIL * 2 + 1);
// make meshes buffer (single vertex buffer object for all geometry & sprites on level)
@@ -293,20 +272,20 @@ struct MeshBuilder {
int aCount = 0;
// build rooms
int vStartRoom = vCount;
aCount++;
for (int i = 0; i < level.roomsCount; i++) {
TR::Room &room = level.rooms[i];
TR::Room::Data &d = room.data;
RoomRange &range = rooms[i];
int vStart;
for (int transp = 0; transp < 2; transp++) { // opaque, opacity
range.geometry[transp].vStart = vCount;
range.geometry[transp].vStart = vStartRoom;
range.geometry[transp].iStart = iCount;
vStart = vCount;
// rooms geometry
buildRoom(!transp, room, level, indices, vertices, iCount, vCount, vStart);
buildRoom(!transp, room, level, indices, vertices, iCount, vCount, vStartRoom);
// static meshes
for (int j = 0; j < room.meshesCount; j++) {
@@ -319,44 +298,44 @@ struct MeshBuilder {
int y = m.y;
int z = m.z - room.info.z;
int d = m.rotation.value / 0x4000;
buildMesh(!transp, mesh, level, indices, vertices, iCount, vCount, vStart, 0, x, y, z, d);
buildMesh(!transp, mesh, level, indices, vertices, iCount, vCount, vStartRoom, 0, x, y, z, d);
}
range.geometry[transp].iCount = iCount - range.geometry[transp].iStart;
if (range.geometry[transp].iCount)
aCount++;
}
// rooms sprites
vStart = vCount;
range.sprites.vStart = vStartRoom;
range.sprites.iStart = iCount;
for (int j = 0; j < d.sCount; j++) {
TR::Room::Data::Sprite &f = d.sprites[j];
TR::Room::Data::Vertex &v = d.vertices[f.vertex];
TR::SpriteTexture &sprite = level.spriteTextures[f.texture];
addSprite(indices, vertices, iCount, vCount, vStart, v.vertex.x, v.vertex.y, v.vertex.z, sprite, intensity(v.lighting));
addSprite(indices, vertices, iCount, vCount, vStartRoom, v.vertex.x, v.vertex.y, v.vertex.z, sprite, intensity(v.lighting));
}
if (d.sCount) aCount++;
range.sprites.iCount = iCount - range.sprites.iStart;
}
// build models geometry
int vStartModel = vCount;
aCount++;
for (int i = 0; i < level.modelsCount; i++) {
TR::Model &model = level.models[i];
ModelRange &range = models[i];
int vStart = vCount;
range.geometry.vStart = vStart;
range.geometry.vStart = vStartModel;
range.geometry.iStart = iCount;
range.opaque = true;
for (int j = 0; j < model.mCount; j++) {
int index = level.meshOffsets[model.mStart + j];
if (!index && model.mStart + j > 0) continue;
aCount++;
TR::Mesh &mesh = level.meshes[index];
bool opaque = buildMesh(true, mesh, level, indices, vertices, iCount, vCount, vStart, j, 0, 0, 0, 0);
bool opaque = buildMesh(true, mesh, level, indices, vertices, iCount, vCount, vStartModel, j, 0, 0, 0, 0);
if (!opaque)
buildMesh(false, mesh, level, indices, vertices, iCount, vCount, vStart, j, 0, 0, 0, 0);
buildMesh(false, mesh, level, indices, vertices, iCount, vCount, vStartModel, j, 0, 0, 0, 0);
TR::Entity::fixOpaque(model.type, opaque);
range.opaque &= opaque;
}
@@ -364,14 +343,27 @@ struct MeshBuilder {
}
// build sprite sequences
for (int i = 0; i < level.spriteSequencesCount; i++)
int vStartSprite = vCount;
aCount++;
for (int i = 0; i < level.spriteSequencesCount; i++) {
MeshRange &range = sequences[i];
range.vStart = vStartSprite;
range.iStart = iCount;
for (int j = 0; j < level.spriteSequences[i].sCount; j++) {
TR::SpriteTexture &sprite = level.spriteTextures[level.spriteSequences[i].sStart + j];
addSprite(indices, vertices, iCount, vCount, sequences[i].vStart, 0, 0, 0, sprite, 255);
addSprite(indices, vertices, iCount, vCount, vStartSprite, 0, 0, 0, sprite, 255);
}
aCount += level.spriteSequencesCount;
range.iCount = iCount - range.iStart;
}
// build shadow blob
// build common primitives
int vStartCommon = vCount;
aCount++;
shadowBlob.vStart = vStartCommon;
shadowBlob.iStart = iCount;
shadowBlob.iCount = 8 * 3 * 3;
for (int i = 0; i < 9; i++) {
Vertex &v0 = vertices[vCount + i * 2 + 0];
v0.normal = { 0, -1, 0, 0 };
@@ -414,10 +406,13 @@ struct MeshBuilder {
}
vCount += 8 * 2 + 1;
iCount += shadowBlob.iCount;
aCount++;
// quad
addQuad(indices, iCount, vCount, quad.vStart, vertices, &whiteTile);
quad.vStart = vStartCommon;
quad.iStart = iCount;
quad.iCount = 2 * 3;
addQuad(indices, iCount, vCount, vStartCommon, vertices, &whiteTile);
vertices[vCount + 3].coord = { -1, -1, 0, 0 };
vertices[vCount + 2].coord = { 1, -1, 1, 0 };
vertices[vCount + 1].coord = { 1, 1, 1, 1 };
@@ -431,12 +426,16 @@ struct MeshBuilder {
v.param = { 0, 0, 0, 0 };
}
vCount += 4;
aCount++;
// circle
circle.vStart = vStartCommon;
circle.iStart = iCount;
circle.iCount = CIRCLE_SEGS * 3;
vec2 pos(32767.0f, 0.0f);
vec2 cs(cosf(PI2 / CIRCLE_SEGS), sinf(PI2 / CIRCLE_SEGS));
int baseIdx = vCount - vStartCommon;
for (int i = 0; i < CIRCLE_SEGS; i++) {
Vertex &v = vertices[vCount + i];
pos.rotate(cs);
@@ -446,22 +445,25 @@ struct MeshBuilder {
v.texCoord = { 32688, 32688, 32767, 32767 };
v.param = { 0, 0, 0, 0 };
indices[iCount++] = i;
indices[iCount++] = (i + 1) % CIRCLE_SEGS;
indices[iCount++] = CIRCLE_SEGS;
indices[iCount++] = baseIdx + i;
indices[iCount++] = baseIdx + (i + 1) % CIRCLE_SEGS;
indices[iCount++] = baseIdx + CIRCLE_SEGS;
}
vertices[vCount + CIRCLE_SEGS] = vertices[vCount];
vertices[vCount + CIRCLE_SEGS].coord = { 0, 0, 0, 0 };
vCount += CIRCLE_SEGS + 1;
aCount++;
// plane
plane.vStart = vStartCommon;
plane.iStart = iCount;
plane.iCount = PLANE_DETAIL * 2 * PLANE_DETAIL * 2 * (2 * 3);
baseIdx = vCount - vStartCommon;
for (int16 j = -PLANE_DETAIL; j <= PLANE_DETAIL; j++)
for (int16 i = -PLANE_DETAIL; i <= PLANE_DETAIL; i++) {
vertices[vCount++].coord = { i, j, 0, 0 };
if (j < PLANE_DETAIL && i < PLANE_DETAIL) {
int idx = (j + PLANE_DETAIL) * (PLANE_DETAIL * 2 + 1) + i + PLANE_DETAIL;
int idx = baseIdx + (j + PLANE_DETAIL) * (PLANE_DETAIL * 2 + 1) + i + PLANE_DETAIL;
indices[iCount + 0] = idx + PLANE_DETAIL * 2 + 1;
indices[iCount + 1] = idx + 1;
indices[iCount + 2] = idx;
@@ -471,7 +473,7 @@ struct MeshBuilder {
iCount += 6;
}
}
aCount++;
LOG("MegaMesh: %d %d %d\n", iCount, vCount, aCount);
// compile buffer and ranges
@@ -483,24 +485,35 @@ struct MeshBuilder {
PROFILE_LABEL(BUFFER, mesh->ID[1], "Geometry vertices");
// initialize Vertex Arrays
MeshRange rangeRoom;
rangeRoom.vStart = vStartRoom;
mesh->initRange(rangeRoom);
for (int i = 0; i < level.roomsCount; i++) {
RoomRange &r = rooms[i];
if (r.geometry[0].iCount)
mesh->initRange(r.geometry[0]);
if (r.geometry[1].iCount)
mesh->initRange(r.geometry[1]);
if (r.sprites.iCount)
mesh->initRange(r.sprites);
r.geometry[0].aIndex = rangeRoom.aIndex;
r.geometry[1].aIndex = rangeRoom.aIndex;
r.sprites.aIndex = rangeRoom.aIndex;
}
for (int i = 0; i < level.spriteSequencesCount; i++)
mesh->initRange(sequences[i]);
MeshRange rangeModel;
rangeModel.vStart = vStartModel;
mesh->initRange(rangeModel);
for (int i = 0; i < level.modelsCount; i++)
mesh->initRange(models[i].geometry);
mesh->initRange(shadowBlob);
mesh->initRange(quad);
mesh->initRange(circle);
mesh->initRange(plane);
models[i].geometry.aIndex = rangeModel.aIndex;
MeshRange rangeSprite;
rangeSprite.vStart = vStartSprite;
mesh->initRange(rangeSprite);
for (int i = 0; i < level.spriteSequencesCount; i++)
sequences[i].aIndex = rangeSprite.aIndex;
MeshRange rangeCommon;
rangeCommon.vStart = vStartCommon;
mesh->initRange(rangeCommon);
shadowBlob.aIndex = rangeCommon.aIndex;
quad.aIndex = rangeCommon.aIndex;
circle.aIndex = rangeCommon.aIndex;
plane.aIndex = rangeCommon.aIndex;
}
~MeshBuilder() {
@@ -808,8 +821,8 @@ struct MeshBuilder {
int count = triangle ? 3 : 4;
for (int i = 0; i < count; i++) {
Vertex &v = vertices[vCount + i];
v.texCoord.x = ((tx + tex->texCoord[i].x) << 5) + 16;
v.texCoord.y = ((ty + tex->texCoord[i].y) << 5) + 16;
v.texCoord.x = ((tx + tex->texCoord[i].x) * 32767) / 1024 + 16;
v.texCoord.y = ((ty + tex->texCoord[i].y) * 32767) / 1024 + 16;
v.texCoord.z = 32767;
v.texCoord.w = 32767;
v.param = { range, frame, 0, 0 };
@@ -924,10 +937,10 @@ struct MeshBuilder {
int tx = (sprite.tile % 4) * 256;
int ty = (sprite.tile / 4) * 256;
int16 u0 = (((tx + sprite.texCoord[0].x) << 5));
int16 v0 = (((ty + sprite.texCoord[0].y) << 5));
int16 u1 = (((tx + sprite.texCoord[1].x) << 5));
int16 v1 = (((ty + sprite.texCoord[1].y) << 5));
int16 u0 = (((tx + sprite.texCoord[0].x) * 32767) / 1024) + 16;
int16 v0 = (((ty + sprite.texCoord[0].y) * 32767) / 1024) + 16;
int16 u1 = (((tx + sprite.texCoord[1].x) * 32767) / 1024) + 24;
int16 v1 = (((ty + sprite.texCoord[1].y) * 32767) / 1024) + 24;
quad[0].texCoord = { u0, v0, sprite.l, sprite.t };
quad[1].texCoord = { u1, v0, sprite.r, sprite.t };

View File

@@ -259,16 +259,16 @@ namespace Sound {
int s = (s1 * inc[pred] + s2 * dec[pred]) >> 6;
s = clamp((value >> shift) + s, -32768, 32767);
s2 = s1;
s2 = s1;
s1 = s;
}
void resample(Frame *frames, short value) {
predicate(value);
frames[0].L = frames[0].R = s2 + (s1 - s2) / 4; // 0.25
frames[1].L = frames[1].R = s2 + (s1 - s2) / 2; // 0.50
frames[2].L = frames[2].R = s2 + (s1 - s2) * 3 / 4; // 0.75
frames[3].L = frames[3].R = s1; // 1.00
frames[0].L = frames[0].R = s2 + (s1 - s2) / 4; // 0.25
frames[1].L = frames[1].R = s2 + (s1 - s2) / 2; // 0.50
frames[2].L = frames[2].R = s2 + (s1 - s2) * 3 / 4; // 0.75
frames[3].L = frames[3].R = s1; // 1.00
}
int processBlock() {
@@ -472,7 +472,7 @@ namespace Sound {
decoder = new VAG(stream);
}
#endif
isPlaying = decoder != NULL;
ASSERT(isPlaying);
}