使用 OpenGL 在 SFML 中获取正确的鼠标位置
我的问题与使用 OpenGL 时从 SFML 获取正确的鼠标坐标有关。
基本上,我正在使多边形在 Z 轴上旋转以查看当前光标位置。
您还可以使用 WASD 键在屏幕上移动多边形。
如果多边形保持在屏幕的中心,一切都会很好,但是当我将多边形移动到屏幕的左上角时,就会出现问题。
基本上,它就像获取了不正确的鼠标坐标并且超出了实际鼠标光标的位置。
我使用 GL_LINES 创建一种十字线来查看我的变量认为鼠标光标在哪里,并且它超出了实际位置。
为了获取当前的鼠标坐标,我正在使用这个:
mouseX = Input.GetMouseX()-App.GetWidth()/2.f;
mouseY = Input.GetMouseY()-App.GetHeight()/2.f;
有人知道我的问题可能是什么吗?
为了提供我能提供的所有信息,下面是我的整个源代码。 另外,如果我为那些有兴趣提供帮助的人提供我的来源,您可以编译它并看看我的意思,因为这对我来说有点难以解释。
抱歉,它太乱了 - 毕竟我是新手:)
#include <SFML/Window.hpp>
#include <iostream>
#include <cmath>
const float PI = 3.14159265f;
int main() {
// Angle of rotation for the polygon
float angle = 0.f;
sf::Window App(sf::VideoMode(800, 600, 32), "SFML OpenGL");
glClearDepth(1.f);
glClearColor(0.f, 0.f, 0.f, 0.f);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.f, 1.2f, 1.f, 500.f);
// Current position of the polygon (used in glTranslatef)
GLfloat currentPosX = 0.f;
GLfloat currentPosY = 0.f;
// Current position of the mouse cursor
float mouseX = 0.f;
float mouseY = 0.f;
const sf::Input &Input = App.GetInput();
App.SetFramerateLimit(30);
while (App.IsOpened()) {
sf::Event Event;
while (App.GetEvent(Event)) {
if (Event.Type == sf::Event::Closed) {
App.Close();
}
if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape)) {
App.Close();
}
if (Event.Type == sf::Event::Resized) {
glViewport(0, 0, Event.Size.Width, Event.Size.Height);
}
}
App.SetActive();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(Input.IsKeyDown(sf::Key::W)) {
currentPosY += 3.f;
}
if(Input.IsKeyDown(sf::Key::S)) {
currentPosY -= 3.f;
}
if(Input.IsKeyDown(sf::Key::D)) {
currentPosX += 3.f;
}
if(Input.IsKeyDown(sf::Key::A)) {
currentPosX -= 3.f;
}
// Minus half of the screen width and height
// because the OpenGL origin is in the middle of the screen
mouseX = Input.GetMouseX()-App.GetWidth()/2.f;
mouseY = Input.GetMouseY()-App.GetHeight()/2.f;
// I don't know any better way to flip the Y axis so this is what I did
if(mouseY >= 0) {
mouseY = -(mouseY);
}
else {
mouseY = abs(mouseY);
}
// Calculate the angle which the polygon needs to rotate at
angle = atan2(mouseY - currentPosY, mouseX - currentPosX)*180/PI;
// Print variables to console to try and figure out what I'm doing wrong
std::cout << mouseX << "(" << currentPosX << ")" << ", " << mouseY << "(" << currentPosY << ")" << " - " << angle << std::endl;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(currentPosX, currentPosY, -200.f);
glRotatef(angle, 0.f, 0.f, 1.f);
// Polygon
glBegin(GL_QUADS);
glVertex3f(-25.f, -25.f, -50.f);
glVertex3f(25.f, -25.f, -50.f);
glVertex3f(25.f, 25.f, -50.f);
glVertex3f(-25.f, 25.f, -50.f);
glEnd();
glLoadIdentity();
glTranslatef(currentPosX, currentPosY, -200.f);
// Axis on polygon
glBegin(GL_LINES);
glVertex3f(-70.f, 0.f, -50.f);
glVertex3f(70.f, 0.f, -50.f);
glVertex3f(0.f, -70.f, -50.f);
glVertex3f(0.f, 70.f, -50.f);
glEnd();
glLoadIdentity();
glTranslatef(currentPosX, currentPosY, -200.f);
glRotatef(angle, 0.f, 0.f, 1.f);
// Line to indicate the direction of the polygon
glBegin(GL_LINES);
glVertex3f(0.f, 0.f, -50.f);
glVertex3f(50.f, 0.f, -50.f);
glEnd();
glLoadIdentity();
glTranslatef(0.f, 0.f, -200.f);
// Screen axis
glBegin(GL_LINES);
glVertex3f(-400.f, 0.f, -60.f);
glVertex3f(400.f, 0.f, -60.f);
glVertex3f(0.f, 300.f, -60.f);
glVertex3f(0.f, -300.f, -60.f);
glEnd();
glLoadIdentity();
glTranslatef(mouseX, mouseY, -200.f);
// Cursor position
glBegin(GL_LINES);
glVertex3f(-10.f, 0.f, -60.f);
glVertex3f(10.f, 0.f, -60.f);
glVertex3f(0.f, 10.f, -60.f);
glVertex3f(0.f, -10.f, -60.f);
glEnd();
App.Display();
}
return 0;
}
My problem is related to getting the correct mouse co-ordinates from SFML while using OpenGL.
Basically I am making a polygon rotate on the Z axis to look at the current cursor position.
You can also move the polygon around the screen with the WASD keys.
If the polygon stays in the center of the screen everything works great, but my problems appear when I move the polygon to, for example, the top left of the screen.
Basically it is like it is getting the incorrect mouse co-ordinates and is overshooting the position of the actual mouse cursor.
I used GL_LINES to create a kind of crosshair to see where my variables thought the mouse cursor was, and it is overshooting the actual position.
To get the current mouse co-ordinates I am using this:
mouseX = Input.GetMouseX()-App.GetWidth()/2.f;
mouseY = Input.GetMouseY()-App.GetHeight()/2.f;
Does anybody know what my problem could be?
For the sake of providing all the information I can, below is my entire source code.
Also, if I provide my source then for those who are interested in helping, you can compile it and see what I mean, since it is a bit hard for me to explain.
Sorry for it being so messy - I am new to this after all :)
#include <SFML/Window.hpp>
#include <iostream>
#include <cmath>
const float PI = 3.14159265f;
int main() {
// Angle of rotation for the polygon
float angle = 0.f;
sf::Window App(sf::VideoMode(800, 600, 32), "SFML OpenGL");
glClearDepth(1.f);
glClearColor(0.f, 0.f, 0.f, 0.f);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.f, 1.2f, 1.f, 500.f);
// Current position of the polygon (used in glTranslatef)
GLfloat currentPosX = 0.f;
GLfloat currentPosY = 0.f;
// Current position of the mouse cursor
float mouseX = 0.f;
float mouseY = 0.f;
const sf::Input &Input = App.GetInput();
App.SetFramerateLimit(30);
while (App.IsOpened()) {
sf::Event Event;
while (App.GetEvent(Event)) {
if (Event.Type == sf::Event::Closed) {
App.Close();
}
if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape)) {
App.Close();
}
if (Event.Type == sf::Event::Resized) {
glViewport(0, 0, Event.Size.Width, Event.Size.Height);
}
}
App.SetActive();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(Input.IsKeyDown(sf::Key::W)) {
currentPosY += 3.f;
}
if(Input.IsKeyDown(sf::Key::S)) {
currentPosY -= 3.f;
}
if(Input.IsKeyDown(sf::Key::D)) {
currentPosX += 3.f;
}
if(Input.IsKeyDown(sf::Key::A)) {
currentPosX -= 3.f;
}
// Minus half of the screen width and height
// because the OpenGL origin is in the middle of the screen
mouseX = Input.GetMouseX()-App.GetWidth()/2.f;
mouseY = Input.GetMouseY()-App.GetHeight()/2.f;
// I don't know any better way to flip the Y axis so this is what I did
if(mouseY >= 0) {
mouseY = -(mouseY);
}
else {
mouseY = abs(mouseY);
}
// Calculate the angle which the polygon needs to rotate at
angle = atan2(mouseY - currentPosY, mouseX - currentPosX)*180/PI;
// Print variables to console to try and figure out what I'm doing wrong
std::cout << mouseX << "(" << currentPosX << ")" << ", " << mouseY << "(" << currentPosY << ")" << " - " << angle << std::endl;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(currentPosX, currentPosY, -200.f);
glRotatef(angle, 0.f, 0.f, 1.f);
// Polygon
glBegin(GL_QUADS);
glVertex3f(-25.f, -25.f, -50.f);
glVertex3f(25.f, -25.f, -50.f);
glVertex3f(25.f, 25.f, -50.f);
glVertex3f(-25.f, 25.f, -50.f);
glEnd();
glLoadIdentity();
glTranslatef(currentPosX, currentPosY, -200.f);
// Axis on polygon
glBegin(GL_LINES);
glVertex3f(-70.f, 0.f, -50.f);
glVertex3f(70.f, 0.f, -50.f);
glVertex3f(0.f, -70.f, -50.f);
glVertex3f(0.f, 70.f, -50.f);
glEnd();
glLoadIdentity();
glTranslatef(currentPosX, currentPosY, -200.f);
glRotatef(angle, 0.f, 0.f, 1.f);
// Line to indicate the direction of the polygon
glBegin(GL_LINES);
glVertex3f(0.f, 0.f, -50.f);
glVertex3f(50.f, 0.f, -50.f);
glEnd();
glLoadIdentity();
glTranslatef(0.f, 0.f, -200.f);
// Screen axis
glBegin(GL_LINES);
glVertex3f(-400.f, 0.f, -60.f);
glVertex3f(400.f, 0.f, -60.f);
glVertex3f(0.f, 300.f, -60.f);
glVertex3f(0.f, -300.f, -60.f);
glEnd();
glLoadIdentity();
glTranslatef(mouseX, mouseY, -200.f);
// Cursor position
glBegin(GL_LINES);
glVertex3f(-10.f, 0.f, -60.f);
glVertex3f(10.f, 0.f, -60.f);
glVertex3f(0.f, 10.f, -60.f);
glVertex3f(0.f, -10.f, -60.f);
glEnd();
App.Display();
}
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Input.GetMouse?
为您提供窗口空间中的坐标,您需要它将它们转换为模型空间。我可能是错的,但我的懒惰修复方法是在第一象限中绘制 2D 场景并获取鼠标位置。您可以通过根据窗口的尺寸设置投影来使编码变得更容易:
Input.GetMouse?
gives you coords in, say, window-space and you need it to transform them to model-space. I could be wrong, but my lazy fix would be draw my 2D scene in the first quadrant and get mouse position byYou could always make your coding easier by setting up your projection accordingly to the window's dimensions: