Hi people,
I’ve got a problem, for which I couldn’t find any solution so far, despite searching the whole internet for several days and trying different formulas.
It’s about clicking inside the world and drawing a “point” at the right 3d x/z-position (y-position in 3d coordinates should always be at 0).
What I’ve got so far, are the sfml mouse-coordinates, but I don’t know the formula for getting the right x,z position, when I click somewhere in the 3d world.
The question is: How to draw the red point at the right position in the 3d world without using any external libraries? (that don’t work for me anyway :-)).
Many thx in advance for any help.
This is the full code example, where you can rotate and move around freely (the problem is in the line with the formula “pointx = …, pointz =…”:
I’m sure, there is a simple solution for it without thousands of lines of code…
#include <SFML/Graphics.hpp>
#include <iostream>
#define _USE_MATH_DEFINES
#include <math.h>
#include <SFML/OpenGL.hpp>
const float height = 1000;
const float width = height*0.75f;
void myGluPerspective(double fovy, double aspect, double zNear, double zFar)
{
double f = 1.0 / tan(fovy * M_PI / 360);
double xform[16] =
{
f / aspect, 0, 0, 0,
0, f, 0, 0,
0, 0, (zFar + zNear)/(zNear - zFar), -1,
0, 0, (2*zFar*zNear)/(zNear - zFar), 0
};
glMultMatrixd(xform);
}
float camposx, camposy, camposz, cammovex, cammovey, cammovez = 0;
short rotationsvariable = 0;
float pointx = 0;
float pointz = 1;
int main()
{
sf::RenderWindow window(sf::VideoMode(height, width, 32), "SFML OpenGL", sf::Style::Close);
window.setFramerateLimit(40);
glClearColor(0.8f, 0.8f, 0.8f, 0);
glClearDepth(1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
myGluPerspective(60,height/width,0.1f,180);
glTranslatef(0,0,-3);
camposz = -3;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
window.close();
break;
case sf::Event::KeyPressed:
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
GLfloat matrixf[16];
glGetFloatv(GL_MODELVIEW_MATRIX, matrixf);
cammovex = (float)sin(rotationsvariable*M_PI/180)*-0.2f;
cammovez = (float)cos(rotationsvariable*M_PI/180)*0.2f;
camposx = camposx + cammovex;
camposz = camposz + cammovez;
glLoadIdentity();
myGluPerspective(60,height/width,0.1f,180);
glRotatef(rotationsvariable, 0, 1.0f, 0);
glTranslatef(camposx,0,camposz);
break;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{
GLfloat matrixf[16];
glGetFloatv(GL_MODELVIEW_MATRIX, matrixf);
cammovex = (float)sin(rotationsvariable*M_PI/180)*-0.2f;
cammovez = (float)cos(rotationsvariable*M_PI/180)*0.2f;
camposx = camposx - cammovex;
camposz = camposz - cammovez;
glLoadIdentity();
myGluPerspective(60,height/width,0.1f,180);
glRotatef(rotationsvariable, 0, 1.0f, 0);
glTranslatef(camposx,0,camposz);
break;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
GLfloat matrixf[16];
glGetFloatv(GL_MODELVIEW_MATRIX, matrixf);
rotationsvariable = rotationsvariable - 10;
if(rotationsvariable==-360)
{
rotationsvariable = 0;
}
glLoadIdentity();
myGluPerspective(60,height/width,0.1f,180);
glRotatef(rotationsvariable, 0, 1.0f, 0);
glTranslatef(camposx,0,camposz);
break;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
rotationsvariable = rotationsvariable + 10;
if(rotationsvariable==360)
{
rotationsvariable = 0;
}
glLoadIdentity();
myGluPerspective(60,height/width,0.1f,180);
glRotatef(rotationsvariable, 0, 1.0f, 0);
glTranslatef(camposx,0,camposz);
break;
}
case sf::Event::MouseButtonPressed:
if (event.mouseButton.button == sf::Mouse::Left)
{
sf::Vector2i pixel_pos = sf::Mouse::getPosition(window);
sf::Vector2f coord_pos = window.mapPixelToCoords(pixel_pos);
pointx = -camposx+(coord_pos.x/650)*2.0f-1.5f; // test
//pointz = ......?
}
}
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1,1,1);
glBegin(GL_QUADS);
glVertex3f(-1,-1,-1);
glVertex3f(-1,-1,1);
glVertex3f(1,-1,1);
glVertex3f(1,-1,-1);
glEnd();
glColor3f(1,0,0);
glPointSize(10);
glBegin(GL_POINTS);
glVertex3f(pointx, -1.0f, pointz);
glEnd( );
window.display();
}
return 0;
}