Class: Quake::Renderer::GLWater
- Inherits:
-
Object
- Object
- Quake::Renderer::GLWater
- Defined in:
- lib/quake/renderer/gl_water.rb
Overview
Renders turbulent water/lava/slime surfaces with sine-wave warping. Quake liquid textures have names starting with ‘*’.
Constant Summary collapse
- TURBSCALE =
~40.74
256.0 / (2.0 * ::Math::PI)
- SUBDIVIDE_SIZE =
64.0
Instance Method Summary collapse
-
#initialize(level, texture_manager) ⇒ GLWater
constructor
A new instance of GLWater.
-
#render(alpha: 1.0) ⇒ Object
Render water surfaces with turbulent sine-wave warp.
- #update(dt) ⇒ Object
Constructor Details
#initialize(level, texture_manager) ⇒ GLWater
Returns a new instance of GLWater.
14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/quake/renderer/gl_water.rb', line 14 def initialize(level, texture_manager) @level = level @texture_manager = texture_manager @water_surfaces = [] @time = 0.0 # Precompute 256-entry sine table matching Quake's turbsin @turbsin = Array.new(256) do |i| (::Math.sin(i * 2.0 * ::Math::PI / 256.0) * 8.0) end precompute_water_surfaces end |
Instance Method Details
#render(alpha: 1.0) ⇒ Object
Render water surfaces with turbulent sine-wave warp. alpha: 1.0 = fully opaque (GLQuake default r_wateralpha).
Values < 1.0 enable semi-transparent water.
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 82 83 84 85 |
# File 'lib/quake/renderer/gl_water.rb', line 35 def render(alpha: 1.0) return if @water_surfaces.empty? GL.Enable(GL::TEXTURE_2D) # Quake BSP stores liquid surfaces as front/back face pairs on the # same plane so the surface is visible from above and below. Without # culling both copies rasterize at the same depth, z-fight, and (with # alpha < 1) double-blend, producing flicker. Match TyrQuake: # glCullFace(GL_FRONT) with default CCW front face. GL.Enable(GL::CULL_FACE) GL.CullFace(GL::FRONT) if alpha < 1.0 GL.Enable(GL::BLEND) GL.BlendFunc(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA) GL.TexEnvi(GL::TEXTURE_ENV, GL::TEXTURE_ENV_MODE, GL::MODULATE) GL.Color4f(1.0, 1.0, 1.0, alpha) else GL.TexEnvi(GL::TEXTURE_ENV, GL::TEXTURE_ENV_MODE, GL::REPLACE) end @water_surfaces.each do |ws| @texture_manager.bind(ws[:miptex_index]) ws[:faces].each do |face_data| GL.Begin(GL::TRIANGLE_FAN) face_data[:verts].each_with_index do |v, i| os, ot = face_data[:texcoords][i] # Cross-modulated sine warp s = os + @turbsin[((ot * 0.125 + @time) * TURBSCALE).to_i & 255] s /= 64.0 t = ot + @turbsin[((os * 0.125 + @time) * TURBSCALE).to_i & 255] t /= 64.0 GL.TexCoord2f(s, t) GL.Vertex3f(v.x, v.y, v.z) end GL.End end end GL.Disable(GL::CULL_FACE) if alpha < 1.0 GL.Disable(GL::BLEND) GL.Color4f(1.0, 1.0, 1.0, 1.0) end GL.TexEnvi(GL::TEXTURE_ENV, GL::TEXTURE_ENV_MODE, GL::MODULATE) end |
#update(dt) ⇒ Object
28 29 30 |
# File 'lib/quake/renderer/gl_water.rb', line 28 def update(dt) @time += dt end |