Skip to content

Rendering: Vertex Format

Jared Ketterer edited this page Jun 24, 2020 · 6 revisions

Copied from the comments of utilities/render.py

44 byte BRUSH vertex:

[ SIZE ]  [  TYPE   ]  [ USE  ]  [  GL ATTRIB  ]
12 bytes  (3 float32)  Position  vertex_position
12 bytes  (3 float32)  Normal    vertex_normal
8  bytes  (2 float32)  UV        vertex_uv
12 bytes  (3 float32)  Colour    editor_colour

44 byte DISPLACEMENT vertex:

[ SIZE ]  [  TYPE   ]  [ USE  ]  [  GL ATTRIB  ]
12 bytes  (3 float32)  Position  vertex_position
12 bytes  (3 float32)  Normal    vertex_normal
8  bytes  (2 float32)  UV        vertex_uv
4  bytes  (1 float32)  Blend     blend_alpha
8  bytes  (2 0x0000 )  Padding

Displacement Structures:

|\|/|\|/|\|/|\|/|
|/|\|/|\|/|\|/|\|
|\|/|\|/|\|/|\|/|  <- Power 3
|/|\|/|\|/|\|/|\|
|\|/|\|/|\|/|\|/|  |\|/|\|/|  <- Power 2
|/|\|/|\|/|\|/|\|  |/|\|/|\|
|\|/|\|/|\|/|\|/|  |\|/|\|/|  |\|/| <- Power 1
|/|\|/|\|/|\|/|\|  |/|\|/|\|  |/|\|

2^ power = number of quads per row
2^ power * 2 = number of triangles per row
2^ power * 2 * 2^ power = number of triangles per displacement
2^ power * 2 * 2^ power * 3 = number of indices per displacement

GL_TRIANGLES method:

index_size = lambda power: ((2 ** power) ** 2) * 24
# 2^ power * 2^ power rows * 2 triangles * 3 vertices * 4 bytes

GL_TRIANGLE_STRIP method:

index_size = lambda power: ((2 ** power) + 1) * (2 ** power) * 8
# (2^ power + 1) * 2^ power rows * 2 vertices * 4 bytes

To draw using GL_TRIANGLE_STRIP you need (start, length) of the indices for each row of any given displacement.
However with GL_TRIANGLES you need only give the (start, length) of the entire displacement's indices.
QtPyHammer uses the GL_TRIANGLES approach, resulting in more slightly VRAM usage, but simpler draw calls.

MEMORY USAGE:

1 Triangle  144 bytes (132 VERTICES +  12 INDICES)
1 Quad      200 bytes (176 VERTICES +  24 INDICES)
1 Cube      496 bytes (352 VERTICES + 144 INDICES)
  9 Vertex Power 1          396 bytes VERTICES
                             96 bytes INDICES GL_TRIANGLES
                             48 bytes INDICES GL_TRIANGLE_STRIP

 25 Vertex Power 2         1100 bytes VERTICES
                            384 bytes INDICES GL_TRIANGLES
                            160 bytes INDICES GL_TRIANGLE_STRIP

 81 Vertex Power 3         3564 bytes VERTICES
                            864 bytes INDICES GL_TRIANGLES
                            576 bytes INDICES GL_TRIANGLE_STRIP

289 Vertex Power 4        12716 bytes VERTICES
                           2176 bytes INDICES GL_TRIANGLES
                           6144 bytes INDICES GL_TRIANGLE_STRIP

100 Power 2 Displacements   110 000 ~ 110KB VERTICES
                             16 000 ~  16KB INDICES GL_TRIANGLES
                            126 000 ~ 126KB VERTICES & INDICES

100 Power 3 Displacements   356 400 ~ 360KB VERTICES
                             57 600 ~  58KB INDICES GL_TRIANGLES
                            414 000 ~ 414KB VERTICES & INDICES

100 Power 2 + 100 Power 3   110 000 + 356 400 = 466 400  ~ 467KB VERTICES
                             16 000 +  57 600 =  73 600  ~  74KB INDICES GL_TRIANGLES
                            466 400 +  73 600 = 540 000  ~ 540KB VERTICES & INDICES
200 Cube Solids = 70 400 bytes ~  71KB VERTICES  
                  28 800 bytes ~  29KB INDICES  
                  99 200 bytes ~ 100KB VERTICES & INDICES
200 Base Cube Brushes + 100 Power2 Displacements + 100 Power3 Displacements
= ~640KB of VRAM (536.8KB VERTICES + 102.4KB INDICES)

pl_upward_d.vmf has 558 Displacement Brushes & 1890 Non-Displacement Brushes