@@ -14,5 +14,6 @@ void guiCursorUnlock(); | |||
extern NVGcontext *gVg; | |||
extern std::shared_ptr<Font> gGuiFont; | |||
extern float gPixelRatio; | |||
} // namespace rack |
@@ -1,24 +1,24 @@ | |||
# All paths here assume the PWD is plugin/something | |||
FLAGS += -fPIC \ | |||
-I../../include | |||
-I../../include -I../../dep/include | |||
include ../../arch.mk | |||
ifeq ($(ARCH), lin) | |||
LDFLAGS += -shared | |||
TARGET = plugin.so | |||
LDFLAGS += -shared | |||
TARGET = plugin.so | |||
endif | |||
ifeq ($(ARCH), mac) | |||
LDFLAGS += -shared -undefined dynamic_lookup | |||
TARGET = plugin.dylib | |||
LDFLAGS += -shared -undefined dynamic_lookup | |||
TARGET = plugin.dylib | |||
endif | |||
ifeq ($(ARCH), win) | |||
LDFLAGS += -shared -L../../ -lRack | |||
TARGET = plugin.dll | |||
LDFLAGS += -shared -L../../ -lRack | |||
TARGET = plugin.dll | |||
endif | |||
@@ -23,6 +23,7 @@ namespace rack { | |||
static GLFWwindow *window = NULL; | |||
std::shared_ptr<Font> gGuiFont; | |||
NVGcontext *gVg = NULL; | |||
float gPixelRatio = 0.0; | |||
void windowSizeCallback(GLFWwindow* window, int width, int height) { | |||
@@ -136,6 +137,7 @@ static int lastWindowX, lastWindowY, lastWindowWidth, lastWindowHeight; | |||
void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) { | |||
if (action == GLFW_PRESS || action == GLFW_REPEAT) { | |||
if (key == GLFW_KEY_F11 || key == GLFW_KEY_ESCAPE) { | |||
/* | |||
// Toggle fullscreen | |||
GLFWmonitor *monitor = glfwGetWindowMonitor(window); | |||
if (monitor) { | |||
@@ -151,6 +153,7 @@ void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods | |||
const GLFWvidmode *mode = glfwGetVideoMode(monitor); | |||
glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); | |||
} | |||
*/ | |||
} | |||
else { | |||
if (gSelectedWidget) { | |||
@@ -167,16 +170,20 @@ void errorCallback(int error, const char *description) { | |||
void renderGui() { | |||
int width, height; | |||
glfwGetFramebufferSize(window, &width, &height); | |||
// glfwGetWindowSize(window, &width, &height); | |||
int windowWidth, windowHeight; | |||
glfwGetWindowSize(window, &windowWidth, &windowHeight); | |||
gPixelRatio = (float)width / windowWidth; | |||
// Update and render | |||
glViewport(0, 0, width, height); | |||
glClearColor(0.0, 0.0, 0.0, 1.0); | |||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | |||
nvgBeginFrame(gVg, width, height, 1.0); | |||
nvgBeginFrame(gVg, width, height, gPixelRatio); | |||
nvgSave(gVg); | |||
nvgReset(gVg); | |||
nvgScale(gVg, gPixelRatio, gPixelRatio); | |||
gScene->draw(gVg); | |||
nvgRestore(gVg); | |||
@@ -225,7 +232,7 @@ void guiInit() { | |||
// GLEW generates GL error because it calls glGetString(GL_EXTENSIONS), we'll consume it here. | |||
glGetError(); | |||
glfwSetWindowSizeLimits(window, 240, 160, GLFW_DONT_CARE, GLFW_DONT_CARE); | |||
glfwSetWindowSizeLimits(window, 640, 480, GLFW_DONT_CARE, GLFW_DONT_CARE); | |||
// Set up NanoVG | |||
gVg = nvgCreateGL2(NVG_ANTIALIAS); | |||
@@ -10,6 +10,7 @@ namespace rack { | |||
struct FramebufferWidget::Internal { | |||
NVGLUframebuffer *fb = NULL; | |||
Rect box; | |||
~Internal() { | |||
setFramebuffer(NULL); | |||
@@ -21,6 +22,7 @@ struct FramebufferWidget::Internal { | |||
} | |||
}; | |||
FramebufferWidget::FramebufferWidget() { | |||
internal = new Internal(); | |||
} | |||
@@ -35,7 +37,9 @@ void FramebufferWidget::step() { | |||
// Render the scene to the framebuffer if dirty | |||
if (dirty) { | |||
Vec fbSize = box.size.plus(padding.mult(2)); | |||
internal->box.pos = padding.neg(); | |||
internal->box.size = box.size.plus(padding.mult(2)); | |||
Vec fbSize = internal->box.size.mult(gPixelRatio); | |||
assert(fbSize.isFinite()); | |||
internal->setFramebuffer(NULL); | |||
@@ -44,14 +48,13 @@ void FramebufferWidget::step() { | |||
return; | |||
internal->setFramebuffer(fb); | |||
// TODO Support screens with pixelRatio != 1.0 (e.g. Retina) by using the actual size of the framebuffer, etc. | |||
const float pixelRatio = 1.0; | |||
nvgluBindFramebuffer(fb); | |||
glViewport(0.0, 0.0, fbSize.x, fbSize.y); | |||
glClearColor(0.0, 0.0, 0.0, 0.0); | |||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | |||
nvgBeginFrame(gVg, fbSize.x, fbSize.y, pixelRatio); | |||
nvgBeginFrame(gVg, fbSize.x, fbSize.y, gPixelRatio); | |||
nvgScale(gVg, gPixelRatio, gPixelRatio); | |||
nvgTranslate(gVg, padding.x, padding.y); | |||
Widget::draw(gVg); | |||
@@ -67,14 +70,13 @@ void FramebufferWidget::draw(NVGcontext *vg) { | |||
return; | |||
// Draw framebuffer image | |||
int width, height; | |||
nvgImageSize(vg, internal->fb->image, &width, &height); | |||
nvgBeginPath(vg); | |||
nvgRect(vg, -padding.x, -padding.y, width, height); | |||
NVGpaint paint = nvgImagePattern(vg, -padding.x, -padding.y, width, height, 0.0, internal->fb->image, 1.0); | |||
nvgRect(vg, internal->box.pos.x, internal->box.pos.y, internal->box.size.x, internal->box.size.y); | |||
NVGpaint paint = nvgImagePattern(vg, internal->box.pos.x, internal->box.pos.y, internal->box.size.x, internal->box.size.y, 0.0, internal->fb->image, 1.0); | |||
nvgFillPaint(vg, paint); | |||
nvgFill(vg); | |||
// For debugging bounding box of framebuffer image | |||
// nvgFillColor(vg, nvgRGBA(255, 0, 0, 64)); | |||
// nvgFill(vg); | |||
} | |||