Closed alior101 closed 5 years ago
receive timer interrupt similar to key press events ?
you can schedule functions calls using the "Timer" class implemented in "easy3d/util/timer.h". Check the examples here: https://github.com/LiangliangNan/Timer
update the model in RT and update the GPU to enable simple animations ?
For animation, you can call drawable->update_vertex_buffer(...);
every time when your geometry changes, followed by the viewer's update()
. For the speed, use the timer functions to schedule the frequency for updating the GPU.
Hi! I followed your advice and set up a timer callback which works fine. I tried to change the color of a simple point cloud (that I created in the main function before calling viewer.run() ) inside that callback. Unfortunatly, as soon as I call update_color_buffer, all points turns green .. Any idea what I'm doing wrong ? (sorry for the lack of code markdown - I replied mistakenly by email...) Thanks
` bool ViewerImGui::callback_event_timer() { printf("booya!\n"); easy3d::Model* model = this->current_model(); if (model) { auto drawable = model->points_drawable("lior"); drawable->set_point_size(25.0f);
easy3d::PointCloud cloud = dynamic_cast<PointCloud>(model);
PointCloud::VertexProperty
for (auto v : cloud->vertices()) // iterate over all vertices { colors[v] = random_color(); // assign a random color to point 'v' } drawable->update_color_buffer(colors.vector());
update(); } return true; } `
call drawable->set_per_vertex_color(true); // vertices have different colors
before update();
also, all OpenGL/GPU related code must be called after the creation of the viewer (otherwise OpenGL context doesn't exist).
I Added the drawable->set_per_vertex_color(true); before update() but got the sample all points turning green results. I'm using tutorial_302_viewer_imgui as a basis and the viewer is created and init the first two lines of main() before all opengl/gpu code.. Any other suggestion ?
can you post your code here?
vec3 random_color() {
float r = rand() % 255 / 255.0f; // in the range [0, 1]
float g = rand() % 255 / 255.0f; // in the range [0, 1]
float b = rand() % 255 / 255.0f; // in the range [0, 1]
return vec3(r, g, b);
}
int main(int argc, char** argv) {
try {
ViewerImGui viewer("Easy3D ImGui Viewer", 80, 3, 2);
viewer.resize(800, 600);
Timer t;
#if 1
PointCloud* cloud = new PointCloud;
for (float i=-5; i<5; ++i) {
for (float j = -5; j < 5; ++j)
{
cloud->add_vertex(vec3(i, j, 0));// z = 0: all points are on XY plane
cloud->add_vertex(vec3(i, j, 4));// z = 0: all points are on XY plane
}
}
auto vertices = cloud->get_vertex_property<vec3>("v:point");
// All the XYZ coordinates
auto colors = cloud->add_vertex_property<vec3>("v:color");
const auto& points = vertices.vector();
for (auto v : cloud->vertices()) // iterate over all vertices
colors[v] = random_color(); // assign a random color to point 'v'
PointsDrawable* points_drawable = cloud->add_points_drawable("lior"); // cloud->points_drawable("vertices");
points_drawable->set_point_size(6.0f);
points_drawable->update_vertex_buffer(points);
points_drawable->update_color_buffer(colors.vector());
points_drawable->set_per_vertex_color(true);
points_drawable->set_visible(true);
#endif
// add the model to the viewer
viewer.add_model(cloud);
viewer.run();
} catch (const std::runtime_error &e) {
std::string error_msg = std::string("Caught a fatal error: ") + std::string(e.what());
std::cerr << error_msg << std::endl;
return EXIT_FAILURE;
}
and
void ViewerImGui::init() {
Viewer::init();
if (!context_) {
// Setup ImGui binding
IMGUI_CHECKVERSION();
context_ = ImGui::CreateContext();
const char* glsl_version = "#version 150";
ImGui_ImplGlfw_InitForOpenGL(window_, false);
ImGui_ImplOpenGL3_Init(glsl_version);
ImGuiIO& io = ImGui::GetIO();
io.WantCaptureKeyboard = true;
io.WantTextInput = true;
io.IniFilename = nullptr;
ImGui::StyleColorsDark();
ImGuiStyle& style = ImGui::GetStyle();
style.FrameRounding = 5.0f;
// load font
reload_font();
t.set_interval(1000, &ViewerImGui::callback_event_timer, this);
}
}
bool ViewerImGui::callback_event_timer() {
printf("booya!\n");
easy3d::Model* model = this->current_model();
if (model)
{
auto drawable = model->points_drawable("lior");
drawable->set_point_size(25.0f);
//rawable->set_default_color(random_color());
easy3d::PointCloud* cloud = dynamic_cast<PointCloud*>(model);
PointCloud::VertexProperty<vec3> colors = cloud->get_vertex_property<vec3>("v:color");
//std::vector<unsigned int> indices;
for (auto v : cloud->vertices()) // iterate over all vertices
{
colors[v] = random_color(); // assign a random color to point 'v'
}
drawable->update_color_buffer(colors.vector());
drawable->set_per_vertex_color(true);
update();
std::cout << "point cloud has " << cloud->n_vertices() << " points" << std::endl;
}
return true;
}
all other code is unmodified
return EXIT_SUCCESS;
}
It seems your random number generator is not initialized. See here for an example: http://www.cplusplus.com/reference/cstdlib/rand/ http://www.cplusplus.com/reference/cstdlib/rand/ -- Liangliang
On Tue, Jun 11, 2019 at 2:51 PM Lior Assouline notifications@github.com wrote:
vec3 random_color() { float r = rand() % 255 / 255.0f; // in the range [0, 1] float g = rand() % 255 / 255.0f; // in the range [0, 1] float b = rand() % 255 / 255.0f; // in the range [0, 1] return vec3(r, g, b); }
int main(int argc, char** argv) { try {
ViewerImGui viewer("Easy3D ImGui Viewer", 80, 3, 2); viewer.resize(800, 600); Timer t; #if 1 PointCloud* cloud = new PointCloud; for (float i=-5; i<5; ++i) { for (float j = -5; j < 5; ++j) { cloud->add_vertex(vec3(i, j, 0));// z = 0: all points are on XY plane cloud->add_vertex(vec3(i, j, 4));// z = 0: all points are on XY plane } } auto vertices = cloud->get_vertex_property<vec3>("v:point"); // All the XYZ coordinates auto colors = cloud->add_vertex_property<vec3>("v:color"); const auto& points = vertices.vector(); for (auto v : cloud->vertices()) // iterate over all vertices colors[v] = random_color(); // assign a random color to point 'v' PointsDrawable* points_drawable = cloud->add_points_drawable("lior"); // cloud->points_drawable("vertices"); points_drawable->set_point_size(6.0f); points_drawable->update_vertex_buffer(points); points_drawable->update_color_buffer(colors.vector()); points_drawable->set_per_vertex_color(true); points_drawable->set_visible(true); #endif // add the model to the viewer viewer.add_model(cloud); viewer.run(); } catch (const std::runtime_error &e) { std::string error_msg = std::string("Caught a fatal error: ") + std::string(e.what()); std::cerr << error_msg << std::endl; return EXIT_FAILURE; }
and
void ViewerImGui::init() { Viewer::init();
if (!context_) { // Setup ImGui binding IMGUI_CHECKVERSION(); context_ = ImGui::CreateContext(); const char* glsl_version = "#version 150"; ImGui_ImplGlfw_InitForOpenGL(window_, false); ImGui_ImplOpenGL3_Init(glsl_version); ImGuiIO& io = ImGui::GetIO(); io.WantCaptureKeyboard = true; io.WantTextInput = true; io.IniFilename = nullptr; ImGui::StyleColorsDark(); ImGuiStyle& style = ImGui::GetStyle(); style.FrameRounding = 5.0f; // load font reload_font(); t.set_interval(1000, &ViewerImGui::callback_event_timer, this); }
}
bool ViewerImGui::callback_event_timer() { printf("booya!\n");
easy3d::Model* model = this->current_model(); if (model) { auto drawable = model->points_drawable("lior"); drawable->set_point_size(25.0f); //rawable->set_default_color(random_color()); easy3d::PointCloud* cloud = dynamic_cast<PointCloud*>(model); PointCloud::VertexProperty<vec3> colors = cloud->get_vertex_property<vec3>("v:color"); //std::vector<unsigned int> indices; for (auto v : cloud->vertices()) // iterate over all vertices { colors[v] = random_color(); // assign a random color to point 'v' } drawable->update_color_buffer(colors.vector()); drawable->set_per_vertex_color(true); update(); std::cout << "point cloud has " << cloud->n_vertices() << " points" << std::endl; } return true; }
all other code is unmodified
return EXIT_SUCCESS;
}
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/LiangliangNan/Easy3D/issues/19?email_source=notifications&email_token=ADWOVCA3X26YNJU64UKCRNDPZ6NW3A5CNFSM4HVZR3SKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODXNAHHQ#issuecomment-500827038, or mute the thread https://github.com/notifications/unsubscribe-auth/ADWOVCBYB4EULYIKVZN542TPZ6NW3ANCNFSM4HVZR3SA .
Hi Liangliang When I'm running random_color() in the main, it is working (Im seeing random colored point cloud). In addition, when I'm running under debugger I see the colors[v] = random_color(); line in the timer event assigning really random numbers into colors vector (I saw random values for r,g,b). I even checked
int status = vao_->create_array_buffer(color_buffer_, ShaderProgram::COLOR, colors, count * sizeof(float) * dim, GL_FLOAT, dim);
in drawable.cpp is returning 0 (no error) but still I get green dots ..
It seems that the color buffer update is causing the green vertex to show regardless of what is inside the color buffer (I put constants in that buffer and it didn't change a thing ..)
Please do a quick test: load the bunny.bin (in $easy3d_root$/data/ directory) model and let me know if it has per point color or has a uniform color? -- Liangliang
On Tue, Jun 11, 2019 at 3:18 PM Lior Assouline notifications@github.com wrote:
It seems that the color buffer update is causing the green vertex to show regardless of what is inside the color buffer (I put constants in that buffer and it didn't change a thing ..)
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/LiangliangNan/Easy3D/issues/19?email_source=notifications&email_token=ADWOVCELD5I3X4IE5WMLB6DPZ6QZVA5CNFSM4HVZR3SKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODXNCTLA#issuecomment-500836780, or mute the thread https://github.com/notifications/unsubscribe-auth/ADWOVCCF4HMPXVHWPIRESMTPZ6QZVANCNFSM4HVZR3SA .
yes, it has per point color.. But in my example also it had a per point color when I initially assigned colors to the points... It's only when updating the color that the color went away ..
Hi Liangliang, Here is a quick way to recreate the issue I'm seeing: Please take tutorial 304_realcamera and add the below lines in main.cpp
RealCamera viewer("Tutorial_305_RealCamera",
bundler_file,
cloud_file);
viewer.resize(960, 800);
// issue recreation code area
easy3d::Model* model = viewer.current_model();
if (model)
{
easy3d::PointCloud* cloud = dynamic_cast<easy3d::PointCloud*>(model);
if (cloud)
{
easy3d::PointCloud::VertexProperty<easy3d::vec3> colors = cloud->get_vertex_property<easy3d::vec3>("v:color");
for (auto v : cloud->vertices()) // iterate over all vertices
{
colors[v] = easy3d::vec3(1, 0, 0); // assign a fix color to point 'v'
}
viewer.update();
}
}
/// end of issue recreation code area
// Run the viewer
viewer.run();
I would expect to see the fountain in red only - but the color is unchanged ... Am I missing something ?
in the RealCamera example, you need to add easy3d::PointsDrawable* drawable = cloud->points_drawable("vertices"); drawable->update_color_buffer(colors.vector()); drawable->set_per_vertex_color(true); before viewer.update(); -- Liangliang
On Tue, Jun 11, 2019 at 5:11 PM Lior Assouline notifications@github.com wrote:
Hi Liangliang, Here is a quick way to recreate the issue I'm seeing: Please take tutorial 304_realcamera and add the below lines in main.cpp
RealCamera viewer("Tutorial_305_RealCamera", bundler_file, cloud_file);
viewer.resize(960, 800); // issue recreation code area easy3d::Model* model = viewer.current_model(); if (model) { easy3d::PointCloud* cloud = dynamic_cast<easy3d::PointCloud*>(model); if (cloud) { easy3d::PointCloud::VertexProperty<easy3d::vec3> colors = cloud->get_vertex_property<easy3d::vec3>("v:color"); for (auto v : cloud->vertices()) // iterate over all vertices { colors[v] = easy3d::vec3(1, 0, 0); // assign a fix color to point 'v' } viewer.update(); } }
/// end of issue recreation code area
// Run the viewer viewer.run();
I would expect to see the fountain in red only - but the color is unchanged ... Am I missing something ?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/LiangliangNan/Easy3D/issues/19?email_source=notifications&email_token=ADWOVCE6ASR2NQYXASMPU5DPZ66CFA5CNFSM4HVZR3SKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODXNOXVA#issuecomment-500886484, or mute the thread https://github.com/notifications/unsubscribe-auth/ADWOVCGV5T2GKO75C2TGSRTPZ66CFANCNFSM4HVZR3SA .
I just updated my post.
well, it works with the RealCamera example! but not with viewer_imgui and the difference is that in real camera example the initial point cloud is taken from a file with all properties whereas in my code I just init vertices and colors ... Could this be the reason ? I used your code above in the timer event but still no success - Any chance you can use my modified totorial 302 and recreate the issue on your side ? It's viewer_imgui.h (for adding the timer declaration) viewer_imgui.cpp (for the callback actual code - just changing the colors of the cloud point) main.cpp (for initializing a simple cloud point not from a file - just from a simple loop)
Again, thanks for the effort you're putting to help me - it's greatly appreciated :) Thanks Lior Tutorial_302_Viewer_imgui.zip
Got the issue and had a solution.
The issue: calling the OpenGL functions in another thread (Timer is implemented this way) is not supported by GLFW. More info here: http://discourse.glfw.org/t/multithreading-glfw/573
A workaround: the callback function notifies the main thread (here the viewer thread) to update the GPU data. Here is the modified code in which the point cloud changes color every second. Tutorial_302_Viewer_imgui.zip
Thanks! works perfect!
Hi, Is there a way to
Thanks