Jump to content

[trunk@23678] Atlas Editor: The map / simulation displayed at 1/4 bottom left corner of its canvas (OSX)


wik
 Share

Recommended Posts

The problem

143418244_Screenshot2020-05-27at03_32_44.thumb.png.a32d7e442fa27335a0e016e3ec78f847.png

 

Looks like something related to retina display, because if I move Editor window to 2nd monitor (not retina) and resize a bit, it shows okay:

1716890999_Screenshot2020-05-27at03_34_40.thumb.png.cbefe94ada517e0daf342ad274840f67.png

and when I move it back to retina, it changes back as per first screenshot.

 

Link to comment
Share on other sites

1 hour ago, Stan` said:

@Nescio had it on linux but I never experienced it on Windows.

Yes, this is something I have too, for years now, both when I open up atlas from inside the game and when I run it from the command line with:

binaries/system/pyrogenesis -editor

It probably has something to do with the fact I have a high resolution (3840×2160) and Atlas treats system settings differently than 0 A.D. @vladislavbelov taught me to use:

GDK_SCALE=1 binaries/system/pyrogenesis -editor

instead, and then Atlas does use the full space indeed.

  • Thanks 1
Link to comment
Share on other sites

Looks like it also helps with altas editor, if I multiply client size by scale factor GetContentScaleFactor():

void Canvas::OnResize(wxSizeEvent&)
{
	// Be careful not to send 'resize' messages to the game before we've
	// told it that this canvas exists
    if (! m_SuppressResize) {
        const wxSize ClientSize = GetClientSize() * GetContentScaleFactor();
		POST_MESSAGE(ResizeScreen, (ClientSize.GetWidth(), ClientSize.GetHeight()));
		// TODO: fix flashing
    }
}

void Canvas::InitSize()
{
	m_SuppressResize = false;
    const wxSize ClientSize = GetClientSize() * GetContentScaleFactor();
	SetSize(ClientSize);
}

265910415_Screenshot2020-05-28at00_21_36.thumb.png.732dff537fb8004b66cc8c6b4a28ef98.png

Link to comment
Share on other sites

On 5/28/2020 at 6:57 AM, wraitii said:

Seems to me you've been sent from above to fix WxWidgets bugs, wik :D .

If you want to, you can make a patch on Phabricator, see SubmittingPatches and Phabricator .

Thanks, I'll try :)

With those changes applied the map fills whole canvas, but I just noticed that it still have offset between mouse pointer and place where it triggers action for some reason. On non-retina display it only happens with my changes applied, so, I probably missing something.

UPDATE: it only happens on retina display, if I move window to non-retina display it back to normal after resize (I keep forgetting to resize)

Edited by wik
Link to comment
Share on other sites

 

12 hours ago, wik said:

still have offset between mouse pointer and place where it triggers action for some reason

This is because scale factor need to applied to wxMouseEvent::GetPosition(), I found some clarification in wxWidgets documentation https://docs.wxwidgets.org/trunk/classwx_g_l_canvas.html

Quote

Please note that wxGLContext always uses physical pixels, even on the platforms where wxWindow uses logical pixels, affected by the coordinate scaling, on high DPI displays. Thus, if you want to set the OpenGL view port to the size of entire window, you must multiply the result returned by wxWindow::GetClientSize() by wxWindow::GetContentScaleFactor() before passing it to glViewport(). Same considerations apply to other OpenGL functions and other coordinates, notably those retrieved from wxMouseEvent in the event handlers.

As an experiment I've tried to apply scale factor of 2.0 (retina) in AlterElevation tool

POST_MESSAGE(BrushPreview, (true, Position(evt.GetPosition() * 2.0))); // multiplied by 2.0 (retina)

Here is illustration, the mouse pointer, in both cases, in the middle (approx) of square 

Before:

975377609_Screenshot2020-05-30at04_17_46.thumb.png.1abcd0c0014b1107cb30010085b36cad.png

After:

1166049862_Screenshot2020-05-30at04_16_08.thumb.png.ae2cb70bf0e11d16d818b4501b0a965a.png

It feels like "Position::Position(const wxPoint& pt)" definition from ScenarioEditor.cpp might be a good place to implement this uniformly.

I also need to figure out how to get scale factor from wxPoint.

Link to comment
Share on other sites

  • 2 weeks later...

I've done some more experiments with opengl examples from wxWidgets and it turns out that if we skip glViewport the system will sort it out automagically,

i.e. scale factor will be applied and even mouse position will be adjusted transparently, wxWidgets will behave as it would run on any other screen

// Renderer.cpp
void CRenderer::SetViewport(const SViewPort &vp)
{
	m_Viewport = vp;
	//glViewport((GLint)vp.m_X,(GLint)vp.m_Y,(GLsizei)vp.m_Width,(GLsizei)vp.m_Height);
}

I've tried to debug GL_VIEWPORT state with the following snippets

int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
std::printf("m_Viewport %d x %d\n", m_Viewport.m_Width, m_Viewport.m_Height);
std::printf("GL_VIEWPORT %d x %d\n", viewport[2], viewport[3]);

Here is results:

Editor: 
m_Viewport 734 x 718
GL_VIEWPORT 1468 x 1436

Game:
m_Viewport 1440 x 900 (also noticed that every 4th call to SetViewport has strange vp 2048 x 2048, i.e. something in 0ad game code tries to set this)
GL_VIEWPORT 1440 x 900 (remains stable, I believe not scaled, probably because some magic in SDL update)

Unfortunatelly I didn't find documentation about default behavior for glViewport and when it should or shouldn't be used explicitly.

 

  • Like 1
Link to comment
Share on other sites

That seems logical, the doc indicates that content scaling is not applied automatically when running a GL viewport:

Quote

Please note that wxGLContext always uses physical pixels, even on the platforms where wxWindow uses logical pixels, affected by the coordinate scaling, on high DPI displays. Thus, if you want to set the OpenGL view port to the size of entire window, you must multiply the result returned by wxWindow::GetClientSize() by wxWindow::GetContentScaleFactor() before passing it to glViewport(). Same considerations apply to other OpenGL functions and other coordinates, notably those retrieved from wxMouseEvent in the event handlers.

 

Link to comment
Share on other sites

14 hours ago, wik said:

Note, I'm using SDL2-2.0.12 and the following commit could probably explain why game, unlike editor, running in 1:1 mode: https://hg.libsdl.org/SDL/rev/46b094f7d20e

i.e. SDL overrides default behavior and the application treated as non hidpi compatible and running in 1:1 mode by default.

I should probably give it a go with SDL2-2.0.5

I've tried it with SDL2-2.0.5 (the version we currently have in trunk) https://github.com/0ad/0ad/blob/master/libraries/osx/build-osx-libs.sh#L27

And it turns out that removing explicit call to glViewport allows game to scale automatically (2880 x 1800), below some examples with and without glViewport

void CRenderer::SetViewport(const SViewPort &vp)
{
	m_Viewport = vp;
	//glViewport((GLint)vp.m_X,(GLint)vp.m_Y,(GLsizei)vp.m_Width,(GLsizei)vp.m_Height);
}

With glViewport (m_Viewport m_Width X m_Height => 1440 x 900)

302516027_Screenshot2020-06-09at16_57_45.thumb.png.62895fbfc369d4bae334981bb142af01.png

Without glViewport (after commenting out the line, also glGetIntegerv(GL_VIEWPORT) reports 2880 x 1800)

1562247117_Screenshot2020-06-09at17_00_19.thumb.png.449fa822a9e7d46aa284d11885e792ee.png

But I've noticed that some text disappeared in "auto-scaled" version, perhaps something to do with fonts.

Link to comment
Share on other sites

 

On 5/27/2020 at 9:16 AM, Nescio said:

It probably has something to do with the fact I have a high resolution (3840×2160) and Atlas treats system settings differently than 0 A.D. @vladislavbelov taught me to use:


GDK_SCALE=1 binaries/system/pyrogenesis -editor

I haven't tried, but there seems to be similar solution for OSX, i.e. disable high dpi capability on per application basis:

https://github.com/ioquake/ioq3/issues/422#issuecomment-541193050

/Contents/Info.plist, right above the "" line:

<key>NSHighResolutionCapable</key>
<false/>

Could be an intermediate option before transitioning to hdpi support.

Link to comment
Share on other sites

I also tried SDL2-2.0.12 + flags |= SDL_WINDOW_ALLOW_HIGHDPI

It enables auto-scaling to 2880 x 1800, but has the same missing text issue as in SDL2-2.0.5

m_Viewport 1440 x 900
GL_VIEWPORT 2880 x 1800

829532853_Screenshot2020-06-09at17_59_37.thumb.png.6e6497037e853c88551048cf30c42ff9.png

Link to comment
Share on other sites

2 minutes ago, Stan` said:

It likely needs *all* the other patches :)

D1925 probably needs to be rebased and updated. Also, from the summary:

Probable TODO: fix screenshots, fix atlas, fix the cinematic. g_GuiScale should probably be added back. Also names are probably not perfect.

Link to comment
Share on other sites

  • 2 weeks later...
On 6/9/2020 at 6:09 PM, Stan` said:

Thanks for pointing that out, I'll need to study it :)

Meanwhile I've done some more experiments and noticed that if we only multiply glViewport components by scale factor, then mouse coordinates not affected.
Previously I've tried to multiple ClientSize in OnResize and InitSize, but those broke mouse coordinates.

 

void CRenderer::SetViewport(const SViewPort &vp)
{
	m_Viewport = vp;
	const float scaleFactor = 2.f;
	glViewport((GLint)vp.m_X * scaleFactor,(GLint)vp.m_Y * scaleFactor,(GLsizei)vp.m_Width * scaleFactor,(GLsizei)vp.m_Height * scaleFactor);
}

Looks a bit more promising IMHO, but still need to figure out how to get content scale factor in there.

  • Thanks 1
Link to comment
Share on other sites

  • 9 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...