要求用户不干涉的情况下让物体自由旋转,这如果用win32的sdk直接来实现的话,就像Nehe的教程上那样是比较容易做的,可以在空闲事件的情况下调用绘图部分代码;
if
(PeekMessage(
&
msg,NULL,
0
,
0
,PM_REMOVE))
//
Is There A Message Waiting?
{
TranslateMessage(
&
msg);
//
Translate The Message
DispatchMessage(
&
msg);
//
Dispatch The Message
}
else
//
If There Are No Messages
{
DrawGLScene();
}
但
MFC
中我不了解到底该怎么弄才好,起先也是想放到空闲事件处理程序中去调用绘图代码,就写了如下代码:
BOOL COpenGLDemoApp::OnIdle(LONG lCount)
{
//
TODO: Add your specialized code here and/or call the base class
CFrameWnd
*
pw
=
(CFrameWnd
*
)AfxGetMainWnd();
((COpenGLDemoView
*
)pw
->
GetActiveView())
->
DrawGLScene();
return
CWinApp::OnIdle(lCount);
}
可发现效果不对劲,必须要用户的鼠标在上面滑动才会旋转,和要求完全不符合呀。于是我就换了个想法,试着用了一个定时器,让它定时刷新重绘,从而产生出旋转的效果,代码如下:
int
COpenGLDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if
(CView::OnCreate(lpCreateStruct)
==
-
1
)
return
-
1
;
//
TODO: Add your specialized creation code here
HWND hWnd
=
this
->
GetSafeHwnd();
HDC hDC
=
::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()
{
CPaintDC dc(
this
);
//
device context for painting
this
->
DrawGLScene();
}
void
COpenGLDemoView::OnTimer(UINT nIDEvent)
{
//
TODO: Add your message handler code here and/or call default
//
控制旋转角度
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's Where We Do All The Drawing
glClear(GL_COLOR_BUFFER_BIT
|
GL_DEPTH_BUFFER_BIT);
//
Clear Screen And Depth Buffer
glShadeModel(GL_SMOOTH);
glLoadIdentity();
//
Reset The Current Modelview Matrix
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
;
}
HWND hWnd
=
this
->
GetSafeHwnd();
HDC hDC
=
::GetDC(hWnd);
SwapBuffers(hDC);
return
TRUE;
//
Everything Went OK
}
这下旋转的效果是有的,但由于是强制其重绘,所以画面刷新不过来,即使我用了双缓冲,画面还是闪烁得很。这个问题困惑了我一晚上,到底应该怎么弄呢?