Class: Quake::Renderer::GLLightmap

Inherits:
Object
  • Object
show all
Defined in:
lib/quake/renderer/gl_lightmap.rb

Overview

Computes and uploads lightmaps for BSP faces. Each face’s lightmap is a small texture (typically 4x4 to 18x18) derived from the lighting lump. Lightmap UVs are computed from the face’s texture-space extents, quantized to a 16-unit grid.

Defined Under Namespace

Classes: LightmapInfo

Constant Summary collapse

LIGHTMAP_BLOCK_WIDTH =
128
LIGHTMAP_BLOCK_HEIGHT =
128

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(level, palette) ⇒ GLLightmap

Returns a new instance of GLLightmap.



19
20
21
22
23
24
25
26
# File 'lib/quake/renderer/gl_lightmap.rb', line 19

def initialize(level, palette)
  @level = level
  @palette = palette
  @face_lightmaps = {}
  @block_textures = []    # GL texture ids for each block
  @block_allocated = []   # row allocation per block column
  @block_pixels = []      # RGBA pixel data per block
end

Instance Attribute Details

#face_lightmapsObject (readonly)

face_index -> LightmapInfo



17
18
19
# File 'lib/quake/renderer/gl_lightmap.rb', line 17

def face_lightmaps
  @face_lightmaps
end

Instance Method Details

#bind(face_index) ⇒ Object



45
46
47
48
49
# File 'lib/quake/renderer/gl_lightmap.rb', line 45

def bind(face_index)
  info = @face_lightmaps[face_index]
  return unless info
  GL.BindTexture(GL::TEXTURE_2D, info.gl_texture)
end

#build_allObject



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/quake/renderer/gl_lightmap.rb', line 28

def build_all
  allocate_block

  @level.faces.each_with_index do |face, face_index|
    texinfo = @level.texinfo[face.texinfo_index]
    next if texinfo.nil?
    next if texinfo.flags & 1 != 0 # TEX_SPECIAL (sky/turb)
    next if face.light_offset < 0

    build_face_lightmap(face, face_index)
  end

  upload_blocks
  count = @face_lightmaps.size
  puts "Built #{count} lightmaps in #{@block_textures.size} blocks"
end

#lightmap_texcoords(face_index, vertex, texinfo) ⇒ Object

Compute lightmap UVs for a vertex given the face’s lightmap info.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/quake/renderer/gl_lightmap.rb', line 52

def lightmap_texcoords(face_index, vertex, texinfo)
  info = @face_lightmaps[face_index]
  return [0.0, 0.0] unless info

  # Compute texture-space coordinate
  s = vertex.dot(texinfo.s_vec) + texinfo.s_offset
  t = vertex.dot(texinfo.t_vec) + texinfo.t_offset

  # Convert to lightmap UV: subtract texture mins, scale by 1/16, offset by 0.5
  # Then convert to atlas UV
  extents = face_extents(face_index)
  return [0.0, 0.0] unless extents

  tex_mins_s, tex_mins_t, _, _ = extents

  ls = (s - tex_mins_s + 8.0) / (info.width * 16.0)
  lt = (t - tex_mins_t + 8.0) / (info.height * 16.0)

  # Map into atlas block coordinates
  atlas_s = (info.s_offset + ls * info.width + 0.5) / LIGHTMAP_BLOCK_WIDTH
  atlas_t = (info.t_offset + lt * info.height + 0.5) / LIGHTMAP_BLOCK_HEIGHT

  [atlas_s, atlas_t]
end