World::World(WindowFramework* windowFramework) : m_windowFramework(windowFramework), m_title(), m_inst1(), m_inst2(), m_inst3(), m_inst4(), m_altCam(), m_teapot(), m_teapotInterval(), m_bufferViewer(NULL) // m_tvMen { // Note: set background color here m_windowFramework->get_graphics_output()->get_active_display_region(0)-> set_clear_color(Colorf(0, 0, 0, 1)); // Post the instructions. m_title = add_title("Panda3D: Tutorial - Using Render-to-Texture"); m_inst1 = add_instructions(0.95,"ESC: Quit"); m_inst2 = add_instructions(0.90,"Up/Down: Zoom in/out on the Teapot"); m_inst3 = add_instructions(0.85,"Left/Right: Move teapot left/right"); m_inst4 = add_instructions(0.80,"V: View the render-to-texture results"); //we get a handle to the default window PT(GraphicsOutput) mainWindow = m_windowFramework->get_graphics_output(); // we now get buffer thats going to hold the texture of our new scene PT(GraphicsOutput) altBuffer = mainWindow->make_texture_buffer( "hello", 256, 256); // now we have to setup a new scene graph to make this scene NodePath altRender("new render"); // this takes care of setting up the camera properly m_altCam = m_windowFramework->make_camera(); // Note: set the size and shape of the "film" within the lens equal to the // buffer of our new scene DCAST(Camera, m_altCam.node())->get_lens()->set_film_size( altBuffer->get_x_size(), altBuffer->get_y_size()); // Note: make a DisplayRegion for the camera PT(DisplayRegion) dr = altBuffer->make_display_region(0, 1, 0, 1); dr->set_sort(0); dr->set_camera(m_altCam); m_altCam.reparent_to(altRender); m_altCam.set_pos(0, -10, 0); // get the teapot and rotates it for a simple animation const NodePath& models = m_windowFramework->get_panda_framework()->get_models(); m_teapot = m_windowFramework->load_model(models, "../models/teapot"); m_teapot.reparent_to(altRender); m_teapot.set_pos(0, 0, -1); const bool bakeInStart = true; const bool fluid = false; m_teapotInterval = new CLerpNodePathInterval("teapotInterval", 1.5, CLerpInterval::BT_no_blend, bakeInStart, fluid, m_teapot, NodePath()); m_teapotInterval->set_start_hpr(m_teapot.get_hpr()); m_teapotInterval->set_end_hpr(LVecBase3f(m_teapot.get_h()+360, m_teapot.get_p()+360, m_teapot.get_r()+360)); m_teapotInterval->loop(); // put some lighting on the teapot PT(DirectionalLight) dlight = new DirectionalLight("dlight"); PT(AmbientLight) alight = new AmbientLight("alight"); NodePath dlnp = altRender.attach_new_node(dlight); NodePath alnp = altRender.attach_new_node(alight); dlight->set_color(Colorf(0.8, 0.8, 0.5, 1)); alight->set_color(Colorf(0.2, 0.2, 0.2, 1)); dlnp.set_hpr(0, -60, 0); altRender.set_light(dlnp); altRender.set_light(alnp); // Panda contains a built-in viewer that lets you view the results of // your render-to-texture operations. This code configures the viewer. WORLD_DEFINE_KEY("v", "toggleBufferViewer", toggle_buffer_viewer); m_bufferViewer = new CBufferViewer(m_windowFramework); m_bufferViewer->set_position(CBufferViewer::CP_llcorner); m_bufferViewer->set_card_size(1.0, 0.0); // Create the tv-men. Each TV-man will display the // offscreen-texture on his TV screen. make_tv_man(-5, 30, 1, altBuffer->get_texture(), 0.9); make_tv_man( 5, 30, 1, altBuffer->get_texture(), 1.4); make_tv_man( 0, 23, -3, altBuffer->get_texture(), 2.0); make_tv_man(-5, 20, -6, altBuffer->get_texture(), 1.1); make_tv_man( 5, 18, -5, altBuffer->get_texture(), 1.7); WORLD_DEFINE_KEY("escape", "exit", quit); WORLD_DEFINE_KEY("arrow_up", "zoomIn", zoom_in); WORLD_DEFINE_KEY("arrow_down", "zoomOut", zoom_out); WORLD_DEFINE_KEY("arrow_left", "moveLeft", move_left); WORLD_DEFINE_KEY("arrow_right", "moveRight", move_right); WORLD_ADD_TASK("worldAsyncTask", async_task); }
World::World(WindowFramework* windowFramework) : m_windowFramework(windowFramework), m_title(), m_escapeEventText(), m_onekeyEventText(), m_twokeyEventText(), m_duckPlane(), m_duckTexs(), m_duckTask(), m_fps(36), m_expPlane(), m_expTask(), m_orientPlane(), m_orientTex(), m_trackball() { // Standard initialization stuff // Standard title that's on screen in every tutorial COnscreenText title("title"); title.set_text("Panda3D: Tutorial - Texture \"Movies\""); title.set_fg(Colorf(1, 1, 1, 1)); title.set_pos(0.7, -0.95); title.set_scale(0.07); const NodePath& aspect2d = m_windowFramework->get_aspect_2d(); title.reparent_to(aspect2d); m_title = title.generate(); // Text to show the keyboard keys and their functions on screen COnscreenText escapeEventText("escapeEvent"); escapeEventText.set_text("ESC: Quit"); escapeEventText.set_fg(Colorf(1, 1, 1, 1)); escapeEventText.set_pos(-1.3, 0.95); escapeEventText.set_align(TextNode::A_left); escapeEventText.set_scale(0.05); escapeEventText.reparent_to(aspect2d); m_escapeEventText = escapeEventText.generate(); COnscreenText onekeyEventText("onekeyEvent"); onekeyEventText.set_text("[1]: Freeview camera"); onekeyEventText.set_fg(Colorf(1, 1, 1, 1)); onekeyEventText.set_pos(-1.3, 0.90); onekeyEventText.set_align(TextNode::A_left); onekeyEventText.set_scale(0.05); onekeyEventText.reparent_to(aspect2d); m_onekeyEventText = onekeyEventText.generate(); COnscreenText twokeyEventText("twokeyEvent"); twokeyEventText.set_text( "[2]: Preset Camera Angle 2 (Verify billboard effect)"); twokeyEventText.set_fg(Colorf(1, 1, 1, 1)); twokeyEventText.set_pos(-1.3, 0.85); twokeyEventText.set_align(TextNode::A_left); twokeyEventText.set_scale(0.05); twokeyEventText.reparent_to(aspect2d); m_twokeyEventText = twokeyEventText.generate(); // Set the background color m_windowFramework->set_background_type(WindowFramework::BT_black); // Set up the key input // Escape quits WORLD_DEFINE_KEY("escape", "exit", quit); //Free view WORLD_DEFINE_KEY("1", "setViewMain", set_view_main); // Billboard effect view WORLD_DEFINE_KEY("2", "setViewBillboard", set_view_billboard); // Initialization specific to this world // Load a polygon plane (4 sided square) to put an animated duck sprite on const NodePath& models = m_windowFramework->get_panda_framework()->get_models(); m_duckPlane = m_windowFramework->load_model(models, "../models/plane"); m_duckPlane.set_pos(-2, 8, 0); // set its position const NodePath& render = m_windowFramework->get_render(); m_duckPlane.reparent_to(render); // reparent to render // Enable tranparency: this attribute needs to be set for Panda to render the // transparency in the duck's texture as transparent rather than opaque m_duckPlane.set_transparency(TransparencyAttrib::M_alpha); // Now we call our special 'loadTextureMovie' function that returns a list // containing all of the textures for the duck sprite. // Check the function definition later in this file for its parameters load_texture_movie(24, "../duck/duck_fly_left", "png", 2, &m_duckTexs); // Next we add a task to our task list that will animate the texture on the // duck plane according to the time elapsed. m_duckTask = WORLD_ADD_TASK("duckTask", TEXTURE_MOVIE(36, m_duckPlane, m_duckTexs)); // The function texture_movie is set to run any texture movie that // animates and loops based on time (rather that some other value like // position). To do that, it is set up to expect a number of parameters set // in the task object. The following lines set those parameters /* Note: passed to the task as template parameters #Framerate: The texture will be changed 36 times per second self.duckTask.fps = 36 #self.duckPlane is the object whose texture should be changed self.duckTask.obj = self.duckPlane #self.duckTexs (which we created earlier with self.oadTextureMovie) #contains the list of textures to animate from self.duckTask.textures = self.duckTexs */ // Now, instead of a duck, we will put an animated explosion onto a polygon // This is the same as loading the duck animation, with the expection that // we will "billboard" the explosion so that it always faces the camera // load the object m_expPlane = m_windowFramework->load_model(models, "../models/plane"); m_expPlane.set_pos(2, 8, 0); // set its position m_expPlane.reparent_to(render); // reparent to render // enable transparency m_expPlane.set_transparency(TransparencyAttrib::M_alpha); // load the texture movie load_texture_movie(51, "../explosion/explosion", "png", 4, &m_expTexs); // create the animation task m_expTask = WORLD_ADD_TASK("explosionTask", TEXTURE_MOVIE(30, m_expPlane, m_expTexs)); /* Note: passed to the task as template parameters m_expTask.fps = 30 #set framerate m_expTask.obj = self.expPlane #set object m_expTask.textures = self.expTexs #set texture list */ // This create the "billboard" effect that will rotate the object so that it // is always rendered as facing the eye (camera) m_expPlane.node()->set_effect(BillboardEffect::make_point_eye()); // The code below generates the plane you see with the numbers and arrows. // This is just to give a sense of orientation as the camera is moved around. // Load the object m_orientPlane = m_windowFramework->load_model(models, "../models/plane"); // load the texture m_orientTex = TexturePool::load_texture( "../models/textures/orientation.png"); m_orientPlane.set_texture(m_orientTex, 1); // Set the texture m_orientPlane.reparent_to(render); // Parent to render // Set the position, orientation, and scale m_orientPlane.set_pos_hpr_scale(0, 8, -1, 0, -90, 0, 10, 10, 10); // Note: mouse support must be activated. The basic method is to call // WindowFramework::setup_trackball. In order to get the same viewpoint // as in the original python tutorial, we get the trackball node and // cancel the previous call to TrackBall::set_pos. Finally, we keep the // trackball's NodePath; we'll use it to enable/disable the mouse. NodePath camera = m_windowFramework->get_camera_group(); m_windowFramework->setup_trackball(); m_trackball = m_windowFramework->get_mouse().find("**/trackball"); DCAST(Trackball, m_trackball.node())->set_pos(0, 0, 0); }