Jump to content
  • Advertisement
Sign in to follow this  
adam_o

[SDL] Translating mouse coordinates in SDL into OpenGL space

This topic is 3887 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I know I've seen the code for this somewhere, but I can't remember, so I'm calling upon your superior memories to help me figure this out: when SDL outputs coordinates, it outputs them in 2D, "screen-level" coordinates. Now from that I would like to figure out how to determine what the mouse would have "touched" in a 2D or 3D OpenGL environment. Is there something that would figure this out for me somehow? All help is appreciated and thanks in advance. adam_o

Share this post


Link to post
Share on other sites
Advertisement
It sounds like you're looking for gluUnProject. It takes screen-space coordinates and returns world-space coordinates, based on the passed viewport and matrices. For help on determining what the user is trying to click on, google around for "opengl mouse picking" (the first result is one simple and common way to do it, though faster methods do exist).

Share this post


Link to post
Share on other sites
Quote:
Original post by jouley
It sounds like you're looking for gluUnProject. It takes screen-space coordinates and returns world-space coordinates, based on the passed viewport and matrices. For help on determining what the user is trying to click on, google around for "opengl mouse picking" (the first result is one simple and common way to do it, though faster methods do exist).


Ok, thank you. I'll try to work with that, and if I have any more problems, I'll post again.

Share this post


