Class: Quake::Renderer::GLViewmodel

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

Overview

Renders the first-person weapon view model. Uses the same projection as the world camera. Depth range is compressed to [0, 0.3] so the weapon always draws in front of world geometry without z-fighting (matches GLQuake’s R_DrawViewModel).

Constant Summary collapse

CL_BOB =

Quake bob cvars (from view.c)

0.02
CL_BOBCYCLE =

cl_bob: amplitude multiplier

0.6
CL_BOBUP =

cl_bobcycle: seconds per full bob cycle

0.5

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pak, palette) ⇒ GLViewmodel

Returns a new instance of GLViewmodel.



20
21
22
23
24
25
26
27
28
# File 'lib/quake/renderer/gl_viewmodel.rb', line 20

def initialize(pak, palette)
  @pak = pak
  @palette = palette
  @weapon_renderers = {} # model_path -> GLAliasModel
  @time = 0.0
  @bob_speed = 0.0
  @bob = 0.0
  @current_model_path = nil
end

Instance Attribute Details

#bobObject (readonly)

Current bob value (applied to camera Z by the game loop)



18
19
20
# File 'lib/quake/renderer/gl_viewmodel.rb', line 18

def bob
  @bob
end

Instance Method Details

#render(camera, aspect) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/quake/renderer/gl_viewmodel.rb', line 42

def render(camera, aspect)
  return unless @current_model_path

  gl_model = @weapon_renderers[@current_model_path]
  return unless gl_model

  # Compress depth range so weapon always appears in front of world
  GL.DepthRange(0.0, 0.3)
  GL.DepthFunc(GL::LEQUAL)

  # Weapon origin = camera position + forward*bob*0.4
  # Camera already has the vertical bob applied (in the game loop),
  # so only the forward push is needed here.
  pos = camera.position + camera.forward * (@bob * 0.4)

  GL.Enable(GL::TEXTURE_2D)

  gl_model.render(
    frame_index: 0,
    lerp: 0.0,
    position: pos,
    yaw: camera.yaw,
    pitch: camera.pitch
  )

  GL.DepthRange(0.0, 1.0)
  GL.DepthFunc(GL::LESS)
end

#set_weapon(model_path) ⇒ Object



30
31
32
33
34
# File 'lib/quake/renderer/gl_viewmodel.rb', line 30

def set_weapon(model_path)
  return if model_path == @current_model_path
  @current_model_path = model_path
  load_weapon(model_path) unless @weapon_renderers.key?(model_path)
end

#update(dt, speed) ⇒ Object



36
37
38
39
40
# File 'lib/quake/renderer/gl_viewmodel.rb', line 36

def update(dt, speed)
  @time += dt
  @bob_speed = speed
  @bob = calc_bob
end