Skip to main content
gamedev.net
🔒 Locked

Cursor without Windows API?

Started by Adams555 16 replies 2.3k views
Original Post
Adams555
Adams555
Hello. I got rid of the windows message handler because I really dont want peolpe in my game to be able to alt tab away etc. I'll write my own simple message handler if it is really neccesary. But now I need to add a cursor. I'm usign direct3d. I have the position of the mouse already. What I need to know is how to render a model specifically on a certain point on the screen.. rather than in world coordinates. How can I do this? Thanks.
Agony
Agony
You'll probably just want to switch your projection and view matrices to be orthogonal, something like this:
D3DXMatrixOrthoOffCenterLH(&mProjectionMatrix, 0.0f, (float)mScreenWidth, (float)mScreenHeight, 0.0f, 0.0f, 1.0f);D3DXMatrixIdentity(&mViewMatrix);D3DXMatrixIdentity(&mWorldMatrix);mpDevice->SetTransform(D3DTS_PROJECTION,     &mProjectionMatrix);mpDevice->SetTransform(D3DTS_VIEW,           &mViewMatrix      );mpDevice->SetTransform(D3DTS_WORLDMATRIX(0), &mWorldMatrix     );

Then you'll basically be in screen coordinate space. Vertex coordinates will match up with pixel coordinates. The z axis still affects depth and the depth buffer and all, but there isn't any shrinking of objects as they get farther away, so x and y are all that really matter.

Then, when you're done rendering your mouse, you can just set the transforms back to what you normally use. Probably at the beginning of every frame, you'd set them back to normal, and then near the end of every frame, use the orthographic mode instead, turn off the z-buffer, and draw the cursor. Then present and repeat.
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas nly, and not for things themselves." - John Locke o
Adams555
Adams555
odd.... when I set it to orthogonal, my cursor jsut doesn't show up anymore at all. I did turn off the zbuffer.. No idea what went wrong.. I have this now..

// Turn off the zbuffer g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE ); //Turn on ortho projectionD3DXMatrixOrthoOffCenterLH(&matProj, 0.0f, (float)640, (float)480, 0.0f, 0.0f, 1.0f);D3DXMatrixIdentity(&matView);D3DXMatrixIdentity(&matWorld);g_pd3dDevice->SetTransform(D3DTS_PROJECTION,     &matProj);g_pd3dDevice->SetTransform(D3DTS_VIEW,           &matView);g_pd3dDevice->SetTransform(D3DTS_WORLDMATRIX(0), &matWorld);//D3DXMatrixTranslation( &matTransCursor,10,10,0);	//combined=matTransCursor*matWorld;//g_pd3dDevice->SetTransform( D3DTS_WORLD, &combined );	for( i=0; i<cursor.g_dwNumMaterials; i++ )	{					// Set the material and texture for this subset		g_pd3dDevice->SetMaterial( &cursor.g_pMeshMaterials );		g_pd3dDevice->SetTexture( 0, cursor.g_pMeshTextures );        		// Draw the mesh subset		cursor.g_pMesh->DrawSubset( i );	}


