allow user to draw lines

hello

has anyone ever tried this? it seems to me that most people use OpenGL for games but I am designing an interior design type application (so that people can explore their own designs in 3D). I have a 2D design screen where I want the user to be able to draw box like shapes which will represent rooms. I know how to detect mouse clicks but I dont know how to draw a line on a screen depending on where the user drags the mouse. I suppose this is similar to Microsoft Word or Paint and other such applications, but, of course, I only want straight lines and boxes, no curves.

I dont know where to start, any ideas?!

thanks a lot

Gareth James
<><

ps I am using C++ in case you wanted to know

OnMouseDown
line start
OnMouseUp
line end

Add line to set

glBegin(GL_LINES)
draw_my_line_set
glEnd();

You don’t need OpenGL to draw 2d lines and boxes. However, if you want to transform this into 3d shapes OpenGL is useful for visualisation.

Gavin

yeh, that’s a great idea and it’s what I am going to do I think. If someone clicks the mouse button I’ll then get the POINT of this click. How can I use the x and y values of the point in a GL_LINES list of vertices? An example list of vertices is like this right?

glBegin(GL_LINES);
glVertex2d(-2.3,1.2);
glVertex2d(2.3,1.2);
glVertex2d(2.3,1.2);
glVertex2d(2.3,-2);
glVertex2d(2.3,-2);
glVertex2d(-2.3,-2);
glVertex2d(-2.3,-2);
glVertex2d(-2.3,1.2);
glEnd();

So, what I am trying to say is, how do I turn the point coordinates into something that can go in the glVertex2d command.
These values will also depend on where I have translated in the scene don’t they?

I hope you can see what I am getting at!

thanks
Gareth
<><

gluUnproject(). This converts a point in windows co-ordinates to OpenGL co-ordinates. Since you’re using glVertex2*() set winz to 0. This will project the point to 0 z in OpenGL which will match the glVertex2*() call.

why does every man and his dog like gluUnProject()??!?! It’s not some magical device that solves everything (though I hear that gluMedicalResearch(GL_CANCER_VACCINE) will be released in opengl 2.0).

If you want to plot lines in 2D, then you do NOT need to use gluUnproject. (If you want to plot lines in 3D, then you probably also don’t need it.)

the trick –
set your camera to ortho projection with some “useful” coordinate system. maybe thats 0,0 - w,h in pixel coordinates, or maybe its 0,0 - 1,1 or mayeb -1,-1 … 1,1. its whaetever makes you happy; its not relevent.

get your mouse coordinate in x,y. you know how big the screen is in pixels, so you can compute the ratio the x,y is within that screen. Since you know the ratio of the mouse to pixels in the window, you can linearly compute the ratio in camera coordinates.

easy.

cheers,
John

Yes use glortho and set it up per pixel sort of idea (as above) so all your 2d stuff is directly related. Assuming you are just wanting to do a simple 2d drawing app.

john, gavin

yes! that sounds good!

ok so in my ReSizeGLScene (which resizes and initializes the GL window) I have, amongst others, these two lines:

glViewport(0, 0, width, height); // Reset the Current Viewport

glMatrixMode(GL_PROJECTION); //Select the Projection Matrix

from what you said, do I take it that I only want to have an ortho projection when I am doing this business with the lines? I hope this is right because I imagine I’m going to have to change a lot of stuff in my code to change complete to an ortho projection.

ie can I change the projection matrix I am using on the fly? and if so, how do I do that.

sorry for my newbie-ness but I really am still finding my feet it seems.

Gareth
<><

Hmmm, are you drawing other 3d stuff as well?

ie can I change the projection matrix I am using on the fly? and if so, how do I do that.

       sorry for my newbie-ness but I really am still finding my feet it seems.

You can change the projection you use whenever you want, even several times within drawing a single frame. Just issue an

glMatrixMode( GL_PROJECTION)
… // projection matrix stuff here
glMatrixMode( GL_MODELVIEW)

