Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 4 of 4

Thread: Panning Newbie Problems

  1. #1
    Junior Member Newbie
    Join Date
    Apr 2014
    Location
    Italia
    Posts
    5

    Question Panning Newbie Problems

    Hi everybody, I'm very new to OpenGL so this might be a very silly question.

    What I'm using: Visual Studio 2010, MFC framework, Windows 7.
    What I'm trying to do: A MFC control based on OpenGL that can show some files preview with zooming, panning and rotation.
    What I've already done:
    1) Derived a class from CButton to handle all events and having a easy access to CClientDC;
    2) Following a less or more recent tutorial I've encapsulated the creation of the OpenGL Device in a class. I don't know if it's good or if I've understood what I've done, but it works:

    Code :
    int COpenGLCtrl::OnCreate( LPCREATESTRUCT lpCreateStruct )
    	{
    		if( CButton::OnCreate( lpCreateStruct ) == -1 )
    			return -1;
    		m_pDC = new CClientDC( this );
                    // This is my encapsulated device.
    		m_GLDevice.Create( m_pDC->m_hDC );
    		InitGL();
    		return 0;
    	}
            void COpenGLCtrl::InitGL( void )
    	{
    		glShadeModel( GL_SMOOTH );
    		glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
    	}
            // Drawing inside button.
            void COpenGLCtrl::OnPaint( void )
    	{
    		m_GLDevice.MakeCurrent();
    		DrawGLScene();
    	}
            // This function is called before DrawGLScene the first time the control is being redrawed.
            void COpenGLCtrl::ZoomOut( int nVal )
    	{
    		glMatrixMode( GL_PROJECTION );  
    		glLoadIdentity();
    		glOrtho( 0.0f, nVal * 1.0f, 0.0f, nVal * 1.0f, nVal * 1.0f, 0.0f );
    		glMatrixMode( GL_MODELVIEW );
    		glLoadIdentity();
    	}
            void COpenGLCtrl::DrawGLScene( void )
    	{
    		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
     
    		glLoadIdentity();
    		glRotatef( m_fRotation_X, 1.0f, .0f, 0.0f );
    		glRotatef( m_fRotation_Y, 0.0f, 1.0f, 0.0f );
    		glTranslatef( m_fTraslation_X, m_fTraslation_Y, 0.0f );
    		glScalef( 1.0f, 1.0f, 0.0f );
     
    		glBegin( GL_TRIANGLES );
    		glColor3f( 1.0f, 0.0f, 0.0f );
    		glVertex3f( 0.0f, 0.0f, 0.0f );
    		glColor3f( 0.0f, 1.0f, 0.0f );
    		glVertex3f( 0.5f, 1.0f, 0.0f );
    		glColor3f( 0.0f, 0.0f, 1.0f );
    		glVertex3f( 1.0f, 0.0f, 0.0f );
    		glEnd();
     
    		SwapBuffers( m_pDC->m_hDC );
    	}

    This stuff is sufficient to draw a small rectangle in my control with low-left vertex centered in OpenGL axis origin. All good, I showed you all this stuff to see if there are some error somewhere.
    Now, I want to pan around my triangle. From what I've understood, I've to modify the value of m_fTranslation_X and _Y. I've decided to pan the view when the user holds down the left button and moves it around:

    Code :
    void COpenGLCtrl::OnMouseMove( UINT nFlags, CPoint point )
    	{
    		int				nRes;
    		CString			strOut;
    		GLfloat			winX, winY, winZ;
    		GLint			viewport[4];
    		GLdouble		vPos[3], modelview[16], projection[16];
     
                    // Converting CPoint MFC coordinates to OpenGL viewport coordinates.
    		 m_p2dPosMouse = point;
    		 glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
    		 glGetDoublev( GL_PROJECTION_MATRIX, projection );
     		glGetIntegerv( GL_VIEWPORT, viewport );
     		winX = (GLfloat)point.x;
     		winY = (GLfloat)viewport[3] - (GLfloat)point.y;
     		glReadPixels( point.x, int( winY ), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
     		nRes = gluUnProject( winX, winY, winZ, modelview, projection, viewport, &vPos[0], &vPos[1], &vPos[2] );
     		m_vPosMouse[0] = (GLfloat)vPos[0];
     		m_vPosMouse[1] = (GLfloat)vPos[1];
    		 m_vPosMouse[2] = (GLfloat)vPos[2];
     		if( nFlags == MK_LBUTTON )
     		{
     			if( !m_bTrasla )
     			{
    				ATLTRACE2( _T("\nInizio traslazione\n\n") );
    				memcpy( m_vPosMouse_ult, m_vPosMouse, 3 * sizeof( GLfloat ) );
    				m_p2dUltPos = point;
    				m_bTrasla = true;
    			}
    			/*OPENGL-WAY
    			m_fTraslation_X += m_vPosMouse[0] - m_vPosMouse_ult[0];
    			m_fTraslation_Y += m_vPosMouse[1] - m_vPosMouse_ult[1];
    			*/
                            /*MFC-WAY*/
    			m_fTraslation_X += ( point.x - m_p2dUltPos.x ) / 5000.0f;
    			m_fTraslation_Y += ( m_p2dUltPos.y - point.y ) / 5000.0f;
    			CString	strBuf;
    			strBuf.Format( _T("%f - %f || CPoint.x: %ld CPoint.y: %ld\n"), m_fTraslation_X, m_fTraslation_Y, point.x, point.y );
    			ATLTRACE2( strBuf );
    			memcpy( m_vPosMouse_ult, m_vPosMouse, 3 * sizeof( GLfloat ) );
    		}
    		if( m_CB_PosAgg.Valid() )
    			m_CB_PosAgg.Execute();
    		Invalidate();
    	}

    In short words: I keep track of mouse last position and calculate how much I've moved on X and on Y. These differences are my traslations.
    Finally my problems:
    1) If I use OpenGL coordinate (commented and labelled OPENGL-WAY) the pan is smooth and precise but shakes. This is because even if my CPoint coordinates increase (or decrease) and so the difference, the OpenGL don't. Here's some values:

    Code :
    m_fTraslate_X  m_fTraslate_Y  CPoint.x CPoint.y
    0.000000         0.000000        274        328
    0.014377         0.141573        283        265
    0.020767         0.152809        287        260
    0.001597         0.002247        288        259
    0.007987         0.020225        292        251
    0.025559         0.164045        295        246
    0.027157         0.170786        296        243


    As you can see, while mouse control position increases (in MFC Y axis is inverted), at step 3 the values for X-axis are suddenly decreased from 0.02 to 0.002 and then back to 0.02! Why this?
    2) If I use MFC coordinate, labelled MFC-WAY, I've got no shakes but a strong inertia. Sometimes happen that if I start moving my mouse to the right (assuming no up-down) then change the direction back to left, my view continues to move to the right. Where is the error?

    Thanks in advance, hope you won't ban me for this noobish essay.

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,117
    Code :
    m_fTraslation_X += m_vPosMouse[0] - m_vPosMouse_ult[0];


    Are you sure you want to keep adding

    I would have thought you want
    Code :
     m_fTranslation_X = original_x+(
    Code :
    m_vPosMouse[0] - m_vPosMouse_ult[0]);


    because
    m_vPosMouse_ult[0] is not changing

  3. #3
    Junior Member Newbie
    Join Date
    Apr 2014
    Location
    Italia
    Posts
    5
    Quote Originally Posted by tonyo_au View Post
    because m_vPosMouse_ult[0] is not changing
    What you mean? m_vPosMouse_ult[0] is actually changing:
    Code :
    memcpy( m_vPosMouse_ult, m_vPosMouse, 3 * sizeof( GLfloat ) );

    EDIT
    You were partially right, in the MFC-WAY I didn't update the last position of mouse. Adding:
    Code :
    m_p2dUltPos = point;
    Last edited by IssamTP; 04-16-2014 at 03:30 AM. Reason: Problem solved

  4. #4
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,117
    Sorry, I was looking at the OPENGL_WAY and thought all the code after MFC-WAY was removed.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •