Browse Source

Add ContextCreateEvent and ContextDestroyEvent.

tags/v2.0.0
Andrew Belt 3 years ago
parent
commit
ad1d109845
5 changed files with 82 additions and 29 deletions
  1. +2
    -0
      include/widget/FramebufferWidget.hpp
  2. +21
    -1
      include/widget/Widget.hpp
  3. +17
    -4
      src/widget/FramebufferWidget.cpp
  4. +36
    -24
      src/window.cpp
  5. +6
    -0
      standalone/main.cpp

+ 2
- 0
include/widget/FramebufferWidget.hpp View File

@@ -32,6 +32,8 @@ struct FramebufferWidget : Widget {
NVGLUframebuffer* getFramebuffer(); NVGLUframebuffer* getFramebuffer();
math::Vec getFramebufferSize(); math::Vec getFramebufferSize();
void setScale(math::Vec scale); void setScale(math::Vec scale);
void onContextCreate(const ContextCreateEvent& e) override;
void onContextDestroy(const ContextDestroyEvent& e) override;
}; };






+ 21
- 1
include/widget/Widget.hpp View File

@@ -452,13 +452,33 @@ struct Widget : WeakBase {
virtual void onHide(const HideEvent& e) { virtual void onHide(const HideEvent& e) {
recurseEvent(&Widget::onHide, e); recurseEvent(&Widget::onHide, e);
} }

/** Occurs after the Window, OpenGL context, and Nanovg are created.
Recurses.
*/
struct ContextCreateEvent : BaseEvent {
NVGcontext* vg;
};
virtual void onContextCreate(const ContextCreateEvent& e) {
recurseEvent(&Widget::onContextCreate, e);
}

/** Occurs before the Window, OpenGL context, and Nanovg are destroyed.
Recurses.
*/
struct ContextDestroyEvent : BaseEvent {
NVGcontext* vg;
};
virtual void onContextDestroy(const ContextDestroyEvent& e) {
recurseEvent(&Widget::onContextDestroy, e);
}
}; };




} // namespace widget } // namespace widget


/** Deprecated Rack v1 event namespace. /** Deprecated Rack v1 event namespace.
Use `FooEvent` instead of `event::Foo` in new code.
Use `FooEvent` (defined in widget::Widget) instead of `event::Foo` in new code.
*/ */
namespace event { namespace event {
using Base = widget::BaseEvent; using Base = widget::BaseEvent;


+ 17
- 4
src/widget/FramebufferWidget.cpp View File

@@ -50,7 +50,7 @@ void FramebufferWidget::setDirty(bool dirty) {




void FramebufferWidget::onDirty(const DirtyEvent& e) { void FramebufferWidget::onDirty(const DirtyEvent& e) {
dirty = true;
setDirty();
Widget::onDirty(e); Widget::onDirty(e);
} }


@@ -71,7 +71,7 @@ void FramebufferWidget::step() {
return; return;


// In case we fail drawing the framebuffer, don't try again the next frame, so reset `dirty` here. // In case we fail drawing the framebuffer, don't try again the next frame, so reset `dirty` here.
dirty = false;
setDirty(false);
NVGcontext* vg = APP->window->vg; NVGcontext* vg = APP->window->vg;


internal->fbScale = internal->scale; internal->fbScale = internal->scale;
@@ -186,12 +186,12 @@ void FramebufferWidget::draw(const DrawArgs& args) {
if (dirtyOnSubpixelChange && !(math::isNear(internal->offsetF.x, internal->fbOffsetF.x, 0.01f) && math::isNear(internal->offsetF.y, internal->fbOffsetF.y, 0.01f))) { if (dirtyOnSubpixelChange && !(math::isNear(internal->offsetF.x, internal->fbOffsetF.x, 0.01f) && math::isNear(internal->offsetF.y, internal->fbOffsetF.y, 0.01f))) {
// If drawing to a new subpixel location, rerender in the next frame. // If drawing to a new subpixel location, rerender in the next frame.
// DEBUG("%p dirty subpixel", this); // DEBUG("%p dirty subpixel", this);
dirty = true;
setDirty();
} }
if (!internal->scale.equals(internal->fbScale)) { if (!internal->scale.equals(internal->fbScale)) {
// If rescaled, rerender in the next frame. // If rescaled, rerender in the next frame.
// DEBUG("%p dirty scale", this); // DEBUG("%p dirty scale", this);
dirty = true;
setDirty();
} }


math::Vec scaleRatio = math::Vec(1, 1); math::Vec scaleRatio = math::Vec(1, 1);
@@ -285,5 +285,18 @@ void FramebufferWidget::setScale(math::Vec scale) {
} }




void FramebufferWidget::onContextCreate(const ContextCreateEvent& e) {
setDirty();
Widget::onContextCreate(e);
}


void FramebufferWidget::onContextDestroy(const ContextDestroyEvent& e) {
if (internal->fb)
nvgluDeleteFramebuffer(internal->fb);
Widget::onContextDestroy(e);
}


} // namespace widget } // namespace widget
} // namespace rack } // namespace rack

+ 36
- 24
src/window.cpp View File

@@ -327,6 +327,11 @@ Window::Window() {
// Load default Blendish font // Load default Blendish font
uiFont = loadFont(asset::system("res/fonts/DejaVuSans.ttf")); uiFont = loadFont(asset::system("res/fonts/DejaVuSans.ttf"));
bndSetFont(uiFont->handle); bndSetFont(uiFont->handle);

if (APP->scene) {
widget::Widget::ContextCreateEvent e;
APP->scene->onContextCreate(e);
}
} }




@@ -344,6 +349,11 @@ Window::~Window() {
settings::windowPos = math::Vec(winX, winY); settings::windowPos = math::Vec(winX, winY);
} }


