Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Render loop for other process

Render loop for other process

Scheduled Pinned Locked Moved C#
winformsgraphicsgame-devjsonhelp
9 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    Jitse
    wrote on last edited by
    #1

    Good day I'm making a backgroundprocess that works as an addon for programs that actually don't support addons. It uses GDI+, and a global keyboard hook, to make the addon work. Now my problem is that I don't really know how to make my render loop. Normally I'd do something that interacts with Application.Idle, and keep on checking if the application is idle by using the Win32 API function PeekMessage and things, but that's when I want a render loop for my own program. Now I actually have to decide when to render for another program. And I don't think I can retrieve in any way when should be the best moment to render for another program. It's not an application though, it's a game, so it has a continuous render loop. So maybe I can just decide for myself when to render? But how would I do that? I never actually really made a good render loop. When I made a game it was the XNA Framework doing it, and if I made an application with a render window or so, it was with the Application.Idle etc. Thanks in advance.

    D 1 Reply Last reply
    0
    • J Jitse

      Good day I'm making a backgroundprocess that works as an addon for programs that actually don't support addons. It uses GDI+, and a global keyboard hook, to make the addon work. Now my problem is that I don't really know how to make my render loop. Normally I'd do something that interacts with Application.Idle, and keep on checking if the application is idle by using the Win32 API function PeekMessage and things, but that's when I want a render loop for my own program. Now I actually have to decide when to render for another program. And I don't think I can retrieve in any way when should be the best moment to render for another program. It's not an application though, it's a game, so it has a continuous render loop. So maybe I can just decide for myself when to render? But how would I do that? I never actually really made a good render loop. When I made a game it was the XNA Framework doing it, and if I made an application with a render window or so, it was with the Application.Idle etc. Thanks in advance.

      D Offline
      D Offline
      Dave Kreskowiak
      wrote on last edited by
      #2

      Depending on how the other game draws itself, you're probably wasting your time. If the other game redraws itself continuously, as do just about every DirectX game out there, then anything you draw on the target form will immediately be overdrawn by the game. At best, your code will have to draw its stuff at the same framerate as the game is drawing (which is usually variable!), and you'll still end up with a horrible flicker that you can't get rid of. Why? Because your code has no access to the drawing buffer in the game. What you see is two buffers, one is visible that the player see, and the other is behind the scenes, being used to draw the next frame. What that frame is complete, the "pages" are flipped. The newly rendered frame is drawn to the screen and the old buffer is used to render the next frame.

      A guide to posting questions on CodeProject[^]
      Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
           2006, 2007

      J 1 Reply Last reply
      0
      • D Dave Kreskowiak

        Depending on how the other game draws itself, you're probably wasting your time. If the other game redraws itself continuously, as do just about every DirectX game out there, then anything you draw on the target form will immediately be overdrawn by the game. At best, your code will have to draw its stuff at the same framerate as the game is drawing (which is usually variable!), and you'll still end up with a horrible flicker that you can't get rid of. Why? Because your code has no access to the drawing buffer in the game. What you see is two buffers, one is visible that the player see, and the other is behind the scenes, being used to draw the next frame. What that frame is complete, the "pages" are flipped. The newly rendered frame is drawn to the screen and the old buffer is used to render the next frame.

        A guide to posting questions on CodeProject[^]
        Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
             2006, 2007

        J Offline
        J Offline
        Jitse
        wrote on last edited by
        #3

        I see, is there a way to bypass that? A window on top of a game window hides the displaying of that piece of the screen drawing, obviously without flickering (because of the z-layering of Windows itself or so). Can I in some way make draw my screen on top of the game instead of in the same window? Then the screen has to be transparent of course, and because the specific regions that are overdrawn by me, overlap the drawing of the game, Windows will automatically disable that region (as it would do with a normal window on top of another normal window), and no flickering would appear. Still the user has to be able to have the game window itself as the active window, so I'd have to make my semi-transparent window an always-on-top window or so. I could draw to a zero pointer (IntPtr.Zero), which makes it the most upper layer (thus the whole screen, ignoring other windows). Still I noticed this flickers. =/ Do you think my idea is worth a try? If yes, how would I do that? Or is it impossible to have some decent drawing in/on a game window by a third party program anyway? Thanks in advance

        D 1 Reply Last reply
        0
        • J Jitse

          I see, is there a way to bypass that? A window on top of a game window hides the displaying of that piece of the screen drawing, obviously without flickering (because of the z-layering of Windows itself or so). Can I in some way make draw my screen on top of the game instead of in the same window? Then the screen has to be transparent of course, and because the specific regions that are overdrawn by me, overlap the drawing of the game, Windows will automatically disable that region (as it would do with a normal window on top of another normal window), and no flickering would appear. Still the user has to be able to have the game window itself as the active window, so I'd have to make my semi-transparent window an always-on-top window or so. I could draw to a zero pointer (IntPtr.Zero), which makes it the most upper layer (thus the whole screen, ignoring other windows). Still I noticed this flickers. =/ Do you think my idea is worth a try? If yes, how would I do that? Or is it impossible to have some decent drawing in/on a game window by a third party program anyway? Thanks in advance

          D Offline
          D Offline
          Dave Kreskowiak
          wrote on last edited by
          #4

          Jitse wrote:

          is there a way to bypass that?

          You're kidding, right?

          Jitse wrote:

          A window on top of a game window hides the displaying of that piece of the screen drawing, obviously without flickering (because of the z-layering of Windows itself or so).

          This doesn't work the way you think it does. The last process to write to a piece of screen real-estate is the winner, even with "transparent" windows. There are no "layers" in GDI or GDI+. The best you're going to be able to do is draw a small window covering just what you want, but you will not be able to "see through it".

          A guide to posting questions on CodeProject[^]
          Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
               2006, 2007

          J 1 Reply Last reply
          0
          • D Dave Kreskowiak

            Jitse wrote:

            is there a way to bypass that?

            You're kidding, right?

            Jitse wrote:

            A window on top of a game window hides the displaying of that piece of the screen drawing, obviously without flickering (because of the z-layering of Windows itself or so).

            This doesn't work the way you think it does. The last process to write to a piece of screen real-estate is the winner, even with "transparent" windows. There are no "layers" in GDI or GDI+. The best you're going to be able to do is draw a small window covering just what you want, but you will not be able to "see through it".

            A guide to posting questions on CodeProject[^]
            Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
                 2006, 2007

            J Offline
            J Offline
            Jitse
            wrote on last edited by
            #5

            Quote: "The best you're going to be able to do is draw a small window covering just what you want, but you will not be able to "see through it"." - By Dave Kreskowiak Seems you were wrong. ;) Credit goes to Rui Godinho Lopes. This is the most important piece of code, works with with the user32.dll UpdateLayeredWindow function. Link is at the bottom. public void SetBitmap(Bitmap bitmap) { IntPtr screenDC = Win32.GetDC(IntPtr.Zero); IntPtr memoryDC = Win32.CreateCompatibleDC(screenDC); IntPtr gdiBitmap = IntPtr.Zero; IntPtr emptyBitmap = IntPtr.Zero; try { gdiBitmap = bitmap.GetHbitmap(); emptyBitmap = Win32.SelectObject(memoryDC, gdiBitmap); Win32.Point pointSource = new Win32.Point(0, 0); Win32.Point topPos = new Win32.Point(_form.Left, _form.Top); Win32.Size size = new Win32.Size(bitmap.Width, bitmap.Height); Win32.BLENDFUNCTION blendFunc = new Win32.BLENDFUNCTION(); blendFunc.AlphaFormat = Win32.AC_SRC_ALPHA; blendFunc.BlendFlags = 0; blendFunc.BlendOp = Win32.AC_SRC_OVER; blendFunc.SourceConstantAlpha = 255; // TODO: TEMP Win32.UpdateLayeredWindow( _form.Handle, screenDC, ref topPos, ref size, memoryDC, ref pointSource, 0, ref blendFunc, Win32.ULW_ALPHA); } finally { Win32.ReleaseDC(IntPtr.Zero, screenDC); if (gdiBitmap != IntPtr.Zero) { Win32.SelectObject(memoryDC, emptyBitmap); Win32.DeleteObject(gdiBitmap); } Win32.DeleteDC(memoryDC); } Here's the link: CodeProject: Per Pixel Alpha Blend in C#[^]

            D 1 Reply Last reply
            0
            • J Jitse

              Quote: "The best you're going to be able to do is draw a small window covering just what you want, but you will not be able to "see through it"." - By Dave Kreskowiak Seems you were wrong. ;) Credit goes to Rui Godinho Lopes. This is the most important piece of code, works with with the user32.dll UpdateLayeredWindow function. Link is at the bottom. public void SetBitmap(Bitmap bitmap) { IntPtr screenDC = Win32.GetDC(IntPtr.Zero); IntPtr memoryDC = Win32.CreateCompatibleDC(screenDC); IntPtr gdiBitmap = IntPtr.Zero; IntPtr emptyBitmap = IntPtr.Zero; try { gdiBitmap = bitmap.GetHbitmap(); emptyBitmap = Win32.SelectObject(memoryDC, gdiBitmap); Win32.Point pointSource = new Win32.Point(0, 0); Win32.Point topPos = new Win32.Point(_form.Left, _form.Top); Win32.Size size = new Win32.Size(bitmap.Width, bitmap.Height); Win32.BLENDFUNCTION blendFunc = new Win32.BLENDFUNCTION(); blendFunc.AlphaFormat = Win32.AC_SRC_ALPHA; blendFunc.BlendFlags = 0; blendFunc.BlendOp = Win32.AC_SRC_OVER; blendFunc.SourceConstantAlpha = 255; // TODO: TEMP Win32.UpdateLayeredWindow( _form.Handle, screenDC, ref topPos, ref size, memoryDC, ref pointSource, 0, ref blendFunc, Win32.ULW_ALPHA); } finally { Win32.ReleaseDC(IntPtr.Zero, screenDC); if (gdiBitmap != IntPtr.Zero) { Win32.SelectObject(memoryDC, emptyBitmap); Win32.DeleteObject(gdiBitmap); } Win32.DeleteDC(memoryDC); } Here's the link: CodeProject: Per Pixel Alpha Blend in C#[^]

              D Offline
              D Offline
              Dave Kreskowiak
              wrote on last edited by
              #6

              Jitse wrote:

              Seems you were wrong. Credit goes to Rui Godinho Lopes. This is the most important piece of code, works with with the user32.dll UpdateLayeredWindow function. Link is at the bottom.

              You haven't tried to cover a DirectX window with this yet, have you??

              A guide to posting questions on CodeProject[^]
              Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
                   2006, 2007

              J 1 Reply Last reply
              0
              • D Dave Kreskowiak

                Jitse wrote:

                Seems you were wrong. Credit goes to Rui Godinho Lopes. This is the most important piece of code, works with with the user32.dll UpdateLayeredWindow function. Link is at the bottom.

                You haven't tried to cover a DirectX window with this yet, have you??

                A guide to posting questions on CodeProject[^]
                Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
                     2006, 2007

                J Offline
                J Offline
                Jitse
                wrote on last edited by
                #7

                Dave Kreskowiak wrote:

                You haven't tried to cover a DirectX window with this yet, have you??

                Was already wondering how I could ever know more than an MVP. ;) I was thinking like: "Where's that catch I'm totally missing.". :laugh: Anyway, yes I did. And it works. Hmmmwell, it almost totally works. I've noticed something weird. I tested it with a few game windows, and they all worked perfectly. (If you want to know: Lord of the Rings Online, Pro Evolution Soccer 6, Tibia.) But! With this game called 'Tibia' (don't search it up, it's a horrible game), I can choose what API to render the game with in the advanced graphics options. You can choose two versions of DirectX, and OpenGL. The DirectX rendering works fine, but when I choose OpenGL the PNG images totally get overdrawn, and are not visible anymore. This is weird though, why would it work with DirectX, but not with OpenGL...? :confused: Or is this just something about the game I tried? Still, it does seem to work perfectly with the other game windows, there's 0% flickering. And the game I primarily want to make an addon for works as well.

                D 1 Reply Last reply
                0
                • J Jitse

                  Dave Kreskowiak wrote:

                  You haven't tried to cover a DirectX window with this yet, have you??

                  Was already wondering how I could ever know more than an MVP. ;) I was thinking like: "Where's that catch I'm totally missing.". :laugh: Anyway, yes I did. And it works. Hmmmwell, it almost totally works. I've noticed something weird. I tested it with a few game windows, and they all worked perfectly. (If you want to know: Lord of the Rings Online, Pro Evolution Soccer 6, Tibia.) But! With this game called 'Tibia' (don't search it up, it's a horrible game), I can choose what API to render the game with in the advanced graphics options. You can choose two versions of DirectX, and OpenGL. The DirectX rendering works fine, but when I choose OpenGL the PNG images totally get overdrawn, and are not visible anymore. This is weird though, why would it work with DirectX, but not with OpenGL...? :confused: Or is this just something about the game I tried? Still, it does seem to work perfectly with the other game windows, there's 0% flickering. And the game I primarily want to make an addon for works as well.

                  D Offline
                  D Offline
                  Dave Kreskowiak
                  wrote on last edited by
                  #8

                  Jitse wrote:

                  Hmmmwell, it almost totally works.

                  You can't say I didn't warn you. :-D

                  A guide to posting questions on CodeProject[^]
                  Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
                       2006, 2007

                  J 1 Reply Last reply
                  0
                  • D Dave Kreskowiak

                    Jitse wrote:

                    Hmmmwell, it almost totally works.

                    You can't say I didn't warn you. :-D

                    A guide to posting questions on CodeProject[^]
                    Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
                         2006, 2007

                    J Offline
                    J Offline
                    Jitse
                    wrote on last edited by
                    #9

                    Dave Kreskowiak wrote:

                    You can't say I didn't warn you.

                    My way works for any game I tried, except one little unknown game, and only when you choose OpenGL as its rendering. So actually it works very well. You were saying, "did you ever try it on an DirectX window", yes I did, with several games, and it all works perfect. You don't seem to be able to explain me why it doesn't work for that one certain game when I choose OpenGL, but still works when I choose DirectX 8 or DirectX 5, or that it works with every other game I tried. Anyone else knows what's the reason for this?

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups