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

Expose reference to original D3D Device of ImguiRenderer #80

Open
Sunderous opened this issue Feb 27, 2023 · 5 comments
Open

Expose reference to original D3D Device of ImguiRenderer #80

Sunderous opened this issue Feb 27, 2023 · 5 comments
Labels
enhancement New feature or request

Comments

@Sunderous
Copy link

Hey, this is more of an enhancement request.

There are some use cases for Imgui (drawing custom overlays in game world space), that are most easily achieved if we have access to the D3D Device that was used when we created the renderer. Not sure about OpenGL at the moment sorry.

The idea being, let's say you want to do an Imgui drawList to draw some lines in the game's world space. Some games already have the projection and view matrices necessary to do this in memory, but in order to call the D3D functions to do the math, you need to pass in the actual device's viewport (device ->GetViewport(*tempViewport)). Which I'm pretty sure wouldn't work with a dummy device, unless you knew the correct creation parameters ahead of time.

So you'd need to hold onto a reference to the D3D device when creating the ImguiRenderer, and expose that to the hooks class that the user actually interacts with in their code.

The alternative is to try and pull the games camera position/orientation + FOV out of memory, and do the math with those but it seems more involved and can't be re-used between games as easily.

The cleanest implementation of this would likely be to expose a function to the user that takes in a 3D vector, projection matrix, and view matrix, and returns the resulting screenspace vector. So that the API is essentially: WorldToScreen(pos, projectionMatrix, viewMatrix) -> screenPos, which could be re-used for any game since the user could handle any position conversions before the function, and handle finding the correct matrices.

If this sounds like something that you'd find useful, once I get to the point I need it I can take a stab at setting it up in a fresh fork. Thanks!

@veeenu
Copy link
Owner

veeenu commented Mar 3, 2023

Hey, this is a great idea! Feel free to submit a PR with this.

A few pointers: I think we may not want to jack up the abstractions and stick to the fundamentals instead; granted most games are going to have a screen-space perspective matrix somewhere but that's not a given, so I think it's going to be hard to find a unifying solution.

A design I'd like would be as follows. I'd have a per-engine trait, say,

pub trait DirectX11Internals {
  fn get_device(&mut self, dev: ID3D11Device);
  fn get_swap_chain(&mut self, dev: ID3D11SwapChain);
}

and the renderer's task would be to register those methods as callbacks and call them accordingly at some point (initialization/resize/whatever). The implementor would have to store that data internally and act on it as desired. I'd like to avoid dynamic dispatch and leverage the compile time type system instead.

Thank you!

@Godnoken
Copy link
Contributor

Godnoken commented May 7, 2023

pub trait DirectX11Internals {
  fn get_device(&mut self, dev: ID3D11Device);
  fn get_swap_chain(&mut self, dev: ID3D11SwapChain);
}

I've tried to implement something like the above, but I don't understand how to make it a part of the hook.

impl HookableBackend for ImguiDx11Hooks {
    fn from_struct<T: ImguiRenderLoop + Send + Sync + Sized + 'static>(t: T) -> Self {
        unsafe { ImguiDx11Hooks::new(t) }
    }
}

I assume I would have to modify this somehow, but I don't know how. Any help is appreciated! :)

@veeenu
Copy link
Owner

veeenu commented May 15, 2023

Might be harder than it looks considering that the type gets erased along the way. I will have to think about this as part of #97 which I wanted to address anyway.

@veeenu veeenu added this to the 0.6.0 milestone May 20, 2023
@veeenu veeenu added the enhancement New feature or request label Aug 19, 2023
@veeenu
Copy link
Owner

veeenu commented Aug 19, 2023

Is this still of interest? I had it planned for 0.5 but I haven't come up with a clean design idea for this, so I will probably postpone this.

@veeenu veeenu removed this from the 0.5.0 milestone Aug 19, 2023
@Sunderous
Copy link
Author

Hey, sorry while I still think it's a good feature, the project I was planning to use it for I've been slacking on for a few months now. So I'm not near a point that I would personally use it, but I do think there's value in figuring it out at some point in the future. If the library gets wider adoption, I imagine more people will have use cases where they want to be able to draw arbitrary things in world space. But if nobody else is asking right now, can't hurt to let it percolate a bit until a clean design presents itself haha.

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

No branches or pull requests

3 participants