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

Mixing Qt 6 metal implementation with MetalAngle #63

Open
demiantres opened this issue Jul 7, 2021 · 7 comments
Open

Mixing Qt 6 metal implementation with MetalAngle #63

demiantres opened this issue Jul 7, 2021 · 7 comments
Labels
question Further information is requested triage

Comments

@demiantres
Copy link

Hi,

I am currently investigating means for converting a big OpenGL ES 2 based project from Qt 5 to Qt 6 for iOS without sticking with OpenGL. Qt 6 offers a native Metal layer implementation in conjunction with Qt 3D. But this would require to completely rewrite my project from scratch for Qt 3D.

MetalAngle seems to be a perfect solution for my problem. Basically Qt creates the Metal surface for its components (i.e. the Qml user interface). My own code keeps to use OpenGL together with the MetalAngle wrapper. Is this possible, or is it necessary to create all surface initialization stuff with MetalAngle?

Thanks,

@kakashidinho
Copy link
Owner

Could you give an example of how you currently use OpenGL with Qt? So that I can give a concrete advice.
There are multiple ways to use MetalANGLE, depending on your use cases.

  • You could pass CALayer, CAMetalLayer created by Qt to low level EGL API layer to create a MetalANGLE context.
  • Or you could create a shared Metal texture that both Qt and MetalANGLE can draw to.

@demiantres
Copy link
Author

demiantres commented Jul 8, 2021

My OpenGL pipeline also draws to frame buffers so I think a single texture drawing approach will not work.

The CAMetalLayer can be accessed as follows:
CAMetalLayer* layer = static_cast<CAMetalLayer*>([UIApplication sharedApplication].keyWindow.rootViewController.view.layer);

The current OpenGL implementation looks like this:


void draw()
{
	//This all happens in the OpenGL context:

	drawQmlSceneGraph(); // Draws all Qml elements such as the user interface
	
	// Custom GL drawing
	glViewPort(...);
	
	// Example functions used in the project
	glClearColor(...);
	
	glBindVertexBuffer(...);
	glUseProgram(...);
	glBindFramebuffer(...);
	
}

@kakashidinho
Copy link
Owner

Will do some researches on what can be done in Qt 6.

@kakashidinho
Copy link
Owner

For now, the easiest method you can do is creating a metal texture to be shared between Metal & MetalANGLE's GL context.
Then in your draw() function:

  • Draw to shared texture using MetalANGLE's GL commands. You can keep your old GL code here.
  • drawQmlSceneGraph().
  • Use Qt's Metal to blit the shared texture to Qt's screen/default framebuffer.

I can share the detailed sample code later.

@kakashidinho
Copy link
Owner

kakashidinho commented Jul 15, 2021

I created an example of mixing MetalANGLE with Qt's Metal here https://github.com/kakashidinho/qml-metalangle/blob/master/metaltextureimport/metaltextureimport.mm#L430
From repo https://github.com/kakashidinho/qml-metalangle

It is based on Qt's metaltextureimport example where a custom Metal texture is displayed on the screen. This texture was originally rendered by Qt's Metal but in my example, I draw to it using MetalANGLE's GL commands. You will need few extra glue code to make the mixing work though (mostly a shared semaphore (shared event in Metal term) needs to be used to synchronize between two worlds). More details can be seen in the example's code.

drawing

@kakashidinho kakashidinho added the question Further information is requested label Jul 15, 2021
@demiantres
Copy link
Author

Thanks a lot for the example 👍. I will try to adapt it to my project and post the result here then.

@ntadej
Copy link

ntadej commented Mar 3, 2022

I want to achieve something similar. I have existing code that passes framebuffer from Qt to be rendered. Should I start from the same example or could it maybe be done even in a simpler way?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested triage
Projects
None yet
Development

No branches or pull requests

3 participants