Link to home
Start Free TrialLog in
Avatar of Brent-Campbell
Brent-Campbell

asked on

Mouse - 2D to 3D coordinates

Hi,

Take the following code for an example:

From my own class...

void Line::OnLeftMouseButtonDown(int x, int y, WPARAM status)
{
   m_StartPoint.x = -1.0 + ((2.0/1024.0f) * x);
   m_StartPoint.y = 1.0 - ((2.0/768.0f) * y);

   m_EndPoint.x = m_StartPoint.x;
   m_EndPoint.y = m_StartPoint.y;
}

void Line::OnMouseMove(int x, int y, WPARAM status)
{
   // Update the end point

   m_EndPoint.x = -1.0 + ((2.0/1024.0f) * x);
   m_EndPoint.y = 1.0 - ((2.0/768.0f) * y);
}

void Line::Render(void)
{
   glBegin(GL_LINES);

      glColor3f(1.0, 1.0, 1.0);

      glVertex2f(m_StartPoint.x, m_StartPoint.y);
      glVertex2f(m_EndPoint.x, m_EndPoint.y);

   glEnd();
}


Ok, no problem, the line draws from m_StartPoint to m_EndPoint.

If I now add several lines to the Render method to change the perspective...

void Line::Render(void)
{
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();

   gluPerspective(45.0f, 1024.0/768.0, 0.0f, 1.0f);

   glTranslatef(0.0, 0.0, -2.0);


   glBegin(GL_LINES);

      glColor3f(1.0, 1.0, 1.0);

      glVertex2f(m_StartPoint.x, m_StartPoint.y);
      glVertex2f(m_EndPoint.x, m_EndPoint.y);

   glEnd();
}

...the line starts and ends miles away from where I specified it using the mouse, so how can I draw the line in 3D like I did before?

Examples would be great as time is of the essense, hence the points.

Many thanks in advance!
ASKER CERTIFIED SOLUTION
Avatar of davebytes
davebytes
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Brent-Campbell
Brent-Campbell

ASKER

Hi Dave,

Fair play mate, that was the desired result, spot on...I needed the push/pop matrix lines!

Many thanks!
Although, now I played with it somemore, it seems things aren't quite going exactly to plan, i'll investigate it a little more and get back to you with more info...
definitely -- i'm monitoring the Q still.  -d
Hi,

Ok, I can sort of see what is going on now, but I'm not sure how to fix it, here is the un-working code but gives the idea of my desired result...


void Line3D::Initialisation(void)
{
  m_Draw = FALSE;

  m_StartPoint.x = 0.0f;
  m_StartPoint.y = 0.0f;

  m_EndPoint.x = 0.0f;
  m_EndPoint.y = 0.0f;
}

void Line3D::OnLeftMouseButtonDown(int x, int y, WPARAM status) // My own method
{
  m_StartPoint.x = -1.0 + ((2.0/1024.0f) * x);
  m_StartPoint.y = 1.0 - ((2.0/768.0f) * y);

  m_EndPoint.x = m_StartPoint.x;
  m_EndPoint.y = m_StartPoint.y;

  m_Draw = TRUE;
}

void Line3D::OnMouseMove(int x, int y, WPARAM status) // My own method
{
  // Update the end point
  m_EndPoint.x = -1.0 + ((2.0/1024.0f) * x);
  m_EndPoint.y = 1.0 - ((2.0/768.0f) * y);
}

void Line3D::OnLeftMouseButtonUp(int x, int y, WPARAM status) // My own method
{
  m_StartX = x;
  m_StartY = y;

  m_Draw = FALSE;
}

void Line3D::Render(void)
{
  if (m_Draw)
  {
    glMatrixMode(GL_PROJECTION);
    // glPushMatrix();

    glLoadIdentity();
    gluPerspective(45.0f, 1024.0/768.0, 0.0f, 1.0f);
    glTranslatef(0.0, 0.0, -2.0);

    // glPopMatrix();

 
    glRotatef(-65, 1.0f, 0.0f, 0.0f);


    Point a, b, c, d;

    a.x = m_EndPoint.x - 0.05;
    a.y = m_EndPoint.y;

    b.x = m_EndPoint.x + 0.05;
    b.y = m_EndPoint.y;

    c.x = m_StartPoint.x + 0.05;
    c.y = m_StartPoint.y;

    d.x = m_StartPoint.x - 0.05;
    d.y = m_StartPoint.y;

    glBegin(GL_QUADS);

      glColor3f(1.0, 1.0, 1.0);

      glVertex2f(a.x, a.y);
      glVertex2f(b.x, b.y);
      glVertex2f(c.x, c.y);
      glVertex2f(d.x, d.y);

    glEnd();
  }
}


Using the glPushMatrix() and glPopMatrix() commands (but without the glRotatef(-65, 1.0f, 0.0f, 0.0f) line) the line is drawn to the mouse coordinates as I'm trying to achieve but the line is not drawn into the distance, therefore I apply glPushMatrix(), glPopMatrix(), and glRotatef commands but then the mouse coordinates don't follow the mouse.

I'm offering 150 points for this as it's quite urgent and it's doing my head in!

Many thanks in advance.
Can you please explain "drawn into the distance"?  You are using 2D screen coordinates, what is 'distance'?  Is the line supposed to be z-buffered, or is it supposed to be NON-2D, but in fact 3D, somehow interacting in the scene view?

-d
Ok,

The plan is....I choose a point on the screen to be the start point (e.g bottom of the screen and in the middle), and then drag the line to the center of the screen which is the end point and I want the line to appear that it is in perspective i.e the line thickness gets shorter the further up the screen the mouse Y point is.  The above code I supplied does this but does not follow the mouse pointer.  Using the glPushMatrix and glPopMatrix (without the glRotate line) the line follows the mouse perfectly but the line is not drawn in perspective, so I added the glRotate command.  This works, I have the perspective now (only if I remove the glPushMatrix and glPopMatrix commands) but then the line doesn't start and end anywhere near my selected mouse start and end points. Does that make any sense?

Cheers.
Yes, because you are translating the points in space, no longer at their original positions.

I'd probably personally recommend that you 'by hand' do the effect, rather than trying to fudge something up via perspective transformation...

For instance, take your start point, and make two new points perpendicular to the current 'line' vector at a distance of, I dunno, two pixels each side?  Then do the same for the destination point, but scale from 0-2 pixels each side based upon something like the ratio of maximum corner-to-corner of the screen versus the current vector/line length.  Then, ignore the actual start/end line points, but instead draw a triangle fan using the four (two start, two end) points.  You can even then set the color of the start and end points in order to get a blend, and also adjust the color based on the vector length.

That's more likely easy to get on the mark, and easy to 'control' the 'effects' on the line as you drag it out.  That any help?

-d
You know more about this than me, and if my current method could have been fixed I'm sure you would have suggested a solution, so yeah the new method seems the way to go.

Many thanks for your help.