indexing description: "Factory creating cylindric texturized XAE world backgrounds" author: "Ralph Wiedemeier" date: "$Date$" revision: "$Revision$" class GUI_WORLD_FACTORY inherit EM_3D_OBJECT_FACTORY EM_SHARED_BITMAP_FACTORY export {NONE} all end GUI_SHARED export {NONE} all end OPEN_GL_LIBRARY export {NONE} all end SINGLE_MATH export {NONE} all end MATH_CONST export {NONE} all end feature -- Operations set_panorama_image (first_image: STRING; second_image: STRING) is -- Set cylindric background texture -- If visible angle of world is greater than 180 degrees, the panorama must be -- split into two parts. The size of the first part must be 2048 x 512 pixels. -- The height of all panorama parts must be 512 pixels. require at_least_one_image: first_image /= Void local p1_w, p1_h, p2_w, p2_h: INTEGER do -- Load first image and create texture map bitmap_factory.create_bitmap_from_image(first_image) if bitmap_factory.last_bitmap = Void then gui.application.throw_unrecoverable_exception ("File not found error: " + first_image) else create texture_1.make_mipmap_from_surface ( bitmap_factory.last_bitmap ) p1_w := bitmap_factory.last_bitmap.width p1_h := bitmap_factory.last_bitmap.height end -- If second image present, load it and create texture map if second_image /= Void then bitmap_factory.create_bitmap_from_image (second_image) if bitmap_factory.last_bitmap = Void then gui.application.throw_unrecoverable_exception ("File not found error: " + first_image) else create texture_2.make_mipmap_from_surface ( bitmap_factory.last_bitmap ) p2_w := bitmap_factory.last_bitmap.width p2_h := bitmap_factory.last_bitmap.height end end -- Calculate panorama size panorama_width := p1_w + p2_w panorama_height := p1_h if panorama_height = 0 then panorama_height := 1 end panorama_aspect := panorama_width / panorama_height panorama_angle := panorama_width * 2 * pi / 4096 end feature -- Status object_width: DOUBLE is 0.0 object_height: DOUBLE is 0.0 object_depth: DOUBLE is 0.0 -- These parameters are not used here! panorama_width: INTEGER panorama_height: INTEGER panorama_aspect: DOUBLE panorama_angle: DOUBLE -- Pixel width and height, aspect ratio and angle of panorama background texture_1: EM3D_TEXTURE_2D[ EMGL_FORMAT_RGBA ] texture_2: EM3D_TEXTURE_2D[ EMGL_FORMAT_RGBA ] -- OpenGL texture ID of the cylinder map feature {NONE} -- Implementation specify_object is -- Specification of the cylinder containing the background local part: INTEGER part_angle: DOUBLE do emgl_disable (EM_gl_polygon_smooth) from part := 1 until part > 2 loop if part = 1 then part_angle := panorama_angle if part_angle > pi then part_angle := pi end emgl_enable (EM_gl_depth_test) macro_bind_texture_antialiased_replace (texture_1) create_gl_cylinder_part (0, part_angle) texture_1.unbind elseif panorama_angle > pi then macro_bind_texture_antialiased_replace (texture_2) create_gl_cylinder_part (pi, panorama_angle) texture_2.unbind end part := part + 1 end end create_gl_cylinder_part (start_angle: DOUBLE; end_angle: DOUBLE) is -- Create an openGL cylinder with texture coordinates local angle, step_angle: DOUBLE tex, tex_old, step_tex: DOUBLE segment, segment_count: INTEGER x, y, z, x_old, z_old: DOUBLE do step_angle := 2 * pi / 50 segment_count := ((end_angle - start_angle) / step_angle + 0.5).truncated_to_integer step_tex := 0.999 / segment_count y := cylinder_height / 2 emgl_begin (EM_gl_quads) from segment := 0 angle := 2 * pi - (start_angle + segment * step_angle) x_old := cylinder_radius * sine (angle) z_old := cylinder_radius * cosine (angle) tex_old := 0.001 until segment = segment_count loop segment := segment + 1 angle := 2 * pi - (start_angle + segment * step_angle) x := cylinder_radius * sine (angle) z := cylinder_radius * cosine (angle) tex := segment * step_tex create_gl_quad (x_old, x, -y, y, z_old, z, tex, tex_old, 0, 1) x_old := x z_old := z tex_old := tex end emgl_end end create_gl_quad (x1: DOUBLE; x2: DOUBLE; y1: DOUBLE; y2: DOUBLE; z1: DOUBLE; z2: DOUBLE; u1: DOUBLE; u2: DOUBLE; v1: DOUBLE; v2: DOUBLE) is -- Create one openGL quad with texture coordinates do emgl_tex_coord2d (u1, v1) emgl_vertex3f (x2, y2, z2) emgl_tex_coord2f (u1, v2) emgl_vertex3f (x2, y1, z2) emgl_tex_coord2f (u2, v2) emgl_vertex3f (x1, y1, z1) emgl_tex_coord2f (u2, v1) emgl_vertex3f (x1, y2, z1) end cylinder_height: INTEGER is 512 -- Height of the 3D cylinder cylinder_radius: INTEGER is 652 -- Radius of the 3D cylinder end -- class XAE_WORLD_FACTORY