what is wrong with this?
Holy Fuzz
Holy Fuzz
That last post was mine, sorry. :-)
psykr
psykr
Well, the thing about transformed coordinates is that they're, well, transformed. You can't apply any of your own transformations and whatnot to them (I think you can't even pass them through shaders), but if you don't need those special effects and know exactly what you want to do, I guess they work fine.

And to convert screen space coordinates to find the appropriate world space coordinates you need to use, you have to multiply by the inverse of each of the matrices in the pipeline. So say you know exactly where on the screen you want your model; then find the appropriate vector and multiply it by the inverse of the projection matrix, the view matrix, the appropriate world-local transformation.. until you have it in local coordinates.

Disabling alt-tab is a bad idea.
Adams555
Adams555
none of this is working for me.. =/.. This seems quite odd.
Etnu
Etnu
Why on earth would you go through all that trouble changing the matrices? Just specify your coordinates in screen space from the get go (use the XYZRHW FVF code), and you're done. If you're using a shader, just don't do the world/view/projection transformation. Works like a charm...



---------------------------Hello, and Welcome to some arbitrary temporal location in the space-time continuum.
Sr_Guapo
Sr_Guapo
Out of curiosity, why are you removing all the windows messaging? What would that really accomplish? There are other way to do it that won't piss off windows. Isn't there a NO_ALT_TAB (or something...) flag that you can pass somewhere... Sorry, don't know the details, but I'm sure I saw it before somewhere.
Sean Henley [C++ Tutor]Rensselaer Polytechnic Institute
The Lion King
The Lion King
Try the World Matrix only. I have got this sort of stuff in my application too but I only use D3DXMatrixIdentity() for the World Matrix not the View Matrix.

Try it ... it works for me ;)
Adams555
Adams555
Well, not using the windows messages prevents peolpe from doing ANYTHING that I dont specify. :-P Control alt delete.. etc. Still no luck lol. I'll keep trying different things.. I'm kinda new to directx.
Sr_Guapo
Sr_Guapo
I you don't allow messages like ctrl-alt-delete and your program crashes/locks up (god forbid) the only way for the user to get out is to yank the power cable. That is usually not a good thing. There are very easy way to handle lost devices and such if that is your main problem.
Sean Henley [C++ Tutor]Rensselaer Polytechnic Institute
DrunkenHyena
DrunkenHyena
Quote:
Original post by Adams555
Well, not using the windows messages prevents peolpe from doing ANYTHING that I dont specify. :-P Control alt delete.. etc. Still no luck lol. I'll keep trying different things.. I'm kinda new to directx.


There are some sequences you cannot block in this way. Wouldn't it be better to just handle these things in the proper way? Disabling Alt+Tab will annoy a lot of users (me included).
Stay Casual,KenDrunken Hyena</FON
Oluseyi
Oluseyi
Quote:
Original post by Adams555
Well, not using the windows messages prevents peolpe from doing ANYTHING that I dont specify. :-P Control alt delete.. etc.
Wrong. Ctrl+Alt+Del is not a window message, it's a system message. You need to install a system to hook to intercept that.

I'd never use your app if I couldn't Alt+Tab away. Don't be so conceited as to think you deserve my exclusive attention.
S1CA
S1CA
1a. If you're using the orthogonal projection matrix method, it could be that the vertices of your mesh are causing it to be clipped by the near or far planes, i.e. the z values of the cursor vertices are <0 or >1 (using your clip plane values). Check the vertices or apply a scale in the world matrix to ensure your z values fall in this range. An easy test to see if this is the case would be to set D3DRS_CLIPPING to FALSE (not advisable generally though).

1b. Additionally, if your cursor mesh is expecting to be in 3d space it may have a scale that makes it tiny (even invisible) in orthogonal space.


2a. If you're using D3DFVF_XYZRHW style vertices, once again ensure the Z values aren't being clipped (see above, for example a Z of 0.0f and a near clip plane of say 0.01f). The D3DRS_CLIPPING=FALSE test applies here too.

2b. Also ensure that RHW is set sensibly (1.0f is best if this is just a sprite).

2c. To make sure some other unrelated part of your program isn't causing all these troubles, you could try copying the rendering code from the "Vertices" tutorial in the DirectX SDK into your code and see if you get the triangle or not.


3. Another alternative to ortho projections and D3DFVF_XYZRHW vertices is to use D3DX's ID3DXSprite interface to do the work for you.


4a. As for disabling Alt-Tab, have you ever heard the phrase "the customer is always right"? In this case, the user is always right, it's their machine not yours!. It's a huge user interface design sin to try and take that functionality away from them.

4b. If the user wants to Alt-Tab or similar, they probably have a good reason such as recieving an instant message, attending to a completed download etc

