现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

MFC下的OpenGL编程:基础篇

2014-05-26 06:16 工业·编程 ⁄ 共 6497字 ⁄ 字号 评论 1 条

MFC是微软件提供的一个C++编程框架,它提供了大量的类库,以更强的封装来简化C++的编程。当然,它与普通的Win32编程有些差别。

在MFC下进行OpenGL编程的步骤如下:

1、在工程中包含OGL函数库

法1. “工程”—“设置”—“连接”—“对象/库模块”中输入glaux.lib, opengl32.lib, glu32.lib。

法2. 在StdAfx.h中加入:

#pragma comment(lib,"glaux.lib")

#pragma comment(lib,"opengl32.lib")

#pragma comment(lib,"glu32.lib")

2、在stdafx.h加入OGL头文件。这样做的好处是不需要在其它的头文件重复包含OGL的这些头文件。

#include <gl/gl.h>

#include <gl/glu.h>

#include <gl/glaux.h>

#include <gl/glut.h>

3、初始化OGL场景

BOOL CGLTestView::InitializeOpenGL(CDC *pDc)

{

m_pDc=pDc;

SetupPixelFormat();  // 设置像素点格式

m_hRc=::wglCreateContext(pDc->GetSafeHdc());  // 生成绘制描述表

::wglMakeCurrent(m_pDc->GetSafeHdc(),m_hRc);  // 置当前绘制描述表

return TRUE;

}

4、设置像素点格式

BOOL CGLTestView::SetupPixelFormat()

{

PIXELFORMATDESCRIPTOR pdf={

sizeof(PIXELFORMATDESCRIPTOR),  // pfd结构的大小

1,  // 版本号

PFD_DRAW_TO_WINDOW |  // 支持在窗口中绘图

PFD_SUPPORT_OPENGL |  // 支持 OpenGL

PFD_DOUBLEBUFFER,  // 双缓存模式

PFD_TYPE_RGBA,  // RGBA 颜色模式

24,  // 24 位颜色深度

0, 0, 0, 0, 0, 0,  // 忽略颜色位

0,  // 没有非透明度缓存

0,  // 忽略移位位

0,  // 无累加缓存

0, 0, 0, 0,  // 忽略累加位

32,  // 32 位深度缓存

0,  // 无模板缓存

0,  // 无辅助缓存

PFD_MAIN_PLANE,  // 主层

0,  // 保留

0, 0, 0  // 忽略层,可见性和损毁掩模

};

int pixedformat;

pixedformat=::ChoosePixelFormat(m_pDc->GetSafeHdc(),&pdf);

::SetPixelFormat(m_pDc->GetSafeHdc(),pixedformat,&pdf);  // 设置像素格式

if(pdf.dwFlags & PFD_NEED_PALETTE)

SetLogicalPalette();  // 设置逻辑调色板

return TRUE;

}

3. 在View类中,声明变量和函数

class CGLTestView : public CView

{

protected: // create from serialization only

CGLTestView();

DECLARE_DYNCREATE(CGLTestView)

// Attributes

public:

CGLTestDoc* GetDocument();

// Operations

public:

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CGLTestView)

public:

virtual void OnDraw(CDC* pDC);  // overridden to draw this view

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

protected:

virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);

virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);

virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

//}}AFX_VIRTUAL

// Implementation

public:

virtual ~CGLTestView();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

CDC *m_pDc;

HGLRC m_hRc;

HPALETTE m_hPalette;

GLfloat  fAspect;

GLuint SelectBuff[512];

int xPos,yPos;

//int z_motion, rotate;

BOOL InitializeOpenGL(CDC *pDc);

BOOL SetupPixelFormat(void);

void SetLogicalPalette(void);

BOOL RenderScene(void);

void Init(GLvoid);

void ProcessSelection(int xPos, int yPos);

CString ProcessPlanet(GLuint *pSelectBuff);

//两个全局变量,z_motion用来控制物体远近

//rotate用来控制物体旋转

protected:

// Generated message map functions

protected:

//{{AFX_MSG(CGLTestView)

afx_msg void OnSize(UINT nType, int cx, int cy);

afx_msg void OnDestroy();

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

afx_msg void OnTimer(UINT nIDEvent);

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

5、Init()函数

void CGLTestView::Init(GLvoid)

{

// 光源值

GLfloat  whiteLight[] = { 0.35f, 0.35f, 0.35f, 1.0f };

GLfloat  sourceLight[] = { 0.65f, 0.65f, 0.65f, 1.0f };

GLfloat  lightPos[] = { 0.0f, 0.0f, 0.0f, 1.0f };

glEnable(GL_DEPTH_TEST);

glFrontFace(GL_CCW);

glEnable(GL_CULL_FACE);

glEnable(GL_LIGHTING);

glLightModelfv(GL_LIGHT_MODEL_AMBIENT,whiteLight);

glLightfv(GL_LIGHT0,GL_DIFFUSE,sourceLight);

glLightfv(GL_LIGHT0,GL_POSITION,lightPos);

glEnable(GL_LIGHT0);

glEnable(GL_COLOR_MATERIAL);

glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

glClearColor(0.60f, 0.60f, 0.60f, 1.0f );

}

6、 在View类的OnDraw中绘制

// CGLTestView drawing

void CGLTestView::OnDraw(CDC* pDC)

{

CGLTestDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

RenderScene();

}

7、场影绘制

BOOL CGLTestView::RenderScene(void)

