Browse Source

Added high DPI support. I bought a Macbook Pro Retina for $450 just for this commit!

tags/v0.3.0
Andrew Belt 7 years ago
parent
commit
837071241e
3 changed files with 21 additions and 11 deletions
  1. +1
    -0
      include/gui.hpp
  2. +10
    -3
      src/gui.cpp
  3. +10
    -8
      src/widgets/FramebufferWidget.cpp

+ 1
- 0
include/gui.hpp View File

@@ -14,5 +14,6 @@ void guiCursorUnlock();


extern NVGcontext *gVg; extern NVGcontext *gVg;
extern std::shared_ptr<Font> gGuiFont; extern std::shared_ptr<Font> gGuiFont;
extern float gPixelRatio;


} // namespace rack } // namespace rack

+ 10
- 3
src/gui.cpp View File

@@ -23,6 +23,7 @@ namespace rack {
static GLFWwindow *window = NULL; static GLFWwindow *window = NULL;
std::shared_ptr<Font> gGuiFont; std::shared_ptr<Font> gGuiFont;
NVGcontext *gVg = NULL; NVGcontext *gVg = NULL;
float gPixelRatio = 0.0;




void windowSizeCallback(GLFWwindow* window, int width, int height) { 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) { void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
if (action == GLFW_PRESS || action == GLFW_REPEAT) { if (action == GLFW_PRESS || action == GLFW_REPEAT) {
if (key == GLFW_KEY_F11 || key == GLFW_KEY_ESCAPE) { if (key == GLFW_KEY_F11 || key == GLFW_KEY_ESCAPE) {
/*
// Toggle fullscreen // Toggle fullscreen
GLFWmonitor *monitor = glfwGetWindowMonitor(window); GLFWmonitor *monitor = glfwGetWindowMonitor(window);
if (monitor) { if (monitor) {
@@ -151,6 +153,7 @@ void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods
const GLFWvidmode *mode = glfwGetVideoMode(monitor); const GLFWvidmode *mode = glfwGetVideoMode(monitor);
glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
} }
*/
} }
else { else {
if (gSelectedWidget) { if (gSelectedWidget) {
@@ -163,16 +166,20 @@ void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods
void renderGui() { void renderGui() {
int width, height; int width, height;
glfwGetFramebufferSize(window, &width, &height); glfwGetFramebufferSize(window, &width, &height);
// glfwGetWindowSize(window, &width, &height);
int windowWidth, windowHeight;
glfwGetWindowSize(window, &windowWidth, &windowHeight);
gPixelRatio = (float)width / windowWidth;


// Update and render // Update and render
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
glClearColor(0.0, 0.0, 0.0, 1.0); glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 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); nvgSave(gVg);
nvgReset(gVg);
nvgScale(gVg, gPixelRatio, gPixelRatio);
gScene->draw(gVg); gScene->draw(gVg);
nvgRestore(gVg); nvgRestore(gVg);


@@ -220,7 +227,7 @@ void guiInit() {
// GLEW generates GL error because it calls glGetString(GL_EXTENSIONS), we'll consume it here. // GLEW generates GL error because it calls glGetString(GL_EXTENSIONS), we'll consume it here.
glGetError(); glGetError();


glfwSetWindowSizeLimits(window, 240, 160, GLFW_DONT_CARE, GLFW_DONT_CARE);
glfwSetWindowSizeLimits(window, 640, 480, GLFW_DONT_CARE, GLFW_DONT_CARE);


// Set up NanoVG // Set up NanoVG
gVg = nvgCreateGL2(NVG_ANTIALIAS); gVg = nvgCreateGL2(NVG_ANTIALIAS);


+ 10
- 8
src/widgets/FramebufferWidget.cpp View File

@@ -10,6 +10,7 @@ namespace rack {


struct FramebufferWidget::Internal { struct FramebufferWidget::Internal {
NVGLUframebuffer *fb = NULL; NVGLUframebuffer *fb = NULL;
Rect box;


~Internal() { ~Internal() {
setFramebuffer(NULL); setFramebuffer(NULL);
@@ -21,6 +22,7 @@ struct FramebufferWidget::Internal {
} }
}; };



FramebufferWidget::FramebufferWidget() { FramebufferWidget::FramebufferWidget() {
internal = new Internal(); internal = new Internal();
} }
@@ -35,7 +37,9 @@ void FramebufferWidget::step() {


// Render the scene to the framebuffer if dirty // Render the scene to the framebuffer if dirty
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()); assert(fbSize.isFinite());


internal->setFramebuffer(NULL); internal->setFramebuffer(NULL);
@@ -44,14 +48,13 @@ void FramebufferWidget::step() {
return; return;
internal->setFramebuffer(fb); 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); nvgluBindFramebuffer(fb);
glViewport(0.0, 0.0, fbSize.x, fbSize.y); glViewport(0.0, 0.0, fbSize.x, fbSize.y);
glClearColor(0.0, 0.0, 0.0, 0.0); glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 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); nvgTranslate(gVg, padding.x, padding.y);
Widget::draw(gVg); Widget::draw(gVg);


@@ -67,14 +70,13 @@ void FramebufferWidget::draw(NVGcontext *vg) {
return; return;


// Draw framebuffer image // Draw framebuffer image
int width, height;
nvgImageSize(vg, internal->fb->image, &width, &height);
nvgBeginPath(vg); 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); nvgFillPaint(vg, paint);
nvgFill(vg); nvgFill(vg);


// For debugging bounding box of framebuffer image
// nvgFillColor(vg, nvgRGBA(255, 0, 0, 64)); // nvgFillColor(vg, nvgRGBA(255, 0, 0, 64));
// nvgFill(vg); // nvgFill(vg);
} }


Loading…
Cancel
Save