#!/usr/bin/ruby -w $: << File.dirname(__FILE__) + "/.." require 'ogre' require 'application' include Ogre class RenderToTextureListener < ApplicationFrameListener def initialize(root, window, cam, reflect_cam, plane) super(root, window, cam) @reflect_cam = reflect_cam @plane = plane end def frame_started(event) return false unless super(event) #GC.start # Update reflection camera @reflect_cam.set_orientation(camera.get_orientation) @reflect_cam.set_position(camera.get_position) # Rotate the plane @plane.yaw(Degree.new(30 * event.time_since_last_frame), Node::TS_PARENT) true end end # Is this class really needed? Not using and the demo looks fine class RTTRenderTargetListener < RenderTargetListener def initialize(plane_entity) super() @plane = plane_entity end def pre_render_target_update(event) @plane.set_visible(false) end def post_render_target_update(event) @plane.set_visible(true) end end class RenderToTextureApplication < Application def create_scene scene_manager.set_ambient_light(Ogre::ColourValue.new(0.2, 0.2, 0.2)) scene_manager.set_sky_box(true, "MorningSkyBox") light = scene_manager.create_light("MainLight") light.set_type(Light::LT_DIRECTIONAL) dir = Vector3.new(0.5, -1, 0) dir.normalise! light.set_direction(dir) light.set_diffuse_colour(1.0, 1.0, 0.8) light.set_specular_colour(1.0, 1.0, 1.0) @plane = MovablePlane.new("ReflectPlane") @plane.d = 0 @plane.normal = Vector3.UNIT_Y MeshManager.instance.create_plane("ReflectionPlane", ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME, @plane, 2000, 2000, 1, 1, true, 1, 1, 1, Vector3.UNIT_Z) @plane_entity = scene_manager.create_entity("Plane", "ReflectionPlane") knot_entity = scene_manager.create_entity("Knot", "knot.mesh") knot_entity.set_material_name("TextureEffect2") ogre_head = scene_manager.create_entity("Head", "ogrehead.mesh") root = scene_manager.root_scene_node # Setting up the plane in the scene @plane_node = root.create_child_scene_node @plane_node.attach_object(@plane_entity) @plane_node.attach_object(@plane) @plane_node.translate(0, -10, 0) # Tilt cause it's cool @plane_node.roll(Degree.new(5)) root.create_child_scene_node("Head").attach_object(ogre_head) texture = TextureManager.instance.create_manual("RttTex", ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 512, 512, 1, -1, PF_R8G8B8, TU_RENDERTARGET) target = texture.get_buffer.get_render_target @reflect_cam = scene_manager.create_camera("ReflectCam") @reflect_cam.set_near_clip_distance(camera.get_near_clip_distance) @reflect_cam.set_far_clip_distance(camera.get_far_clip_distance) # Make sure these are floats, otherwise we get a much smaller aspect ratio than expected @reflect_cam.set_aspect_ratio( window.get_viewport(0).get_actual_width * 1.0 / window.get_viewport(0).get_actual_height * 1.0) viewport = target.add_viewport(@reflect_cam) viewport.set_clear_every_frame(true) viewport.set_background_colour(ColourValue.Black) mat = MaterialManager.instance.create("RttMat", ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME) mat.get_technique(0).get_pass(0).create_texture_unit_state("RustedMetal.jpg") tex_unit_state = mat.get_technique(0).get_pass(0).create_texture_unit_state("RttTex") tex_unit_state.set_colour_operation_ex(LBX_BLEND_MANUAL, LBS_TEXTURE, LBS_CURRENT, ColourValue.White, ColourValue.White, 0.25) tex_unit_state.set_texture_addressing_mode(TextureUnitState::TAM_CLAMP) tex_unit_state.set_projective_texturing(true, @reflect_cam) #puts "", "Registering our listener" #@rt_listener = RTTRenderTargetListener.new(@plane_entity) #target.add_listener(@rt_listener) @reflect_cam.enable_reflection(@plane) @reflect_cam.enable_custom_near_clip_plane(@plane) @plane_entity.set_material_name("RttMat") # Create some knots clone_ent = nil 10.times do |i| node = scene_manager.create_scene_node pos = Vector3.new pos.x = Ogre::Math.symmetric_random * 750.0 pos.y = Ogre::Math.symmetric_random * 100.0 + 25 pos.z = Ogre::Math.symmetric_random * 750.0 node.set_position(pos) root.add_child(node) # Clone it clone_name = "Knot#{i}" clone_ent = knot_entity.clone(clone_name) node.attach_object(clone_ent) end camera.set_position(-50, 100, 500) camera.look_at(0, 0, 0) end def create_frame_listener self.frame_listener = RenderToTextureListener.new(root, window, camera, @reflect_cam, @plane_node) end end app = RenderToTextureApplication.new app.go