visual c++ - Panning in a MFC Control using OpenGL -
i'm new opengl might silly question.
what i'm using: visual studio 2010, mfc framework, windows 7.
what i'm trying do: mfc control based on opengl can show files preview zooming, panning , rotation.
what i've done:
- derived class cbutton handle events , having easy access cclientdc;
- following less or more recent tutorial i've encapsulated creation of opengl device in class.
let me show code:
int copenglctrl::oncreate( lpcreatestruct lpcreatestruct ) { if( cbutton::oncreate( lpcreatestruct ) == -1 ) return -1; m_pdc = new cclientdc( ); // 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(); } // function called before drawglscene first time control 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 ); } all code sufficient draw small triangle in control low-left vertex centered in opengl axis origin. good, showed stuff see if there error somewhere. want pan around triangle: i've understood, i've modify value of m_ftranslation_x , m_ftranslation_y. i've decided pan view when user holds down mouse left button , moves around:
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 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 ); /////////////////////// // edit: added in edit solve mfc-way m_p2dultpos = point; /////////////////////// memcpy( m_vposmouse_ult, m_vposmouse, 3 * sizeof( glfloat ) ); } if( m_cb_posagg.valid() ) m_cb_posagg.execute(); invalidate(); } in short words: keep track of mouse last position , calculate how i've moved on x , on y. these differences traslations.
problems:
- if use opengl coordinate (commented , labelled opengl-way) pan smooth , precise shakes. because if cpoint coordinates increase (or decrease) , difference, opengl don't. here's values:
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 243as can see, while mouse control position increases (in mfc y axis inverted), @ step 3 values x-axis decreased 0.02 0.002 , 0.02! why this?
- edit: solved in answer. if use mfc coordinate, labelled mfc-way, i've got no shakes strong inertia. happen if start moving mouse right (assuming no up-down) change direction left, view continues move right. error?
problem 1)
first problem when view gets invalidated , redrawed, traslation has still performed! solution:
if( nflags == mk_rbutton && m_btrasla ) { // converting mfc coordinates opengl system. conversionecoordinatemfc_a_opengl( m_vposmouse_ult, m_p2dultpos ); m_ftraslation_x += m_vposmouse[0] - m_vposmouse_ult[0]; m_ftraslation_y += m_vposmouse[1] - m_vposmouse_ult[1]; problem 2)
mfc-style panning not updating last position of mouse pointer. adding line:
m_p2dultpos = point; solved problem.
Comments
Post a Comment