bool App::update() { game_time.update(); options->set_needs_render(); options->set_rect(clan::Size(canvas.get_size())); options->update(clan::Colorf(0.6f, 0.6f, 0.2f, 1.0f)); int num_particles = options->num_particles; if (num_particles > max_particles) num_particles = max_particles; move_particles(game_time.get_time_elapsed(), num_particles); const float grid_xpos = 10.0f; const float grid_ypos = 10.0f; // Draw the grid image_grid.draw(canvas, grid_xpos, grid_ypos); if (num_particles > 0) { std::vector<clan::Vec2f> positions; std::vector<clan::Colorf> colors; positions.resize(num_particles); colors.resize(num_particles); for (int cnt=0; cnt<num_particles; cnt++) { positions[cnt] = clan::Vec2f(grid_xpos + particles[cnt].xpos, grid_ypos + particles[cnt].ypos); switch (cnt % 3) { case 0: colors[cnt] = clan::Colorf(1.0f, 0.0f, 0.0f, 1.0f); break; case 1: colors[cnt] = clan::Colorf(0.0f, 1.0f, 0.0f, 1.0f); break; case 2: colors[cnt] = clan::Colorf(0.0f, 0.0f, 1.0f, 1.0f); break; } }; canvas.flush(); clan::GraphicContext gc = canvas.get_gc(); canvas.set_blend_state(blend_state); clan::RasterizerStateDescription raster_state_desc; raster_state_desc.set_point_size(options->point_size); raster_state_desc.set_point_sprite_origin(clan::origin_upper_left); clan::RasterizerState raster_state(canvas, raster_state_desc); canvas.set_rasterizer_state(raster_state); clan::PrimitivesArray primarray(gc); clan::VertexArrayVector<clan::Vec2f> gpu_positions = clan::VertexArrayVector<clan::Vec2f>(gc, &positions[0], positions.size()); clan::VertexArrayVector<clan::Colorf> gpu_colors = clan::VertexArrayVector<clan::Colorf>(gc, &colors[0], colors.size()); primarray.set_attributes(0, gpu_positions); primarray.set_attributes(1, gpu_colors); ProgramUniforms buffer; buffer.cl_ModelViewProjectionMatrix = canvas.get_projection() * canvas.get_transform(); clan::UniformVector<ProgramUniforms> uniform_vector(gc, &buffer, 1); gc.set_uniform_buffer(0, uniform_vector); gc.set_texture(0, texture_particle); gc.set_program_object(program_object); gc.draw_primitives(clan::type_points, num_particles, primarray); gc.reset_program_object(); gc.reset_texture(0); gc.reset_blend_state(); gc.reset_rasterizer_state(); } window.flip(1); return !quit; }
// The start of the Application int App::start(const std::vector<std::string> &args) { clan::DisplayWindowDescription win_desc; //win_desc.set_version(3, 2, false); win_desc.set_allow_resize(true); win_desc.set_title("Point Sprite Example"); win_desc.set_size(clan::Size( 800, 480 ), false); clan::DisplayWindow window(win_desc); clan::SlotContainer cc; cc.connect(window.sig_window_close(), clan::bind_member(this, &App::on_window_close)); cc.connect(window.get_ic().get_keyboard().sig_key_up(), clan::bind_member(this, &App::on_input_up)); std::string theme; if (clan::FileHelp::file_exists("../../../Resources/GUIThemeAero/theme.css")) theme = "../../../Resources/GUIThemeAero"; else if (clan::FileHelp::file_exists("../../../Resources/GUIThemeBasic/theme.css")) theme = "../../../Resources/GUIThemeBasic"; else throw clan::Exception("No themes found"); clan::GUIWindowManagerTexture wm(window); clan::GUIManager gui(wm, theme); clan::Canvas canvas(window); // Deleted automatically by the GUI Options *options = new Options(gui, clan::Rect(0, 0, canvas.get_size())); clan::Image image_grid(canvas, "../Blend/Resources/grid.png"); clan::Texture2D texture_particle(canvas, "Resources/particle.png"); float grid_width = (float) image_grid.get_width(); float grid_height = (float) image_grid.get_height(); grid_space = (float) (image_grid.get_width()); setup_particles(); clan::ShaderObject vertex_shader(canvas, clan::shadertype_vertex, text_shader_vertex); if(!vertex_shader.compile()) { throw clan::Exception(clan::string_format("Unable to compile vertex shader object: %1", vertex_shader.get_info_log())); } clan::ShaderObject fragment_shader(canvas, clan::shadertype_fragment, text_shader_fragment); if(!fragment_shader.compile()) { throw clan::Exception(clan::string_format("Unable to compile fragment shader object: %1", fragment_shader.get_info_log())); } clan::ProgramObject program_object(canvas); program_object.attach(vertex_shader); program_object.attach(fragment_shader); program_object.bind_attribute_location(0, "InPosition"); program_object.bind_attribute_location(1, "InColor"); if (!program_object.link()) { throw clan::Exception(clan::string_format("Unable to link program object: %1", program_object.get_info_log())); } program_object.set_uniform1i("Texture0", 0); options->request_repaint(); clan::BlendStateDescription blend_state_desc; blend_state_desc.enable_blending(true); blend_state_desc.set_blend_function(clan::blend_src_alpha, clan::blend_one, clan::blend_src_alpha, clan::blend_one); clan::BlendState blend_state(canvas, blend_state_desc); clan::GameTime game_time; while (!quit) { game_time.update(); wm.process(); wm.draw_windows(canvas); int num_particles = options->num_particles; if (num_particles > max_particles) num_particles = max_particles; move_particles(game_time.get_time_elapsed(), num_particles); const float grid_xpos = 10.0f; const float grid_ypos = 10.0f; // Draw the grid image_grid.draw(canvas, grid_xpos, grid_ypos); if (num_particles > 0) { std::vector<clan::Vec2f> positions; std::vector<clan::Colorf> colors; positions.resize(num_particles); colors.resize(num_particles); for (int cnt=0; cnt<num_particles; cnt++) { positions[cnt] = clan::Vec2f(grid_xpos + particles[cnt].xpos, grid_ypos + particles[cnt].ypos); switch (cnt % 3) { case 0: colors[cnt] = clan::Colorf(1.0f, 0.0f, 0.0f, 1.0f); break; case 1: colors[cnt] = clan::Colorf(0.0f, 1.0f, 0.0f, 1.0f); break; case 2: colors[cnt] = clan::Colorf(0.0f, 0.0f, 1.0f, 1.0f); break; } }; canvas.flush(); clan::GraphicContext gc = canvas.get_gc(); canvas.set_blend_state(blend_state); clan::RasterizerStateDescription raster_state_desc; raster_state_desc.set_point_size(options->point_size); raster_state_desc.set_point_sprite_origin(clan::origin_upper_left); clan::RasterizerState raster_state(canvas, raster_state_desc); canvas.set_rasterizer_state(raster_state); clan::PrimitivesArray primarray(gc); clan::VertexArrayVector<clan::Vec2f> gpu_positions = clan::VertexArrayVector<clan::Vec2f>(gc, &positions[0], positions.size()); clan::VertexArrayVector<clan::Colorf> gpu_colors = clan::VertexArrayVector<clan::Colorf>(gc, &colors[0], colors.size()); primarray.set_attributes(0, gpu_positions); primarray.set_attributes(1, gpu_colors); ProgramUniforms buffer; buffer.cl_ModelViewProjectionMatrix = canvas.get_projection() * canvas.get_modelview(); clan::UniformVector<ProgramUniforms> uniform_vector(gc, &buffer, 1); gc.set_uniform_buffer(0, uniform_vector); gc.set_texture(0, texture_particle); gc.set_program_object(program_object); gc.draw_primitives(clan::type_points, num_particles, primarray); gc.reset_program_object(); gc.reset_texture(0); gc.reset_blend_state(); gc.reset_rasterizer_state(); } window.flip(1); clan::KeepAlive::process(); } return 0; }
// The start of the Application int App::start(const std::vector<std::string> &args) { quit = false; DisplayWindowDescription desc; desc.set_title("ClanLib Quaternion's Example"); desc.set_size(Size(900, 700), true); desc.set_multisampling(4); desc.set_allow_resize(true); desc.set_depth_size(16); DisplayWindow window(desc); // Connect the Window close event Slot slot_quit = window.sig_window_close().connect(this, &App::on_window_close); // Connect a keyboard handler to on_key_up() Slot slot_input_up = (window.get_ic().get_keyboard()).sig_key_up().connect(this, &App::on_input_up); // Set up GUI std::string theme; if (FileHelp::file_exists("../../../Resources/GUIThemeAero/theme.css")) theme = "../../../Resources/GUIThemeAero"; else if (FileHelp::file_exists("../../../Resources/GUIThemeBasic/theme.css")) theme = "../../../Resources/GUIThemeBasic"; else throw Exception("No themes found"); GUIWindowManagerTexture wm(window); GUIManager gui(wm, theme); Canvas canvas(window); // Deleted automatically by the GUI Options *options = new Options(gui, Rect(8, 8, Size(canvas.get_width()-16, 170))); options->request_repaint(); // Setup graphic store GraphicStore graphic_store(canvas); scene.gs = &graphic_store; RasterizerStateDescription rasterizer_state_desc; rasterizer_state_desc.set_culled(true); rasterizer_state_desc.set_face_cull_mode(cull_back); rasterizer_state_desc.set_front_face(face_clockwise); RasterizerState raster_state(canvas, rasterizer_state_desc); DepthStencilStateDescription depth_state_desc; depth_state_desc.enable_depth_write(true); depth_state_desc.enable_depth_test(true); depth_state_desc.enable_stencil_test(false); depth_state_desc.set_depth_compare_function(compare_lequal); DepthStencilState depth_write_enabled(canvas, depth_state_desc); create_scene(canvas); clan::Font font(canvas, "tahoma", 24); FramerateCounter framerate_counter; active_lerp = false; ubyte64 time_last = System::get_time(); ubyte64 time_start = time_last; // Run until someone presses escape while (!quit) { framerate_counter.frame_shown(); // Calculate time since last frame ubyte64 time_now = System::get_time(); current_time = time_now - time_start; time_delta = time_now - time_last; time_last = time_now; // Control the target options control_target(options); // Use the euler angle options rotation_euler_a->rotation_y = options->rotation_y; rotation_euler_b->rotation_x = options->rotation_x; rotation_euler_c->rotation_z = options->rotation_z; teapot_euler->rotation_x = options->rotation_x; teapot_euler->rotation_y = options->rotation_y; teapot_euler->rotation_z = options->rotation_z; // Use the target angle options rotation_target_a->rotation_y = options->target_y; rotation_target_b->rotation_x = options->target_x; rotation_target_c->rotation_z = options->target_z; teapot_target->rotation_x = options->target_x; teapot_target->rotation_y = options->target_y; teapot_target->rotation_z = options->target_z; // Render the scene using euler angles calculate_matricies(canvas); update_light(canvas, options); canvas.set_depth_stencil_state(depth_write_enabled); canvas.set_rasterizer_state(raster_state); render(canvas); // Show the quaternion teapot Mat4f modelview_matrix = scene.gs->camera_modelview; modelview_matrix.translate_self(0.0f, 0.0f, 0.0f); modelview_matrix = modelview_matrix * options->quaternion.to_matrix(); modelview_matrix.scale_self(5.0f, 5.0f, 5.0f); model_teapot.Draw(canvas, scene.gs, modelview_matrix); // Draw information boxes canvas.reset_rasterizer_state(); canvas.reset_depth_stencil_state(); std::string fps(string_format("%1 fps", framerate_counter.get_framerate())); font.draw_text(canvas, 16-2, canvas.get_height()-16-2, fps, Colorf(0.0f, 0.0f, 0.0f, 1.0f)); font.draw_text(canvas, 16, canvas.get_height()-16-2, fps, Colorf(1.0f, 1.0f, 1.0f, 1.0f)); font.draw_text(canvas, 60, 250, "Euler Orientation"); font.draw_text(canvas, 330, 250, "Quaternion Orientation"); font.draw_text(canvas, 600, 250, "Target Euler Orientation"); font.draw_text(canvas, 16, 630, "(Using YXZ rotation order)"); wm.process(); wm.draw_windows(canvas); // Use flip(1) to lock the fps window.flip(0); KeepAlive::process(); } return 0; }