void text::draw( platform::context &ctxt ) { if ( _update ) update( ctxt ); if ( _mesh.valid() ) { auto &fgc = _stash->_font_glyph_cache; auto x = fgc.find( _font ); if ( x != fgc.end() ) { std::shared_ptr<gl::texture> texture = x->second.texture; gl::api &ogl = ctxt.api(); ogl.save_matrix(); ogl.model_matrix().scale( to_api( _scale[0] ), to_api( _scale[1] ) ); ogl.model_matrix().translate( to_api( _pos[0] ), to_api( _pos[1] ) ); auto txt = texture->bind(); auto b = _mesh.bind(); // std::cout << "scale: " << _scale[0] << " (" << to_api( _scale[0] ) << ")" // << _scale[1] << " (" << to_api(_scale[1]) << ")" << std::endl; // std::cout << "pos: " << _pos[0] << " (" << to_api( _pos[0] ) << ")" // << _pos[1] << " (" << to_api(_pos[1]) << ")" << std::endl; // std::cout << "draw matrix: " << ogl.current_matrix() << std::endl; b.set_uniform( _mat_pos, ogl.current_matrix() ); b.set_uniform( _col_pos, _color ); b.set_uniform( _tex_pos, static_cast<int>( txt.unit() ) ); b.draw(); ogl.restore_matrix(); } } }
void rectangle::draw( platform::context &ctxt ) { initialize( ctxt ); auto bound = _stash->_mesh.bind(); bound.set_uniform( _stash->_matrix_loc, _rect * ctxt.api().current_matrix() ); bound.set_uniform( _stash->_color_loc, _color ); bound.draw(); }
void GBufferPass::display_quads(RenderContext const& ctx, SerializedScene const& scene, CameraMode eye, View const& view) { auto meshubershader = ubershaders_[typeid(node::TriMeshNode)]; if (!scene.textured_quads_.empty()) { meshubershader->get_program()->use(ctx); { for (auto const& node : scene.textured_quads_) { std::string texture_name(node->get_texture()); if (node->is_stereo_texture()) { if (eye == CameraMode::LEFT) { texture_name += "_left"; } else if (eye == CameraMode::RIGHT) { texture_name += "_right"; } } if (TextureDatabase::instance()->is_supported(texture_name)) { auto texture = TextureDatabase::instance()->lookup(texture_name); auto mapped_texture( meshubershader->get_uniform_mapping()->get_mapping( "gua_textured_quad", "texture")); meshubershader->set_uniform( ctx, texture, mapped_texture.first, mapped_texture.second); auto mapped_flip_x(meshubershader->get_uniform_mapping()->get_mapping( "gua_textured_quad", "flip_x")); meshubershader->set_uniform( ctx, node->flip_x(), mapped_flip_x.first, mapped_flip_x.second); auto mapped_flip_y(meshubershader->get_uniform_mapping()->get_mapping( "gua_textured_quad", "flip_y")); meshubershader->set_uniform( ctx, node->flip_y(), mapped_flip_y.first, mapped_flip_y.second); } meshubershader->draw( ctx, "gua_plane_geometry", "gua_textured_quad", node->get_scaled_world_transform(), scm::math::inverse(node->get_scaled_world_transform()), scene.frustum, view); } } meshubershader->get_program()->unuse(ctx); } }
void do_stuff() { float eyepoint[3], viewpoint[3]; int k; glEnable(GL_DEPTH_TEST); glClearColor(0.8, 0.6, 0.62, 1.0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 1); glUseProgram(0); for (k=0; k<3; k++) { eyepoint[k] = light0_position[k]; viewpoint[k] = light0_direction[k] + light0_position[k]; } view_volume(eyepoint, viewpoint); drawquads(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); save_matrix(eyepoint, viewpoint); glUseProgram(sprogram); set_uniform(sprogram); glActiveTexture(GL_TEXTURE7); glBindTexture(GL_TEXTURE_2D, 1); eyepoint[0] = 1.0; eyepoint[1] = 2.0; eyepoint[2] = 2.0; viewpoint[0] = 0.0; viewpoint[1] = 0.0; viewpoint[2] = 0.0; view_volume(eyepoint, viewpoint); drawquads(); glutSwapBuffers(); }
void MaterialShaderMethod::set_uniforms_from_serialized_string(std::string const& value) { auto tokens(string_utils::split(value, ';')); for (auto& token : tokens) { auto parts(string_utils::split(token, '#')); set_uniform(parts[0], ViewDependentUniform::create_from_serialized_string(parts[1])); } }
void render_terrain_chunk(App *app, TerrainChunk *chunk, Model *model) { mat4 model_view; model_view = glm::translate(model_view, vec3(chunk->x * CHUNK_SIZE_X, 0.0f, chunk->y * CHUNK_SIZE_Y)); mat3 normal = glm::inverseTranspose(mat3(model_view)); if (shader_has_uniform(app->current_program, "uNMatrix")) { set_uniform(app->current_program, "uNMatrix", normal); } if (shader_has_uniform(app->current_program, "uMVMatrix")) { set_uniform(app->current_program, "uMVMatrix", model_view); } if (shader_has_uniform(app->current_program, "in_color")) { set_uniform(app->current_program, "in_color", vec4(0.0f, 0.3f, 0.1f, 1.0f)); } use_model_mesh(app, &model->mesh); glDrawElements(GL_TRIANGLES, model->mesh.data.indices_count, GL_UNSIGNED_INT, 0); }
static void set_brush_uniform(struct brush *b, const char *n, int r, int c, int d, const float *v) { struct uniform *u; /* Apply the given values to the uniform cache and OpenGL state. */ if ((u = get_uniform(b, n))) { set_uniform(u, r, c, d, v); use_uniform(b, u); } }
void from_distribution(const Distribution& distribution, const int& new_size) { // we first create a local array to sample to. this way, if this // is passed as an argument the locations and pmf are not overwritten // while sampling LocationArray new_locations(new_size); for(int i = 0; i < new_size; i++) { new_locations[i] = distribution.sample(); } set_uniform(new_size); locations_ = new_locations; }
MaterialShaderMethod& MaterialShaderMethod::load_from_json(std::string const& json_string) { Json::Value value; Json::Reader reader; if (!reader.parse(json_string, value)) { Logger::LOG_WARNING << "Failed to parse material method description: " "Invalid json String!" << std::endl; return *this; } if (value["name"] != Json::Value::null && value["source"] != Json::Value::null) { set_name(value["name"].asString()); set_source(value["source"].asString()); if (value["uniforms"] != Json::Value::null && value["uniforms"].isArray()) { for (int i(0); i < value["uniforms"].size(); ++i) { auto uniform_string(value["uniforms"][i]); if (uniform_string["name"] != Json::Value::null && uniform_string["type"] != Json::Value::null && uniform_string["value"] != Json::Value::null) { auto uniform(UniformValue::create_from_strings( uniform_string["value"].asString(), uniform_string["type"].asString() )); set_uniform(uniform_string["name"].asString(), ViewDependentUniform(uniform)); } else { Logger::LOG_WARNING << "Failed to load uniform: " "Please provide name, type and value in the description!" << std::endl; } } } } else { Logger::LOG_WARNING << "Failed to load material method: " "Please provide name and source in the description!" << std::endl; } return *this; }
int main(int argc,char** argv) { int p; glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); glutInitWindowSize(500,500); glutInitWindowPosition(100,100); glutCreateWindow("phong shaded teapot"); glActiveTexture(GL_TEXTURE0); load_texture(argv[1],1); glActiveTexture(GL_TEXTURE1); load_texture(argv[2],2); glEnable(GL_DEPTH_TEST); view_volume(); set_light(); set_material(); p = set_shaders(); set_uniform(p); glutDisplayFunc(renderScene); //glutIdleFunc(renderScene); glutMainLoop(); return 0; }
void gl_display_object(t_resources *res, t_mesh *mesh, t_mode mode) { t_mat *model_mat; set_uniform(res, mode); if (mode == MODE_COLOR) glUseProgram(res->shader_color->program_id); else glUseProgram(res->shader_texture->program_id); model_mat = model_matrix(mesh); glUniformMatrix4fv(get_uniform_id(&res->gl_model_uni, mode), 1, GL_FALSE, model_mat->array); bind_buffer(mesh->gl_buff_vertex, 0, 3); if (mode == MODE_COLOR) bind_buffer(mesh->gl_buff_colors, 1, 3); else bind_buffer(mesh->gl_buff_uv, 1, 2); bind_buffer(mesh->gl_buff_normal, 2, 3); glDrawArrays(GL_TRIANGLES, 0, mesh->size); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); free(model_mat); }
inline int basic_gridmap<T>::set_uniform(const T v) { return set_uniform(&v); }
int main(int argc, char** argv) { // initialize guacamole gua::init(argc, argv); ///////////////////////////////////////////////////////////////////////////// // create a set of materials ///////////////////////////////////////////////////////////////////////////// // create simple untextured material shader auto pbr_keep_input_desc = std::make_shared<gua::MaterialShaderDescription>("./data/materials/PBR_use_input_color.gmd"); auto pbr_uniform_color_desc = std::make_shared<gua::MaterialShaderDescription>("./data/materials/PBR_uniform_color.gmd"); //use this material for models where shading does not make sense auto pbr_keep_color_shader(std::make_shared<gua::MaterialShader>("PBR_pass_input_color", pbr_keep_input_desc)); auto pbr_overwrite_color_shader(std::make_shared<gua::MaterialShader>("PBR_overwrite_input_color", pbr_uniform_color_desc)); gua::MaterialShaderDatabase::instance()->add(pbr_keep_color_shader); gua::MaterialShaderDatabase::instance()->add(pbr_overwrite_color_shader); // create different materials for point-based input auto plod_glossy = pbr_keep_color_shader->make_new_material(); auto plod_rough = pbr_keep_color_shader->make_new_material(); auto plod_passthrough = pbr_keep_color_shader->make_new_material(); // glossy has high metalness, low roughness and no emissivity (=no passthrough) plod_glossy->set_uniform("metalness", 1.0f); plod_glossy->set_uniform("roughness", 0.3f); plod_glossy->set_uniform("emissivity", 0.0f); // rough has no metalness, high roughness and no emissivity (=no passthrough) plod_rough->set_uniform("metalness", 0.0f); plod_rough->set_uniform("roughness", 0.8f); plod_rough->set_uniform("emissivity", 1.0f); // passthrough has emissivity of 1.0 plod_passthrough->set_uniform("emissivity", 1.0f); auto rough_white = pbr_overwrite_color_shader->make_new_material(); rough_white->set_uniform("color", gua::math::vec3f(1.0f, 1.0f, 1.0f)); rough_white->set_uniform("metalness", 0.0f); rough_white->set_uniform("roughness", 0.8f); rough_white->set_uniform("emissivity", 0.0f); auto rough_red = pbr_overwrite_color_shader->make_new_material(); rough_red->set_uniform("color", gua::math::vec3f(0.8f, 0.0f, 0.0f)); rough_red->set_uniform("metalness", 0.0f); rough_red->set_uniform("roughness", 0.8f); rough_red->set_uniform("emissivity", 0.0f); // setup scene gua::SceneGraph graph("main_scenegraph"); gua::LodLoader plodLoader; plodLoader.set_upload_budget_in_mb(32); plodLoader.set_render_budget_in_mb(2048); plodLoader.set_out_of_core_budget_in_mb(4096); auto transform = graph.add_node<gua::node::TransformNode>("/", "transform"); auto model_xf = graph.add_node<gua::node::TransformNode>("/transform", "model_xf"); auto setup_plod_node = [](std::shared_ptr<gua::node::PLodNode> const& node) { node->set_radius_scale(1.0f); node->set_enable_backface_culling_by_normal(false); node->set_draw_bounding_box(true); }; #if WIN32 auto plod_pig_node = plodLoader.load_lod_pointcloud("plod_pig", "data/objects/Area_4_hunter_with_bow_knn.bvh", plod_rough, gua::LodLoader::NORMALIZE_POSITION | gua::LodLoader::NORMALIZE_SCALE | gua::LodLoader::MAKE_PICKABLE); #else auto plod_pig_node = plodLoader.load_lod_pointcloud("plod_pig", "/mnt/pitoti/3d_pitoti/groundtruth_data/rocks/seradina12c/areas/objects/Area_4_hunter_with_bow_knn.bvh", plod_rough, gua::LodLoader::NORMALIZE_POSITION | gua::LodLoader::NORMALIZE_SCALE | gua::LodLoader::MAKE_PICKABLE); #endif plod_pig_node->scale(5.0, 5.0, 5.0); plod_pig_node->rotate(269, gua::math::vec3(0.0, 0.0, 1.0)); gua::TriMeshLoader loader; auto root_plod_pig_model = graph.add_node("/", plod_pig_node); auto nav = graph.add_node<gua::node::TransformNode>("/", "nav"); nav->translate(0.0, 0.0, 1.0); #if WIN32 auto window = std::make_shared<gua::OculusWindow>(":0.0"); gua::WindowDatabase::instance()->add("main_window", window); window->config.set_enable_vsync(false); window->config.set_fullscreen_mode(false); window->open(); #else auto window = std::make_shared<gua::OculusWindow>(":0.0"); gua::WindowDatabase::instance()->add("main_window", window); window->config.set_enable_vsync(false); window->config.set_fullscreen_mode(true); window->config.set_size(window->get_window_resolution()); window->config.set_resolution(window->get_window_resolution()); window->open(); #endif //get the resolution from the oculus window gua::math::vec2ui res(window->get_window_resolution()); auto resolve_pass = std::make_shared<gua::ResolvePassDescription>(); resolve_pass->background_mode(gua::ResolvePassDescription::BackgroundMode::QUAD_TEXTURE); resolve_pass->tone_mapping_exposure(1.0f); auto neck = graph.add_node<gua::node::TransformNode>("/nav", "neck"); auto camera = graph.add_node<gua::node::CameraNode>("/nav/neck", "cam"); float camera_trans_y = 0.0; float camera_trans_z = 0.0; camera->translate(0.0, camera_trans_y, camera_trans_z); camera->config.set_resolution( res ); camera->config.set_left_screen_path("/nav/neck/cam/left_screen"); camera->config.set_right_screen_path("/nav/neck/cam/right_screen"); camera->config.set_scene_graph_name("main_scenegraph"); camera->config.set_output_window_name("main_window"); camera->config.set_enable_stereo(true); camera->config.set_eye_dist(window->get_IPD()); auto pipe = std::make_shared<gua::PipelineDescription>(); pipe->add_pass(std::make_shared<gua::PLodPassDescription>()); pipe->add_pass(std::make_shared<gua::LightVisibilityPassDescription>()); pipe->add_pass(std::make_shared<gua::ResolvePassDescription>()); camera->set_pipeline_description(pipe); // retreive the complete viewing setup from the oculus window //************** auto left_screen = graph.add_node<gua::node::ScreenNode>("/nav/neck/cam", "left_screen"); left_screen->data.set_size(window->get_left_screen_size()); left_screen->translate(window->get_left_screen_translation()); auto right_screen = graph.add_node<gua::node::ScreenNode>("/nav/neck/cam", "right_screen"); right_screen->data.set_size(window->get_right_screen_size()); right_screen->translate(window->get_right_screen_translation()); //****************/ gua::Renderer renderer; gua::Timer timer; timer.start(); double time(0); float desired_frame_time(1.0 / 60.0); gua::events::MainLoop loop; // application loop gua::events::Ticker ticker(loop, desired_frame_time); ticker.on_tick.connect([&]() { double frame_time(timer.get_elapsed()); time += frame_time; timer.reset(); window->process_events(); std::function<void (std::shared_ptr<gua::node::Node>, int)> rotate; rotate = [&](std::shared_ptr<gua::node::Node> node, int depth) { node->rotate(frame_time * (1+depth) * 0.5, 1, 1, 0); for (auto child: node->get_children()) { rotate(child, ++depth); } }; float frame_offset = 1.0 * frame_time; camera->set_transform(window->get_oculus_sensor_orientation()); //neck->set_transform(window->get_oculus_sensor_orientation()); renderer.queue_draw({&graph}); }); loop.start(); return 0; }
void KinectDataRenderer::init(Camera *camera) { this->camera = camera; ///--- Create vertex array object if(!vao.isCreated()){ bool success = vao.create(); assert(success); vao.bind(); } ///--- Load/compile shaders if (!program.isLinked()) { const char* vshader = ":/KinectDataRenderer/KinectDataRenderer_vshader.glsl"; const char* fshader = ":/KinectDataRenderer/KinectDataRenderer_fshader.glsl"; bool vok = program.addShaderFromSourceFile(QGLShader::Vertex, vshader); bool fok = program.addShaderFromSourceFile(QGLShader::Fragment, fshader); bool lok = program.link (); assert(lok && vok && fok); bool success = program.bind(); assert(success); } ///--- Used to create connectivity Grid grid(camera->width(),camera->height()); ///--- Create vertex buffer/attributes "position" { bool success = vertexbuffer.create(); assert(success); vertexbuffer.setUsagePattern( QGLBuffer::StaticDraw ); success = vertexbuffer.bind(); assert(success); vertexbuffer.allocate( grid.vertices.data(), grid.vertices.size() * sizeof(GLfloat) ); program.setAttributeBuffer("vpoint", GL_FLOAT, 0, 2 ); program.enableAttributeArray("vpoint"); } ///--- Create vertex buffer/attributes "uv" { bool success = uvbuffer.create(); assert(success); uvbuffer.setUsagePattern( QGLBuffer::StaticDraw ); success = uvbuffer.bind(); assert(success); uvbuffer.allocate( grid.texcoords.data(), grid.texcoords.size() * sizeof(GLfloat) ); program.setAttributeBuffer("uv", GL_FLOAT, 0, 2 ); program.enableAttributeArray("uv"); } ///--- Create the index "triangle" buffer { bool success = indexbuffer.create(); assert(success); indexbuffer.setUsagePattern( QGLBuffer::StaticDraw ); success = indexbuffer.bind(); assert(success); indexbuffer.allocate( grid.indices.data(), grid.indices.size() * sizeof(unsigned int) ); } ///--- Create texture to colormap the point cloud { // const int sz=2; GLfloat tex[3*sz] = {/*green*/ 0.000, 1.000, 0, /*red*/ 1.000, 0.000, 0,}; // const int sz=2; GLfloat tex[3*sz] = {/*gray*/ .1, .1, .1, /*black*/ 0.8, 0.8, 0.8}; const int sz=3; GLfloat tex[3*sz] = {/*red*/ 1.000, 0.000, 0, /*yellow*/ 1.0, 1.0, 0.0, /*green*/ 0.000, 1.000, 0}; glActiveTexture(GL_TEXTURE2); glGenTextures(1, &texture_id_cmap); glBindTexture(GL_TEXTURE_1D, texture_id_cmap); glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, sz, 0, GL_RGB, GL_FLOAT, tex); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); program.setUniformValue("colormap", 2 /*GL_TEXTURE2*/); } ///--- @todo upload data to do inverse projection set_uniform("inv_proj_matrix",camera->inv_projection_matrix()); ///--- upload near/far planes set_zNear(camera->zNear()); set_zFar(camera->zFar()); // set_alpha(1.0); ///< default no alpha blending set_alpha(.7); ///< default no alpha blending set_discard_cosalpha_th(.3); ///< default sideface clipping ///--- save for glDrawElements num_indexes = grid.indices.size(); num_vertices = grid.vertices.size(); ///--- Avoid pollution program.release(); vao.release(); }
void KinectDataRenderer::enable_colormap(bool enable){ set_uniform("enable_colormap", (enable)?+1.0f:-1.0f); }
void KinectDataRenderer::set_zFar(float alpha){ set_uniform("zFar",alpha); }
void KinectDataRenderer::set_alpha(float alpha){ set_uniform("alpha", alpha); this->alpha = alpha; }
void KinectDataRenderer::set_discard_cosalpha_th(float val){ set_uniform("discard_cosalpha_th", val); }
/** * edges using geometry shader. */ int build_triangle_edges(lulog *log, GLuint *program) { int status = LU_OK; luary_uint32 *shaders = NULL; try(compile_shader_from_file(log, GL_VERTEX_SHADER, "flat_model_g.vert", &shaders)); try(compile_shader_from_file(log, GL_GEOMETRY_SHADER, "edge_lines.geom", &shaders)); try(compile_shader_from_file(log, GL_FRAGMENT_SHADER, "direct_colour.frag", &shaders)); try(link_program(log, shaders, program)); finally: status = free_shaders(log, &shaders, status); return status; } /** * copy a frame by rendering a texture directly (needs a quad to select the area). */ int build_direct_texture(lulog *log, direct_texture *program) { int status = LU_OK; luary_uint32 *shaders = NULL; try(compile_shader_from_file(log, GL_VERTEX_SHADER, "direct_texture.vert", &shaders)); try(compile_shader_from_file(log, GL_FRAGMENT_SHADER, "direct_texture.frag", &shaders)); try(link_program(log, shaders, &program->name)); try(set_uniform(log, program->name, "frame", &program->frame, 0)); finally: status = free_shaders(log, &shaders, status); return status; } /** * merge two frames via textures. */ int build_merge_frames(lulog *log, merge_frames *program) { int status = LU_OK; luary_uint32 *shaders = NULL; try(compile_shader_from_file(log, GL_VERTEX_SHADER, "direct_texture.vert", &shaders)); try(compile_shader_from_file(log, GL_FRAGMENT_SHADER, "merge_frames.frag", &shaders)); try(link_program(log, shaders, &program->name)); try(set_uniform(log, program->name, "frame1", &program->frame1, 0)); try(set_uniform(log, program->name, "frame2", &program->frame2, 1)); finally: status = free_shaders(log, &shaders, status); return status; } /** * blur a frame (roughly uniform over 5 pixels radius). */ int build_blur(lulog *log, blur *program) { int status = LU_OK; luary_uint32 *shaders = NULL; try(compile_shader_from_file(log, GL_VERTEX_SHADER, "direct_texture.vert", &shaders)); try(compile_shader_from_file(log, GL_FRAGMENT_SHADER, "blur.frag", &shaders)); try(link_program(log, shaders, &program->name)); try(set_uniform(log, program->name, "frame", &program->frame, 0)); try(set_uniform(log, program->name, "horizontal", &program->horizontal, 1)); finally: status = free_shaders(log, &shaders, status); return status; } int draw_triangle_edges(lulog *log, model *model, programs *programs) { int status = LU_OK; gl_try(glBindVertexArray(model->vao)); // gl_try(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)); gl_try(glUseProgram(programs->triangle_edges)); gl_try(glMultiDrawArrays(GL_TRIANGLE_STRIP, model->offsets->i, model->counts->i, model->counts->mem.used)); // gl_try(glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)); finally: GL_CLEAN(glBindVertexArray(0)) GL_CLEAN(glUseProgram(0)) return status; }
void Engine::init_scene() { Node* scene = nodes["scene"] = new Node(NULL); // shaders // // "simple_shader" shaders["simple_shader"] = make_shader("shaders/p_v.glsl", "shaders/unicolor_f.glsl"); // "light1" { Shader* shader = shaders["light1"] = make_shader("shaders/pn_v.glsl", "shaders/light1_f.glsl"); // TODO put uniforms in "material"-class or something? set_uniform(shader, "mycolor", glm::vec4(1.f)); set_uniform(shader, "ambient_intensity", glm::vec4(.1f,.1f,.1f,1.f)); set_uniform(shader, "diffuse_color", glm::vec4(.5f,.5f,.5f,1.f)); set_uniform(shader, "specular_color", glm::vec4(1.f,1.f,1.f,1.f)); set_uniform(shader, "atten_k", .04f); set_uniform(shader, "gauss_k", .1f); } // objects // // grid { Shader* shader = shaders["simple_shader"]; Node* node = nodes["grid"] = new Node(scene); int no = 5; glm::vec3 scale = glm::vec3(20.f); VAO* vao = create_grid(no, scale); std::vector<Uniform*> material; glm::vec4 white = glm::vec4(1.f); StoredUniform<glm::vec4>* mycolor = new StoredUniform<glm::vec4>(shader, "mycolor", white); material.push_back(mycolor); renderables.push_back( new BasicRenderObject(shader, node, vao, material)); // mem vaos.push_back(vao); uniforms.push_back(mycolor); } // redcube { Shader* shader = shaders["light1"]; Node* node = nodes["redcube"] = new Node(scene); node->position = glm::vec3(.5f,.5f,-1.7f); glm::vec3 scale = glm::vec3(.05f); VAO* vao = create_cube_with_normals(scale); std::vector<Uniform*> material; glm::vec4 red = glm::vec4(1.f,0.f,.5f,1.f); StoredUniform<glm::vec4>* mycolor = new StoredUniform<glm::vec4>(shader, "mycolor", red); material.push_back(mycolor); renderables.push_back( new LitRenderObject(shader, node, vao, material)); // physics btCollisionShape* cube_shape = new btBoxShape(from_vec3(scale/2.f)); float mass = 0.f; redcube_rb = create_rigid_body(mass, node, cube_shape); physics->add_rigid_body(redcube_rb); // mem vaos.push_back(vao); uniforms.push_back(mycolor); collision_shapes.push_back(cube_shape); } make_litcube("cyancube", glm::vec4(0.f, 1.f, 1.f, 1.f), glm::vec3(0.05f)); nodes["cyancube"]->orientation = glm::angleAxis(glm::radians(45.f), glm::normalize(glm::vec3(-1.f, 1.f, 1.f))); make_litcube("yellowcube", glm::vec4(1.f, 1.f, 0.f, 1.f), glm::vec3(0.05f)); nodes["yellowcube"]->orientation = nodes["cyancube"]->orientation; make_litcube("bluecube", glm::vec4(0.f, 0.f, 1.f, 1.f), glm::vec3(1.f), 30.f, glm::vec3(0.f, 1.5f, -5.f)); // lightcube { Shader* shader = shaders["simple_shader"]; Node* node = nodes["lightcube"] = new Node(scene); node->position = glm::vec3(0.f, 1.f, 0.f); glm::vec3 scale = glm::vec3(.3f,.3f,.3f); VAO* vao = create_cube(scale); std::vector<Uniform*> material; glm::vec4 white = glm::vec4(1.f,1.f,1.f,1.f); StoredUniform<glm::vec4>* mycolor = new StoredUniform<glm::vec4>(shader, "mycolor", white); material.push_back(mycolor); renderables.push_back( new BasicRenderObject(shader, node, vao, material)); // sync point light with position PointLight light0(node, glm::vec4(.7f,.7f,.7f,1.f)); set_uniform(shaders["light1"], "light.position", glm::vec3(light0.get_position())); set_uniform(shaders["light1"], "light.intensity", light0.get_intensity()); // mem vaos.push_back(vao); uniforms.push_back(mycolor); } // plane { Shader* shader = shaders["light1"]; Node* node = nodes["plane"] = new Node(scene); node->position = glm::vec3(0.f, -.5f, 0.f); glm::vec3 scale = glm::vec3(20.f, 1.f, 20.f); VAO* vao = create_cube_with_normals(scale); std::vector<Uniform*> material; glm::vec4 goldish = glm::vec4(1.f,1.f,0.f,1.f); StoredUniform<glm::vec4>* mycolor = new StoredUniform<glm::vec4>(shader, "mycolor", goldish); material.push_back(mycolor); renderables.push_back( new LitRenderObject(shader, node, vao, material)); // physics btCollisionShape* shape = new btBoxShape(from_vec3(scale/2.f)); float mass = 0.f; btRigidBody* rigid_body = create_rigid_body(mass, node, shape); physics->add_rigid_body(rigid_body); // mem uniforms.push_back(mycolor); vaos.push_back(vao); collision_shapes.push_back(shape); } // bound { Shader* shader = shaders["light1"]; Node* node = nodes["bound"] = new Node(scene); glm::vec3 scale = glm::vec3(20.f); bool face_inward = true; VAO* vao = create_cube_with_normals(scale, face_inward); std::vector<Uniform*> material; glm::vec4 greenblueish = glm::vec4(0.f,1.f,1.f,1.f); StoredUniform<glm::vec4>* mycolor = new StoredUniform<glm::vec4>(shader, "mycolor", greenblueish); material.push_back(mycolor); renderables.push_back( new LitRenderObject(shader, node, vao, material)); // mem vaos.push_back(vao); uniforms.push_back(mycolor); } // roboarm { nodes["roboarm0"] = new Node(scene); nodes["roboarm1"] = new Node(scene); nodes["roboarm2"] = new Node(scene); nodes["roboarm3"] = new Node(scene); glm::vec3 scale = glm::vec3(0.1f, 0.4f, 0.1f); nodes["roboarm0"]->position = glm::vec3(0.f, 1.f, -2.f); //nodes["roboarm0"]->orientation = // glm::angleAxis(glm::radians(180.f), glm::vec3(1.f, 0.f, 0.f)); nodes["roboarm1"]->position = nodes["roboarm0"]->position + nodes["roboarm0"]->orientation * glm::vec3(0.f, scale.y, 0.f); nodes["roboarm1"]->orientation = nodes["roboarm0"]->orientation; nodes["roboarm2"]->position = nodes["roboarm1"]->position + nodes["roboarm1"]->orientation * glm::vec3(0.f, scale.y, 0.f); nodes["roboarm2"]->orientation = nodes["roboarm1"]->orientation; nodes["roboarm3"]->position = nodes["roboarm2"]->position + nodes["roboarm2"]->orientation * glm::vec3(0.f, scale.y, 0.f); nodes["roboarm3"]->orientation = nodes["roboarm2"]->orientation; // render { Shader* shader = shaders["light1"]; glm::vec4 black = glm::vec4(0.f,0.f,0.f,1.f); StoredUniform<glm::vec4>* mycolor = new StoredUniform<glm::vec4>(shader, "mycolor", black); std::vector<Uniform*> material; material.push_back(mycolor); // TODO use rounder shapes... VAO* vao = create_cube_with_normals(scale); auto make_renderable = [&shader, &material, &vao] (Node* node) { return new LitRenderObject(shader, node, vao, material); }; renderables.insert(renderables.end(), { make_renderable(nodes["roboarm0"]), make_renderable(nodes["roboarm1"]), make_renderable(nodes["roboarm2"]), make_renderable(nodes["roboarm3"]), } ); // mem uniforms.push_back(mycolor); vaos.push_back(vao); } btCollisionShape *shape = new btBoxShape(from_vec3(scale/2.f)); float density = 1000.f, volume = scale.x * scale.y * scale.z, mass = density * volume; // mem collision_shapes.push_back(shape); btRigidBody *rb0 = create_rigid_body(0.f, nodes["roboarm0"], shape), *rb1 = create_rigid_body(mass, nodes["roboarm1"], shape), *rb2 = create_rigid_body(mass, nodes["roboarm2"], shape), *rb3 = create_rigid_body(mass, nodes["roboarm3"], shape); rb1->setActivationState(DISABLE_DEACTIVATION); rb2->setActivationState(DISABLE_DEACTIVATION); rb3->setActivationState(DISABLE_DEACTIVATION); physics->add_rigid_body(rb0); physics->add_rigid_body(rb1); physics->add_rigid_body(rb2); physics->add_rigid_body(rb3); btMatrix3x3 rot; rot.setIdentity(); btTransform trans_up(rot, btVector3(0.f, scale.y/2, 0.f)), trans_down(rot, btVector3(0.f, -scale.y/2, 0.f)); rc1 = new btHingeConstraint(*rb0, *rb1, trans_up, trans_down); rc2 = new btHingeConstraint(*rb1, *rb2, trans_up, trans_down); rc3 = new btHingeConstraint(*rb2, *rb3, trans_up, trans_down); float pi = glm::pi<float>(); rc1->setLimit(-pi/2, pi/2); rc2->setLimit(-pi/2, pi/2); rc3->setLimit(-pi/2, pi/2); bool intercollision = false; physics->add_constraint(rc1, intercollision); physics->add_constraint(rc2, intercollision); physics->add_constraint(rc3, intercollision); roboarm0 = new KinematicChain(nullptr, rb0, nullptr); roboarm1 = new KinematicChain(roboarm0, rb1, rc1); roboarm2 = new KinematicChain(roboarm1, rb2, rc2); roboarm3 = new KinematicChain(roboarm2, rb3, rc3); } }
void Program::set_uniform(const std::string &name, glm::vec4 value) { glUniform4fv(set_uniform(name), 1, &value[0]); }
void GBufferPass::rendering(SerializedScene const& scene, SceneGraph const& graph, RenderContext const& ctx, CameraMode eye, Camera const& camera, FrameBufferObject* target, View const& view) { // pipeline_->camera_block_left_->update(ctx.render_context, pipeline_->get_current_scene(CameraMode::LEFT).frustum); // pipeline_->camera_block_right_->update(ctx.render_context, pipeline_->get_current_scene(CameraMode::RIGHT).frustum); if (!depth_stencil_state_ || !bfc_rasterizer_state_ || !no_bfc_rasterizer_state_) { initialize_state_objects(ctx); } ctx.render_context->set_rasterizer_state( pipeline_->config.enable_backface_culling() ? bfc_rasterizer_state_ : no_bfc_rasterizer_state_); ctx.render_context->set_depth_stencil_state(depth_stencil_state_); // make sure all ubershaders are available update_ubershader_from_scene(ctx, scene, graph); // draw all drawable geometries for (auto const& type_ressource_pair : scene.geometrynodes_) { auto const& type = type_ressource_pair.first; auto const& ressource_container = type_ressource_pair.second; auto ubershader = ubershaders_.at(type); // set frame-consistent per-ubershader uniforms ubershader->set_left_resolution(pipeline_->config.get_left_resolution()); ubershader->set_right_resolution(pipeline_->config.get_right_resolution()); ubershader->set_material_uniforms( scene.materials_, ShadingModel::GBUFFER_VERTEX_STAGE, ctx); ubershader->set_material_uniforms( scene.materials_, ShadingModel::GBUFFER_FRAGMENT_STAGE, ctx); ubershader->set_uniform(ctx, scene.enable_global_clipping_plane, "gua_enable_global_clipping_plane"); ubershader->set_uniform( ctx, scene.global_clipping_plane, "gua_global_clipping_plane"); ubershader->set_uniform(ctx, false, "gua_render_shadow_map"); for (auto const& program : ubershader->programs()) { Pass::bind_inputs(*program, eye, ctx); program->set_uniform(ctx, static_cast<int>(eye), "gua_eye"); if (eye == CameraMode::LEFT || eye == CameraMode::CENTER) { ctx.render_context->bind_uniform_buffer(pipeline_->camera_block_left_->block().block_buffer(), 0); } else { ctx.render_context->bind_uniform_buffer(pipeline_->camera_block_right_->block().block_buffer(), 0); } } // 1. call preframe callback if available for type if (ubershader->get_stage_mask() & GeometryUberShader::PRE_FRAME_STAGE) { ubershader->preframe(ctx); } // 2. iterate all drawables of current type and call predraw of current // ubershader if (ubershader->get_stage_mask() & GeometryUberShader::PRE_DRAW_STAGE) { for (auto const& node : ressource_container) { auto const& ressource = GeometryDatabase::instance()->lookup(node->get_filename()); auto const& material = MaterialDatabase::instance()->lookup(node->get_material()); if (ressource && material) { ubershader->predraw(ctx, node->get_filename(), node->get_material(), node->get_cached_world_transform(), scm::math::transpose(scm::math::inverse( node->get_cached_world_transform())), scene.frustum, view); } else { if (!material) { Logger::LOG_WARNING << "GBufferPass::rendering() Cannot find material. " << material << std::endl; } if (!ressource) { Logger::LOG_WARNING << "GBufferPass::rendering() Cannot find geometry ressource." << ressource << std::endl; } } } } // 3. iterate all drawables of current type and call draw of current // ubershader if (ubershader->get_stage_mask() & GeometryUberShader::DRAW_STAGE) { for (auto const& node : ressource_container) { auto const& ressource = GeometryDatabase::instance()->lookup(node->get_filename()); auto const& material = MaterialDatabase::instance()->lookup(node->get_material()); if (ressource && material) { ubershader->draw(ctx, node->get_filename(), node->get_material(), node->get_cached_world_transform(), scm::math::transpose(scm::math::inverse( node->get_cached_world_transform())), scene.frustum, view); } else { if (!material) { Logger::LOG_WARNING << "GBufferPass::rendering() Cannot find material. " << material << std::endl; } if (!ressource) { Logger::LOG_WARNING << "GBufferPass::rendering() Cannot find geometry ressource." << ressource << std::endl; } } } } // 4. iterate all drawables of current type and call postdraw of current // ubershader if (ubershader->get_stage_mask() & GeometryUberShader::POST_DRAW_STAGE) { for (auto const& node : ressource_container) { auto const& ressource = GeometryDatabase::instance()->lookup(node->get_filename()); auto const& material = MaterialDatabase::instance()->lookup(node->get_material()); if (ressource && material) { ubershader->postdraw(ctx, node->get_filename(), node->get_material(), node->get_cached_world_transform(), scm::math::transpose(scm::math::inverse( node->get_cached_world_transform())), scene.frustum, view); } else { if (!material) { Logger::LOG_WARNING << "GBufferPass::rendering() Cannot find material. " << material << std::endl; } if (!ressource) { Logger::LOG_WARNING << "GBufferPass::rendering() Cannot find geometry ressource." << ressource << std::endl; } } } } // 5. call postframe callback if available for type if (ubershader->get_stage_mask() & GeometryUberShader::POST_FRAME_STAGE) { ubershader->postframe(ctx); } } /////////////////////////////////////////////////////////////// // draw debug and helper information /////////////////////////////////////////////////////////////// display_quads(ctx, scene, eye, view); ctx.render_context->set_rasterizer_state(bbox_rasterizer_state_); display_bboxes(ctx, scene, view); display_rays(ctx, scene, view); ctx.render_context->reset_state_objects(); }
void Program::set_uniform(const std::string &name, glm::mat4 value) { glUniformMatrix4fv(set_uniform(name), 1, GL_FALSE, &value[0][0]); }
int main(int argc, char** argv) { gua::init(argc, argv); //create simple untextured material shader auto lod_keep_input_desc = std::make_shared<gua::MaterialShaderDescription>("./data/materials/PLOD_use_input_color.gmd"); auto lod_keep_color_shader(std::make_shared<gua::MaterialShader>("PLOD_pass_input_color", lod_keep_input_desc)); gua::MaterialShaderDatabase::instance()->add(lod_keep_color_shader); //create material for pointcloud auto lod_rough = lod_keep_color_shader->make_new_material(); lod_rough->set_uniform("metalness", 0.2f); lod_rough->set_uniform("roughness", 0.4f); lod_rough->set_uniform("emissivity", 0.8f); //configure lod backend gua::LodLoader lod_loader; lod_loader.set_out_of_core_budget_in_mb(512); lod_loader.set_render_budget_in_mb(512); lod_loader.set_upload_budget_in_mb(20); //load a sample pointcloud auto plod_node = lod_loader.load_lod_pointcloud( "pointcloud", "/opt/3d_models/lamure/plod/pig_pr.bvh", lod_rough, gua::LodLoader::NORMALIZE_POSITION | gua::LodLoader::NORMALIZE_SCALE | gua::LodLoader::MAKE_PICKABLE); //load a sample mesh-based lod model auto mlod_node = lod_loader.load_lod_trimesh( //"tri_mesh", "/opt/3d_models/lamure/mlod/xyzrgb_dragon_7219k.bvh", //plod_rough, gua::LodLoader::NORMALIZE_POSITION | gua::LodLoader::NORMALIZE_SCALE/* | gua::LodLoader::MAKE_PICKABLE*/ ); mlod_node->set_error_threshold(0.25); //setup scenegraph gua::SceneGraph graph("main_scenegraph"); auto scene_transform = graph.add_node<gua::node::TransformNode>("/", "transform"); auto mlod_transform = graph.add_node<gua::node::TransformNode>("/transform", "mlod_transform"); auto plod_transform = graph.add_node<gua::node::TransformNode>("/transform", "plod_transform"); graph.add_node("/transform/mlod_transform", mlod_node); graph.add_node("/transform/plod_transform", plod_node); mlod_transform->translate(-0.4, 0.0, 0.0); plod_transform->rotate(180.0, 0.0, 1.0, 0.0); plod_transform->translate(0.3, 0.08, 0.0); //create a lightsource auto light_transform = graph.add_node<gua::node::TransformNode>("/transform", "light_transform"); auto light = graph.add_node<gua::node::LightNode>("/transform/light_transform", "light"); light->data.set_type(gua::node::LightNode::Type::POINT); light->data.set_enable_shadows(false); light->data.set_shadow_map_size(4096); light->data.brightness = 5.0f; light->translate(0.f, 0.2f, 0.f); light->scale(4.f); light->translate(0.f, 0.f, 1.f); auto screen = graph.add_node<gua::node::ScreenNode>("/", "screen"); screen->data.set_size(gua::math::vec2(1.92f, 1.08f)); screen->translate(0, 0, 1.0); //add mouse interaction scm::gl::trackball_manipulator trackball; trackball.transform_matrix()*scm::math::make_translation(0.01f, 0.002f, 0.2f); trackball.dolly(0.2f); float dolly_sens = 1.5f; gua::math::vec2 trackball_init_pos(0.f); gua::math::vec2 last_mouse_pos(0.f); int button_state = -1; //setup rendering pipeline and window auto resolution = gua::math::vec2ui(1920, 1080); auto camera = graph.add_node<gua::node::CameraNode>("/screen", "cam"); camera->translate(0.0f, 0, 2.5f); camera->config.set_resolution(resolution); //use close near plane to allow inspection of details //camera->config.set_near_clip(0.01f); //camera->config.set_far_clip(200.0f); camera->config.set_screen_path("/screen"); camera->config.set_scene_graph_name("main_scenegraph"); camera->config.set_output_window_name("main_window"); camera->config.set_enable_stereo(true); auto PLod_Pass = std::make_shared<gua::PLodPassDescription>(); auto pipe = std::make_shared<gua::PipelineDescription>(); pipe->add_pass(std::make_shared<gua::MLodPassDescription>()); pipe->add_pass(PLod_Pass); pipe->add_pass(std::make_shared<gua::BBoxPassDescription>()); pipe->add_pass(std::make_shared<gua::LightVisibilityPassDescription>()); pipe->add_pass(std::make_shared<gua::ResolvePassDescription>()); pipe->add_pass(std::make_shared<gua::DebugViewPassDescription>()); camera->set_pipeline_description(pipe); pipe->get_resolve_pass()->tone_mapping_exposure(1.f); pipe->get_resolve_pass()->tone_mapping_method(gua::ResolvePassDescription::ToneMappingMethod::UNCHARTED); pipe->get_resolve_pass()->background_mode(gua::ResolvePassDescription::BackgroundMode::SKYMAP_TEXTURE); pipe->get_resolve_pass()->background_texture("data/textures/envlightmap.jpg"); //init window and window behaviour auto window = std::make_shared<gua::GlfwWindow>(); gua::WindowDatabase::instance()->add("main_window", window); window->config.set_enable_vsync(false); window->config.set_size(resolution); window->config.set_resolution(resolution); window->config.set_stereo_mode(gua::StereoMode::MONO); window->on_resize.connect([&](gua::math::vec2ui const& new_size) { window->config.set_resolution(new_size); camera->config.set_resolution(new_size); screen->data.set_size(gua::math::vec2(0.001 * new_size.x, 0.001 * new_size.y)); }); //trackball controls bool drag_mode = false; window->on_move_cursor.connect([&](gua::math::vec2 const& pos) { float nx = 2.f * float(pos.x - (resolution.x/2))/float(resolution.x); float ny = -2.f * float(resolution.y - pos.y - (resolution.y/2))/float(resolution.y); if (button_state != -1) { if (drag_mode) { auto ssize = screen->data.get_size(); gua::math::vec3 trans = gua::math::vec3(ssize.x *(nx - last_mouse_pos.x), ssize.y * (ny - last_mouse_pos.y), 0.f); auto object_trans = scm::math::inverse(screen->get_world_transform()) * mlod_transform->get_world_transform(); mlod_transform->set_world_transform(screen->get_world_transform() * scm::math::make_translation(trans) * object_trans); } else { if (button_state == 0) { // left trackball.rotation(trackball_init_pos.x, trackball_init_pos.y, nx, ny); } if (button_state == 1) { // right trackball.dolly(dolly_sens*0.5f * (ny - trackball_init_pos.y)); } if (button_state == 2) { // middle float f = dolly_sens < 1.0f ? 0.02f : 0.3f; trackball.translation(f*(nx - trackball_init_pos.x), f*(ny - trackball_init_pos.y)); } trackball_init_pos.x = nx; trackball_init_pos.y = ny; } } last_mouse_pos.x = nx; last_mouse_pos.y = ny; }); window->on_button_press.connect([&](int mousebutton, int action, int mods) { if (action == 1) { drag_mode = mods == 1; trackball_init_pos = last_mouse_pos; button_state = mousebutton; } else button_state = -1; }); window->on_key_press.connect(std::bind([&](gua::PipelineDescription& pipe, gua::SceneGraph& graph, int key, int scancode, int action, int mods) { if (action == 0) return; switch (std::tolower(key)) { case '1': PLod_Pass->mode(gua::PLodPassDescription::SurfelRenderMode::HQ_TWO_PASS); PLod_Pass->touch(); break; case '2': PLod_Pass->mode(gua::PLodPassDescription::SurfelRenderMode::HQ_LINKED_LIST); PLod_Pass->touch(); break; default: break; } }, std::ref(*(camera->get_pipeline_description())), std::ref(graph), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); window->open(); gua::Renderer renderer; //application loop gua::events::MainLoop loop; gua::events::Ticker ticker(loop, 1.0 / 500.0); ticker.on_tick.connect([&]() { screen->set_transform(scm::math::inverse(gua::math::mat4(trackball.transform_matrix()))); light->rotate(0.1, 0.f, 1.f, 0.f); window->process_events(); if (window->should_close()) { renderer.stop(); window->close(); loop.stop(); } else { renderer.queue_draw({ &graph }); std::cout << "FPS: " << window->get_rendering_fps() << " Frametime: " << 1000.f / window->get_rendering_fps() << std::endl; } }); loop.start(); return 0; }
int main(int argc, char** argv) { // initialize guacamole gua::init(argc, argv); // setup scene gua::SceneGraph graph("main_scenegraph"); gua::math::vec4 iron(0.560, 0.570, 0.580, 1); gua::math::vec4 silver(0.972, 0.960, 0.915, 1); gua::math::vec4 aluminium(0.913, 0.921, 0.925, 1); gua::math::vec4 gold(1.000, 0.766, 0.336, 1); gua::math::vec4 copper(0.955, 0.637, 0.538, 1); gua::math::vec4 chromium(0.550, 0.556, 0.554, 1); gua::math::vec4 nickel(0.660, 0.609, 0.526, 1); gua::math::vec4 titanium(0.542, 0.497, 0.449, 1); gua::math::vec4 cobalt(0.662, 0.655, 0.634, 1); gua::math::vec4 platinum(0.672, 0.637, 0.585, 1); auto pbrMat(gua::MaterialShaderDatabase::instance()->lookup("gua_default_material")->make_new_material()); // pbrMat.set_uniform("Color", chromium); // pbrMat.set_uniform("Roughness", 0.2f); // pbrMat.set_uniform("Metalness", 1.0f); std::string directory("/opt/3d_models/Cerberus_by_Andrew_Maximov/Textures/"); pbrMat->set_uniform("ColorMap", directory + "Cerberus_A.tga"); pbrMat->set_uniform("MetalnessMap", directory + "Cerberus_M.tga"); pbrMat->set_uniform("RoughnessMap", directory + "Cerberus_R.tga"); pbrMat->set_uniform("NormalMap", directory + "Cerberus_N.negated_green.tga"); gua::TriMeshLoader loader; auto transform = graph.add_node<gua::node::TransformNode>("/", "transform"); auto cerberus(loader.create_geometry_from_file( "cerberus", "/opt/3d_models/Cerberus_by_Andrew_Maximov/Cerberus_LP.3ds", pbrMat, gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::NORMALIZE_SCALE)); graph.add_node("/transform", cerberus); cerberus->set_draw_bounding_box(true); cerberus->rotate(90, 0.f, 1.f, 0.f); cerberus->rotate(90, 0.f, 0.f, 1.f); auto pointLight = graph.add_node<gua::node::LightNode>("/", "pointLight"); pointLight->data.set_type(gua::node::LightNode::Type::POINT); pointLight->data.color = gua::utils::Color3f(1.0f, 1.0f, 1.0f); pointLight->data.brightness = 150.0f; // lm pointLight->scale(9.f); pointLight->translate(-2.f, 3.f, 5.f); auto screen = graph.add_node<gua::node::ScreenNode>("/", "screen"); screen->data.set_size(gua::math::vec2(1.92f, 1.08f)); screen->translate(0, 0, 1.0); // add mouse interaction gua::utils::Trackball trackball(0.01, 0.002, 0.2); // setup rendering pipeline and window // auto resolution = gua::math::vec2ui(1920, 1080); auto resolution = gua::math::vec2ui(2560, 1440); std::string skymaps_dir("/opt/guacamole/resources/skymaps/"); for(auto const& file : {std::string(directory + "Cerberus_A.tga"), std::string(directory + "Cerberus_M.tga"), std::string(directory + "Cerberus_R.tga"), std::string(directory + "Cerberus_N.negated_green.tga"), std::string(skymaps_dir + "skymap.jpg")}) { gua::TextureDatabase::instance()->load(file); } auto tiledPipe(std::make_shared<gua::PipelineDescription>()); tiledPipe->add_pass(std::make_shared<gua::TriMeshPassDescription>()); tiledPipe->add_pass(std::make_shared<gua::LightVisibilityPassDescription>()); tiledPipe->add_pass(std::make_shared<gua::ResolvePassDescription>()); auto camera = graph.add_node<gua::node::CameraNode>("/screen", "cam"); camera->translate(0, 0, 2.0); camera->config.set_resolution(resolution); camera->config.set_screen_path("/screen"); camera->config.set_scene_graph_name("main_scenegraph"); camera->config.set_output_window_name("main_window"); camera->config.set_enable_stereo(false); camera->set_pipeline_description(tiledPipe); auto window = std::make_shared<gua::GlfwWindow>(); gua::WindowDatabase::instance()->add("main_window", window); window->config.set_enable_vsync(false); window->config.set_size(resolution); window->config.set_resolution(resolution); window->config.set_stereo_mode(gua::StereoMode::MONO); window->on_resize.connect([&](gua::math::vec2ui const& new_size) { window->config.set_resolution(new_size); camera->config.set_resolution(new_size); screen->data.set_size(gua::math::vec2(0.001 * new_size.x, 0.001 * new_size.y)); }); window->on_move_cursor.connect([&](gua::math::vec2 const& pos) { trackball.motion(pos.x, pos.y); }); window->on_button_press.connect(std::bind(mouse_button, std::ref(trackball), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); window->open(); gua::Renderer renderer; // application loop gua::events::MainLoop loop; gua::events::Ticker ticker(loop, 1.0 / 500.0); size_t ctr{}; ticker.on_tick.connect([&]() { // apply trackball matrix to object gua::math::mat4 modelmatrix = scm::math::make_translation(gua::math::float_t(trackball.shiftx()), gua::math::float_t(trackball.shifty()), gua::math::float_t(trackball.distance())) * gua::math::mat4(trackball.rotation()); transform->set_transform(modelmatrix); if(ctr++ % 150 == 0) gua::Logger::LOG_WARNING << "Frame time: " << 1000.f / window->get_rendering_fps() << " ms, fps: " << window->get_rendering_fps() << std::endl; window->process_events(); if(window->should_close()) { renderer.stop(); window->close(); loop.stop(); } else { renderer.queue_draw({&graph}); } }); loop.start(); return 0; }
void Video3DUberShader::draw(RenderContext const& ctx, std::string const& ksfile_name, std::string const& material_name, scm::math::mat4 const& model_matrix, scm::math::mat4 const& normal_matrix, Frustum const& /*frustum*/, View const& view) const { if (!GeometryDatabase::instance()->is_supported(ksfile_name) || !MaterialDatabase::instance()->is_supported(material_name)) { gua::Logger::LOG_WARNING << "Video3DUberShader::draw(): No such video or material." << ksfile_name << ", " << material_name << std::endl; return; } auto video3d_ressource = std::static_pointer_cast<Video3DRessource>(GeometryDatabase::instance()->lookup(ksfile_name)); auto material = MaterialDatabase::instance()->lookup(material_name); if (!video3d_ressource || !material) { gua::Logger::LOG_WARNING << "Video3DUberShader::draw(): Invalid video or material." << std::endl; return; } // update stream data video3d_ressource->update_buffers(ctx); // make sure ressources are on the GPU upload_to(ctx); { // single texture only scm::gl::context_all_guard guard(ctx.render_context); ctx.render_context->set_rasterizer_state(no_bfc_rasterizer_state_); ctx.render_context->set_depth_stencil_state(depth_stencil_state_warp_pass_); // set uniforms ctx.render_context->bind_texture(video3d_ressource->depth_array(ctx), nearest_sampler_state_, 0); get_program(warp_pass)->get_program(ctx)->uniform_sampler("depth_video3d_texture", 0); get_program(warp_pass)->set_uniform(ctx, normal_matrix, "gua_normal_matrix"); get_program(warp_pass)->set_uniform(ctx, model_matrix, "gua_model_matrix"); get_program(warp_pass)->set_uniform(ctx, int(1), "bbxclip"); auto bbox(video3d_ressource->get_bounding_box()); get_program(warp_pass)->set_uniform(ctx, bbox.min, "bbx_min"); get_program(warp_pass)->set_uniform(ctx, bbox.max, "bbx_max"); // pre passes for (unsigned layer = 0; layer != video3d_ressource->number_of_cameras(); ++layer) { // configure fbo warp_result_fbo_->clear_attachments(); warp_result_fbo_->attach_depth_stencil_buffer(warp_depth_result_, 0, layer); warp_result_fbo_->attach_color_buffer(0, warp_color_result_, 0, layer); // bind and clear fbo ctx.render_context->set_frame_buffer(warp_result_fbo_); ctx.render_context->clear_depth_stencil_buffer(warp_result_fbo_); ctx.render_context->clear_color_buffer(warp_result_fbo_, 0, scm::math::vec4f(0.0f, 0.0f, 0.0f, 0.0f)); ctx.render_context->set_viewport(scm::gl::viewport(scm::math::vec2ui(0,0), warp_color_result_->dimensions())); // set uniforms get_program(warp_pass)->set_uniform(ctx, video3d_ressource->calibration_file(layer).getTexSizeInvD(), "tex_size_inv"); get_program(warp_pass)->set_uniform(ctx, int(layer), "layer"); if (material && video3d_ressource) { get_program(warp_pass)->set_uniform(ctx, video3d_ressource->calibration_file(layer).getImageDToEyeD(), "image_d_to_eye_d"); get_program(warp_pass)->set_uniform(ctx, video3d_ressource->calibration_file(layer).getEyeDToWorld(), "eye_d_to_world"); get_program(warp_pass)->set_uniform(ctx, video3d_ressource->calibration_file(layer).getEyeDToEyeRGB(), "eye_d_to_eye_rgb"); get_program(warp_pass)->set_uniform(ctx, video3d_ressource->calibration_file(layer).getEyeRGBToImageRGB(), "eye_rgb_to_image_rgb"); ctx.render_context->bind_texture(video3d_ressource->cv_xyz(ctx,layer), linear_sampler_state_, 1); get_program(warp_pass)->get_program(ctx)->uniform_sampler("cv_xyz", 1); ctx.render_context->bind_texture(video3d_ressource->cv_uv(ctx,layer), linear_sampler_state_, 2); get_program(warp_pass)->get_program(ctx)->uniform_sampler("cv_uv", 2); get_program(warp_pass)->set_uniform(ctx, video3d_ressource->calibration_file(layer).cv_min_d, "cv_min_d"); get_program(warp_pass)->set_uniform(ctx, video3d_ressource->calibration_file(layer).cv_max_d, "cv_max_d"); get_program(warp_pass)->use(ctx); { video3d_ressource->draw(ctx); } get_program(warp_pass)->unuse(ctx); } ctx.render_context->reset_framebuffer(); } } { // single texture only scm::gl::context_all_guard guard(ctx.render_context); ctx.render_context->set_depth_stencil_state(depth_stencil_state_warp_pass_); // second pass get_program(blend_pass)->use(ctx); { if (material && video3d_ressource) { set_uniform(ctx, material->get_id(), "gua_material_id"); set_uniform(ctx, normal_matrix, "gua_normal_matrix"); set_uniform(ctx, model_matrix, "gua_model_matrix"); // needs to be multiplied with scene scaling set_uniform(ctx, 0.075f, "epsilon"); set_uniform(ctx, int(video3d_ressource->number_of_cameras()), "numlayers"); get_program(blend_pass)->set_uniform(ctx, int(material_name == default_video_material_name()), "using_default_video_material"); get_program(blend_pass)->set_uniform(ctx, int(video3d_ressource->do_overwrite_normal()), "overwrite_normal"); get_program(blend_pass)->set_uniform(ctx, video3d_ressource->get_overwrite_normal(), "o_normal"); ctx.render_context->bind_texture(warp_color_result_, nearest_sampler_state_, 0); get_program(blend_pass)->get_program(ctx)->uniform_sampler("quality_texture", 0); ctx.render_context->bind_texture(warp_depth_result_, nearest_sampler_state_, 1); get_program(blend_pass)->get_program(ctx)->uniform_sampler("depth_texture", 1); ctx.render_context->bind_texture(video3d_ressource->color_array(ctx), linear_sampler_state_, 2); get_program(blend_pass)->get_program(ctx)->uniform_sampler("video_color_texture", 2); fullscreen_quad_->draw(ctx.render_context); } } get_program(blend_pass)->unuse(ctx); } }
int main(int argc, char** argv) { // initialize guacamole gua::init(argc, argv); auto load_mat = [](std::string const& file){ gua::MaterialShaderDescription desc; desc.load_from_file(file); auto shader(std::make_shared<gua::MaterialShader>(file, std::make_shared<gua::MaterialShaderDescription>(desc))); gua::MaterialShaderDatabase::instance()->add(shader); return shader->make_new_material(); }; // setup scene gua::SceneGraph graph("main_scenegraph"); gua::TriMeshLoader loader; auto transform = graph.add_node<gua::node::TransformNode>("/", "transform"); // load material and create monkey geometry auto projective_material(load_mat("data/materials/Projective_Texture_Material.gmd")); projective_material->set_uniform("projective_texture", std::string("data/textures/smiley.jpg")); auto monkey(loader.create_geometry_from_file("monkey", "data/objects/monkey.obj", projective_material, gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::NORMALIZE_SCALE)); monkey->scale(3); monkey->translate(0.0, 0.0, -1.0); graph.add_node("/transform", monkey); auto light2 = graph.add_node<gua::node::LightNode>("/", "light2"); light2->data.set_type(gua::node::LightNode::Type::POINT); light2->data.brightness = 150.0f; light2->scale(12.f); light2->translate(-3.f, 5.f, 5.f); auto screen = graph.add_node<gua::node::ScreenNode>("/", "screen"); screen->data.set_size(gua::math::vec2(1.92f, 1.08f)); screen->translate(0, 0, 1.0); // add mouse interaction gua::utils::Trackball trackball(0.01, 0.002, 0.2); // setup rendering pipeline and window auto resolution = gua::math::vec2ui(1920, 1080); auto camera = graph.add_node<gua::node::CameraNode>("/screen", "cam"); camera->translate(0, 0, 2.0); camera->config.set_resolution(resolution); camera->config.set_screen_path("/screen"); camera->config.set_scene_graph_name("main_scenegraph"); camera->config.set_output_window_name("main_window"); camera->config.set_enable_stereo(false); camera->get_pipeline_description()->add_pass(std::make_shared<gua::DebugViewPassDescription>()); // projector transform node, screen and transform node auto projector_transform = graph.add_node<gua::node::TransformNode>("/", "projector_transform"); projector_transform->translate(0.7, 0.0, 0.7); projector_transform->rotate(45.0, 0.0, 1.0, 0.0); graph.add_node("/", projector_transform); auto projector_screen = graph.add_node<gua::node::ScreenNode>("/projector_transform", "projector_screen"); projector_screen->data.set_size(gua::math::vec2(0.5f, 0.5f)); projector_screen->translate(0.0, 0.0, -1.0); graph.add_node("/projector_transform", projector_screen); auto projector_geometry(loader.create_geometry_from_file("projector_geometry", "data/objects/projector.obj", gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::LOAD_MATERIALS)); projector_geometry->scale(0.1); graph.add_node("/projector_transform", projector_geometry); auto window = std::make_shared<gua::GlfwWindow>(); gua::WindowDatabase::instance()->add("main_window", window); window->config.set_enable_vsync(false); window->config.set_size(resolution); window->config.set_resolution(resolution); window->config.set_stereo_mode(gua::StereoMode::MONO); window->on_resize.connect([&](gua::math::vec2ui const& new_size) { window->config.set_resolution(new_size); camera->config.set_resolution(new_size); screen->data.set_size(gua::math::vec2(0.001 * new_size.x, 0.001 * new_size.y)); }); window->on_move_cursor.connect([&](gua::math::vec2 const& pos) { trackball.motion(pos.x, pos.y); }); window->on_button_press.connect(std::bind(mouse_button, std::ref(trackball), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); window->open(); gua::Renderer renderer; // application loop gua::events::MainLoop loop; gua::events::Ticker ticker(loop, 1.0/500.0); ticker.on_tick.connect([&]() { // apply trackball matrix to object gua::math::mat4 modelmatrix = scm::math::make_translation(gua::math::float_t(trackball.shiftx()), gua::math::float_t(trackball.shifty()), gua::math::float_t(trackball.distance())) * gua::math::mat4(trackball.rotation()); projector_transform->set_transform(modelmatrix); // use the guacamole frustum to calculate a view mat and projection mat for the projection auto projection_frustum = gua::Frustum::perspective(projector_transform->get_world_transform(), projector_screen->get_scaled_world_transform(), 0.1f, 1000.0f); auto projection_mat = projection_frustum.get_projection(); auto view_mat = projection_frustum.get_view(); // set these matrices as uniforms for the projection material projective_material->set_uniform("projective_texture_matrix", gua::math::mat4f(projection_mat * view_mat)); projective_material->set_uniform("view_texture_matrix", gua::math::mat4f(view_mat)); window->process_events(); if (window->should_close()) { renderer.stop(); window->close(); loop.stop(); } else { renderer.queue_draw({&graph}); } }); loop.start(); return 0; }