[Something to Ponder] WPF in WoW menu

User Tag List

Results 1 to 10 of 10
  1. #1
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [Something to Ponder] WPF in WoW

    I've been doing some research after something amadmonk said the other day.

    With .NET 3.5 SP1, WPF directly uses DirectX to do all rendering (it prefers to push to hardware, but has a full software fallback).

    Anyhow, my research has led me in circles for the most part, but some progress has been made. From what I understand, every WPF 'control' actually renders to a specific D3DSurface (or an HWND as so many people refer to it), which is just used to push the WPF backbuffer into the frontbuffer. (AKA: Present())

    At any rate; after a few hours of messing around looking at various things, I've pretty much given up for the night, and decided to start a little discussion with those who actually understand this stuff. (I'm not a huge fan of WPF due to its old performance issues, but the new stuff is screaming fast, so I may be transitioning soon)

    TL;DR version: In game UIs using WPF. Kgo.

    Eventually I'll get up some example code I'm working on (none of it works honestly...). The worst part is that it requires 90% of the actual 'interop' code to be in either C++/CLI or a COMified C++. Both of which are horrific options IMO,

    If anybody has done any other research on the subject, please do post any findings. I may write a public lib to handle rendering WPF in WoW if I can get it working.

    Edit; before I hear anybody bitching and moaning about using a prebuilt lib such as CEGUI or CEGUI#, I'm specifically avoiding them so I can use the awesome WPF facilities that are available. (Not to mention, awesome design time support via VS or Blend) Having to setup a bunch of XML or other formatting code is a pain in the balls.
    Last edited by Apoc; 02-12-2010 at 11:46 PM.

    [Something to Ponder] WPF in WoW
  2. #2
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yeah, I think you're about where I was on this a couple months back. A bit further, actually. It should, in theory, be possible. I think I got blocked on how to actually tell WPF to use an existing D3DImage based upon an existing D3D handle -- it should be possible, but making it work without COM hacks is dicey.

    At the time, I was looking at SlimDX, because IIRC, it had a critical feature I needed that the managed DX runtime was missing. It's been a while though.

    It would absolutely rock, however. If you could make it work, its rich control palette, strong data binding, and design time support would make things like CEGUI look like tinker toys.

    Edit: here's something similar. I think it's going the other direction (hosting a DirectX app in WPF), but it might help.

    http://www.codeproject.com/KB/WPF/Og...71#xx2829371xx
    Last edited by amadmonk; 02-13-2010 at 06:39 PM.
    Don't believe everything you think.

  3. #3
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, I think we've got it boiled down to what *may* be required (thanks kynox)

    WPF uses Direct3DCreate9 on XP, and D3DC9Ex on Vista+ to do most of it's rendering and updating. The idea is to feed WPF WoW's D3D info instead of a 'new' device. We hope it'll be enough to force it to use WoW's stuff instead (most likely not gonna happen first try obviously) but it's quite possible.

    At any rate, just getting a WPF application to load properly from an injected standpoint is sort of a hassle due to how they have things setup.

    1) They don't 'set' the entry point for the application. You need to do so manually. (Easy: just a small change in the project properties)
    2) They don't declare the [STAThread] attribute in the static Main func. You need to set the thread apartment state *before* calling the entry point. (Again, easy. Thread.CurrentThread.SetApartmentState(ApartmentState.Sta); )
    3) You need to manually set the resource assembly *only* if you're being injected. If you're not injected, you shouldn't set it. (Not an issue if you do your designing all in game, quite an issue otherwise. Though, some simple process ID checking should be enough to handle the issue.)

    Some sample code for #3 up there;

    Code:
    public App()
            {
                // Store it to avoid excessive reflection calls.
                var asmName = Assembly.GetExecutingAssembly().GetName().Name;
                // Find any procs that CONTAIN the assembly name. (This allows us to also include the VS debugger)
                // If the count is 0, that means we're injected into another process.
                // (Eg; the proc name would be Wow.exe, but the assembly is still loaded)
                if (Process.GetProcesses().Where(proc => proc.ProcessName.Contains(asmName)).Count() == 0)
                {
                    ResourceAssembly = Assembly.GetExecutingAssembly();
                }
            }
    It may be a total pain getting it to render in WoW, but research MUST be done!

  4. #4
    adaephon's Avatar Active Member
    Reputation
    76
    Join Date
    May 2009
    Posts
    167
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I've been looking into this a bit myself as well and was interested to see amadmonk's post saying he'd been trying it.

    Admittedly, I haven't done a huge amount, but thought it would be an interesting project to have a go at. I haven't made a huge amount of progress at the moment, but here's a brief summary of what I have done:

    1. Injecting WPF in a similar manner to WinForms (i.e. inject CLR then call a method to start WPF application) works fine* with no extra headaches to WinForms (except the STAThread attribute seems to be ignored, but can be fixed by manually calling SetApartmentState as Apoc said).

    Code:
    public static int DllMain(string arg)
            {
                var guiThread = new Thread(App.Initialise);
                guiThread.SetApartmentState(ApartmentState.STA);
                guiThread.Start();
                return 0;
            }
    Code:
    public static void Initialise()
            {
                App app = new App();
                app.InitializeComponent();
                app.Run(new MainWindow());
            }
    2. Running WPF off the same device as WoW seems to work* (or WoW off the same device as WPF, not sure which initialised first and haven't extensively tested yet). Caveats: WoW can't use a IDirect3DDevice9Ex (pretty sure my hooking function wasn't working, but if WoW uses any D3DPOOL_MANAGED then it wouldn't work off an Ex device anyway, as they don't support managed). However, WPF does seem to run fine* on a IDirect3DDevice9. This was checked by hooking Direct3DCreate9 and Direct3DCreate9Ex, and redirecting the latter to return the former. By no means am I saying this is definitive or accurate, and I can think of a few issues with my 'testing' anyway, but as I said these are my preliminary findings.

    * When I say 'works fine' I'm generally meaning I am able to get a WPF window showing within WoW. This is pretty much a blank window with a background from resources. In the same way as WinForms, this is a separate window that can be moved around independently of the WoW window (windowed mode).

    None of this really leads to a WPF HUD-like integration where WPF controls are overlayed over the DirectX render (which if I understand correctly is actually what you're after - and what I'd ideally love to achieve).

    The next area I'm intending to look at is to see if I can somehow trick WPF into constructing a WPF window from WoW's main window HWND. Or at the very least perhaps load a XAML control tree and attach it / render it from a HwndSource.

    @Apoc: I'm not sure what you were meaning with regards to having to manually bugger around to set the resource assembly? In my experience, I've been able to inject a WPF window and access resources in XAML without having to do any code I wouldn't do in a standard WPF app..
    i.e.:
    Code:
    <Application.Resources>
            <LinearGradientBrush x:Key="Gradient1">
            	<GradientStop Color="#FFC61616" Offset="0"/>
            	<GradientStop Color="#FFB17777" Offset="0.932"/>
    		</LinearGradientBrush>
        </Application.Resources>
    Code:
    <Grid Background="{StaticResource Gradient1}">
            
        </Grid>
    works fine for me without having to do anything unusual.

    EDIT: Hmm no sooner said than I go and change some stuff and start getting XAML parse exceptions with Resources not being found. Interesting, will try your code and see what happens.
    Last edited by adaephon; 02-14-2010 at 05:58 AM.

  5. #5
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well the difference between our implementations requires a few different things.

    My loader (originally kynox's) uses some C++/CLI to automatically find the entry point for the .NET application. (Thus, using an exe to load, instead of a dll)

    So the 'extra' stuff is required.

  6. #6
    adaephon's Avatar Active Member
    Reputation
    76
    Join Date
    May 2009
    Posts
    167
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ah interesting. I'm assuming that lets you run your module as an exe or as an injected module?

    I was fiddling with something before and when I set the owner handle on a WPF window, suddenly it can't find its resources anymore, even using the code you have in your other post. Will have to look into it some more but at least I can get an independent WPF window injected working fine (or so it seems thus far).

  7. #7
    !@^^@!'s Avatar Active Member
    Reputation
    23
    Join Date
    Feb 2007
    Posts
    155
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Okay i've also been doing a little research on this although i by no means are an expert when it comes to Dx, wpf and such but here are a few links i think put together could contribute to a solution for hosting wow inside a WPF window (wich imo is a better option as you could get a cleaner/more userfriendly GUI)

    Introduction to D3DImage - CodeProject (use 3DImage to show the wow dx surface)
    Programming Stuff: Hooking Direct3D9 with C#. (for hooking up and sending the right HWND to get the device/surface that sould be displayed on the 3DImage)
    Walkthrough: Hosting Direct3D9 Content in WPF (some 3DImage info)
    XNA and D3DImage - WOOO! - WPF Disciples | Google Groups (more xna implementation stuff, might be good to see how they do the transistion from xna to wpf and hook up our wow surface instead of the xna one)
    XNA integration inside WPF - CodeProject (more xna again, same reason as above)

    Im tired and haven't really bothered to look all that much at the code of the different articles, but if im completly wrong i'd like to know so i can do some more research on dx in general
    Last edited by !@^^@!; 02-14-2010 at 06:44 PM.

  8. #8
    adaephon's Avatar Active Member
    Reputation
    76
    Join Date
    May 2009
    Posts
    167
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nice info already found most of those links myself in my research but there's a couple there I hadn't seen yet that seem to have some interesting leads. +rep cheers.

  9. #9
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I stopped pursuing the WPF-in-WoW issue because, unless you run WoW full-screen, there's really no benefit to having a shared DX canvas between WPF and WoW. The only real nice-to-have would be to be able to draw directly on the DX scene using WPF, but you're probably better using DX primitives of something like CEGUI for that.

    If you routinely run WoW full-screen, that's a different story. It's a bummer that the 9ex interfaces don't work, since IIRC you need those to get D3DImage working, which you need to avoid the airspace issues that normal WPF compositing has.
    Don't believe everything you think.

  10. #10
    adaephon's Avatar Active Member
    Reputation
    76
    Join Date
    May 2009
    Posts
    167
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You don't need 9ex to get d3dimage working at least not in normal usage. It doesn't exist on xp and thus isn't a requirement to have but it's a nice to have on vista for perf benefits. I don't imagine the perf hit would be too great... Or at least no greater than any arbitrarily complex scene of comparable resolution, as I believe the perf hit is due to speed of copying the directx image to the wpf d3dimage.

    But as you said for non fullscreen there's no real benefit except theinternal 'feel'. But it's still interesting to pursue :-)

Similar Threads

  1. Something Other Than Wow-v Plz.....
    By Snailz in forum World of Warcraft Emulator Servers
    Replies: 7
    Last Post: 12-31-2007, 08:38 AM
  2. WoW login help or something
    By asdsad in forum World of Warcraft General
    Replies: 2
    Last Post: 08-28-2007, 12:27 PM
  3. Replies: 3
    Last Post: 02-11-2007, 10:35 AM
  4. Something to do when the WoW servers are down
    By Fault in forum Community Chat
    Replies: 2
    Last Post: 01-16-2007, 12:52 AM
  5. How do i make WOW screenshots i can it game into jpegs or something i can send?
    By Kaiserdog8390 in forum World of Warcraft General
    Replies: 4
    Last Post: 09-20-2006, 04:45 PM
All times are GMT -5. The time now is 06:19 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search