threepp icon indicating copy to clipboard operation
threepp copied to clipboard

Framebuffer size and Canvas size should be different

Open jmacey opened this issue 4 years ago • 7 comments

On a Mac with Retina display the screen size is wrong and you only get an image in the bottom quater of the screen.

To fix you need to use

int width,height;
glfwGetFramebufferSize(window,&width,&height);
size_.width=width;
size_.height=height; 

In the Canvas::Impl method after window construction.

Also the resize event needs changing

  static void window_size_callback(GLFWwindow *w, int width, int height) {
      auto p = static_cast<Canvas::Impl *>(glfwGetWindowUserPointer(w));
      glfwGetFramebufferSize(w,&width,&height);
      p->size_ = {width, height};
      if (p->resizeListener) p->resizeListener.value().operator()(p->size_);
  }

It may be better to split frambuffer size and canvas size into different things as this will cause issues with some platforms. Great project BTW.

jmacey avatar Dec 05 '21 09:12 jmacey

Actually just tested the water and texture demos and there is still an issue when you use a Renderbuffer as this size is wrong. I will try and figure out where this comes from.

jmacey avatar Dec 05 '21 09:12 jmacey

Just reproduced the same thing, a workaround that fixed viewport for me:

diff --git a/src/threepp/Canvas.cpp b/src/threepp/Canvas.cpp
index a55f5f9..0885818 100644
--- a/src/threepp/Canvas.cpp
+++ b/src/threepp/Canvas.cpp
@@ -26,6 +26,7 @@ public:
         glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
         glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
         glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+        glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, GLFW_FALSE);

         if (params.antialiasing_ > 0) {
             glfwWindowHint(GLFW_SAMPLES, params.antialiasing_);

...although simply disabling retina is not the point, what you suggested above makes more sense.

Anyway, cool project, gives me a feeling similar to raylib.

dbeef avatar Dec 05 '21 13:12 dbeef

As someone with zero Mac experience, its a bit hard to push a fix for this. I suggest a PR. Then, if the code looks ok and it works here and for the reporter, we can apply the fix.

markaren avatar Dec 06 '21 07:12 markaren

I will try and do a PR later. Can you point me to where the canvas size is used for Framebuffer Objects as this seems to be one of the issues as well. They need to be set to the same size as the default FBO which on a mac is basically twice the size.

jmacey avatar Dec 06 '21 09:12 jmacey

I might say something wrong now, but the framebuffer size and canvas size is not directly related. You set a size for the canvas, and you set a size for the renderer. By default, the renderer will copy the canvas size, but you are free to set the renderer size as you see fit. https://github.com/markaren/threepp/blob/master/src/threepp/renderers/GLRenderer.cpp

markaren avatar Dec 06 '21 09:12 markaren

There is also the pixelRatio setting, but I see that I have not exposed a setter for that variable. So there might not be much of an issue after all? I.e. it is possible to configure the renderer to match your screen.

markaren avatar Dec 06 '21 10:12 markaren

Oh, GLRenderer::setSize actually updates the canvas size. So the pixelRatio might be the correct thing. But I would take a look at what threejs does about this..

markaren avatar Dec 06 '21 10:12 markaren

Closing this as I assume pixelRatio handles this case. Re-open if that is not the case.

markaren avatar Apr 20 '23 06:04 markaren