{

//  glRenderMode(GL_SELECT);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清一下当前屏幕

glMatrixMode(GL_MODELVIEW);

glPushMatrix();

//根据z_motion rotate两个参数确定变换的具体数值:

//z_motion改变时,物体从原Z坐标-25,平移z_motion个单位

glTranslatef(0.0,0.0,-30.0+z_motion);

//rotate改变时,物体延Y轴(上下方向)旋转5*rotate度

glRotatef(rotate*5.0,0.0,0.0,1.0);

glTranslatef(0.0+x_motion,0.0,0.0);

glTranslatef(0.0,0.0+y_motion,0.0);

//  glMatrixMode(GL_SELECT);

//  glMatrixMode(GL_PROJECTION);

glInitNames();

glPushName(0);

glPushMatrix();

glRGB(120,120,250);

glTranslatef(-6.0f,-5.0f,-20.0f);

glLoadName(1);

auxSolidSphere(3.0f);

glTranslatef(15.0f,-5.0f,-20.0f);

glLoadName(2);

auxWireTeapot(4.0f);

glPopName();

glPopMatrix();

//   glTranslatef(0,0,-20);

//   int  x=(int)(40*2);

//   glBegin(GL_LINE_LOOP);

//   for(int i=-x; i<x; i+=4)

//   {

//   glVertex3i(-x,i,0);

//   glVertex3i(x,i,0);

// 

//   glVertex3i(i,x,0);

//   glVertex3i(i,-x,0);

//   }

//  glEnd();

// glBegin(GL_POLYGON);

//  glVertex2f(0.0,0.0);

//  glVertex2f(0.0,3.0);

//  glVertex2f(3.0,0.0);

//  glVertex2f(3.0,3.0);

//

//  glEnd();

//   glPushMatrix();

//   glTranslatef(0.f,-5.0f,-40.0f);

//   glBegin(GL_TRIANGLE_STRIP);//画连续填充的多个三角

//   glColor3f(1.0,0.0,0.0);

//   glVertex3f(15.0,0.0,0.0);

//   glColor3f(0.0,1.0,0.0);

//   glVertex3f(-15.0,0.0,0.0);

//   glColor3f(0.0,0.0,1.0);

//   glVertex3f(0.0,15.0,15.0);

//   //   //第一个三角

//   // 

//   glColor3f(0.0,1.0,1.0);

//   glVertex3f(10.0,15.0,-15.0);

//   //   //第二个三角

//   // 

//   glColor3f(1.0,1.0,0.0);

//   glVertex3f(15.0,0.0,0.0);

//   //  //第三个三角

//   //

//   glEnd();

//   // 

//   glPopMatrix();

glPopMatrix();

glFlush();

::SwapBuffers(m_pDc->GetSafeHdc());  //交互缓冲区

return TRUE;

}

8、设置逻辑调色板

void CGLTestView::SetLogicalPalette()

{

struct

{

WORD Version;

WORD NumberOfEntries;

PALETTEENTRY aEntries[256];

} logicalPalette = { 0x300, 256 };

BYTE reds[] = {0, 36, 72, 109, 145, 182, 218, 255};

BYTE greens[] = {0, 36, 72, 109, 145, 182, 218, 255};

BYTE blues[] = {0, 85, 170, 255};

for (int colorNum=0; colorNum<256; ++colorNum)

{

logicalPalette.aEntries[colorNum].peRed = reds[colorNum & 0x07];

logicalPalette.aEntries[colorNum].peGreen =greens[(colorNum >> 0x03) & 0x07];

logicalPalette.aEntries[colorNum].peBlue = blues[(colorNum >> 0x06) & 0x03];

logicalPalette.aEntries[colorNum].peFlags = 0;

}

m_hPalette = CreatePalette ((LOGPALETTE*)&logicalPalette);

}

9、建立窗口时

int CGLTestView::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CView::OnCreate(lpCreateStruct) == -1)

return -1;

// TODO: Add your specialized creation code here

// 初始化OGL和设置定时器

z_motion=0;

x_motion=0;

y_motion=0;

rotate=0;

m_pDc = new CClientDC(this);

SetTimer(1,20,NULL);  // 事件ID为1,  20毫秒间距

InitializeOpenGL(m_pDc);  // 初始化场境

Init();

return 0;

}

10、适应窗口

// CGLTestView message handlers

// 在OnSize中定义当前视区,投影模型和物体模型,光源

void CGLTestView::OnSize(UINT nType, int cx, int cy)

{

CView::OnSize(nType, cx, cy);

//添加窗口缩放时的图形变换函数

glViewport(0,0,cx,cy);  // 按目标窗口设置,视口设置

fAspect = (GLfloat)cx/(GLfloat)cy;  // 窗口尺寸比率,为GLfloat型

glMatrixMode(GL_PROJECTION);   // 设置投影模式

glLoadIdentity();  // 重置当前指定的矩阵为单位矩阵

gluPerspective(45.0f, fAspect, 1.0, 425.0);   // 透视图, 视角,比例,zNear, zFar

glMatrixMode(GL_MODELVIEW);  // 模型视图模式

glLoadIdentity();

}

11、关闭窗口时

void CGLTestView::OnDestroy()

{

CView::OnDestroy();

//删除调色板和渲染上下文、定时器

::wglMakeCurrent(0,0);

::wglDeleteContext(m_hRc);  // 删除 绘制描述表

if (m_hPalette)

DeleteObject(m_hPalette);  // 删除对象“调色板”

if (m_pDc)

{

delete m_pDc;  // 删除DC

}

KillTimer(1);

}

目前有 1 条留言    访客:0 条, 博主:0 条 ,引用: 1 条

    外部的引用: 1 条

    • MFC下的OpenGL编程:提高篇 | 求索阁

    给我留言

    留言无头像?