help with ui mouse intersection

Started by
30 comments, last by 31337noob 18 years, 3 months ago
Quote:ok, this is werider. i just found out it doesnt do this werid problem when its in fullscreen. ok so how can i deal with it when its not in fullscreen.

Just a quick glance at your post..

in fullscreen mode, dx screen coordinates are same as windows screen coordinate, whereas, in windowed mode, dx screen coord. are not equal to windows screen coord. you might be missing clicking on button just because of that.

Advertisement
In fullscreen screen mode the mouse co-ordinates and the window co-ordinates are the same. This let me think that the co-ordinates you use may be related to the screen and not to the window. (EDIT: Ahem, Taha Ansari was quicker in stating this :)

Please consider this:

(1) In UIControl::cursorIntersection do a cout on x and y. Position the button in the upper left corner of the window. Compile, run, and move the window to the upper left corner of the screen. Click in the upper left corner of the button. Are the printed co-ordinates near at zero, or else are their values in the range of the border thicknesses of the window? If so, you have first to subtract the window's border thicknesses from x and y. (You said, 0,0 is in the upper left corner, right?)

(2) Now click in the lower right corner of the button. If you subtract the printed values from those printed earlier at clicking in the upper left corner, are the differences as big as the size of the button?

(3) The window being in the upper left corner. Click on the center of the button and remember the printed values. Then move the window to the lower right corner of the screen. Click again on the center of the button. Do the printed values change significantly (say more than a few pixels)? If so, then the mouse co-ordinates are screen related, and not window related, and you have to subtract the window position from x and y.

(4) Please post more of the code that is related to the problem.
ok, i have a picture thats 100,50 and i did what you said. i put my mouse at the upper left hand corner and i get 0,0 and then i move my mouse the lower right of the button and i get 127,61. i think directx just drawn the sprite a little bigger then 100,50. its the same in fullscreen the width is bigger and so is the height
when i move my window to the lower-right, the intersection is all wrong. its like it shifts down alot.
Are your getX and getY functions relative to the origin or to the parent window? Because if they are relative to the parent window your getAbsPos function is wrong.
"I just wanted to hang a picture on my wall, but somehow now I'm in the Amazon Jungle looking for raw materials." - Jekler
Quote:Original post by 31337noob
ok, i have a picture thats 100,50 and i did what you said. i put my mouse at the upper left hand corner and i get 0,0 and then i move my mouse the lower right of the button and i get 127,61. i think directx just drawn the sprite a little bigger then 100,50. its the same in fullscreen the width is bigger and so is the height

That sounds that not the mouse is the problem (at least not alone) but the projection set-up. Please post that piece of code (also of interest is the VIEW matrix set-up). Good would be an orthogonal projection with a widht/height equally to the width/height of the window, so that you could work with pixel co-ordinates directly. But I expect your set-up being something other, independent on the window size.

[Edited by - haegarr on December 21, 2005 1:03:12 PM]
Quote:Original post by haegarr
Quote:Original post by 31337noob
ok, i have a picture thats 100,50 and i did what you said. i put my mouse at the upper left hand corner and i get 0,0 and then i move my mouse the lower right of the button and i get 127,61. i think directx just drawn the sprite a little bigger then 100,50. its the same in fullscreen the width is bigger and so is the height

That sounds that not the mouse is the problem (at least not alone) but the projection set-up. Please post that piece of code (also of interest is the VIEW matrix set-up). Good would be an orthogonal projection with a widht/height equally to the width/height of the window, so that you could work with pixel co-ordinates directly. But I expect your set-up being something other, independent on the window size.


do you mean this?

D3DXMATRIX projMatrix;D3DXMatrixPerspectiveFovLH( &projMatrix, D3DX_PI / 4, (float)d3dpp.BackBufferWidth / (float)d3dpp.BackBufferHeight, 1.0f, 5000.0f);this->pDevice->SetTransform( D3DTS_PROJECTION, &projMatrix );
do you?
Quote:Original post by 31337noob
do you?

Yes, in part. (Sorry, I was busy yesterday.)

Perhaps I lack enough knowledge of what you are doing with your app. However, I assume you are making a GUI, maybe a kind of 2D overlay or something similar?

You set-up a perspective projection. As you'll already know, perspective projections do a depth scaling; there is only one specific distance where the depth scaling is 1. Now it depends: Either you want to have your GUI element like a bill board integrated into the scene. That is, it faces always the camera, but it should be hidden by "normal" 3D scene elements (say, a tree trunk in front of the button should hide it). Then using perspective transformation is ok. However, in this case you have to consider perspective depth shortening also for your mouse click, since the click occurs onto the plane where depth shortening is 1 but does track all depth values on a straight line _not_ perpendicular to the screen! In other words, in such a case you have to scale your click co-ordinates depending on the GUI element's depth value before comparing them with the button co-ordinates.

Or (the more likely case): Your GUI is always in front of the 3D scene, like an overlay (e.g. a HUD) or a GUI even without 3D in behind. Your wish is to draw 2D GUI elements with pixel accuracy. (All of the following belongs to this case).

In such case I suggest not to use the perspective projection at all (also it is possible, too), but to use the orthogonal projection. This kind of projection has the advantage that it does not show any depth scaling. You could set it up using the D3DXMatrixOrthoLH function. Without proven, I assume something like
D3DXMatrixOrthoLH(&projMatrix,widhtInPixels,heightInPixels,-1,1);
should be possible (you could also take into account of using the "OffCenter" variant of this routine).

However, in the case of ortho projection you also have to set-up a suitable view matrix. I suggest the view matrix to do 2 things (you have to ignore the second thing if you use the "OffCenter" variant of projection): mirror the y axis since you want the y co-ordinate system of the GUI to grow from top to bottom, right?
D3DXMatrixScaling(&viewScale,1,-1,1);
computes such a matrix. But notice that doing so will probably require texture co-ordinates to be adapted, too). You also wants the origin to be located in the upper left corner, instead of the center of the screen, so you also have to translate the view by
D3DXMatrixTranslation(&viewTranslate,widhtInPixels/2,0.5f*heightInPixels/2,0);
(please notice that I write this from mind, not copying it from a tested app).

After setting up the view matrix from the proper product of those stuff above, it should be possible to push GUI geometry in a co-ordinate system (0,0,0) in the upper left and (widht-1,height-1,0) in the lower right corner. Render the GUI elements without depth test and in back to front order to get the overlapping right.

[Edited by - haegarr on December 23, 2005 4:15:35 AM]
i will try that. oh, just to let you know, i am using the ID3DXSprite class.

what i am doing is i am making a game engine

This topic is closed to new replies.

Advertisement