Jump to content

  • Log In with Google      Sign In   
  • Create Account


Tape_Worm

Member Since 21 Apr 2000
Offline Last Active Yesterday, 07:46 AM

Topics I've Started

Weird behaviour when changing RIDEV_CAPTUREMOUSE on register

15 August 2014 - 09:26 AM

So I'm having the weirdest issue with Raw Input.  

 

So I have a nice little wrapper class for Raw Input, and on that wrapper I have an "Exclusive" mode (kinda like what DirectInput did) property.  This property calls RegisterRawInputDevices with the dwFlags member set to RIDEV_CAPTUREMOUSE | RIDEV_INPUTSINK | RIDEV_NOLEGACY when Exclusive is TRUE and to 0 when I set Exclusive to FALSE.

 

Now for the weirdness.  If I try to set Exclusive to TRUE by right-clicking the mouse down and set Exclusive to FALSE on mouse up, it sometimes deactivates my window messes up the state since exclusive gets turned off when the window loses focus.  This happens randomly.  When it "works" and the mouse goes into exclusive mode and out of exclusive mode my window stops responding to mouse over events in the window decorations (e.g. the close button doesn't highlight), I can't press ALT+F4 to exit the application (although other key presses are intercepted with no problems), and I can't click on the close button until I left click on the window.  Also, sometimes Windows explorer gets all messed up when this happens.  For example, on the taskbar, no icons respond to mouse events and I have to right click a couple of times to get it responding again.

 

I've tried this code on two machines with Windows 7, and Windows 8.1 (x64 for both) and both exhibit the same behaviour.  I've dug around on-line and I can't find anything related to this.

 

I considered that it might be due to calling RegisterRawInputDevices multiple times without unregistering the device.  So, I unregistered by settings the dwFlags to RIDEV_REMOVE and setting the window handle to NULL before registering the device with the new dwFlags combination, but that didn't work.

 

Could it be due to the flags I'm using?  Could it be due to calling RegisterRawInputDevices multiple times?  Could this just be a quirk with Raw Input?  

 

Here's the code that registers the device just for clarity (FYI, GetRawData just reads the data sent back by the WM_INPUT message, and does little else, so I did not include it):

		protected override void BindDevice()
		{
			BoundControl.MouseLeave -= Owner_MouseLeave;

			_device.UsagePage = HIDUsagePage.Generic;
			_device.Usage = (ushort)HIDUsage.Mouse;
			_device.Flags = RawInputDeviceFlags.Remove;
			_device.WindowHandle = IntPtr.Zero;

			// Attempt to register the device.
		    if (!Win32API.RegisterRawInputDevices(_device))
		    {
		        throw new BindException(Resources.RAW_CANNOT_UNBIND_POINTING_DEVICE);
		    }


			if (_messageFilter != null)
			{
				_messageFilter.RawInputPointingDeviceData -= GetRawData;
				_messageFilter.RawInputPointingDeviceData += GetRawData;
			}

			_device.UsagePage = HIDUsagePage.Generic;
			_device.Usage = (ushort)HIDUsage.Mouse;
			_device.Flags = RawInputDeviceFlags.None;

			// Enable background access.
		    if ((AllowBackground) || (Exclusive))
		    {
		        _device.Flags |= RawInputDeviceFlags.InputSink;
		    }

		    // Enable exclusive access.
			if (Exclusive)
			{
				_device.Flags |= RawInputDeviceFlags.CaptureMouse | RawInputDeviceFlags.NoLegacy;
			}

		    _device.WindowHandle = BoundControl.Handle;

			// Attempt to register the device.
		    if (!Win32API.RegisterRawInputDevices(_device))
		    {
		        throw new BindException(Resources.RAW_CANNOT_BIND_POINTING_DEVICE);
		    }

			if (!Exclusive)
			{
				OnWindowBound(BoundControl);
			}
		}

And this is how I process the WM_INPUT message, I register this message filter using Application.AddMessageFilter(MessageFilter);:

	internal class MessageFilter
		: System.Windows.Forms.IMessageFilter
	{
		#region Events.
		/// <summary>
		/// Event fired when a raw input keyboard event occours.
		/// </summary>
		public event EventHandler<RawInputKeyboardEventArgs> RawInputKeyboardData = null;
		/// <summary>
		/// Event fired when a pointing device event occurs.
		/// </summary>
		public event EventHandler<RawInputPointingDeviceEventArgs> RawInputPointingDeviceData = null;
		/// <summary>
		/// Event fired when an HID event occurs.
		/// </summary>
		public event EventHandler<RawInputHIDEventArgs> RawInputHIDData = null;
		#endregion

		#region Variables.
		private readonly int _headerSize = DirectAccess.SizeOf<RAWINPUTHEADER>();	// Size of the input data in bytes.
		#endregion

		#region IMessageFilter Members
		/// <summary>
		/// Filters out a message before it is dispatched.
		/// </summary>
		/// <param name="m">The message to be dispatched. You cannot modify this message.</param>
		/// <returns>
		/// true to filter the message and stop it from being dispatched; false to allow the message to continue to the next filter or control.
		/// </returns>
		public bool PreFilterMessage(ref System.Windows.Forms.Message m)
		{
			// Handle raw input messages.
			if ((WindowMessages)m.Msg != WindowMessages.RawInput)
			{
				return false;
			}

			unsafe
			{
				int dataSize = 0;

				// Get data size.			
				int result = Win32API.GetRawInputData(m.LParam, RawInputCommand.Input, IntPtr.Zero, ref dataSize, _headerSize);

				if (result == -1)
				{
					throw new GorgonException(GorgonResult.CannotRead, Resources.GORINP_RAW_CANNOT_READ_DATA);
				}

				// Get actual data.
				var rawInputPtr = stackalloc byte[dataSize];
				result = Win32API.GetRawInputData(m.LParam, RawInputCommand.Input, (IntPtr)rawInputPtr, ref dataSize, _headerSize);

				if ((result == -1) || (result != dataSize))
				{
					throw new GorgonException(GorgonResult.CannotRead, Resources.GORINP_RAW_CANNOT_READ_DATA);
				}

				var rawInput = (RAWINPUT*)rawInputPtr;

				switch (rawInput->Header.Type)
				{
					case RawInputType.Mouse:
						if (RawInputPointingDeviceData != null)
						{
							RawInputPointingDeviceData(this,
							                           new RawInputPointingDeviceEventArgs(rawInput->Header.Device, ref rawInput->Union.Mouse));
						}
						break;
					case RawInputType.Keyboard:
						if (RawInputKeyboardData != null)
						{
							RawInputKeyboardData(this, new RawInputKeyboardEventArgs(rawInput->Header.Device, ref rawInput->Union.Keyboard));
						}
						break;
					default:
						if (RawInputHIDData != null)
						{
							var HIDData = new byte[rawInput->Union.HID.Size * rawInput->Union.HID.Count];
							var hidDataPtr = ((byte*)rawInput) + _headerSize + 8;

							fixed (byte* buffer = &HIDData[0])
							{
								DirectAccess.MemoryCopy(buffer, hidDataPtr, HIDData.Length);
							}

							RawInputHIDData(this, new RawInputHIDEventArgs(rawInput->Header.Device, ref rawInput->Union.HID, HIDData));
						}
						break;
				}
			}

			return false;
		}
		#endregion


Weird corruption when drawing text with DrawString

07 March 2014 - 10:18 AM

OK, so I'm experiencing the weirdest problem.  I'm drawing some text and it's showing up corrupted:

Attached File  Corrupted.png   15.71KB   4 downloads

 

So, as you can see, the image on the left shows the corrupted text in Windows 8.1 and on the right the actual text is being rendered correctly in Windows 7.  

 

The corruption only happens when I have the CompositingMode set to SourceCopy and the TextRenderingHint set to SingleBitPerPixel (with and without GridFit).  I require SourceCopy as my compositing mode because I need to write to the alpha channel of the bitmap instead of blending the alpha with the bitmap contents.

 

The code that draws this text is incredibly simple, so I am at a loss as to why this is happening.  

 

Anyone else run into this problem?  Know of a way around it?

 

Here's the code that I used to repro the error:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TestFontAntiAlisBug
{
    public partial class Form1 : Form
    {
        private Bitmap _image;
        private Font _font;

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            _font = new Font("Andalus", 48.0f, GraphicsUnit.Point);
            _image = new Bitmap(256, 256, PixelFormat.Format32bppArgb);

            using (Graphics g = Graphics.FromImage(_image))
            {
                g.Clear(Color.Black);
                g.CompositingMode = CompositingMode.SourceCopy;
                g.CompositingQuality = CompositingQuality.HighQuality;
                g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;

                using (Brush brush = new SolidBrush(Color.White))
                {
                    g.DrawString("Are you corrupted?", _font, brush, new PointF(0, 0));
                }
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            e.Graphics.DrawImage(_image, new Point(0, 0));
        }

        public Form1()
        {
            InitializeComponent();
        }
    }
}


Performance of geometry shaders for sprites instead of batching.

25 September 2012 - 02:16 PM

I haven't really used the Geometry Shader stuff before. I'm old and don't like change. It frightens me.

But, currently with Gorgon I'm recycling a dynamic vertex buffer to display my sprites. Basically if the sprites use the same texture, shader, etc... it adds the sprite to the buffer until it's full or until there's a state change. If the buffer is full, then it's discarded, otherwise more sprites get appended until full. Upon state change or discard, it gets flushed to the render target in one draw primitive call. This seems pretty standard to me, and it's been working quite well for me.

However, I've been giving some thought to using a geometry shader to stream out the sprites. I've done a little reading and it seems that this is an ideal use case for GS. But, apparently there's a few gotcha's with these shaders? Notably, the 1024 32 bit float limit. I understand that the size of data out might an issue as well?

Currently, I'm using a position, color and uv coordinates for my sprites vertices. I suspect I'd need to send all of these, and more besides to shader to meet my needs. So would that cause an issue? I pre-transform my vertices before sending them to the vertex buffer (i.e. no world matrix, I've found this to improve performance), and update the vertex position by the camera and projection matrix in the vertex shader. Will this cause an issue?

Has anyone here used a GS to power a sprite renderer? Did you compare its performance to a batched solution (like the one I presented above)? I'm not able to set up a test project for the time being, so if I could get some feedback, that'd be swell.

Thanks.

File I/O streaming performance.

17 September 2012 - 09:28 AM

I have a Windows application in C++ here that's got a very large file to stream in. The file is ~5GB in size, and currently the code does this:
  • Open file if not already open.
  • Read in a block of data (~9 MB)
  • Copy to volume texture
  • Render
  • Repeat...
The file access is sequential and called at the end of every frame and currently I'm using the CRT file I/O stuff (fopen, fseek, fread, and fclose). And I'm wondering if there's a better way with regard to performance?

Would using memory mapped files be a good idea here? I've read conflicting statements about performance when it comes to reading a file sequentially.

I've considered loading a larger chunk of the file (i.e. multiple volume textures) in one shot, but I'm thinking that it'll hit a bottleneck when it's used up those textures and has to read in the next chunk.

Obviously, I can't read in the entire file (needs to run on 32 bit, that'd kill my process space quickly) and because of the environment I have to use (I really have no choice regarding this) I can't use threading.

Thanks.

Getting spam

28 May 2012 - 07:06 PM

I don't know who to contact about this, or if this is the right forum for this, but I just received a spam message:

nice to meet you
MY dear friend my name is
morein i,m very decent girl
with honest love caring please
i will like be your friend
wirte me back with my mail
(email)
so that i will give you my picturesmy
i found your profile here
It's never my desire to remain what I am now,
but struggling to become what am.
pls dont reply me in dis site( website)
reply me in dis email

(email)


The user name is morein500

Just letting you guys know.

PARTNERS