when you need it. If you do not want to disturb the ‘overall’ projection matrix (the one used in the rest of your application, issue a glPushMatrix() before modifying the projection matrix and a glPopMatrix() once you’re done with it (again in GL_PROJECTION matrix mode!).
Do keep in mind that usually there is only room for 2 projection matrices on the stack!

It is quite common to mix ortho projections (console display, GUI display, window-dressing like crosshairs etc.) with perspective projections (drawing 3d objects in a scene).

HTH

Jean-Marc.

oh excellent.

yes I am doing other 3D stuff as well. The part I am working on now is for allowing the user to draw 2D things but I am going to use the points (which I will store in a linked list/array) to not only display the lines they’ve drawn but also to later build a 3D scene out of them.

Gareth
<><

[This message has been edited by dfanuk (edited 04-17-2002).]

By the way: changing the projection matrix will keep the previously rendered frame buffer intact, including values written to the depth buffer. However, those depth values are ‘remapped’ to the new projection matrix.

Example (assuming ortho projections in both cases):

1st projection has zNear = 1, zFar = 100. Draw object at z=40 results in depth buffer value of 0.4.

2nd projection has zNear=1, zFar = 50. Draw object at z=30 results in depth buffer value of 0.6

The second object will be obscured by the first object, even though you might think that it should be visible when comparing their z values.

For perspective projections the same applies, only the calculation of the actual depth buffer value differs (the depth buffer values are not mapped linear in that case).

HTH

Jean-Marc

ok well I’ve found the C spec for glortho on this website but now I don’t understand what values I should be filling it with.

void glOrtho( GLdouble left,
GLdouble right,
GLdouble bottom,
GLdouble top,
GLdouble zNear,
GLdouble zFar )

What are clipping planes?

thanks
Gareth
<><

Originally posted by dfanuk:
[b]ok well I’ve found the C spec for glortho on this website but now I don’t understand what values I should be filling it with.

void glOrtho( GLdouble left,
GLdouble right,
GLdouble bottom,
GLdouble top,
GLdouble zNear,
GLdouble zFar )

What are clipping planes?

thanks
Gareth
<><[/b]

First: no offense, but try to get a copy of the redbook. It explains in detail what the purpose of all the gl functions are and shows their use via examples. You should also checkout some of the excellent tutorials on the net (nehe.gamedev.net being one of them).

Second: clip planes are planes in 3d space that split the space in two parts: a part that gets clipped away (i.e. fragments on that side are not draw) and a part that gets drawn.
The ortho projection sets up 6 planes that effectively reduce the infinite world to a orthogonal box. Only fragments drawn inside the box turn up on your screen, all else is thrown away.
The perspective projection does a similar job, only now the planes are not all parallel/perpendicular to each other, but they are part of a piramid that is missing its top:

±—+
/
/
±---------+
(and that in 3D)

HTH

Jean-Marc.

ok thanks Jean-Marc. Don’t worry, I’m not offended!

I have many of the nehe tutorials and they have been a great help. I just haven’t fully understood the perspective stuff. your description helps a lot. did you know that there is a copy of the red book on the net? I shall use that for help as well.

thanks again

Gareth
<><

Well depends where you want the origin to be, but they should be relevant to the window width and height that you are using in the resize func. so you could use
0, width, 0, height

or

-height/2, -width/2, height/2, width/2

see…

Gavin

if I used (0, width, 0 height) then that would mean that I am setting the origin to the bottom left of the screen yeh?
would it be easier for me to set it to the top left, ie to make converting my pixel coordinates to window coordinates easier, as pixel origin is top left.

In the red book it says this:

For the special case of projecting a two-dimensional image onto a two-dimensional screen, use the Utility Library routine gluOrtho2D(). This routine is identical to the three-dimensional version, glOrtho(), except that all the z coordinates for objects in the scene are assumed to lie between -1.0 and 1.0. If you’re drawing two-dimensional objects using the two-dimensional vertex commands, all the z coordinates are zero; thus, none of the objects are clipped because of their z values. void gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top);

isn’t this more what I need? I am projecting a 2D image.

from what you’ve all said, am I right in saying that if I switch to an ortho projection whilst in DrawGLScene, everything else that has already been drawn will not be altered? I just want to be clear on that

Gareth
<><

Originally posted by dfanuk:
from what you’ve all said, am I right in saying that if I switch to an ortho projection whilst in DrawGLScene, everything else that has already been drawn will not be altered? I just want to be clear on that

What has already been drawn will not be altered by changing the projection for subsequent draws.

It will of course be affected by what you draw next

Jean-Marc.

ok, this is what I have got at the moment (I’ve been working on my linked list)

glPushMatrix();
glMatrixMode(GL_PROJECTION);
gluOrtho2D( 0, 640, 480, 0 ); //switch to ortho projection to draw the lines
glMatrixMode(GL_MODELVIEW);

//LOOP THROUGH THE ARRAY AND
//USE glortho WITH THE MOUSE
//COORDINATES AND SCREEN SIZE IN PIXELS

glPopMatrix();

what I am unsure of at the moment is:
a) whether the values I have put in the gluOrtho2D proc are correct, and
b) what kind of values I need to change the pixel coordinates returned by GetCursorPos to

any help would be much appreciated!

thanks
Gareth
<><

It looks ok. Do a printf when you click the mouse and output what you arte getting for the x/y of the mouse and see if it is what you think it should be. Then try drawing a point form this click.

int x_pos = 50, y_pos = 50;

and in your draw draw this point, you should see it at 50, 50. Then in your mouse click func do…
x_pos = mouse_x… and so on, just make em global for now. to check everything works…

oh if the width of a window is 600 the left will be 0 and right will be 599!!!