1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-01-24 17:26:41 +00:00

Instead of drawing the entire grid, draw only the horiz. slice that is on screen

Still a single draw call but the vertex range to draw is greatly reduced.
This commit is contained in:
fgenesis 2024-01-13 05:59:23 +01:00
parent 511f064bbe
commit 22c8471bf2
2 changed files with 46 additions and 23 deletions

View file

@ -64,7 +64,6 @@ GridRender::GridRender(ObsType obsType)
, vbo(GPUBUF_VERTEXBUF | GPUBUF_STATIC) , vbo(GPUBUF_VERTEXBUF | GPUBUF_STATIC)
, primsToDraw(0) , primsToDraw(0)
, obsType(obsType) , obsType(obsType)
//, ibo(GPUBUF_INDEXBUF | GPUBUF_STATIC)
, markedForRebuild(true) , markedForRebuild(true)
{ {
color = Vector(1, 0, 0); color = Vector(1, 0, 0);
@ -72,7 +71,7 @@ GridRender::GridRender(ObsType obsType)
position.z = 5; position.z = 5;
cull = false; cull = false;
alpha = 0.5f; alpha = 0.5f;
this->scale.x = TILE_SIZE; this->scale.x = TILE_SIZE; // See comment about value scaling below
this->scale.y = TILE_SIZE; this->scale.y = TILE_SIZE;
} }
@ -92,6 +91,31 @@ void GridRender::rebuildBuffers(const std::vector<ObsRow>& rows)
if(!N) if(!N)
return; return;
// Construct lookup table so we know the vertex index to start drawing, for each line
{
const size_t H = game->getGridSize().y;
primIndexInLine.resize(H);
size_t lasty = 0;
size_t lastidx = 0;
for(size_t i = 0; i < N; ++i)
{
const ObsRow& row = rows[i];
assert(row.ty >= lasty); // rows must be sorted, lowest y first
if(row.ty > lasty)
{
// Handle this correctly even if there is no row on some lines
for(size_t y = lasty; y < row.ty; ++y)
primIndexInLine[y] = lastidx;
lasty = row.ty;
lastidx = i * 6;
}
}
// Don't bother filling the rest, anything beyond the end is eval'd as primsToDraw
primIndexInLine.resize(lasty);
}
// 2 tris = 6 verts per ObsRow, each vertex is 2x uint16, makes 24b per quad. // 2 tris = 6 verts per ObsRow, each vertex is 2x uint16, makes 24b per quad.
// We could use indexed rendering and use 2 verts less (16b), // We could use indexed rendering and use 2 verts less (16b),
// but the 6 indices would cost another 12b so it's definitely cheaper to send // but the 6 indices would cost another 12b so it's definitely cheaper to send
@ -157,34 +181,32 @@ void GridRender::onRender(const RenderState& rs) const
if(!primsToDraw) if(!primsToDraw)
return; return;
/* const TileVector ct(core->cameraPos);
const signed char obsType = this->obsType; const int H = primIndexInLine.size();
Vector camPos = core->cameraPos; int startY = ct.y;
camPos.x -= core->getVirtualOffX() * (core->invGlobalScale);
const TileVector ct(camPos);
const int width = int((core->getVirtualWidth() * (core->invGlobalScale))/TILE_SIZE) + 1; // Note that it's possible that the scale factor is negative (mods can use this),
// so this might end up upside down. Still needs to render correctly.
const int height = int((600 * (core->invGlobalScale))/TILE_SIZE) + 1; const int height = int((600 * (core->invGlobalScale))/TILE_SIZE) + 1;
int endY = ct.y+height;
if(endY < startY)
std::swap(startY, endY);
int startX = ct.x-1, endX = ct.x+width+1; --startY;
int startY = ct.y-1, endY = ct.y+height+1; ++endY;
if (startX < 0)
startX = 0; if(endY < 0 || startY >= H)
if (endX >= MAX_GRID)
endX = MAX_GRID-1;
if (startY < 0)
startY = 0;
if (endY >= MAX_GRID)
endY = MAX_GRID-1;
if (startY > endY)
return; return;
*/ if(startY < 0)
startY = 0;
// TODO: keep track of prim index at which a row starts const size_t beginIdx = primIndexInLine[startY];
// then horizontally span only as much prims as are necessary? const size_t endIdx = endY < H ? primIndexInLine[endY] : primsToDraw;
if(beginIdx >= endIdx)
return;
vbo.apply(); vbo.apply();
glDrawArrays(GL_TRIANGLES, 0, primsToDraw); glDrawArrays(GL_TRIANGLES, beginIdx, endIdx - beginIdx);
} }
SongLineRender::SongLineRender() SongLineRender::SongLineRender()

View file

@ -47,6 +47,7 @@ public:
protected: protected:
DynamicGPUBuffer vbo; DynamicGPUBuffer vbo;
size_t primsToDraw; size_t primsToDraw;
std::vector<size_t> primIndexInLine;
const ObsType obsType; const ObsType obsType;
bool markedForRebuild; bool markedForRebuild;