aap/librw

Incorrect Render Size on Macbook Pro M1

SubstituteR opened this issue · 5 comments

When building another project of yours that uses librw on the Macbook Pro M1, the in-game rendered world is incorrectly sized. It is roughly twice the width and height vs the actual framebuffer. This is probably due to Retina.

I was able to fix it by changing the following

librw/src/gl/gl3device.cpp

Lines 1256 to 1257 in 373f839

float32 invwx = 1.0f/cam->viewWindow.x;
float32 invwy = 1.0f/cam->viewWindow.y;

to

	float32 invwx = 1.0f/cam->viewWindow.x/2;
	float32 invwy = 1.0f/cam->viewWindow.y/2;

and by changing

librw/src/gl/gl3device.cpp

Lines 1400 to 1401 in 373f839

glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x, (dst->height-src->height)-y,
0, 0, src->width, src->height);

to

			glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x, (dst->height-src->height)-y,
				src->width/2, src->height/2, src->width, src->height);

I'm not knowledable enough in your engine or OpenGL to see why this happens, but if you are unable, or unwilling, I can try to investigate the root cause, if there is one.

Extra note: Particle effects aren't fixed with just this and move around 2x as quickly on the rasterized image when moving the camera.

halpz commented

would it be a difficult process to enable rendering on Metal rather than openGL ES ?

would it be a difficult process to enable rendering on Metal rather than openGL ES ?

Not if I knew the required flag for premake :)
This issue is most likely not just on Apple only and might be high-DPI specific. I have a little bit of code written to calculate the scaling using the expected size vs actual, but I want to figure it out more (and fix the particle layer)
I would prefer building for Metal on OS X simply for performance though.

I am able to fix the particles by changing this

librw/src/camera.cpp

Lines 232 to 233 in 373f839

proj.pos.x = -cam->viewOffset.x*xscl;
proj.pos.y = cam->viewOffset.y*yscl;

to

        float dpiScaleX = (float) 2/1.f;
        float dpiScaleY = (float) 2/1.f;
        //TODO calculate this properly
        float32 xscl = 1.0f/(2.0f*cam->viewWindow.x*dpiScaleX);
        float32 yscl = 1.0f/(2.0f*cam->viewWindow.y*dpiScaleY);

it's a messy hack (and again isn't portable) but this does reinforce my thoughts that this is DPI related.

I've created a very rudimentary "getDPIScale" function in the device for OpenGL.
SubstituteR@a8e005e
This could probably be done better but it works for me.