4c. Do you have a specific reason for wanting the user to not be able to switch to the desktop, other programs or even change current user while your app is running? If your primary reason is due to your application crashing or such when the user does that or laziness in not wanting to handle things like lost devices or fast user switching (XP & LH feature), then PLEASE do say, I'm sure the good people of this forum will be happy to help (far preferable to having an app which can't be exited temporarily or makes the machine unstable).

4d. Are you using Windows 98 or Windows ME by any chance? Methods of disabling Alt-Tab, Alt-F4, Ctrl-Alt-Del etc which work on Windows 9x (such as ignoring messages in the message queue, running as a screensaver or installing a keyboard hook) will fail miserably on other operating systems such as Windows XP.

4e. Ctrl-Alt-Del in particular is considered a "system level security" key sequence on NT based OSes (NT, 2000, XP) since it is used to switch between users, lock the workstation, log on/off, restart the machine etc. On NT based OSes that key sequence is owned and handled by the GINA DLL which starts before most other parts of the OS. GINA (Graphical Identification and Authentication) isn't easy to get around without writing your own custom GINA DLL or a kernel mode driver (most likely a keyboard filter driver). Not nice unless absolutely necessary.

4f. ISTR under NT based OSes, if an app doesn't respond to Windows messages for long enough for its input queue to fill then that application becomes the prime candidate for an "Application Blah is not responding" dialog box and imminent termination. Additionally if you're not pumping messages for some performance reason, then you're way off.

4g. Sr_Guapo may be thinking of the DDSCL_ALLOWREBOOT flag you could specify to SetCooperativeLevel() in DirectDraw. AFAIK there isn't a substitute in recent versions of D3D.
Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site
Sr_Guapo
Sr_Guapo
Quote:
4g. Sr_Guapo may be thinking of the DDSCL_ALLOWREBOOT flag you could specify to SetCooperativeLevel() in DirectDraw. AFAIK there isn't a substitute in recent versions of D3D.


hehe... Actually there is a "NoWindowsKey" flag that can be passed to a DIDevice, which I am pretty sure is what I was reffering to, another one of those annoying keys, this one you can hit on accident though... Sorry about that, though :).

Note that handeling event such as alt-tab and other messages that disrupt your game is rather easy. Just do something like this in your main loop:

if (DeviceLost)
//Do nothing, well maybe DoEvents
else
{
//run normally
}

Sorry about the pseudo code, I don't do unmanaged DX... That way, your game will pretty much pause while the device is lost (ie, the user is answering an instant message), then it will continue to function once the device is reinitialized and everything. Obviously this will need to be a little different for a multiplayer game (most people wouldn't like it if the whole server froze as you answered an IM...). Good luck!
Sean Henley [C++ Tutor]Rensselaer Polytechnic Institute
Etnu
Etnu
You can't prevent CTRL + ALT + DELETE (nor should you).

If you're blocking system messages to prevent losing devices, you're just being lazy (and you won't prevent lost devices anyway).

If you're blocking system messages to prevent your users from running cheating programs in the background (the way that Everquest did up until a year or two ago), then I have some bad news for you: it won't work :-p.

Handle windows messages properly, or else you'll feel the wrath of your end users.
---------------------------Hello, and Welcome to some arbitrary temporal location in the space-time continuum.
v1nd1cat10n
v1nd1cat10n
For what it's worth as far as your original question, I render my cursor as a sprite. The Draw method takes screen coordinates by default. (At least in Managed DX9). I am using DirectInput mouse in exclusive mode so it kills my cursor (No mouse related Windows Messages). Couldn't seem to get a hardware cursor working with Device.SetCursor() and Device.SetCursorPosition(). I have a seperate thread polling the mouse and every frame I use the Sprite.Draw to put it on the screen. Works good for me. It is frame-rate dependent though. As long as my frame-rate doesn't drop below 1/2 my refresh rate, it should be fine.
v1nd1cat10n"It's nice to be nice to the nice." - Frank Burns

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.