用MFC(单文档)开发OpenGL程序

OpenGL是一个优秀的专业化的3D的API(Application Programming Interface,应用编程接口)

下面通过一个简单的例子说明如何在MFC中建立OpenGL的视场

1.建立一个单文档工程Point

2.单击Project菜单中的Setting...命令,打开Project Setting对话框,单击Link属性页,在Object/library modules中加入opengl32.lib glu32.lib

3.在PointView.cpp文件中加入头文件:
#include "gl/gl.h"
#include "gl/glu.h"

4.在PointView.h文件中加入所需的成员变量和函数:
public:
 CClientDC *m_pDC;
 void Init();
 BOOL bSetupPixelFormat(void);
 void DrawScene(void);

5.在PointView.cpp文件中,在CPointView的构造函数中加入:
m_pDC=NULL;

6.在PointView.cpp文件中,加入相应的成员函数:
void CPointView::Init()
{
 PIXELFORMATDESCRIPTOR pfd;
 int n;
 HGLRC hrc;

 m_pDC=new CClientDC(this);

 ASSERT(m_pDC != NULL);

 if(!bSetupPixelFormat())
  return;

 n=::GetPixelFormat(m_pDC->GetSafeHdc());

 ::DescribePixelFormat(m_pDC->GetSafeHdc(), n,sizeof(pfd),&pfd);

 hrc=wglCreateContext(m_pDC->GetSafeHdc());
 wglMakeCurrent(m_pDC->GetSafeHdc(),hrc);

 glClearDepth(1.0f);
 glEnable(GL_DEPTH_TEST);
}

BOOL CPointView::bSetupPixelFormat()
{
 static PIXELFORMATDESCRIPTOR pfd =
 {
        sizeof(PIXELFORMATDESCRIPTOR),
        1,
        PFD_DRAW_TO_WINDOW |
          PFD_SUPPORT_OPENGL|
    PFD_DOUBLEBUFFER, 
        PFD_TYPE_RGBA,
        24,
        0, 0, 0, 0, 0, 0,
        0,
        0,
        0,
        0, 0, 0, 0,
        32,
        0,
        0,
        PFD_MAIN_PLANE,
        0,
        0, 0, 0
    };
    int pixelformat;

    if((pixelformat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) == 0)
    {
        MessageBox("ChoosePixelFormat failed");
        return FALSE;
    }

    if(SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE)
    {
        MessageBox("SetPixelFormat failed");
        return FALSE;
    }

    return TRUE;
}

void CPointView::DrawScene(void)
{
 //设置清屏颜色为黑色
 glClearColor(0.0f,0.0f,0.0f,0.0f);
 //清除颜色缓冲区和深度缓冲区
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 //矩阵堆栈函数,和glPopMatrix()相对应
 glPushMatrix();

 //设置点的大小
 glPointSize(10.0);
 //说明几何图元为“点”,和glEnd()相对应
 glBegin(GL_POINTS);
  //绘制红色的点
  glColor3f(1.0,0.0,0.0);
  glVertex3f(-0.7,-0.7,0.0);
  //绘制绿色的点
  glColor3f(0.0,1.0,0.0);
  glVertex3f(0.7,-0.7,0.0);
  //绘制白色的点
  glColor3f(1.0,1.0,1.0);
  glVertex3f(0.0,0.0,0.0);
  //绘制兰色的点
  glColor3f(0.0,0.0,1.0);
  glVertex3f(0.7,0.7,0.0);
  //绘制黄色的点
  glColor3f(1.0,1.0,0.0);
  glVertex3f(-0.7,0.7,0.0);
 glEnd();

 glPopMatrix();
 glFinish();
 SwapBuffers(wglGetCurrentDC());
}

7.在PointView.cpp文件中,在PreCreateWindow函数中加入:
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;

8.在PointView.cpp文件中,在OnDraw函数中加入:
DrawScene();

9.在CPointView中,建立如下消息的映射函数:WM_CREATE, WM_DESTROY, WM_SIZE, WM_ERASEBKGND,并加入划线的代码,如下所示:
int CPointView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (CView::OnCreate(lpCreateStruct) == -1)
  return -1;
 
 // TODO: Add your specialized creation code here
 Init();

 return 0;
}

void CPointView::OnDestroy()
{
 CView::OnDestroy();
 
 // TODO: Add your message handler code here
 HGLRC hrc;
 hrc = ::wglGetCurrentContext();
 ::wglMakeCurrent(NULL,NULL);
 if(hrc)
  ::wglDeleteContext(hrc);
 if(m_pDC)
  delete m_pDC;

}

BOOL CPointView::OnEraseBkgnd(CDC* pDC)
{
 return TRUE;
}

void CPointView::OnSize(UINT nType, int cx, int cy)
{
 CView::OnSize(nType, cx, cy);
 
 // TODO: Add your message handler code here
 int w=cx;
 int h=cy;
 GLfloat nRange=1.0f;

 //避免除数为0
 if(h==0)
  h=1;

 //设置视口与窗口匹配
 glViewport(0,0,w,h);

 //重新设置坐标系统
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();

 //建立正交变换下的剪切体
 if(w<h)
  glOrtho(-nRange,nRange,-nRange*h/w,nRange*h/w,-nRange,nRange);
 else
  glOrtho(-nRange*w/h,nRange*w/h,-nRange,nRange,-nRange,nRange);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();

}

 运行程序后,如果你能看到五个点,那就表明你现在已经建立起OpenGL的视场了。

    Windows应用程序是使用设备描述表(Device Context)进行图形的绘制输出,但OpenGL并不使用标准的设备描述表,它使用渲染描述表(Rendering Context)完成图形图像的映射。描述表的映射核心是像素格式的设置。

    当进行OpenGL的绘图操作时,实际上是在进行设备像素的操作。OpenGL将数据转化为像素操作写入帧缓存中,就需要知道Windows的像素格式,或者说需要与其一致起来。在初始化OpenGL时,需要一个叫做PIXELFORMATDESCRIPTOR的结构来完成对像素属性的设置。Win32提供了4个函数管理像素格式。

  ①ChoosePixelFormat():返回和&pfd指定的像素格式最匹配的DC支持的像素格式的索引值,如果函数调用不成功,返回零。

  ②SetPixelFormat():在DC中设置pixelformat指定的设备的像素格式,如果函数调用成功,返回TRUE。

  ③GetPixelFormat():返回当前DC的像素格式的索引,如果函数调用不成功,返回零。

  ④DescribePixelFormat():用n指定的DC的像素格式的数据设置&pfd,如果函数调用成功,返回DC的像素格式的最大索引,否则,返回零。

    OpenGL的渲染描述表保存着在窗口中用来渲染一个场景所需的信息。一个OpenGL应用程序必须有一个渲染描述表,并且在OpenGL进行绘制之前它应该是当前的。在渲染描述表存入信息后,OpenGL就可以在Windows系统中更新一个窗口的图形状态。Win32提供了5个函数管理渲染描述表。

  ①wglCreateContext():创建一个与给定的DC兼容的RC,调用成功返回RC的句柄,不成功返回NULL。

  ②wglMakeCurrent():使指定的RC成为当前的,调用成功返回GL_TRUE,否则返回GL_FALSE。

  ③wglGetCurrentCotext():获得当前的RC句柄。

  ④wglGetCurrentDC():获得和当前的RC联系的DC句柄。

  ⑤wglDeleteContext():删除RC。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值