Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run Magnum on different runtime #385

Closed
janbajana opened this issue Nov 4, 2019 · 12 comments
Projects
Milestone

Comments

@janbajana
Copy link

@janbajana janbajana commented Nov 4, 2019

Magnum has runtime implementation in Magnum::Application.
We have our own runtime implementation for Android using EGL, GLES3, and directly Qualcomm services, DRM mainline graphics stack.
We also generate our glGenFramebuffers. I know Magnum has this GL/DefaultFramebuffer.
I am still not so familiar with Magnum API.

I want to use Magnum as rendering middleware on the application level with our runtime.
I can call direct GL wrapper like:
GL::Renderer::setClearColor({0.5, 0, 0, 1});

The app crashes if I try to call Mesh, Shader and other:
GL::defaultFramebuffer.clear(GL::FramebufferClear::Color);
GL::Mesh _mesh;
Shaders::VertexColor2D _shader;

There is nothing in the logs.

I know it is difficult to say without the code and logs.
But are there any ideas what should I set up for Magnum? Should I somehow pass our framebuffers or rendering textures to Magnum?

This was just one day afford, I will try more tomorrow to get some logs.
Thank you for your thoughts.

@mosra mosra added this to the 2019.1c milestone Nov 5, 2019
@mosra mosra added this to TODO in GL via automation Nov 5, 2019
@mosra

This comment has been minimized.

Copy link
Owner

@mosra mosra commented Nov 5, 2019

Hi!

The Application classes are provided for convenience of 90% of users, but are completely optional. Magnum can work without them, but then you're responsible for creating a GL context on your own and then instantiating GL::Context and keeping it alive as long as you want to call Magnum GL APIs.

The crashes you're getting are because the GL::Context is querying GL function pointers, setting up a state tracker etc., and if you don't instantiate it, glGenVertexArrays() and such are nullptr and thus the app crashes (or aborts, when it tries to access a nonexistent GL::Context instance).

Docs to help you with the custom setup: https://doc.magnum.graphics/magnum/platform.html#platform-custom

Let me know if you need anything else.

EDIT: in the logs, if you adb logcat *:S magnum, it should something like the following -- indicating that a GL::Context instance is not set up. If not, then it probably called a nullptr GL function pointer and died right away.

magnum : GL::Context::current(): no current context

If GL::Context is set up properly, then the Android log output should contain "the usual" engine startup log, like you're used to from desktop.

@janbajana

This comment has been minimized.

Copy link
Author

@janbajana janbajana commented Nov 5, 2019

Super thank you for the update. Now it looks working.
Following QT example:
https://github.com/mosra/magnum-bootstrap/blob/base-qt/src/MyApplication.cpp

Is it recommended to call resetState?
GL::Context::current().resetState(GL::Context::State::ExitExternal);

We are binding our frame buffers with stereoscopy setup so I do not do any calls to GL::defaultFramebuffer.
So my render call at the end looks like this but I am not sure if resetState is necessary here:

void CubeDelegate::onRenderView(Runtime& /* self */, const RenderParams& renderParams)
{
    GL::Context::current().resetState(GL::Context::State::ExitExternal);

    GL::Renderer::setClearColor({0.5, 0, 0, 1});
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    _mesh->draw(*_shader);

    GL::Context::current().resetState(GL::Context::State::EnterExternal);
}
@mosra

This comment has been minimized.

Copy link
Owner

@mosra mosra commented Nov 5, 2019

In that case, instead of calling GL APIs directly, I recommend wrapping the custom framebuffer with GL::Framebuffer::wrap() and using Magnum's own APIs to clear it. You can find more info (although still Qt-related) on the mailing list archives, e.g.:

The resetState() is needed when code (either yours or from a 3rd party lib) calls into GL, creates GL objects and so on (in case of Qt, Qt itself is using OpenGL to render itself, so there it was needed). If you're 100% sure there's no such thing happening, you don't need to.

@janbajana

This comment has been minimized.

Copy link
Author

@janbajana janbajana commented Nov 6, 2019

Ok, I see. Thanks for the info.
I have to think more about this later. Currently, we are hiding FrameBuffer setup and binding behind the implementation. Also glClear().
So for now I can not use GL::Framebuffer class, so my render call looks like this:

