我对OpenGL很新,所以这可能是一个非常愚蠢的问题。
我正在使用的是什么:Visual Studio 2010,MFC框架,Windows 7
我正在尝试做什么:基于OpenGL的MFC控件,可以通过缩放,平移和旋转显示一些文件预览。
我已经完成了什么:
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 );
}
所有这些代码足以在我的控件中绘制一个小三角形,其左下顶点以OpenGL轴原点为中心。好的,我告诉你所有这些东西,看看是否有某些错误。 现在我想围绕我的三角形:从我所理解的,我要修改m_fTranslation_X和m_fTranslation_Y的值。当用户按住鼠标左键并移动它时,我决定平移视图:
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 );
///////////////////////
// EDIT: Added in edit to 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();
}
简而言之:我跟踪鼠标的最后位置并计算我在X和Y上的移动量。这些差异是我的翻译。
最后我的问题:
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
正如您所看到的,当鼠标控制位置增加(在MFC Y轴反转时),在步骤3,X轴的值突然从0.02减少到0.002然后再回到0.02!为什么这样?
答案 0 :(得分:0)
问题1)
第一个问题是,当视图失效然后重绘时,仍然需要执行转换!解决方案:
if( nFlags == MK_RBUTTON && m_bTrasla )
{
// Converting MFC coordinates to 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];
问题2)
MFC-STYLE平移不会更新鼠标指针的最后位置。添加此行:
m_p2dUltPos = point;
解决了这个问题。