void LightingScene::render_frame_for_time (TimeT time) { Scene::render_frame_for_time(time); _trail_particles->update(time); for (std::size_t i = 0; i < 3; i += 1) { _flowing_lights[i].update(); _light_positions[i] = _flowing_lights[i].position << 1.0; if (_flowing_lights[i].history.size() > 1) { // Add some particle effects _trail_particles->add(_flowing_lights[i].end_segment(), _light_colors[i].reduce()); } } _rotation += 0.01; /// Dequeue any button/motion/resize events and process them now (in this thread). manager()->process_pending_events(this); check_graphics_error(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); { check_graphics_error(); auto binding = _textured_program->binding(); _renderer_state->texture_manager->bind(0, _crate_texture); Mat44 modelview_matrix = Mat44::rotating_matrix_around_z(_rotation); //modelview_matrix = modelview_matrix * _viewport->display_matrix(); modelview_matrix = _viewport->display_matrix() * modelview_matrix; GLuint display_matrix_uniform = _textured_program->uniform_location("display_matrix"); binding.set_uniform("light_colors", _light_colors); binding.set_uniform(_light_positions_uniform, _light_positions); check_graphics_error(); //Vec2 p(0.5 * Math::sin(time), 0.5 * Math::cos(time)); binding.set_uniform(_position_uniform, _point); check_graphics_error(); // Draw the various objects to the screen: binding.set_uniform(display_matrix_uniform, _viewport->display_matrix()); _grid_mesh_buffer->draw(); binding.set_uniform(display_matrix_uniform, modelview_matrix); _object_mesh_buffer->draw(); check_graphics_error(); } { auto binding = _solid_program->binding(); binding.set_uniform("display_matrix", _viewport->display_matrix()); for (std::size_t i = 0; i < 3; i += 1) { binding.set_uniform("light_position", _light_positions[i]); binding.set_uniform("light_color", _light_colors[i]); auto array_binding = _flowing_array->binding(); array_binding.attach(*_flowing_buffer); auto buffer_binding = _flowing_buffer->binding<Vec3>(); buffer_binding.set_data(_flowing_lights[i].history); array_binding.draw_arrays(GL_LINE_STRIP, 0, (GLsizei)_flowing_lights[i].history.size()); check_graphics_error(); } } { auto binding = _wireframe_program->binding(); binding.set_uniform("display_matrix", _viewport->display_matrix()); binding.set_uniform("major_color", Vec4(1.0, 0.0, 0.0, 1.0)); AlignedBox3 xbox = AlignedBox3::from_center_and_size(Vec3(15.0, 0.0, 0.0), 1.0); _wireframe_renderer->render(xbox); binding.set_uniform("major_color", Vec4(0.0, 1.0, 0.0, 1.0)); AlignedBox3 ybox = AlignedBox3::from_center_and_size(Vec3(0.0, 15.0, 0.0), 1.0); _wireframe_renderer->render(ybox); binding.set_uniform("major_color", Vec4(0.0, 0.0, 1.0, 1.0)); AlignedBox3 zbox = AlignedBox3::from_center_and_size(Vec3(0.0, 0.0, 15.0), 1.0); _wireframe_renderer->render(zbox); } { glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); auto binding = _particle_program->binding(); binding.set_uniform("display_matrix", _viewport->display_matrix()); _renderer_state->texture_manager->bind(0, _particle_texture); _trail_particles->draw(); glDisable(GL_BLEND); glDepthMask(GL_TRUE); } }
void LightingScene::will_become_current(ISceneManager * manager) { Scene::will_become_current(manager); glEnable(GL_DEPTH_TEST); //glEnable(GL_CULL_FACE); //glCullFace(GL_BACK); check_graphics_error(); _camera = new BirdsEyeCamera; _camera->set_distance(10); _camera->set_multiplier(Vec3(0.1, 0.1, 0.01)); _projection = new PerspectiveProjection(R90 * 0.7, 1, 1024 * 12); _viewport = new Viewport(_camera, _projection); _viewport->set_bounds(AlignedBox<2>(ZERO, manager->display_context()->size())); _point.zero(); _light_positions[0].zero(); _light_positions[1].zero(); _light_positions[2].zero(); _rotation = 0.0; _light_colors[0] = Vec4(2.0, 0.8, 0.4, 0.0); _light_colors[1] = Vec4(0.4, 0.8, 2.0, 0.0); _light_colors[2] = Vec4(0.4, 2.0, 0.8, 0.0); //_light_colors[0] = Vec4(1.2, 0.2, 0.2, 0.0); //_light_colors[1] = Vec4(0.2, 0.2, 1.2, 0.0); //_light_colors[2] = Vec4(0.2, 1.2, 0.2, 0.0); _renderer_state = new RendererState; _renderer_state->shader_manager = new ShaderManager; _renderer_state->texture_manager = new TextureManager; _renderer_state->resource_loader = this->resource_loader(); { _crate_texture = _renderer_state->load_texture(TextureParameters::LINEAR, "Textures/Checkers"); _particle_texture = _renderer_state->load_texture(TextureParameters::LINEAR, "Textures/Trail"); } check_graphics_error(); { _pixel_buffer_renderer = new PixelBufferRenderer(_renderer_state->texture_manager); } { _solid_program = _renderer_state->load_program("Shaders/solid"); } { _wireframe_program = _renderer_state->load_program("Shaders/wireframe"); _wireframe_program->set_attribute_location("position", WireframeRenderer::POSITION); _wireframe_program->link(); _wireframe_renderer = new WireframeRenderer; } { _particle_program = _renderer_state->load_program("Shaders/particle"); _particle_program->set_attribute_location("position", TrailParticles::POSITION); _particle_program->set_attribute_location("offset", TrailParticles::OFFSET); _particle_program->set_attribute_location("mapping", TrailParticles::MAPPING); _particle_program->set_attribute_location("color", TrailParticles::COLOR); _particle_program->link(); auto binding = _particle_program->binding(); binding.set_texture_unit("diffuse_texture", 0); _trail_particles = new TrailParticles; } { // Setup the buffer for drawing the light trails. _flowing_array = new VertexArray; _flowing_buffer = new VertexBuffer<BasicVertex<Vec3>>; auto binding = _flowing_array->binding(); auto attributes = binding.attach(*_flowing_buffer); attributes[0] = &BasicVertex<Vec3>::element; check_graphics_error(); } { _flat_program = _renderer_state->load_program("Shaders/flat"); _flat_program->set_attribute_location("position", 0); _flat_program->set_attribute_location("mapping", 1); _flat_program->link(); auto binding = _flat_program->binding(); binding.set_texture_unit("diffuse_texture", 0); check_graphics_error(); } { _textured_program = _renderer_state->load_program("Shaders/surface"); _textured_program->set_attribute_location("position", POSITION); _textured_program->set_attribute_location("normal", NORMAL); _textured_program->set_attribute_location("color", COLOR); _textured_program->set_attribute_location("mapping", MAPPING); _textured_program->link(); _position_uniform = _textured_program->uniform_location("point"); _diffuse_uniform = _textured_program->uniform_location("diffuse"); _light_positions_uniform = _textured_program->uniform_location("light_positions"); check_graphics_error(); } { using namespace Geometry; Shared<MeshT> mesh = new MeshT; mesh->layout = TRIANGLE_STRIP; Generate::sphere(*mesh, 4, 8*2, (16*2)+1); //Generate::solid_color(*mesh, Vec4(0.5, 0.5, 0.5, 1.0)); /* { LogBuffer buffer; buffer << "Mesh vertices: " << std::endl; for (auto i : mesh->indices) { MeshT::VertexT vertex = mesh->vertices[i]; buffer << "Vertex " << i << ": " << vertex.position << "; " << vertex.mapping << std::endl; } logger()->log(LOG_DEBUG, buffer); } */ _object_mesh_buffer = new MeshBuffer<MeshT>(); _object_mesh_buffer->set_mesh(mesh); { auto binding = _object_mesh_buffer->vertex_array().binding(); // Attach indices binding.attach(_object_mesh_buffer->index_buffer()); // Attach attributes auto attributes = binding.attach(_object_mesh_buffer->vertex_buffer()); attributes[POSITION] = &MeshT::VertexT::position; attributes[NORMAL] = &MeshT::VertexT::normal; //attributes[COLOR] = &MeshT::VertexT::color; attributes[MAPPING] = &MeshT::VertexT::mapping; } } { using namespace Geometry; Shared<MeshT> mesh = new MeshT; mesh->layout = LINES; Generate::grid(*mesh, 32, 2.0); _grid_mesh_buffer = new MeshBuffer<MeshT>(); _grid_mesh_buffer->set_mesh(mesh); { auto binding = _grid_mesh_buffer->vertex_array().binding(); // Attach indices binding.attach(_grid_mesh_buffer->index_buffer()); // Attach attributes auto attributes = binding.attach(_grid_mesh_buffer->vertex_buffer()); attributes[POSITION] = &MeshT::VertexT::position; attributes[NORMAL] = &MeshT::VertexT::normal; attributes[MAPPING] = &MeshT::VertexT::mapping; } } { _flowing_lights[0].rotations[0].set_to_angle_axis_rotation(R90 / 25.0, Vec3(0.0, 0.3, 1.0).normalize()); _flowing_lights[0].rotations[1].set_to_angle_axis_rotation(R10 / 10.0, Vec3(0.0, 1.0, 1.0).normalize()); _flowing_lights[0].rotations[2].set_to_angle_axis_rotation(R180 / 5, Vec3(1.0, 0.0, 0.5).normalize()); _flowing_lights[0].position = Vec3(10, 0, 0); _flowing_lights[1].rotations[0].set_to_angle_axis_rotation(R90 / 25.0, Vec3(0.0, 1.0, 0.0)); _flowing_lights[1].rotations[1].set_to_angle_axis_rotation(R30 / 10.0, Vec3(1.0, 1.0, 0.0).normalize()); _flowing_lights[1].rotations[2].set_to_angle_axis_rotation(R180 / 2, Vec3(1.0, 0.0, 0.7).normalize()); _flowing_lights[1].position = Vec3(0, 10, 0); _flowing_lights[2].rotations[0].set_to_angle_axis_rotation(R90 / 25.0, Vec3(0.5, 1.0, 0.0).normalize()); _flowing_lights[2].rotations[1].set_to_angle_axis_rotation(R30 / 10.0, Vec3(-0.7, 0.0, 0.2).normalize()); _flowing_lights[2].rotations[2].set_to_angle_axis_rotation(R180 / 2, Vec3(0.4, -0.2, 0.3).normalize()); _flowing_lights[2].position = Vec3(0, 0, 10); } glClearColor(0.0, 0.0, 0.0, 1.0); logger()->log(LOG_INFO, "Will become current."); }