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

Add texture drawing example [help needed] #2

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

faern
Copy link
Contributor

@faern faern commented Mar 18, 2024

Do you know how to draw textures with glium in a gtk4 application? I completely fail doing so and I find no good examples of this being done online. So I thought I'd kill two birds with one stone by submitting an example. This example does not yet work. But if we can figure out what's wrong together and fix it, and merge it, then we have a working example for others to learn from.

This example is an adaptation of glium's own texture drawing example. That example works! But I can't make the same texture loading + drawing code work in a gtk4 application.

I have also asked the same question in the gtk4-rs repository. But I thought I can do the same here since this library is supposed to be a smooth overlap between glium and gtk4.

@remcokranenburg
Copy link
Owner

Thanks for diving into this! I haven't used gtk4-glium myself extensively, so I never got around to figuring out texturing. My free time is limited, so I can't promise working on this, but I'd definitely welcome a solution and push a new release to crates.io.

@faern
Copy link
Contributor Author

faern commented Mar 20, 2024

Ok! I'm not actively debugging this right now. I kind of gave up since I found no pointers as to what was wrong, and I have not found anyone with expertise in the area to ask. I'm currently exploring reworking my app in a different UI framework instead 😂 But if I find a solution I'll surely post it here!

@remcokranenburg
Copy link
Owner

No worries, it's all volunteer work here! 😃

@remcokranenburg
Copy link
Owner

I don't know exactly how or why, but I got it working when I introduced a second dummy texture!

https://github.com/remcokranenburg/gtk4-glium/tree/add-texture-drawing-example

@remcokranenburg
Copy link
Owner

I've tried several combinations of the same and different textures, in different orders. I can't quite figure out the pattern here. It seems like one texture needs to be loaded into a place so that the next one gets loaded correctly to draw with.

@faern
Copy link
Contributor Author

faern commented Mar 26, 2024

Did you push the working version to that branch? Because I checked it out now, and I still just have a black frame 🤔

EDIT: I'm trying out 7a6ab22

@faern
Copy link
Contributor Author

faern commented Mar 26, 2024

An indication that something is awfully wrong, is what happens if I change all the TexVertex::position corners to be at 0.9 and -0.9 instead of at the exact corners. And then change the clear color to a dark blue. If everything worked as expected I would get a blue border and the texture properly drawn in a rectangle in the middle. But I get these behaviors depending on how I draw:

  1. My initial example, just sample a single texture: The rectangle draw call does nothing. The entire window is evenly dark blue (clear color)
  2. Your example, loading and sampling two textures for each fragment: Wow, see attached screenshot. It renders smaller and smaller rectangles with different shades of blue, and it's all very glitchy. You can't see it in the single screenshot, but it flickers a lot. It feels like there is a bunch of invalid memory access going on here, drawing color values and coordinates from the wrong places?

screenshot_2024-03-26_23-27-50

My diff
diff --git a/examples/texture.rs b/examples/texture.rs
index c317b48..7f08873 100644
--- a/examples/texture.rs
+++ b/examples/texture.rs
@@ -19,19 +19,19 @@ fn create_rectangle_buffer<F: Facade>(context: &F) -> VertexBuffer<TexVertex> {
         context,
         &[
             TexVertex {
-                position: [-1.0, 1.0],
+                position: [-0.9, 0.9],
                 tex_coords: [0.0, 1.0],
             },
             TexVertex {
-                position: [1.0, 1.0],
+                position: [0.9, 0.9],
                 tex_coords: [1.0, 1.0],
             },
             TexVertex {
-                position: [-1.0, -1.0],
+                position: [-0.9, -0.9],
                 tex_coords: [0.0, 0.0],
             },
             TexVertex {
-                position: [1.0, -1.0],
+                position: [0.9, -0.9],
                 tex_coords: [1.0, 0.0],
             },
         ],
@@ -129,7 +129,7 @@ fn main() {

             let mut frame = Frame::new(context.clone(), context.get_framebuffer_dimensions());

-            frame.clear_color(0.0, 0.0, 0.0, 1.0);
+            frame.clear_color(0.0, 0.0, 0.2, 1.0);

             frame
                 .draw(

I have this exact behavior both in debug builds and release builds on two different Fedora machines running Sway (Wayland).

@remcokranenburg
Copy link
Owner

Yes there must be going something wrong with the accounting of texture memory. I'm suspecting that some textures are secretly already loaded in from GTK side, but Glium doesn't know, so it allocates the same GPU memory again. Or the other way around. I'll try to do some more debugging soon.

@faern
Copy link
Contributor Author

faern commented Mar 27, 2024

Haha. Wow, OpenGL global state 🤯 Interesting. At least you are on to something here! I'm not at all an OpenGL expert. I'll try to read up on the topic, but we'll see. I wish you good luck with debugging this! 💪

@faern
Copy link
Contributor Author

faern commented Mar 27, 2024

I was hoping it would then work to tell GTK to not render itself with OpenGL, but GSK_RENDERER=cairo target/debug/examples/texture made no difference.

@faern faern force-pushed the add-texture-drawing-example branch from a7a8bd3 to e4f3f3f Compare March 27, 2024 18:34
@faern
Copy link
Contributor Author

faern commented Mar 27, 2024

So, it works if I load the texture inside the glarea.connect_render closure. Meaning on every frame render. This way I'll load it just when needed, and not let GTK get in between and mess stuff up. I pushed this actually working example to this branch. But it's of course not in a nice enough state to merge, there is still a pretty nasty bug somewhere in glutin or gtk4.

This fixes the issue of colliding somewhere with GTK
@faern faern force-pushed the add-texture-drawing-example branch from e4f3f3f to 5fb28ea Compare March 27, 2024 18:37
@remcokranenburg
Copy link
Owner

I spent a few moments this weekend exploring the problem and I think it's a mismatch of OpenGL state between Glium and GTK. I haven't tried it yet, but I think we need to print the current state before all of our drawing calls and once more after all of our drawing calls, then we'll probably see that Gtk messes with the texture IDs. It might be messing with more than just the textures.

Then, the fix will be to either make Gtk stop messing with the OpenGL context, or to inform Glium of the changes. Glium maintains state so that it doesn't have to send a bunch of commands every frame, so it might be a bit of a performance issue if we just do a complete reset of OpenGL state every frame.

Anyway, something to look for at least.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants