要求用户不干涉的情况下让物体自由旋转,这如果用win32的sdk直接来实现的话,就像Nehe的教程上那样是比较容易做的,可以在空闲事件的情况下调用绘图部分代码;
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
if
(PeekMessage(
&
msg,NULL,
0
,
0
,PM_REMOVE))
//
IsThereAMessageWaiting?
{
TranslateMessage( & msg); // TranslateTheMessage
DispatchMessage( & msg); // DispatchTheMessage
}
else // IfThereAreNoMessages
{
DrawGLScene();
}
但
MFC
中我不了解到底该怎么弄才好,起先也是想放到空闲事件处理程序中去调用绘图代码,就写了如下代码:
{
TranslateMessage( & msg); // TranslateTheMessage
DispatchMessage( & msg); // DispatchTheMessage
}
else // IfThereAreNoMessages
{
DrawGLScene();
}
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
BOOLCOpenGLDemoApp::OnIdle(LONGlCount)
{
// TODO:Addyourspecializedcodehereand/orcallthebaseclass
CFrameWnd * pw = (CFrameWnd * )AfxGetMainWnd();
((COpenGLDemoView * )pw -> GetActiveView()) -> DrawGLScene();
return CWinApp::OnIdle(lCount);
}
{
// TODO:Addyourspecializedcodehereand/orcallthebaseclass
CFrameWnd * pw = (CFrameWnd * )AfxGetMainWnd();
((COpenGLDemoView * )pw -> GetActiveView()) -> DrawGLScene();
return CWinApp::OnIdle(lCount);
}
可发现效果不对劲,必须要用户的鼠标在上面滑动才会旋转,和要求完全不符合呀。于是我就换了个想法,试着用了一个定时器,让它定时刷新重绘,从而产生出旋转的效果,代码如下:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
int
COpenGLDemoView::OnCreate(LPCREATESTRUCTlpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == - 1 )
return - 1 ;
// TODO:Addyourspecializedcreationcodehere
HWNDhWnd = this -> GetSafeHwnd();
HDChDC = ::GetDC(hWnd);
if ( this -> SetWindowPixelFormat(hDC) == FALSE)
{ // 设置像素格式
return 0 ;
}
if ( this -> CreateViewGLContext(hDC) == FALSE)
{ // 创建RC并选为所用
return 0 ;
}
if ( ! this -> InitGL())
{ // 初始化openGL
return 0 ;
}
this -> SetTimer( 1 , 10 ,NULL);
return 0 ;
}
void COpenGLDemoView::OnPaint()
{
CPaintDCdc( this ); // devicecontextforpainting
this -> DrawGLScene();
}
void COpenGLDemoView::OnTimer(UINTnIDEvent)
{
// TODO:Addyourmessagehandlercodehereand/orcalldefault
// 控制旋转角度
rTri += 1.2f ;
if (rTri >= 360.0f )
{
rTri -= 360.0f ;
}
rQuads -= 1.15f ;
if (rQuads <=- 360.0f )
{
rQuads += 360.0f ;
}
InvalidateRect(NULL,FALSE); // 角度更新了,通知其重绘
CView::OnTimer(nIDEvent);
}
int COpenGLDemoView::DrawGLScene()
{ // Here'sWhereWeDoAllTheDrawing
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // ClearScreenAndDepthBuffer
glShadeModel(GL_SMOOTH);
glLoadIdentity(); // ResetTheCurrentModelviewMatrix
glTranslatef( - 1.5f , 0.0f , - 6.0f ); // 物体左移1.5,向内移6,相当于移动镜头一样,让物体进入镜头中
glRotatef(rTri, 0.0f , 1.0f , 0.0f );
glBegin(GL_TRIANGLES); // 绘制三角形
glColor3f( 1.0f , 0.0f , 0.0f );
glVertex3f( 0.0f , 1.0f , 0.0f ); // 上顶点
glColor3f( 0.0f , 1.0f , 0.0f );
glVertex3f( - 1.0f , - 1.0f , 0.0f ); // 左下
glColor3f( 0.0f , 0.0f , 1.0f );
glVertex3f( 1.0f , - 1.0f , 0.0f ); // 右下
glEnd(); // 三角形绘制结束
glShadeModel(GL_FLAT);
glLoadIdentity();
glTranslatef( 1.5f , 0.0f , - 6.0f );
glRotatef(rQuads, 1.0f , 0.0f , 0.0f );
glBegin(GL_QUADS); // 绘制正方形
glColor3f( 1.0f , 0.0f , 0.0f );
glVertex3f( - 1.0f , 1.0f , 0.0f ); // 左上
glColor3f( 1.0 , 1.0f , 1.0f );
glVertex3f( - 1.0f , - 1.0f , 0.0f ); // 右下
glColor3f( 0.0f , 0.0f , 1.0f );
glVertex3f( 1.0f , - 1.0f , 0.0f ); // 左下
glColor3f( 0.0f , 1.0f , 0.0f );
glVertex3f( 1.0f , 1.0f , 0.0f ); // 右上
glEnd(); // 正方形绘制结束
glFlush();
rTri += 1.2f ;
if (rTri >= 360.0f )
{
rTri -= 360.0f ;
}
rQuads -= 1.15f ;
if (rQuads <=- 360.0f )
{
rQuads += 360.0f ;
}
HWNDhWnd = this -> GetSafeHwnd();
HDChDC = ::GetDC(hWnd);
SwapBuffers(hDC);
return TRUE; // EverythingWentOK
}
{
if (CView::OnCreate(lpCreateStruct) == - 1 )
return - 1 ;
// TODO:Addyourspecializedcreationcodehere
HWNDhWnd = this -> GetSafeHwnd();
HDChDC = ::GetDC(hWnd);
if ( this -> SetWindowPixelFormat(hDC) == FALSE)
{ // 设置像素格式
return 0 ;
}
if ( this -> CreateViewGLContext(hDC) == FALSE)
{ // 创建RC并选为所用
return 0 ;
}
if ( ! this -> InitGL())
{ // 初始化openGL
return 0 ;
}
this -> SetTimer( 1 , 10 ,NULL);
return 0 ;
}
void COpenGLDemoView::OnPaint()
{
CPaintDCdc( this ); // devicecontextforpainting
this -> DrawGLScene();
}
void COpenGLDemoView::OnTimer(UINTnIDEvent)
{
// TODO:Addyourmessagehandlercodehereand/orcalldefault
// 控制旋转角度
rTri += 1.2f ;
if (rTri >= 360.0f )
{
rTri -= 360.0f ;
}
rQuads -= 1.15f ;
if (rQuads <=- 360.0f )
{
rQuads += 360.0f ;
}
InvalidateRect(NULL,FALSE); // 角度更新了,通知其重绘
CView::OnTimer(nIDEvent);
}
int COpenGLDemoView::DrawGLScene()
{ // Here'sWhereWeDoAllTheDrawing
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // ClearScreenAndDepthBuffer
glShadeModel(GL_SMOOTH);
glLoadIdentity(); // ResetTheCurrentModelviewMatrix
glTranslatef( - 1.5f , 0.0f , - 6.0f ); // 物体左移1.5,向内移6,相当于移动镜头一样,让物体进入镜头中
glRotatef(rTri, 0.0f , 1.0f , 0.0f );
glBegin(GL_TRIANGLES); // 绘制三角形
glColor3f( 1.0f , 0.0f , 0.0f );
glVertex3f( 0.0f , 1.0f , 0.0f ); // 上顶点
glColor3f( 0.0f , 1.0f , 0.0f );
glVertex3f( - 1.0f , - 1.0f , 0.0f ); // 左下
glColor3f( 0.0f , 0.0f , 1.0f );
glVertex3f( 1.0f , - 1.0f , 0.0f ); // 右下
glEnd(); // 三角形绘制结束
glShadeModel(GL_FLAT);
glLoadIdentity();
glTranslatef( 1.5f , 0.0f , - 6.0f );
glRotatef(rQuads, 1.0f , 0.0f , 0.0f );
glBegin(GL_QUADS); // 绘制正方形
glColor3f( 1.0f , 0.0f , 0.0f );
glVertex3f( - 1.0f , 1.0f , 0.0f ); // 左上
glColor3f( 1.0 , 1.0f , 1.0f );
glVertex3f( - 1.0f , - 1.0f , 0.0f ); // 右下
glColor3f( 0.0f , 0.0f , 1.0f );
glVertex3f( 1.0f , - 1.0f , 0.0f ); // 左下
glColor3f( 0.0f , 1.0f , 0.0f );
glVertex3f( 1.0f , 1.0f , 0.0f ); // 右上
glEnd(); // 正方形绘制结束
glFlush();
rTri += 1.2f ;
if (rTri >= 360.0f )
{
rTri -= 360.0f ;
}
rQuads -= 1.15f ;
if (rQuads <=- 360.0f )
{
rQuads += 360.0f ;
}
HWNDhWnd = this -> GetSafeHwnd();
HDChDC = ::GetDC(hWnd);
SwapBuffers(hDC);
return TRUE; // EverythingWentOK
}
这下旋转的效果是有的,但由于是强制其重绘,所以画面刷新不过来,即使我用了双缓冲,画面还是闪烁得很。这个问题困惑了我一晚上,到底应该怎么弄呢?