Link to post
Share on other sites
I finally got around to trying out gluUnProject(), but my program crashed and the data was wrong. So I tried gluProject() (because I figured it might be the other way around; I'm using mouse coordinates to find what the mouse clicked on) and it gave me weird numbers, but I got the numbers. The problem is, with both versions of Project(), my program crashes, and if I simply comment the Project() code, the program works fine. Here's my code:

int x_loc = event.button.x;
int y_loc = event.button.y;
fileout << "(" << x_loc << "," << y_loc << ")" << endl << flush;
GLdouble mv_matrix;
GLdouble prj_matrix;
GLint vp;
GLdouble xdest, ydest, zdest;
glGetDoublev(GL_MODELVIEW, &mv_matrix);
glGetDoublev(GL_PROJECTION, &prj_matrix);
glGetIntegerv(GL_VIEWPORT, &vp);
gluProject(x_loc, y_loc, 0, &mv_matrix, &prj_matrix, &vp,
&xdest, &ydest, &zdest);
fileout << "(" << xdest << ", " << ydest << ", "
<< zdest << ")" << endl << flush;


And here's what I got:
(431,82)
(504.471, 380.626, -0.108788)
(14,37)
(504.471, 383.39, -0.10159)
(433,329)
(504.471, 378.919, -0.113231)
(222,153)
(504.471, 379.571, -0.111534)
(74,332)
(504.471, 378.914, -0.113244)
(these are five random points on the screen, SDL coordinate pairs first and OpenGL triples second)

So am I using this code wrong? Why is it hanging up? Is it gluProject() or gluUnproject()?

EDIT: I'd like to add that the program crashes iff I click the mouse button (which activates glu*Project()). Otherwise, it runs just fine. Another weird thing to note is that it crashes on exit, not when I click the button.

[Edited by - adam_o on January 21, 2008 9:57:14 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by adam_o
I finally got around to trying out gluUnProject()...
Which is the function you're looking for. gluProject is used to turn world space coordinates into screen space
Quote:
...but my program crashed and the data was wrong.
Taking a look at your code, I've commented some trouble spots:
int x_loc = event.button.x;
int y_loc = event.button.y;
fileout << "(" << x_loc << "," << y_loc << ")" << endl << flush;

// you create one GLdouble here, but glGetDoublev will try to fill the
// pointed-at space with 16 doubles (each element of a 4x4 matrix).
GLdouble mv_matrix; // should be: GLdouble mv_matrix[16];
GLdouble prj_matrix; // likewise
GLint vp; // here, the viewport will only hold 4 values
GLdouble xdest, ydest, zdest;
glGetDoublev(GL_MODELVIEW, &mv_matrix);
glGetDoublev(GL_PROJECTION, &prj_matrix);
glGetIntegerv(GL_VIEWPORT, &vp);
gluProject(x_loc, y_loc, 0, &mv_matrix, &prj_matrix, &vp,
&xdest, &ydest, &zdest);
fileout << "(" << xdest << ", " << ydest << ", "
<< zdest << ")" << endl << flush;


Quote:
So am I using this code wrong? Why is it hanging up? Is it gluProject() or gluUnproject()?
To summarize: Yep. Because it's trying to write to memory space it doesn't own. gluUnProject( ).

Quote:
EDIT: I'd like to add that the program crashes iff I click the mouse button (which activates glu*Project()). Otherwise, it runs just fine. Another weird thing to note is that it crashes on exit, not when I click the button.
The crash only happens iff you click because nothing is going wrong otherwise, meaning the problem is definitely within the given code. The crash happening on exit is just how this particular bug has chosen to manifest itself. You're lucky it didn't turn your oven on for you. The garbage numbers you were getting is likely because the values from one matrix were overwriting those from the others, since the allocated space was contiguous. You can learn more about the glGet* functions here, including what their parameters/return values are.

Best of luck!
-jouley

Share this post


Link to post
Share on other sites
I just tried what you suggested, but got these errors:

92: error: cannot convert 'GLdouble (*)[4][4]' to 'GLdouble*' for argument '2' to 'void glGetDoublev(GLenum, GLdouble*)'
(etc)

So it says that the second argument of glGetDoublev is not a 4x4 array.

EDIT: An interesting thing that I found is that under the link you gave me (*Mac shudders) is that the enum is GL_MODELVIEW_MATRIX, not GL_MODELVIEW. I'll test this out and edit again with results.

Share this post


Link to post
Share on other sites
Something that warranted a new post... when I changed the code to this:
int x_loc = event.button.x;
int y_loc = event.button.y;
fileout << "(" << x_loc << "," << y_loc << ")" << endl << flush;
GLdouble mv_matrix;
GLdouble prj_matrix;
GLint vp;
GLdouble xdest, ydest, zdest;
glGetDoublev(GL_MODELVIEW_MATRIX, &mv_matrix);
glGetDoublev(GL_PROJECTION_MATRIX, &prj_matrix);
glGetIntegerv(GL_VIEWPORT, &vp);
gluProject(x_loc, y_loc, 0, &mv_matrix, &prj_matrix, &vp,
&xdest, &ydest, &zdest);
fileout << "(" << xdest << ", " << ydest << ", "
<< zdest << ")" << endl << flush;

The debugger came up as usual, but it did shut itself off after printing this:
Loading program into debugger…
GNU gdb 6.3.50-20050815 (Apple version gdb-768) (Tue Oct 2 04:11:19 UTC 2007)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "powerpc-apple-darwin".Program loaded.
sharedlibrary apply-load-rules all
Attaching to program: `/Users/atg/Desktop/Projects/Xcode Projects/Release/Tetris_020.app/Contents/MacOS/Tetris_020', process 864.
gdb stack crawl at point of internal error:
[ 0 ] /Developer/usr/libexec/gdb/gdb-powerpc-apple-darwin (align_down+0x0) [0x11d4fc]
[ 1 ] /Developer/usr/libexec/gdb/gdb-powerpc-apple-darwin (frame_register+0x98) [0x123c6c]
[ 2 ] /Developer/usr/libexec/gdb/gdb-powerpc-apple-darwin (frame_register_read+0x2c) [0x123d78]
[ 3 ] /Developer/usr/libexec/gdb/gdb-powerpc-apple-darwin (do_frame_register_read+0x10) [0x123dc0]
[ 4 ] /Developer/usr/libexec/gdb/gdb-powerpc-apple-darwin (regcache_save+0xd8) [0x2b900]
[ 5 ] /Developer/usr/libexec/gdb/gdb-powerpc-apple-darwin (frame_save_as_regcache+0x4c) [0x122b88]
[ 6 ] /Developer/usr/libexec/gdb/gdb-powerpc-apple-darwin (frame_pop+0x20) [0x124e64]
[ 7 ] /Developer/usr/libexec/gdb/gdb-powerpc-apple-darwin (hand_function_call+0xde4) [0x5e38c]
[ 8 ] /Developer/usr/libexec/gdb/gdb-powerpc-apple-darwin (allocate_space_in_inferior_malloc+0xc8) [0x38e80]
[ 9 ] /Developer/usr/libexec/gdb/gdb-powerpc-apple-darwin (macosx_allocate_space_in_inferior_helper+0x24) [0x18265c]
[ 10 ] /Developer/usr/libexec/gdb/gdb-powerpc-apple-darwin (catch_exceptions_with_msg+0x5c) [0x76568]
[ 11 ] /Developer/usr/libexec/gdb/gdb-powerpc-apple-darwin (macosx_allocate_space_in_inferior+0x88) [0x182704]
[ 12 ] /Developer/usr/libexec/gdb/gdb-powerpc-apple-darwin (value_string+0x15c) [0x3e1a8]
/SourceCache/gdb/gdb-768/src/gdb/frame.c:661: internal-error: frame_register: Assertion `frame != NULL && frame->next != NULL' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.

The Debugger Debugger is attaching to process(gdb)
Now I know that the 0-12 list is something very important, but I have no clue what, as I do not know how to use this newer version of XCode. If you know what it means, that would be helpful, but I think I may have to go to the Mac mailing lists for this.

Share this post


Link to post
Share on other sites
Quote:
Original post by smart_idiot
OpenGL uses a 16 element one-dimensional array for its matrices.


I understand this. I have understood this from my first day programming OpenGL. Your brief "helpfulness" didn't do anything. I suggest if you really want to help, that you go over this topic and see what I mean. Otherwise, waste your time in the Lounge.

Share this post


Link to post
Share on other sites
Quote:
Original post by adam_o
Quote:
Original post by smart_idiot
OpenGL uses a 16 element one-dimensional array for its matrices.


I understand this. I have understood this from my first day programming OpenGL. Your brief "helpfulness" didn't do anything. I suggest if you really want to help, that you go over this topic and see what I mean. Otherwise, waste your time in the Lounge.


The hardest things to learn are the things you think you already know.


double modelMatrix[16]; // <-- A one dimensional array, with 16 elements.
double projMatrix[16];
int viewport[4];

glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
glGetIntegerv(GL_VIEWPORT, viewport);

gluUnProject(mouse_x, viewport[3]-mouse_y, mouse_depth, modelMatrix, projMatrix, viewport, &position_x, &position_y, &position_z);




The value for mouse_depth is a tricky value to get, how far into the screen is the mouse? You can either use gluProject on a known point, and use its depth, making the mouse as far into the screen as that point is, or you can read the data from the depth buffer, and use the point under the mouse, in which case it will follow the surface of the geometry being rendered.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!