Class: Quake::Renderer::GLAliasModel
- Inherits:
-
Object
- Object
- Quake::Renderer::GLAliasModel
- Defined in:
- lib/quake/renderer/gl_alias_model.rb
Overview
Renders Quake MDL (alias) models with texture mapping and frame animation.
Constant Summary collapse
- ANORMS =
Quake’s pre-computed normal table (162 normals for lighting) Simplified to just the first few key directions for now
nil
Instance Method Summary collapse
- #frame_count ⇒ Object
-
#initialize(model, palette) ⇒ GLAliasModel
constructor
Full table would be loaded from anorms.h.
-
#render(frame_index:, lerp: 0.0, position: Math::Vec3::ORIGIN, yaw: 0.0, pitch: 0.0, scale: 1.0) ⇒ Object
Render the model at a given frame (interpolation between two frames).
Constructor Details
#initialize(model, palette) ⇒ GLAliasModel
Full table would be loaded from anorms.h
13 14 15 16 17 18 |
# File 'lib/quake/renderer/gl_alias_model.rb', line 13 def initialize(model, palette) @model = model @palette = palette @skin_textures = [] upload_skins end |
Instance Method Details
#frame_count ⇒ Object
83 84 85 |
# File 'lib/quake/renderer/gl_alias_model.rb', line 83 def frame_count @model.frames.size end |
#render(frame_index:, lerp: 0.0, position: Math::Vec3::ORIGIN, yaw: 0.0, pitch: 0.0, scale: 1.0) ⇒ Object
Render the model at a given frame (interpolation between two frames). frame_index: current frame number lerp: 0.0-1.0 interpolation factor to next frame position: Vec3 world position yaw: rotation angle in degrees
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 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 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/quake/renderer/gl_alias_model.rb', line 25 def render(frame_index:, lerp: 0.0, position: Math::Vec3::ORIGIN, yaw: 0.0, pitch: 0.0, scale: 1.0) frame = resolve_frame(frame_index) next_frame = resolve_frame(frame_index + 1) GL.PushMatrix GL.Translatef(position.x, position.y, position.z) GL.Rotatef(yaw, 0.0, 0.0, 1.0) GL.Rotatef(pitch, 0.0, 1.0, 0.0) GL.Enable(GL::TEXTURE_2D) GL.BindTexture(GL::TEXTURE_2D, @skin_textures[0]) if @skin_textures.any? GL.Begin(GL::TRIANGLES) @model.triangles.each do |tri| tri.vertex_indices.each_with_index do |vi, _ti| # Texture coordinates stvert = @model.stverts[vi] s = stvert.s.to_f t = stvert.t.to_f # Adjust seam UVs for back-facing triangles if stvert.on_seam != 0 && tri.faces_front == 0 s += @model.skin_width * 0.5 end s = (s + 0.5) / @model.skin_width t = (t + 0.5) / @model.skin_height GL.TexCoord2f(s, t) # Decompress vertex position v1 = frame.vertices[vi] x1 = v1.x * @model.scale.x + @model.scale_origin.x y1 = v1.y * @model.scale.y + @model.scale_origin.y z1 = v1.z * @model.scale.z + @model.scale_origin.z if lerp > 0.0 && next_frame v2 = next_frame.vertices[vi] x2 = v2.x * @model.scale.x + @model.scale_origin.x y2 = v2.y * @model.scale.y + @model.scale_origin.y z2 = v2.z * @model.scale.z + @model.scale_origin.z x = x1 + (x2 - x1) * lerp y = y1 + (y2 - y1) * lerp z = z1 + (z2 - z1) * lerp else x = x1 y = y1 z = z1 end GL.Vertex3f(x * scale, y * scale, z * scale) end end GL.End GL.PopMatrix end |