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

Generate Type-Safe Bindings for OpenGL? #106

Closed
TannerRogalsky opened this issue Nov 20, 2019 · 6 comments
Closed

Generate Type-Safe Bindings for OpenGL? #106

TannerRogalsky opened this issue Nov 20, 2019 · 6 comments
Labels
question & discussion A question or a discussion about a topic

Comments

@TannerRogalsky
Copy link
Contributor

I ask this question knowing that it's beyond the scope of this crate. It just seems like the best to ask in case someone else is wondering the same thing.

Is there a project to use this crate to generate type-safe bindings for communication with OpenGL shaders? If not, have you thought about if that is feasible/what that might look like?

I ask this because of your work on luminance-derive and on this crate. Thanks in advance!

@hadronized
Copy link
Owner

What do you have in mind exactly? I had, in cheddar and spectra, some stuff that would drive pipelines from shaders, but I gave up on that as it was really convoluted.

@TannerRogalsky
Copy link
Contributor Author

I'm definitely more interested in a developer-facing interface generation than driving a pipeline (although I don't pretend they're completely separate). I'm going to try to make something rather than bikeshedding from a position of such limited experience in procedural macros. I'll request your thoughts when I have something that I think illustrates what I have in mind and you can feel free to comment or not. :D

@hadronized
Copy link
Owner

Sure I will! Feel free to share what you have on mind. What kind of bindings are you talking about?

And also, the more people use glsl, the happier I am. 🙂

@hadronized hadronized added the question & discussion A question or a discussion about a topic label Nov 21, 2019
@TannerRogalsky
Copy link
Contributor Author

TannerRogalsky commented Nov 22, 2019

Okay, I have something in place so I feel a little more comfortable commenting. The most basic thing that I think would still be useful is generating, from shader source, type-safe (and cached) bindings to uniforms.

Given something like this:

uniform mat4 projection;

I'd like to generate something like this:

struct MyShader {
    projection: [f32; 16],
    projection_location: u32,
}

impl MyShader {
    pub fn new() -> Self {
        // create & compile shader, get uniform locations, etc
    }
}

pub fn set_projection(&mut self, projection: [f32; 16]) {
    if self.projection != projection {
        unsafe { glUniformMatrix4fv(self.location, 1, false, projection.as_ptr()) }; 
        self.projection = projection;
    }
}

pub fn get_projection(&self) -> [f32; 16] {
    &self.projection
}

There's a lot left out of this. Ensuring this program is active, error handling, other stuff. But this, I think, is the core.

I don't think I'm settled on what the best fit for the macro is yet but this feels the best so far:

#[derive_shader(("./shader.vert", "./shader.frag"))]
struct ShaderTest;

All of this is far from settled but it seems eminently possible and would be useful at least to me.

Thoughts? Ideas? Suggestions?

@hadronized
Copy link
Owner

Ooookay, now I get it. That’s 100% possible, but that would depend on the backend.

  • On gfx, I don’t really see what it would look like.
  • As for luminance, that would mean generating a type implementing UniformInterface, which is completely feasible (and it should be fast to do). However, I don’t really think it’s a thing I would use.

For the last point, let me explain. I tend to see uniforms as a set of GPU variables exposed via a shader program to the host program (i.e. running on a CPU thread). The main problem is how we map from one to another. You have two possibilities:

  • Either you do a 1:1 binding. In this case, two posibilities:
    • The source of truth is on a type on your host program, which means you need to generate GLSL.
    • The source of truth is your GLSL code, which means you need to generate a type in Rust. That corresponds to what you seem to want to do.
  • You don’t want a 1:1 binding and let the possibility to have, either:
    • Some GLSL uniforms unused by the host programs.
    • Some host variables without a GLSL counterpart
    • This situation is what luminance does.

Because I do a lot of data-oriented rendering, I prefer the second option as it’s more flexible, especially when you’re loading shaders on the fly. However, what you want might be useful too, yeah. I’m not sure how to make that backend-agnostic, though.

@TannerRogalsky
Copy link
Contributor Author

You raise some good points. Particularly, I hadn't been thinking about source of truth and how that related to this prospect.

I still think it would be lovely to have more compile-time validation of GLSL (which, really, was the primary goal here) but as that relates to creating a Rust type around the bindings, I'm not sure it's even possible in the way I imagined it. That shaders are compiled at runtime and variables can be optimized away means that a type generated from the GLSL source wouldn't necessarily behave like you'd think.

The joys of OpenGL. :P

Thanks again for your insight and for this crate. This has been illuminating.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question & discussion A question or a discussion about a topic
Projects
None yet
Development

No branches or pull requests

2 participants