void 
AppDelegate::onRenderView(Runtime& /* self */, const RenderParams& renderParams)
{
    GL::Context::current().resetState(GL::Context::State::ExitExternal);

    const RenderParams& r = renderParams;
    glViewport(r.viewPort.origin.x, r.viewPort.origin.y, r.viewPort.dimensions.width, r.viewPort.dimensions.height);

    mCubeMagnum->draw(renderParams.viewMatrix,
                      renderParams.projectionMatrix);

    GL::Context::current().resetState(GL::Context::State::EnterExternal);
}

Only glViewport() remains. This setup looks good for now. I am going to write some shaders to render with our projection params.
I am going to have a look also on OvrIntegration for Magnum. How it is done there.

Another thing I will be testing with Magnum is GL_OVR_multiview2 extension.
https://arm-software.github.io/opengl-es-sdk-for-android/multiview.html

Really thanks for the support and fast answers.

@mosra

This comment has been minimized.

Copy link
Owner

@mosra mosra commented Nov 6, 2019

As long as you don't use magnum's GL:.Framebuffer for anything else, calling glBindFramebuffer(), glViewport(), glClear() directly will be fine. Once you start using the magnum framebuffer classes for offscreen rendering, you'll need to resetState() with State::Framebuffers to avoid state tracker confusion. (But I still think you could "just" use GL::Framebuffer::wrap() and avoid all those issues, there shouldn't be any bad interactions coming from this API.)

For the multiview extension I'll check and ping you back, I think someone already did some investigation (or maybe a partial implementation already).

@mosra

This comment has been minimized.

Copy link
Owner

@mosra mosra commented Nov 8, 2019

Regarding OVR_multiview: unfortunately there's no in-progress implementation I know of, however I added at least the entry points for it -- see a0fa21c.

@janbajana

This comment has been minimized.

Copy link
Author

@janbajana janbajana commented Nov 8, 2019

Hi Vladimír,

thank you for your answers. This will help us to make future decisions about integration.
For GL::Framebuffer::wrap() I have to change our API because it requires Framebuffer id which we do not expose yet.

So far all looks good and I have working Magnum on our devices.
I have one more problem and it is compiled-in resources from Utility::Resource for Android. I am not sure my cmake config is right. Any ideas, here is my config?
https://github.com/janbajana/magnum-bootstrap-android/blob/master/src/CMakeLists.txt

corrade_add_resource(MagnumBootstrapData_RESOURCES resources/resources.conf)
add_library(MyApplication SHARED ${native_heads} ${native_srcs} ${MagnumBootstrapData_RESOURCES})

Compilation error is:
ninja: error: '/c/Corrade/bin/corrade-rc.exe', needed by 'src/resource_MagnumBootstrapData_RESOURCES.cpp', missing and no known rule to make it

@mosra

This comment has been minimized.

Copy link
Owner

@mosra mosra commented Nov 8, 2019

This looks like some bad interaction between a MinGW / Git Bash shell and CMake .. :/ Are you passing CORRADE_RC_EXECUTABLE on the command-line? Then the shell is probably changing C:/ to /c/ which CMake doesn't understand. Some options:

@janbajana

This comment has been minimized.

Copy link
Author

@janbajana janbajana commented Nov 8, 2019

Yes, you are right. I was passing the path in Git Bash format.
If I run gradlew from the Git Bash command line all is working. But from Android Studion it did not work. I should go back to Linux probably :). All god now. Thanks.

One more question. What is the prefered coordinate system in Magnum?
Left or Right handed?

@mosra

This comment has been minimized.

Copy link
Owner

@mosra mosra commented Nov 8, 2019

The preferred one is what matches OpenGL -- +X is to the right, +Y up, +Z backward.

@mosra

This comment has been minimized.

Copy link
Owner

@mosra mosra commented Nov 18, 2019

@janbajana anything left to be done here? :)

@janbajana janbajana closed this Nov 25, 2019
GL automation moved this from TODO to Done Nov 25, 2019
@janbajana

This comment has been minimized.

Copy link
Author

@janbajana janbajana commented Nov 25, 2019

No, thanks for help. Forgot to close this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
GL
  
Done
2 participants
You can’t perform that action at this time.