indexing description: "[ This scene is from the tunnel example ]" date: "$Date$" revision: "$Revision$" class TUNNEL_SCENE inherit EM_DRAWABLE_SCENE rename make_scene as make redefine initialize_scene, redraw end EM_CONSTANTS export {NONE} all end EM_SHARED_BITMAP_FACTORY export {NONE} all end EM_SHARED_SUBSYSTEMS export {NONE} all end GL_FUNCTIONS export {NONE} all end MATH_CONST export {NONE} all end DOUBLE_MATH export {NONE} all end create make feature {NONE} -- Initialization initialize_scene is -- Set the scene ready local file: RAW_FILE i: INTEGER do set_frame_counter_visibility (true) -- we need this to reset some setting to draw this scene correctly -- if cube was shown before if Video_subsystem.video_surface.is_opengl_blitting_enabled then Video_subsystem.video_surface.disable_opengl_blitting gl_tex_envi (Em_gl_texture_env, Em_gl_texture_env_mode, Em_gl_modulate) end turn := 0 w_times_h := width * height create angle.make (1, w_times_h) create depth.make (1, w_times_h) create texture.make (1, 16384) create file.make_open_read ("./image/texture.data") initialize_tab from i := 1 until i > 16384 loop file.read_integer texture.put (file.last_integer.bit_shift_left (16).to_integer_16, i) texture.put (file.last_integer.bit_and (65535).to_integer_16, i + 1) i := i + 2 end -- create bitmap and add it to drawn objects bitmap_factory.create_empty_bitmap (width, height) bitmap := bitmap_factory.last_bitmap bitmap.set_x_y (44, 59) main_container.extend (bitmap) -- some openGl stuff (needed for clipping) if video_subsystem.opengl_enabled and not video_subsystem.video_surface.is_opengl_blitting_enabled then video_subsystem.video_surface.enable_opengl_blitting end end initialize_tab is -- Initializes the angle and the depth arrays local a, i, j: INTEGER x, y: DOUBLE do a := 1 from j := 1 until j > height loop from i := 1 until i > width loop y := j - height / 2 x := i - width / 2 angle.put ((128 + atan2 (y, x) * 255 / 6.24).truncated_to_integer.to_integer_8, a) if x = 0.0 and y = 0.0 then depth.put ((0).to_integer_8, a) else depth.put (((radius*distance) / sqrt ((x)*(x)+(y)*(y))).truncated_to_integer.to_integer_8, a) end a := a + 1 i := i + 1 end j := j + 1 end end feature -- Drawing redraw is -- Redraw `Current' scene. -- Causes to clear `screen' and redraw `main_container' onto it. do refresh if video_subsystem.opengl_enabled then gl_clear (Em_gl_color_buffer_bit | Em_gl_depth_buffer_bit) end main_container.draw (screen) if is_frame_counter_displayed then frame_counter.draw (screen) end screen.redraw end refresh is -- Does strange things local i,j: INTEGER a, x, y, depX, depY: INTEGER do a := 1 depX := (w_half * (1 + sine (turn))).truncated_to_integer.abs \\ 256 depY := (w_half * (1 + cosine (turn))).truncated_to_integer.abs \\ 256 turn := turn + 0.0314 from j := 0 until j = height loop from i := 0 until i = width loop x := (((angle @ (a) + depX) \\ 256) |>> 1).abs y := (((depth @ (a) + depY) \\ 256) |>> 1).abs bitmap.put_pixel_value (i, j, texture @ ((y |<< 7).abs + x + 1)) a := a + 1 i := i + 1 end j := j + 1 end end atan2 (y, x: DOUBLE): DOUBLE is -- Compute the principal value of the arc tangent of (`y'/`x') -- in the range [-pi, +pi] -- Same as atan2 in standart c/c++ lib do if y < 0.0 then if x < 0.0 then Result := arc_tangent (y / x) - Pi elseif x = 0.0 then Result := - Pi / 2 else Result := arc_tangent (y / x) end elseif y = 0.0 then if x < 0 then Result := Pi else Result := 0.0 end else if x < 0.0 then Result := arc_tangent (y / x) + Pi elseif x = 0.0 then Result := Pi / 2 else Result := arc_tangent (y / x) end end end feature {NONE} -- Implementation bitmap: EM_BITMAP -- on this we draw everything angle: ARRAY [INTEGER_8] -- Angle depth: ARRAY [INTEGER_8] -- Angle texture: ARRAY [INTEGER_16] -- Textur image: ARRAY [INTEGER_16] -- Textur width: INTEGER is 512 -- The width of the surface height: INTEGER is 512 -- The height of the surface w_half: INTEGER is 256 -- Half ot the width of the surface w_times_h: INTEGER -- result for width * height radius: INTEGER is 64 -- The radius distance: INTEGER is 128 -- The distance turn: DOUBLE -- The turn end