I'm implementing a FPS style mouse look to "fly" around my scene.
I've got the right camera rotation and everything, my only problem is that when I try to warp the mouse to the middle of the screen, it performs multiple calls to the glutPassiveMotionFunc call back. So instead of teleporting the mouse, its moving it there over a few movements. These movements get processed and move the camera back to the original position.
How do I check that the mouse was actually moved and it was not triggered by the glutWarpPointer function.
I've tried to not process a movements if the pointer is in the middle of the screen but this doesn't help.
I want my program to run on Linux and Windows so I cannot use OS specific functions.
I wouldn't call this a great solution, but it should work:
bool isWarpingPointer = false;
void MyPassiveMovementCallback()
{
if (isWarpingPointer)
{
return;
}
//proceed normally
}
//elsewhere
isWarpingPointer = true;
glutWarpPointer();
isWarpingPointer = false;
Related
i've tried to make a project, but i can't draw a sprite as i want. I mean that everything works when i just draw a sprite, but it stop working when i am trying to draw the sprite by clicking left mouse button. There's code i tried:
if(zdarzenie.type == Event::MouseButtonPressed && zdarzenie.mouseButton.button == Mouse::Left)
{
pocisk.setPosition(10, 10);
oknoAplikacji.draw(pocisk);
}
Btw, I am writing in Polish as if it would change something.
And yes, i have everything good besides that.
(and i am using 2.4.1 version of SFML)
I don't know what you are doing now because you didn't provide enough of your code and I actually don't understand your if statement but, it can just be :
if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
sprite.setPosition(sf::Mouse::getPosition());
renderTarget.draw(sprite);
}
By the way I strongly suggest that you do not use the draw function here but organize your code to have a draw method called in a render loop, because depending on where your code is in your program, the sprite could be drawn for only one frame and then erased since it's not updated.
From what I understand in your code in Polish, you have the right code to do what you want, but the problem comes from the fact that you draw the sprite only once.
The draw method is called every frame and it will erase everything on screen and then redraw them. Doing it only once, like in your code, will only draw it a single time then delete it the very next frame.
At that point multiple solution can be used. If its a GameObject clicking can activate the object to then draw it or a simple bool could be used has a switch in your draw to make it appear.
I am in need of drawing a custom mouse cursor using C++ for my application. I am using a device to track hand movements and translate them into a cursor position on the screen.
However, for this application the system cursor may or may not be displayed, so I need to somehow draw onto the screen. I also need to interact with any window. Because of this, I'm not sure of my course of action - I believe I can create a "transparent" window to draw on while passing clicks/drags through onto the next window but am not sure how to go about this.
EDIT: Clarification - This application might be run on a touchscreen device where the cursor is hidden by some means. I'm trying my best to create this application as "hands-off" of the host system as possible - this program is meant to be a drag and drop application that will just work on a system with none or very very minimal actions done to the settings of the host system itself.
Currently, I have the following which draws a cursor at the location of the "mouse" but I cannot figure out how to refresh the screen or draw over the old "cursor" before drawing the new one. This causes a repeated cursor across the screen:
// Some thread
DWORD WINAPI Cursor(LPVOID lpParam) {
auto dc = GetDC(NULL);
std::optional<POINT> point;
while (true) {
if (point.has_value()) {
auto p = point.value();
RoundRect(......); // Paint over old cursor
}
POINT p;
if (GetCursorPos(&p)) {
point.emplace(p);
RoundRect(......); // Paint new cursor
}
}
I've read that simply calling another RoundRect on the same location will clear it but that's obviously not the case or I'm doing it wrong.
I believe my program can have super privileges if it needs to. Working with WINAPI seems to be kind of a hassle compared to this kind of stuff on linux, regarding permissions of working with different windows and allowing clicks and such to go through....
Any suggestions for how to proceed?
I'm trying to adjust user mouse input (slow down/fasten mouse pointer) by calculating and setting the new position of the pointer every mouseMoveEvent().
It looks like the pointer is drawn in it's normal position before mouseMoveEvent() is executed. This results in a bad looking, twitching cursor.
Here is an example of how I would try to keep the pointer in a place, ignoring user input.
Expected behaviour: The pointer stays steady in one place when I move the mouse.
Observed bahaviour: The pointer jiggles. For a fraction of a second, a new pointer is drawn in the position where the mouse is moved, after which it's moved back to it's oldPosition.
void MainWindow::mouseMoveEvent(QMouseEvent *)
{
// [event->accept();] Setting this does not help
// [setCursor(Qt::BlankCursor);] Setting this does not help
QCursor::setPos(oldPosition);
// [setCursor(Qt::ArrowCursor);]
}
P.S. May be there are other ways to adjust mouse sensitivity in qt embedded. Am I doing it right?
Short answer: No.
Unfortunately, there is no way to adjust mouse sensitivity using only QT libraries.
The twitching you are experiencing is because the OS does the work of drawing the mouse pointer, the frequency of which can be different from how frequently you receive mouse move events from the OS.
There is also no way to tell QT or the OS to send you mouse move events before every frame the cursor is drawn.
Workaround: You could hide the mouse pointer completely, and draw your own. This way you will have full control over when the cursor is drawn avoiding the glitches.
I'm using SFML to detect mouse clicks.
A basic wrapper to detect where clicks occur, may look like this:
sf::Vector2i Block_Until_Mouse_Click(){
static bool pressed=false;
sf::Vector2i position;
while (true){
if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
if (!pressed){
position = sf::Mouse::getPosition();
pressed=true;
break;
}
}
else{
pressed = false;
}
}
return position;
}
This allows the printing of coordinates, each time the mouse has been clicked:
while (true){
auto position = Block_Until_Mouse_Click();
std::cout << position.x << " " << position.y << '\n';
}
Is it possible for the application to absorb these mouse clicks,
without the click having any affect?
For example, if I had a paint program open, and this "mouse click absorb" program minimized, would it be possible to click on the canvas without being able to draw anything, but still have the coordinates recorded by the "mouse click absorb" program?
I'm not sure if this requires operating system changes, changes to the device/driver, or whether it could be achieved through code. Are there usual software implementations that provide this kind of functionality?
Is it possible for the application to absorb these mouse clicks,
without the click having any affect?
With SFML, no. Using OS features, maybe, depending on the OS.
On OS X, there's a screen capture program called Grab that is able to do that. How? Apple hasn't published the software source code (AFAIK) so I can't tell.
I'm not familiar enough with Windows and Linux to answer the question.
SFML internally uses operating system handles for their real-time events if I am not mistaken. To be able to achieve what you want you would have to interfere with the other process in code. That work SFML will not do for you since the getter for mouse position of the operating system knows nothing of any other processes living in memory.
A quote from the SFML docs:
sf::Mouse provides an interface to the state of the mouse.
It only contains static functions (a single mouse is assumed), so it's not meant to be instantiated.
This class allows users to query the mouse state at any time and directly, without having to deal with a window and its events. Compared to the MouseMoved, MouseButtonPressed and MouseButtonReleased events, sf::Mouse can retrieve the state of the cursor and the buttons at any time (you don't need to store and update a boolean on your side in order to know if a button is pressed or released), and you always get the real state of the mouse, even if it is moved, pressed or released when your window is out of focus and no event is triggered.
The setPosition and getPosition functions can be used to change or retrieve the current position of the mouse pointer. There are two versions: one that operates in global coordinates (relative to the desktop) and one that operates in window coordinates (relative to a specific window).
Check the following link: http://www.sfml-dev.org/documentation/2.3.2/classsf_1_1Mouse.php#details
So using this mouse API will not block anything in the operating system, it will just interact directly with the mouse.
I'm trying to detect mouse movement event and move it back to the middle of the screen using sf::RenderWindow pollEvent method and detect the event type sf::Event::MousePressed. The problem is when I'm detecing the mouse movment I need to move the mouse back to the middle of the screen and for that im using sf::Mouse::setPosition but I think (maybe I'm wrong) that function itself calling sf::Event::MouseMoved when it used, and im afraid it creates an infinite loop.
Exmaple of the way im doing that: (I know 0, 0 it's not the middle it is just and exmaple)
while (app.pollEvent(Event))
{
if(Event.type == sf::Event::MouseMoved)
{
sf::Mouse::setPosition(0 , 0));
}
}
Sorry for my bad english!
Thanks in advance!
Try using app.SetCursorPosition(x, y); instead.
Also, i would skip the check for events, since you will want the cursor to end in the middle at the end of each frame anyway.