mirror of
https://github.com/dpethes/rerogue.git
synced 2025-06-07 18:58:32 +02:00
terrain viewer: memory pool for batched data render
This commit is contained in:
parent
c3be5c72f0
commit
82794422bd
@ -31,16 +31,30 @@ type
|
|||||||
face_indices: PInteger;
|
face_indices: PInteger;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TMemPool }
|
||||||
|
|
||||||
|
TMemPool = class
|
||||||
|
private
|
||||||
|
_p: pbyte;
|
||||||
|
_end: pbyte;
|
||||||
|
_capacity: ptruint;
|
||||||
|
public
|
||||||
|
constructor Create(capacity: ptruint);
|
||||||
|
destructor Destroy; override;
|
||||||
|
function Alloc(size:ptruint): pointer;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TTerrainMesh }
|
{ TTerrainMesh }
|
||||||
TTerrainMesh = class
|
TTerrainMesh = class
|
||||||
const
|
const
|
||||||
FacesPerBlock = 4 * 4 * 2;
|
FacesPerBlock = 4 * 4 * 2;
|
||||||
private
|
private
|
||||||
terrain: TWorld;
|
terrain: TWorld;
|
||||||
|
render_batches_mempool: TMemPool;
|
||||||
blocks: array of array of TTerrainBlock;
|
blocks: array of array of TTerrainBlock;
|
||||||
block_texcoords: array of Tvector2_single; //static, 25*2*4 = 200B
|
block_texcoords: array of Tvector2_single; //static, 25*2*4 = 200B
|
||||||
block_face_indices: array[0..FacesPerBlock*3 - 1] of byte; //static, 96B
|
|
||||||
render_batches: array of TRenderBlockBatch;
|
render_batches: array of TRenderBlockBatch;
|
||||||
|
block_face_indices: array[0..FacesPerBlock*3 - 1] of byte; //static, 96B
|
||||||
|
|
||||||
function TileToBlock(var tile: TTile; basey, basex: integer): TTerrainBlock;
|
function TileToBlock(var tile: TTile; basey, basex: integer): TTerrainBlock;
|
||||||
procedure TransformTiles;
|
procedure TransformTiles;
|
||||||
@ -67,6 +81,28 @@ begin
|
|||||||
result := a^.texture_index - b^.texture_index;
|
result := a^.texture_index - b^.texture_index;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TMemPool }
|
||||||
|
|
||||||
|
constructor TMemPool.Create(capacity: ptruint);
|
||||||
|
begin
|
||||||
|
_p := system.GetMem(capacity);
|
||||||
|
_end := _p;
|
||||||
|
_capacity := capacity;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TMemPool.Destroy;
|
||||||
|
begin
|
||||||
|
inherited Destroy;
|
||||||
|
Freemem(_p);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TMemPool.Alloc(size: ptruint): pointer;
|
||||||
|
begin
|
||||||
|
Assert(_end + size <= _p + _capacity);
|
||||||
|
result := _end;
|
||||||
|
_end += size;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TileToBlock
|
{ TileToBlock
|
||||||
Create single terrain block at given position using RS3D tile.
|
Create single terrain block at given position using RS3D tile.
|
||||||
Basex/y is the position in block units for given dimension.
|
Basex/y is the position in block units for given dimension.
|
||||||
@ -183,15 +219,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TTerrainMesh.Destroy;
|
destructor TTerrainMesh.Destroy;
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
begin
|
begin
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
for i := 0 to Length(render_batches) - 1 do begin
|
render_batches_mempool.Free;
|
||||||
freemem(render_batches[i].vertices);
|
|
||||||
freemem(render_batches[i].normals);
|
|
||||||
freemem(render_batches[i].face_indices);
|
|
||||||
end;
|
|
||||||
block_texcoords := nil;
|
block_texcoords := nil;
|
||||||
render_batches := nil;
|
render_batches := nil;
|
||||||
blocks := nil;
|
blocks := nil;
|
||||||
@ -243,8 +273,10 @@ var
|
|||||||
x, y: integer;
|
x, y: integer;
|
||||||
tex, k, vidx: integer;
|
tex, k, vidx: integer;
|
||||||
render_blocks: TList;
|
render_blocks: TList;
|
||||||
start_idx, end_idx, block_count: integer;
|
start_idx, how_many, block_count: integer;
|
||||||
element_array_size: integer;
|
element_array_size, i: integer;
|
||||||
|
render_batches_mempool_size: UInt32;
|
||||||
|
blocks_for_texture: array of integer;
|
||||||
begin
|
begin
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
@ -254,26 +286,28 @@ begin
|
|||||||
render_blocks.Add(@blocks[y, x]);
|
render_blocks.Add(@blocks[y, x]);
|
||||||
render_blocks.Sort(@TerrainBlockOrderByTex);
|
render_blocks.Sort(@TerrainBlockOrderByTex);
|
||||||
|
|
||||||
SetLength(render_batches, terrain.heightmap.texture_count);
|
Setlength(blocks_for_texture, terrain.heightmap.texture_count);
|
||||||
start_idx := 0;
|
FillByte(blocks_for_texture[0], terrain.heightmap.texture_count, 0);
|
||||||
end_idx := 0;
|
for i := 0 to render_blocks.Count - 1 do
|
||||||
for tex := 0 to terrain.heightmap.texture_count - 1 do begin
|
blocks_for_texture[PTerrainBlock(render_blocks.Items[i])^.texture_index] += 1;
|
||||||
render_batches[tex].texture_gl_index := GenTexture(tex, true);
|
|
||||||
|
|
||||||
while PTerrainBlock(render_blocks.Items[end_idx])^.texture_index = tex do begin
|
SetLength(render_batches, terrain.heightmap.texture_count);
|
||||||
end_idx += 1;
|
render_batches_mempool_size := render_blocks.Count * (VerticesPerBlock * sizeof(Tvector3_single) * 2)
|
||||||
if end_idx > render_blocks.Count - 1 then
|
+ render_blocks.Count * (FacesPerBlock * 3 * sizeof(integer));
|
||||||
break;
|
render_batches_mempool := TMemPool.Create(render_batches_mempool_size);
|
||||||
end;
|
|
||||||
block_count := end_idx - start_idx;
|
start_idx := 0;
|
||||||
|
for tex := 0 to terrain.heightmap.texture_count - 1 do begin
|
||||||
|
block_count := blocks_for_texture[tex];
|
||||||
|
render_batches[tex].texture_gl_index := GenTexture(tex, true);
|
||||||
render_batches[tex].blocks := block_count;
|
render_batches[tex].blocks := block_count;
|
||||||
if block_count = 0 then
|
if block_count = 0 then
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
element_array_size := block_count * VerticesPerBlock * sizeof(Tvector3_single);
|
element_array_size := block_count * VerticesPerBlock * sizeof(Tvector3_single);
|
||||||
render_batches[tex].vertices := getmem (element_array_size);
|
render_batches[tex].vertices := render_batches_mempool.Alloc(element_array_size);
|
||||||
render_batches[tex].normals := getmem (element_array_size);
|
render_batches[tex].normals := render_batches_mempool.Alloc(element_array_size);
|
||||||
render_batches[tex].face_indices := getmem (block_count * FacesPerBlock*3 * 4);
|
render_batches[tex].face_indices := render_batches_mempool.Alloc(block_count * FacesPerBlock * 3 * sizeof(integer));
|
||||||
|
|
||||||
for k := 0 to block_count - 1 do begin
|
for k := 0 to block_count - 1 do begin
|
||||||
move(PTerrainBlock(render_blocks.Items[start_idx + k])^.vertices[0],
|
move(PTerrainBlock(render_blocks.Items[start_idx + k])^.vertices[0],
|
||||||
@ -287,10 +321,9 @@ begin
|
|||||||
block_face_indices[vidx] + k * VerticesPerBlock;
|
block_face_indices[vidx] + k * VerticesPerBlock;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
start_idx := end_idx;
|
start_idx += block_count;
|
||||||
if end_idx > render_blocks.Count - 1 then
|
|
||||||
break;
|
|
||||||
end;
|
end;
|
||||||
|
blocks_for_texture := nil;
|
||||||
render_blocks.Free;
|
render_blocks.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user