Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: SFML on PictureBox with no render loop and GDI+  (Read 5055 times)

0 Members and 1 Guest are viewing this topic.

metx

  • Newbie
  • *
  • Posts: 3
    • View Profile
SFML on PictureBox with no render loop and GDI+
« on: November 01, 2013, 11:22:33 am »
Hi Guys,

First, congrats to the authors for a great library from a new user! I've been looking for a long time for a replacement for the GDI/GDI+ drawing routines I use in my application until I found your site. Keep up the great job you are doing.

I have a couple of questions so let's start from the top. In my WinForm application I have a System.Windows.Forms.PictureBox that is hosting a SFML RenderWindow. Since my app is not a game I have no need for high framerates or continuous redrawing via a render loop. The graphics (entire window) are redrawn only if some information changes or the form/PictureBox is resized. So the framerate could be said to be "on demand". I have been playing around with this a few days and while it seems to work without glitches I still have to ask before proceeding with more complex implementations; should I expect any problems using this kind of logic with SFML.Net?

Question two concerns mixing SFML drawing with GDI+ in a PictureBox: I am able to mix the two by creating a new System.Windows.Bitmap, drawing on it, returning it as a MemoryStream to SFML.Image and from there create a Texture and then Sprite before finally drawing it on the RenderWindow along the other SFML graphics. Everything looks great concerning transparency and so on. However, I initially tried the reverse, i.e. finalize the SFML graphics, then create a System.Drawing.Graphics object using the RenderWindow handle and draw the GDI+ stuff on that. This also worked to a degree, the problem is that transparency is not preserved using this method. For example, drawing a GDI+ circle would cause the background under it to have some solid color (probably the parent Form's background color) and effectively overdraw everything underneath. This was not the outcome I expected but perhaps I am missing something here. Could it be related to the underlying bitmap format? I need the GDI+ drawing for some overlay information and the latter method would probably be more efficient since it does not involve creating a MemoryStream, Image, Texture and Sprite. But if not possible I'll just stick with what works or eventually switch over to full SFML drawing.

If needed I'd be happy to provide sample code or screenshots demonstrating the above problem.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: SFML on PictureBox with no render loop and GDI+
« Reply #1 on: November 01, 2013, 02:52:19 pm »
These are two situations SFML is not designed for, so I'm afraid I can't answer you. All I can say is that you may face unexpected problems. Are you really sure that SFML is the best tool for what you want to do?
Laurent Gomila - SFML developer

metx

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: SFML on PictureBox with no render loop and GDI+
« Reply #2 on: November 01, 2013, 04:56:31 pm »
I can easily draw in a render loop if that is required to guarantee stability. Will be bit of an overkill for my app which does not update the contents excessively but should not be a problem otherwise. The GDI+ stuff is just some legacy code that I can do away with.

To answer your question, I've been over MonoGame, SDL, SlimDX SharpDX, SharpGL and OpenTK which are either buggy, poorly maintained, not suited for 2D primitives drawing or poorly documented. I've also tried WPF which turned out to be a huge dissapointment in terms of performance. GDI, while sufficiently fast on WinXP/7/8, is considered deprecated technology by Microsoft and not hardware accelerated on Vista. GDI+ of course is all software rendered and unacceptably slow. Direct2D would be an alternative but it's not supported on XP. This essentially also rules out the SharpDX/SlimDX libs which both wrap D2D. From what I have seen so far SFML is the only library that ticks all the boxes I need.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: SFML on PictureBox with no render loop and GDI+
« Reply #3 on: November 01, 2013, 05:22:21 pm »
What I don't understand is that your app doesn't require constant refresh, yet you talk about performances. What exactly is slow with GDI+?
Laurent Gomila - SFML developer

metx

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: SFML on PictureBox with no render loop and GDI+
« Reply #4 on: November 01, 2013, 08:07:27 pm »
This is a form of mapping software that draws vector maps with an optional terrain layer. Once a map is drawn it doesn't have to change until the user interacts with it, for example zooming or repositioning, or the window is resized. As an example, the 2D terrain rendering for central Europe with GDI+ takes 6 seconds compared to 3 secs with GDI. A bit is too slow. The actual performance is required at the point when the map needs to be redrawn.

Chris12

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: SFML on PictureBox with no render loop and GDI+
« Reply #5 on: November 16, 2013, 09:24:12 am »
Do you just want to draw inside a Form? Then try the following code.
After copying my code you just need to add a timer, set it's interval to 5ms and enable it.

Quote
   public partial class Form1 : Form
   {
      RenderWindow renderWnd;
      public Form1()
      {
         InitializeComponent();
         SetDoubleBuffered(panel1);
      }

      protected override void OnShown(EventArgs e)
      {
         base.OnShown(e);
         renderWnd = new RenderWindow(panel1.Handle, new ContextSettings(32, 0, 8));
      }

      public static void SetDoubleBuffered(Control c)
      {
         System.Reflection.PropertyInfo aProp =
              typeof(Control).GetProperty(
                  "DoubleBuffered",
                  System.Reflection.BindingFlags.NonPublic |
                  System.Reflection.BindingFlags.Instance);

         aProp.SetValue(c, true, null);
      }

      private void timer1_Tick(object sender, EventArgs e)
      {
         renderWnd.Clear(new SFML.Graphics.Color(0,0,0));

         var circle = new CircleShape(5);
         circle.FillColor = SFML.Graphics.Color.Red;
         var cursor = panel1.PointToClient(MousePosition);
         circle.Position = new Vector2f(cursor.X, cursor.Y);

         renderWnd.Draw(circle);

         renderWnd.Display();
      }
   }