I'm trying to do ray tracing but I'm having no luck with the code that converts an x,y pixel into an x,y,z world position. The image plane is at z = 0, so the distance from the camera to the image plane is 1. I'm trying to avoid using glUnProject
My code is in void mouse_func, near the top of the snippet below:
#include <cstdlib>
#include <cmath>
#include <GLUT/glut.h> /* Header File For The GLut Library*/
#include <string>
using std::string;
#include <sstream>
using std::ostringstream;
#include <iostream>
using std::cout;
using std::endl;
GLint win_id = 0;
GLint win_x = 800, win_y = 600;
int mouse_x = 0;
int mouse_y = 0;
bool lmb_down = false;
bool mmb_down = false;
bool rmb_down = false;
float last_click_float_x = 0;
float last_click_float_y = 0;
void mouse_func(int button, int state, int x, int y)
{
if(GLUT_LEFT_BUTTON == button)
{
if(GLUT_DOWN == state)
lmb_down = true;
else
{
lmb_down = false;
float aspect = static_cast<float>(win_x)/static_cast<float>(win_y);
float fx = 2 * (float(x) / win_x) - 1;
float fy = 2 * (float(y) / win_y) - 1;
float tangent = tan(0.785398163 / 2);
last_click_float_x = aspect * tangent * fx;
last_click_float_y = tangent * fy;
}
}
else if(GLUT_MIDDLE_BUTTON == button)
{
if(GLUT_DOWN == state)
mmb_down = true;
else
mmb_down = false;
}
else if(GLUT_RIGHT_BUTTON == button)
{
if(GLUT_DOWN == state)
rmb_down = true;
else
rmb_down = false;
}
}
void draw_objects(void)
{
glPushMatrix();
glDisable(GL_LIGHTING);
glPointSize(4.0);
glColor3f(1, 1, 1);
glBegin(GL_POINTS);
glVertex3f(last_click_float_x, last_click_float_y, 0);
glEnd();
glPopMatrix();
}
void display_func(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// Draw the model's components using OpenGL/GLUT primitives.
draw_objects();
glFlush();
glutSwapBuffers();
}
void init_opengl(const int &width, const int &height)
{
win_x = width;
win_y = height;
if(win_x < 1)
win_x = 1;
if(win_y < 1)
win_y = 1;
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
glutInitWindowPosition(0, 0);
glutInitWindowSize(win_x, win_y);
win_id = glutCreateWindow("GLUT Window");
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);
glShadeModel(GL_SMOOTH);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glClearColor(0, 0, 0, 1);
glClearDepth(1.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0,
static_cast<GLfloat>(win_x)/static_cast<GLfloat>(win_y),
0.01, 20.0);
gluLookAt(0,0,1, // Eye position.
0,0,-1, // Look at position (not direction).
0,1,0); // Up direction vector.
}
void reshape_func(int width, int height)
{
win_x = width;
win_y = height;
if(win_x < 1)
win_x = 1;
if(win_y < 1)
win_y = 1;
glutSetWindow(win_id);
glutReshapeWindow(win_x, win_y);
glViewport(0, 0, win_x, win_y);
gluPerspective(45.0,
static_cast<GLfloat>(win_x)/static_cast<GLfloat>(win_y),
0.01, 20.0);
gluLookAt(0,0,1, // Eye position.
0,0,-1, // Look at position (not direction).
0,1,0); // Up direction vector.
}
void idle_func(void)
{
glutPostRedisplay();
}
void keyboard_func(unsigned char key, int x, int y)
{
switch(tolower(key))
{
default:
break;
}
}
void motion_func(int x, int y)
{
int prev_mouse_x = mouse_x;
int prev_mouse_y = mouse_y;
mouse_x = x;
mouse_y = y;
int mouse_delta_x = mouse_x - prev_mouse_x;
int mouse_delta_y = prev_mouse_y - mouse_y;
}
void passive_motion_func(int x, int y)
{
mouse_x = x;
mouse_y = y;
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
init_opengl(win_x, win_y);
glutReshapeFunc(reshape_func);
glutDisplayFunc(display_func);
glutIdleFunc(idle_func);
glutKeyboardFunc(keyboard_func);
glutMouseFunc(mouse_func);
glutMotionFunc(motion_func);
glutPassiveMotionFunc(passive_motion_func);
glutMainLoop();
return 0;
}