if (APP->scene) {
widget::Widget::ContextDestroyEvent e;
APP->scene->onContextDestroy(e);
}

#if defined NANOVG_GL2 #if defined NANOVG_GL2
nvgDeleteGL2(vg); nvgDeleteGL2(vg);
#elif defined NANOVG_GL3 #elif defined NANOVG_GL3
@@ -422,30 +432,32 @@ void Window::step() {
glfwGetWindowSize(win, &winWidth, &winHeight); glfwGetWindowSize(win, &winWidth, &winHeight);
windowRatio = (float)fbWidth / winWidth; windowRatio = (float)fbWidth / winWidth;


// DEBUG("%f %f %d %d", pixelRatio, windowRatio, fbWidth, winWidth);
// Resize scene
APP->scene->box.size = math::Vec(fbWidth, fbHeight).div(pixelRatio);

// Step scene
APP->scene->step();

// Render scene
bool visible = glfwGetWindowAttrib(win, GLFW_VISIBLE) && !glfwGetWindowAttrib(win, GLFW_ICONIFIED);
if (visible) {
// Update and render
nvgBeginFrame(vg, fbWidth, fbHeight, pixelRatio);
nvgScale(vg, pixelRatio, pixelRatio);

// Draw scene
widget::Widget::DrawArgs args;
args.vg = vg;
args.clipBox = APP->scene->box.zeroPos();
APP->scene->draw(args);

glViewport(0, 0, fbWidth, fbHeight);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
nvgEndFrame(vg);
if (APP->scene) {
// DEBUG("%f %f %d %d", pixelRatio, windowRatio, fbWidth, winWidth);
// Resize scene
APP->scene->box.size = math::Vec(fbWidth, fbHeight).div(pixelRatio);

// Step scene
APP->scene->step();

// Render scene
bool visible = glfwGetWindowAttrib(win, GLFW_VISIBLE) && !glfwGetWindowAttrib(win, GLFW_ICONIFIED);
if (visible) {
// Update and render
nvgBeginFrame(vg, fbWidth, fbHeight, pixelRatio);
nvgScale(vg, pixelRatio, pixelRatio);

// Draw scene
widget::Widget::DrawArgs args;
args.vg = vg;
args.clipBox = APP->scene->box.zeroPos();
APP->scene->draw(args);

glViewport(0, 0, fbWidth, fbHeight);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
nvgEndFrame(vg);
}
} }


glfwSwapBuffers(win); glfwSwapBuffers(win);


+ 6
- 0
standalone/main.cpp View File

@@ -223,6 +223,12 @@ int main(int argc, char* argv[]) {
INFO("Running window"); INFO("Running window");
APP->window->run(); APP->window->run();
INFO("Stopped window"); INFO("Stopped window");
delete APP->window;
APP->window = NULL;

INFO("Re-creating window");
APP->window = new Window;
APP->window->run();
} }


// Destroy context // Destroy context


Loading…
Cancel
Save