mirror of
https://github.com/dpethes/rerogue.git
synced 2025-06-07 18:58:32 +02:00
terrain viewer: sort terrain blocks by texture - faster rendering
This commit is contained in:
parent
22d812fe4f
commit
aaedff5e21
@ -22,6 +22,7 @@ type
|
|||||||
vertices: array[0..24] of Tvector3_single; //25*3*4 = 300B
|
vertices: array[0..24] of Tvector3_single; //25*3*4 = 300B
|
||||||
normals: array[0..24] of Tvector3_single; //25*3*4 = 300B
|
normals: array[0..24] of Tvector3_single; //25*3*4 = 300B
|
||||||
end; //~600B per block
|
end; //~600B per block
|
||||||
|
PTerrainBlock = ^TTerrainBlock;
|
||||||
|
|
||||||
{ TTerrainMesh }
|
{ TTerrainMesh }
|
||||||
TTerrainMesh = class
|
TTerrainMesh = class
|
||||||
@ -31,6 +32,8 @@ type
|
|||||||
block_texcoords: array[0..24] of Tvector2_single; //static, 25*2*4 = 200B
|
block_texcoords: array[0..24] of Tvector2_single; //static, 25*2*4 = 200B
|
||||||
block_face_indices: array[0..16*2*3 - 1] of byte; //static, 96B
|
block_face_indices: array[0..16*2*3 - 1] of byte; //static, 96B
|
||||||
textures_glidx: array of integer;
|
textures_glidx: array of integer;
|
||||||
|
render_blocks: TList;
|
||||||
|
|
||||||
function TileToBlock(var tile: TTile; basey, basex: integer): TTerrainBlock;
|
function TileToBlock(var tile: TTile; basey, basex: integer): TTerrainBlock;
|
||||||
procedure TransformTiles;
|
procedure TransformTiles;
|
||||||
procedure InitBlockStaticData;
|
procedure InitBlockStaticData;
|
||||||
@ -159,7 +162,18 @@ begin
|
|||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function OrderByTex(Item1: Pointer; Item2: Pointer): integer;
|
||||||
|
var
|
||||||
|
a, b: PTerrainBlock;
|
||||||
|
begin
|
||||||
|
a := PTerrainBlock(Item1);
|
||||||
|
b := PTerrainBlock(Item2);
|
||||||
|
result := a^.texture_index - b^.texture_index;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTerrainMesh.Load(const hmp_filename: string);
|
procedure TTerrainMesh.Load(const hmp_filename: string);
|
||||||
|
var
|
||||||
|
x, y: integer;
|
||||||
begin
|
begin
|
||||||
terrain := TWorld.Create;
|
terrain := TWorld.Create;
|
||||||
terrain.LoadFromFiles('hmp_0', 'lv_0.text', 'lv_0.tex');
|
terrain.LoadFromFiles('hmp_0', 'lv_0.text', 'lv_0.tex');
|
||||||
@ -169,6 +183,12 @@ begin
|
|||||||
WriteLn(Format('terrain size: %dx%d, tris: %d',
|
WriteLn(Format('terrain size: %dx%d, tris: %d',
|
||||||
[terrain.TileWidth, terrain.TileHeight,
|
[terrain.TileWidth, terrain.TileHeight,
|
||||||
terrain.TileWidth * terrain.TileHeight * 4 * 4 * 2]));
|
terrain.TileWidth * terrain.TileHeight * 4 * 4 * 2]));
|
||||||
|
|
||||||
|
render_blocks := TList.Create;
|
||||||
|
for y := 0 to terrain.TileHeight - 1 do
|
||||||
|
for x := 0 to terrain.TileWidth - 1 do
|
||||||
|
render_blocks.Add(@blocks[y, x]);
|
||||||
|
render_blocks.Sort(@OrderByTex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
//generate textures. TODO texture atlas?
|
//generate textures. TODO texture atlas?
|
||||||
@ -208,11 +228,16 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
//draw vertices from each block
|
{ DrawGL
|
||||||
|
Renders terrain blocks.
|
||||||
|
Terrain textures are stored independently, and if we process the blocks in spatial order,
|
||||||
|
repeated texture binding slows this down a lot (68->30fps).
|
||||||
|
So we sort blocks by texture and render them out of order.
|
||||||
|
}
|
||||||
procedure TTerrainMesh.DrawGL(opts: TRenderOpts);
|
procedure TTerrainMesh.DrawGL(opts: TRenderOpts);
|
||||||
var
|
var
|
||||||
x, y: integer;
|
i: integer;
|
||||||
blk: TTerrainBlock;
|
b: PTerrainBlock;
|
||||||
last_tex_index: integer;
|
last_tex_index: integer;
|
||||||
begin
|
begin
|
||||||
if opts.wireframe then
|
if opts.wireframe then
|
||||||
@ -226,19 +251,16 @@ begin
|
|||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
last_tex_index := -1;
|
last_tex_index := -1;
|
||||||
|
|
||||||
for y := 0 to terrain.TileHeight - 1 do
|
for i := 0 to terrain.TileHeight * terrain.TileWidth - 1 do begin
|
||||||
for x := 0 to terrain.TileWidth - 1 do begin
|
b := PTerrainBlock(render_blocks[i]);
|
||||||
blk := blocks[y, x];
|
|
||||||
|
|
||||||
//repeated texture binding slows this down a lot (68->30fps)
|
if last_tex_index <> b^.texture_index then begin
|
||||||
//todo sort by texture?
|
last_tex_index := b^.texture_index;
|
||||||
if last_tex_index <> blk.texture_index then begin
|
|
||||||
last_tex_index := blk.texture_index;
|
|
||||||
glBindTexture(GL_TEXTURE_2D, textures_glidx[last_tex_index]);
|
glBindTexture(GL_TEXTURE_2D, textures_glidx[last_tex_index]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
glVertexPointer(3, GL_FLOAT, sizeof(Tvector3_single), @blk.vertices[0].data[0]);
|
glVertexPointer(3, GL_FLOAT, sizeof(Tvector3_single), @b^.vertices[0].data[0]);
|
||||||
glNormalPointer(GL_FLOAT, sizeof(Tvector3_single), @blk.normals[0].data[0]);
|
glNormalPointer(GL_FLOAT, sizeof(Tvector3_single), @b^.normals[0].data[0]);
|
||||||
glTexCoordPointer(2, GL_FLOAT, sizeof(Tvector2_single), @block_texcoords[0].data[0]);
|
glTexCoordPointer(2, GL_FLOAT, sizeof(Tvector2_single), @block_texcoords[0].data[0]);
|
||||||
|
|
||||||
if opts.points then
|
if opts.points then
|
||||||
|
Loading…
x
Reference in New Issue
Block a user