From 2cba748bf3b4ae225557077e4c0b7b709cea3c9d Mon Sep 17 00:00:00 2001 From: Kasper Peeters Date: Wed, 13 Nov 2024 18:47:01 +0000 Subject: [PATCH] Add dynamic updates and various temporary testing routines for 3d views. --- core/DataCell.cc | 4 ++ examples/gltf.cnb | 81 ++++++++++++++++++++++++++++ examples/test.glb | Bin 0 -> 3112 bytes frontend/gtkmm/GraphicsView.cc | 89 ++++++++++++++++++++++++++----- frontend/gtkmm/GraphicsView.hh | 47 ++++++++++------ frontend/gtkmm/NotebookWindow.cc | 19 +++++-- frontend/gtkmm/NotebookWindow.hh | 6 ++- 7 files changed, 211 insertions(+), 35 deletions(-) create mode 100644 examples/gltf.cnb create mode 100644 examples/test.glb diff --git a/core/DataCell.cc b/core/DataCell.cc index 97abd006d2..c6dcb37b14 100644 --- a/core/DataCell.cc +++ b/core/DataCell.cc @@ -522,6 +522,10 @@ void cadabra::JSON_in_recurse(DTree& doc, DTree::iterator loc, const nlohmann::j DataCell dc(id, cadabra::DataCell::CellType::image_svg, textbuf.get(), hide); last=doc.append_child(loc, dc); } + else if(cell_type=="graphics_view") { + DataCell dc(id, cadabra::DataCell::CellType::graphics_view, textbuf.get(), hide); + last=doc.append_child(loc, dc); + } else { std::cerr << "cadabra-client: found unknown cell type '"+cell_type+"', ignoring" << std::endl; continue; diff --git a/examples/gltf.cnb b/examples/gltf.cnb new file mode 100644 index 0000000000..55c151a263 --- /dev/null +++ b/examples/gltf.cnb @@ -0,0 +1,81 @@ +{ + "cell_id": 16461605748738409030, + "cells": [ + { + "cell_id": 10635152356046299518, + "cell_origin": "client", + "cell_type": "input", + "source": "a=server.send(\"hello\", \"graphics_view\", 0, 123, False)" + }, + { + "cell_id": 11350501809507979634, + "cell_origin": "client", + "cell_type": "input", + "source": "from pathlib import Path\ngltf = Path('test.glb').read_bytes()" + }, + { + "cell_id": 13867252481123575504, + "cell_origin": "client", + "cell_type": "input", + "source": "gltf64=base64.b64encode(gltf)" + }, + { + "cell_id": 2928652340647885648, + "cell_origin": "client", + "cell_type": "input", + "cells": [ + { + "cell_id": 123, + "cell_origin": "server", + "cell_type": "graphics_view", + "source": "Z2xURgIAAAAoDAAAOAgAAEpTT057ImFzc2V0Ijp7ImdlbmVyYXRvciI6Iktocm9ub3MgZ2xURiBCbGVuZGVyIEkvTyB2NC4xLjYzIiwidmVyc2lvbiI6IjIuMCJ9LCJleHRlbnNpb25zVXNlZCI6WyJLSFJfbWF0ZXJpYWxzX3NoZWVuIl0sInNjZW5lIjowLCJzY2VuZXMiOlt7Im5hbWUiOiJTY2VuZSIsIm5vZGVzIjpbMCwxXX1dLCJub2RlcyI6W3sibWVzaCI6MCwibmFtZSI6IkN1YmUifSx7Im1lc2giOjEsIm5hbWUiOiJQbGFuZSIsInJvdGF0aW9uIjpbMCwwLC0wLjcwNTk0NDQxODkwNzE2NTUsMC43MDgyNjcyMTE5MTQwNjI1XSwic2NhbGUiOlsyLjU3Mjk3MzcyODE3OTkzMTYsMi41NzI5NzM3MjgxNzk5MzE2LDIuNTcyOTczNzI4MTc5OTMxNl0sInRyYW5zbGF0aW9uIjpbLTEuMDc0NTU1Mzk3MDMzNjkxNCwtMC44MDY2MzAxMzQ1ODI1MTk1LC0wLjYwNDcxNDAzNTk4Nzg1NF19XSwibWF0ZXJpYWxzIjpbeyJkb3VibGVTaWRlZCI6dHJ1ZSwiZXh0ZW5zaW9ucyI6eyJLSFJfbWF0ZXJpYWxzX3NoZWVuIjp7InNoZWVuQ29sb3JGYWN0b3IiOlsxLjAsMS4wLDEuMF0sInNoZWVuUm91Z2huZXNzRmFjdG9yIjowLjYzMDQzNDc1MTUxMDYyMDF9fSwibmFtZSI6Ik1hdGVyaWFsIiwicGJyTWV0YWxsaWNSb3VnaG5lc3MiOnsiYmFzZUNvbG9yRmFjdG9yIjpbMC44MDAwMDAwMTE5MjA5MjksMC44MDAwMDAwMTE5MjA5MjksMC44MDAwMDAwMTE5MjA5MjksMC40MjkzNDc4MTMxMjk0MjUwNV0sIm1ldGFsbGljRmFjdG9yIjowLCJyb3VnaG5lc3NGYWN0b3IiOjAuNTIxNzM5MTI1MjUxNzd9fV0sIm1lc2hlcyI6W3sibmFtZSI6IkN1YmUiLCJwcmltaXRpdmVzIjpbeyJhdHRyaWJ1dGVzIjp7IlBPU0lUSU9OIjowLCJOT1JNQUwiOjEsIlRFWENPT1JEXzAiOjJ9LCJpbmRpY2VzIjozLCJtYXRlcmlhbCI6MH1dfSx7Im5hbWUiOiJQbGFuZSIsInByaW1pdGl2ZXMiOlt7ImF0dHJpYnV0ZXMiOnsiUE9TSVRJT04iOjQsIk5PUk1BTCI6NSwiVEVYQ09PUkRfMCI6Nn0sImluZGljZXMiOjd9XX1dLCJhY2Nlc3NvcnMiOlt7ImJ1ZmZlclZpZXciOjAsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoyNCwibWF4IjpbMSwxLDFdLCJtaW4iOlstMSwtMSwtMV0sInR5cGUiOiJWRUMzIn0seyJidWZmZXJWaWV3IjoxLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MjQsInR5cGUiOiJWRUMzIn0seyJidWZmZXJWaWV3IjoyLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MjQsInR5cGUiOiJWRUMyIn0seyJidWZmZXJWaWV3IjozLCJjb21wb25lbnRUeXBlIjo1MTIzLCJjb3VudCI6MzYsInR5cGUiOiJTQ0FMQVIifSx7ImJ1ZmZlclZpZXciOjQsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50Ijo0LCJtYXgiOlsxLDAsMV0sIm1pbiI6Wy0xLDAsLTFdLCJ0eXBlIjoiVkVDMyJ9LHsiYnVmZmVyVmlldyI6NSwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjQsInR5cGUiOiJWRUMzIn0seyJidWZmZXJWaWV3Ijo2LCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6NCwidHlwZSI6IlZFQzIifSx7ImJ1ZmZlclZpZXciOjcsImNvbXBvbmVudFR5cGUiOjUxMjMsImNvdW50Ijo2LCJ0eXBlIjoiU0NBTEFSIn1dLCJidWZmZXJWaWV3cyI6W3siYnVmZmVyIjowLCJieXRlTGVuZ3RoIjoyODgsImJ5dGVPZmZzZXQiOjAsInRhcmdldCI6MzQ5NjJ9LHsiYnVmZmVyIjowLCJieXRlTGVuZ3RoIjoyODgsImJ5dGVPZmZzZXQiOjI4OCwidGFyZ2V0IjozNDk2Mn0seyJidWZmZXIiOjAsImJ5dGVMZW5ndGgiOjE5MiwiYnl0ZU9mZnNldCI6NTc2LCJ0YXJnZXQiOjM0OTYyfSx7ImJ1ZmZlciI6MCwiYnl0ZUxlbmd0aCI6NzIsImJ5dGVPZmZzZXQiOjc2OCwidGFyZ2V0IjozNDk2M30seyJidWZmZXIiOjAsImJ5dGVMZW5ndGgiOjQ4LCJieXRlT2Zmc2V0Ijo4NDAsInRhcmdldCI6MzQ5NjJ9LHsiYnVmZmVyIjowLCJieXRlTGVuZ3RoIjo0OCwiYnl0ZU9mZnNldCI6ODg4LCJ0YXJnZXQiOjM0OTYyfSx7ImJ1ZmZlciI6MCwiYnl0ZUxlbmd0aCI6MzIsImJ5dGVPZmZzZXQiOjkzNiwidGFyZ2V0IjozNDk2Mn0seyJidWZmZXIiOjAsImJ5dGVMZW5ndGgiOjEyLCJieXRlT2Zmc2V0Ijo5NjgsInRhcmdldCI6MzQ5NjN9XSwiYnVmZmVycyI6W3siYnl0ZUxlbmd0aCI6OTgwfV191AMAAEJJTgAAAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAAAAAAAAAAAAgL8AAAAAAACAPwAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAgL8AAAAAAACAvwAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAAAAAACAvwAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAgL8AAAAAAACAPwAAAAAAAIC/AAAAAAAAAAAAAAAAAAAAAAAAgL8AAAAAAACAvwAAAAAAAIC/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAAAAAAIC/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAAAAAACAvwAAAAAAAIC/AAAAAAAAAAAAACA/AAAAPwAAID8AAAA/AAAgPwAAAD8AAMA+AAAAPwAAwD4AAAA/AADAPgAAAD8AACA/AACAPgAAID8AAIA+AAAgPwAAgD4AAMA+AACAPgAAwD4AAIA+AADAPgAAgD4AACA/AABAPwAAYD8AAAA/AAAgPwAAQD8AAMA+AABAPwAAAD4AAAA/AADAPgAAQD8AACA/AAAAAAAAYD8AAIA+AAAgPwAAgD8AAMA+AAAAAAAAAD4AAIA+AADAPgAAgD8BAA0AEwABABMABwAJAAYAEgAJABIAFQAXABQADgAXAA4AEQAQAAQACgAQAAoAFgAFAAIACAAFAAgACwAPAAwAAAAPAAAAAwAAAIC/AAAAAAAAgD8AAIA/AAAAAAAAgD8AAIC/AAAAAAAAgL8AAIA/AAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAgD8AAIA/AAAAAAAAAAAAAIA/AAAAAAAAAQADAAAAAwACAA==" + } + ], + "source": "a=server.send(gltf64, \"graphics_view\", 0, 123, False)" + }, + { + "cell_id": 15466627643580859060, + "cell_origin": "client", + "cell_type": "input", + "cells": [ + { + "cell_id": 13223587008277543184, + "cell_origin": "server", + "cell_type": "latex_view", + "cells": [ + { + "cell_id": 10140132123478261128, + "cell_origin": "server", + "cell_type": "input_form", + "source": "A_{m n}" + } + ], + "source": "\\begin{dmath*}{}A_{m n}\\end{dmath*}" + } + ], + "source": "ex:=A_{m n};" + }, + { + "cell_id": 528262603261906739, + "cell_origin": "client", + "cell_type": "input", + "cells": [ + { + "cell_id": 2406524992584598329, + "cell_origin": "server", + "cell_type": "error", + "source": "{\\color{red}{\\begin{verbatim}NameError: name 'GraphicsView' is not defined\n\nAt:\n cadabra2_defaults.py(323): display\n Notebook Cell (Line 1): _ = print(\"hi\"); display(_)\n\\end{verbatim}}}" + } + ], + "source": "print(\"hi\");" + }, + { + "cell_id": 7971209662709436916, + "cell_origin": "client", + "cell_type": "input", + "source": "" + } + ], + "description": "Cadabra JSON notebook format", + "version": 1.0 +} diff --git a/examples/test.glb b/examples/test.glb new file mode 100644 index 0000000000000000000000000000000000000000..0b7e756030806990eba6be266dda62aa3816ee6f GIT binary patch literal 3112 zcmb7GTXWh*6kaF2xM`a5u3S>N$%Rgus|!ug>ndpYI$k45PD`4+tT@d_#!0Psm^0_UVKMStfJZn9!k& zWg6s3N*namb(+LURvUsz?Rg~QflO;hzqV_)cAeE7iyHJ+rdgQ8pv>zgof=fW&t;6P z>`f*Iv~f;f{n@!31-VSaAj&SYYbj%TVbH7(k!Zs#b{VKnXdH}yN4rX9&^Q@L6qp9P zn1YQyPv}Ty*UGrCXpMUk!fOEo-MOpRQ2=2KnkIRWt4zV0X&jh!*A%{O+syM#mpMWh z$nv=3a>jgSn+_K$%^-r5&Usz9+;=UPd(8EHi#f(lEO3#hL7YW8`T?t(t}TSHeAl!r z2SQ;sp6NK2$t+uVTrgiC&oONm60wBuxt_2U1Pde;UV~)Zi)1$(Ak=v}mgNRuJ2!z3 zY}JKU5+&)&ps$*J4rv+1!m_bVon$<`j%Ait)<`lRSFfPK?T zPh=iMQP^Mjz-)R!CRd|k;pzjJbJOQObYT~c&3#D2V;1AS&4r1r8WkZI*<#n%DiEBx zme05Vm|b^@V}-+{=4>&5YMh{sG#rI_cv}dAJWs>kILG6JzHWDq&W_rrY79@?os+|3 z+JM13d+~Rx-R}HxY0?GW~hH)sR&;Sls7*n>qg!bG{ZG&|Z(On5s4l$}FOHTZhMooiztg z{JMiBI3;ZGdMaT9w+o)P)dpR=$M-gCmBig`gUpuJ>%h31VlRPN#|3IxwzWJ&YJhql za(OJ{VGj2(_dL)AM*HeYeV@SXo(Jg=zgjHYci?q^OF#|a{kF>4uGVmStVR|t7P4b( zw_@x%P)FI=+LE|ksoAqXq3ShbM6eur8)Q}`ZC?%bjy1EY@p{dR#urU5b=vpv0{ibF zA`|_D?%Fp?KJMCUA1L3n*F2=#_FBG;Hj8|;A3Rt0`iykL9w1U5 zl;H>QD%1I?;AtIA3*8l+ioN!?QD>W-B p0xy%A9rTZ}a4q&9i#^ZTTke{g>r?DvO7Z-~Zp+55oWe literal 0 HcmV?d00001 diff --git a/frontend/gtkmm/GraphicsView.cc b/frontend/gtkmm/GraphicsView.cc index bdb8fcd028..23e1bbb45c 100644 --- a/frontend/gtkmm/GraphicsView.cc +++ b/frontend/gtkmm/GraphicsView.cc @@ -12,6 +12,8 @@ #include #include #include +#include +#include using namespace cadabra; @@ -23,8 +25,8 @@ static constexpr uint8_t RESOURCES_BAKEDCOLOR_DATA[] = { #include "bakedcolor.inc" }; -GraphicsView::GraphicsView(filament::Engine *engine_) - : glview(engine_), sizing(false), prev_x(0), prev_y(0), height_at_press(0), width_at_press(0) +GraphicsView::GraphicsView(filament::Engine *engine_, filament::Renderer *renderer_) + : glview(engine_, renderer_), sizing(false), prev_x(0), prev_y(0), height_at_press(0), width_at_press(0) { add(vbox); vbox.add(glview); @@ -35,7 +37,7 @@ GraphicsView::GraphicsView(filament::Engine *engine_) | Gdk::POINTER_MOTION_MASK); set_name("GraphicsView"); // to be able to style it with CSS - set_size_request( 400, 400 ); + set_size_request( 400, 600 ); show_all(); } @@ -44,8 +46,8 @@ void GraphicsView::set_gltf(const std::string& str) glview.set_gltf(str); } -GraphicsView::GLView::GLView(filament::Engine *engine_) - : engine(engine_), zoom(1.0) +GraphicsView::GLView::GLView(filament::Engine *engine_, filament::Renderer *renderer_) + : engine(engine_), renderer(renderer_), need_setup_on_first_render(true), zoom(1.0) { } @@ -71,6 +73,11 @@ void GraphicsView::GLView::set_gltf(const std::string& str) gltf_str = Glib::Base64::decode(str); } +GraphicsView::GLView::~GLView() + { + std::cerr << "GLView going away, still implement! ****" << std::endl; + } + void GraphicsView::GLView::first_render() { // Setup swapchain. @@ -79,10 +86,16 @@ void GraphicsView::GLView::first_render() throw std::logic_error("GraphicsView::GLView::first_render: not inside an X11 window?"); Window x11_window_id = gdk_x11_window_get_xid(gdk_window->gobj()); + + if(engine==0) + throw std::logic_error("GraphicsView: engine not initialised."); swapChain = engine->createSwapChain((void*)x11_window_id, filament::SwapChain::CONFIG_TRANSPARENT); + if(swapChain==0) + throw std::logic_error("GraphicsView: cannot create swapchain."); + // Setup buffers. vb = filament::VertexBuffer::Builder() .vertexCount(3) @@ -113,22 +126,65 @@ void GraphicsView::GLView::first_render() .build(*engine, renderable); scene = engine->createScene(); + if(scene==0) + throw std::logic_error("GraphicsView: cannot create scene."); + view = engine->createView(); + if(view==0) + throw std::logic_error("GraphicsView: cannot create view."); + view->setViewport(filament::Viewport(0, 0, 400, 400)); camera = utils::EntityManager::get().create(); cam = engine->createCamera(camera); view->setCamera(cam); view->setScene(scene); + // Main sun light overhead. mainlight = utils::EntityManager::get().create(); filament::LightManager::Builder(filament::LightManager::Type::DIRECTIONAL) .color(filament::Color::toLinear(filament::sRGBColor(1.0f, 1.0f, 1.0f))) - .intensity(100000.0) + .intensity(800000.0) .position({0.0, 10.0, 0.0}) .direction({0.0, -1.0, 0.0}) .castShadows(true) .build(*engine, mainlight); scene->addEntity(mainlight); + + // Spotlight for structure + spotlight = utils::EntityManager::get().create(); + filament::LightManager::Builder(filament::LightManager::Type::SPOT) + .color(filament::Color::toLinear(filament::sRGBColor(1.0f, 1.0f, 1.0f))) + .falloff(10) + .intensity(100000000.0) + .spotLightCone(0.001, 0.4) + .position({5.0, 0, 5}) + .direction({-0.71, 0.0, -0.71}) + .castShadows(true) + .build(*engine, spotlight); + scene->addEntity(spotlight); + + // Ambient light using a white texture. + static unsigned char oneWhitePixel[] = { 0xFF, 0xFF, 0xFF }; + filament::backend::PixelBufferDescriptor whitePixBuf( oneWhitePixel, sizeof(oneWhitePixel), + filament::backend::PixelDataFormat::RGB, + filament::backend::PixelDataType::UBYTE ); + static const filament::math::float3 irr[]={ filament::math::float3({1.0f, 1.0f, 1.0f}) }; + ambient_texture = filament::Texture::Builder() + .width(1) + .height(1) + .levels(1) + .sampler( filament::backend::SamplerType::SAMPLER_CUBEMAP ) + .format( filament::backend::TextureFormat::RGB8 ) + .build( *engine ); + filament::Texture::FaceOffsets offsets( 0 ); + ambient_texture->setImage( *engine, 0, std::move(whitePixBuf), offsets ); + ambient_light = filament::IndirectLight::Builder() + .reflections(ambient_texture) + .radiance(1, irr) + .intensity(10000.0) + .build(*engine); + scene->setIndirectLight(ambient_light); + // skybox = filament::Skybox::Builder().color({0.1, 0.125, 0.25, 1.0}).build(*engine); skybox = filament::Skybox::Builder().color({4.0, 4.0, 4.0, 1.0}).build(*engine); @@ -137,7 +193,6 @@ void GraphicsView::GLView::first_render() auto color_grading = filament::ColorGrading::Builder().toneMapper(&tone_mapper).build(*engine); view->setColorGrading(color_grading); - renderer = engine->createRenderer(); view->setPostProcessingEnabled(true); filament::Renderer::ClearOptions co; co.clear=true; @@ -161,22 +216,22 @@ void GraphicsView::GLView::first_render() //bool GraphicsView::GLView::on_render(const Glib::RefPtr< Gdk::GLContext > &context) bool GraphicsView::GLView::on_draw(const Cairo::RefPtr& context) { - static bool first=true; - int a, b; // context->get_version(a, b); - std::cerr << "GLView::on_render " << std::endl; + // std::cerr << "GLView::on_render " << std::endl; - if(first) { - first=false; + if(need_setup_on_first_render) { + need_setup_on_first_render=false; std::cerr << "first render" << std::endl; first_render(); } + // Always set camera, as its position may change from one frame + // to the next. setup_camera(); if(renderer->beginFrame(swapChain) || true /* always render */) { - std::cerr << "filament rendering" << std::endl; + // std::cerr << "filament rendering" << std::endl; renderer->render(view); renderer->endFrame(); } @@ -231,7 +286,7 @@ void GraphicsView::GLView::setup_camera() // setup view matrix // const filament::math::float3 eye(0.f, 0.f, 1.f); - const filament::math::float3 eye(2.f, 2.f, 1.f); + const filament::math::float3 eye(2.f, 2.0f*(std::cos(6.28*angle/1000.0)), 1.f); const filament::math::float3 target(0.f, 0.f, 0.f); const filament::math::float3 up(0.f, 1.f, 0.f); cam->lookAt(eye, target, up); @@ -254,6 +309,12 @@ void GraphicsView::GLView::setup_camera() // cam->setExposure(1); //, 1.2, 100.0); } +bool GraphicsView::update(long timestamp_millis) + { + glview.angle = (glview.angle+1)%1000; + return true; + } + bool GraphicsView::GLView::load(const std::string& gltf) { auto materials = filament::gltfio::createJitShaderProvider(engine); diff --git a/frontend/gtkmm/GraphicsView.hh b/frontend/gtkmm/GraphicsView.hh index b85442cb65..2787cd5c9e 100644 --- a/frontend/gtkmm/GraphicsView.hh +++ b/frontend/gtkmm/GraphicsView.hh @@ -31,13 +31,16 @@ namespace cadabra { class GraphicsView : public Gtk::EventBox { public: - GraphicsView(filament::Engine *); + GraphicsView(filament::Engine *, filament::Renderer *); virtual ~GraphicsView(); virtual bool on_motion_notify_event(GdkEventMotion *event) override; virtual bool on_button_press_event(GdkEventButton *event) override; virtual bool on_button_release_event(GdkEventButton *event) override; + /// Update the data visualised. + bool update(long timestamp_millis); + /// Set the content of this 3d view to be the gltf (json). void set_gltf(const std::string&); @@ -45,38 +48,48 @@ namespace cadabra { public Gtk::DrawingArea { // public Gtk::GLArea { public: - GLView(filament::Engine *); + GLView(filament::Engine *, filament::Renderer *); + virtual ~GLView(); + //virtual bool on_render (const Glib::RefPtr< Gdk::GLContext > &context); virtual bool on_draw(const Cairo::RefPtr& cr) override; void set_gltf(const std::string&); + + int angle=0; private: + bool need_setup_on_first_render; + void first_render(); void setup_camera(); bool load(const std::string& gltf_data); std::string gltf_str; - // Filament things. The engine is owned by the NotebookWindow and passed - // in on creation of GraphicsView. The swapchain, on the other hand, is + // Filament things. The engine and renderer are owned + // by the NotebookWindow and passed in on creation of + // GraphicsView. The swapchain, on the other hand, is // per-view, so we are responsible for it. - filament::Engine *engine=0; - filament::SwapChain *swapChain=0; + filament::Engine *engine=0; + filament::Renderer *renderer=0; + filament::SwapChain *swapChain=0; // Test stuff for filament. - filament::VertexBuffer* vb; - filament::IndexBuffer* ib; - filament::Material* mat; - filament::Camera* cam; - filament::Scene* scene; - filament::Skybox *skybox; - filament::View* view; - utils::Entity camera; - utils::Entity renderable; - utils::Entity mainlight; - filament::Renderer *renderer; + filament::VertexBuffer *vb=0; + filament::IndexBuffer *ib=0; + filament::Material *mat=0; + filament::Camera *cam=0; + filament::Scene *scene=0; + filament::Skybox *skybox=0; + filament::View *view=0; + utils::Entity camera; + utils::Entity renderable; + utils::Entity mainlight, spotlight; + filament::Texture *ambient_texture=0; + filament::IndirectLight *ambient_light=0; float zoom; + }; private: diff --git a/frontend/gtkmm/NotebookWindow.cc b/frontend/gtkmm/NotebookWindow.cc index ea981192d7..7c003b80e9 100644 --- a/frontend/gtkmm/NotebookWindow.cc +++ b/frontend/gtkmm/NotebookWindow.cc @@ -768,6 +768,7 @@ NotebookWindow::NotebookWindow(Cadabra *c, bool ro) // engineConfig.stereoscopicType = filament::Engine::StereoscopicType::NONE; // filament_engine = filament::Engine::create(filament::Engine::Backend::OPENGL); filament_engine = filament::Engine::create(filament::Engine::Backend::VULKAN); + filament_renderer = filament_engine->createRenderer(); } NotebookWindow::~NotebookWindow() @@ -1260,8 +1261,9 @@ void NotebookWindow::add_cell(const DTree& tr, DTree::iterator it, bool visible) break; } case DataCell::CellType::graphics_view: { - newcell.graphicsbox = manage( new GraphicsView(filament_engine) ); + newcell.graphicsbox = manage( new GraphicsView(filament_engine, filament_renderer) ); newcell.graphicsbox->set_gltf(it->textbuf); + widgets_needing_periodic_update.insert(newcell.graphicsbox); w=newcell.graphicsbox; break; } @@ -1379,7 +1381,8 @@ void NotebookWindow::add_cell(const DTree& tr, DTree::iterator it, bool visible) } // Connect - Glib::signal_idle().connect(sigc::mem_fun(*this, &NotebookWindow::idle_handler)); +// Glib::signal_idle().connect(sigc::mem_fun(*this, &NotebookWindow::idle_handler)); + Glib::signal_timeout().connect(sigc::mem_fun(*this, &NotebookWindow::idle_handler), 33); // if(current_cell!=doc.end()) // setup_focus_after_allocate(it); @@ -3094,7 +3097,17 @@ bool NotebookWindow::idle_handler() } to_reveal.clear(); #endif - return false; // disconnect + + // Queue widgets for drawing. + for(auto& gv: widgets_needing_periodic_update) { + bool need_more = gv->update(0); + gv->queue_draw(); + } + // FIXME: disconnect the idle handler if no further updates + // are needed. + + return true; + //return false; // disconnect } void NotebookWindow::unselect_output_cell() diff --git a/frontend/gtkmm/NotebookWindow.hh b/frontend/gtkmm/NotebookWindow.hh index ce99998c14..d0140b368a 100644 --- a/frontend/gtkmm/NotebookWindow.hh +++ b/frontend/gtkmm/NotebookWindow.hh @@ -159,6 +159,8 @@ namespace cadabra { Gtk::Label search_result; Gtk::HBox statusbarbox; + std::set widgets_needing_periodic_update; + Console console; Gtk::Dialog console_win; @@ -333,7 +335,9 @@ namespace cadabra { #endif bool idle_handler(); - filament::Engine *filament_engine=0; + filament::Engine *filament_engine=0; + filament::Renderer *filament_renderer=0; + }; };