像素格式结构-PIXELFORMATDESCRIPTOR

3、OpenGL for Windows 95图形库

OpenGL图形库一共有100多个函数。其中核心函数有115个,它们是最基本的函数,其前缀是gl,OpenGL实用库(OpenGL utility library,GLU)的函数功能更高一些,如绘制复杂的曲线曲面、高级坐标变换、多边形分割等,共有43个,前缀为glu;OpenGL辅助库(OpenGL auxiliarylibrary,GLAUX)的函数是一些特殊的函数,包括简单的窗口管理、输入事件处理、某些复杂三维物体绘制等函数,共有31个,前缀为aux。

此外,还有六个WGL函数非常重要,专门用于OpenGL和Windows 95窗口系统的联接,其前缀为wgl,主要用于创建和选择图形操作描述表(renderingcontexts)以及在窗口内任一位置显示字符位图。这些功能是Windows 95对OpenGL的唯一补充。另外,还有五个Win32函数用来处理像素格式(pixel formats)和双缓存。由于它们是对Win32系统的扩展,因此不能应用在其它OpenGL平台上。

4、OpenGL for Windows 95程序设计

OpenGL for Windows 95的设计与OpenGL for UNIX的程序设计有一点小区别,关键就在于如何将OpenGL与不同的操作系统下的窗口系统联系起来。如果调用OpenGL辅助库窗口管理函数,则不用考虑这些问题。下面简要介绍在Windows 95下OpenGL的程序设计关键。

4.1 图形操作描述

在Windows 95下窗口程序必须首先处理设备描述表(Device Contexts,DC),DC包括许多如何在窗口上显示图形的信息,既指定画笔和刷子的颜色,设置绘图模式、调色板、映射模式以及其它图形属性。同样,OpenGL for Windows95的程序也必须使用DC,这与其它Windows 95程序类似。但是,OpenGL for Windows 95必须处理特殊的DC图形操作描述表,这是DC中专为OpenGL使用的一种。一个OpenGL应用图形操作描述表内有OpenGL与Windows 95窗口系统相关的各种信息。一个OpenGL应用首先必须创建一个图形操作描述表,然后再启动它,最后在所定义的窗口内按常规方式调用OpenGL函数绘制图形。

一个图形操作描述表不同于其它DC,它们调用每个GDI函数都需要一个句柄,而图形操作描述表方式下只需一个句柄就可以任意调用OpenGL函数。也就是说,只要当前启用了某个图形操作描述表,那么在未删除图形操作描述表之前可以调用任何OpenGL函数,进行各种操作。

4.2 像素格式

在创建一个图形操作表之前,首先必须设置像素格式。像素格式含有设备绘图界面的属性,这些属性包括绘图界面是用RGBA模式还是颜色表模式,像素缓存是用单缓存还是双缓存,以及颜色位数、深度缓存和模板缓存所用的位数,还有其它一些属性信息。

4.3 像素格式结构

每个OpenGL显示设备都支持一种指定的像素格式。一般用一个名为PIXELFORMATDESCRIPTOR的结构来表示某个特殊的像素格式,这个结构包含26个属性信息。Win32定义PIXELFORMATDESCRIPTOR如下所示:

01. typedef struct tagPIXELFORMATDESCRIPTOR
02.   {
03.     WORD nSize;
04.     WORD nVersion;
05.     DWORD dwFlags;
06.     BYTE iPixelType;
07.     BYTE cColorBits;
08.     BYTE cRedBits;
09.     BYTE cRedShift;
10.     BYTE cGreenBits;
11.     BYTE cGreenShift;
12.     BYTE cBlueBits;
13.     BYTE cBlueShift;
14.     BYTE cAlphaBits;
15.     BYTE cAlphaShift;
16.     BYTE cAccumBits;
17.     BYTE cAccumRedBits;
18.     BYTE cAccumGreenBits;
19.     BYTE cAccumBlueBits;
20.     BYTE cAccumAlphaBits;
21.     BYTE cDepthBits;
22.     BYTE cStencilBits;
23.     BYTE cAuxBuffers;
24.     BYTE iLayerType;
25.     BYTE bReserved;
26.     DWORD dwLayerMask;
27.     DWORD dwVisibleMask;
28.     DWORD dwDamageMask;
29.   } PIXELFORMATDESCRIPTOR;

4.4 初始化PIXELFORMATDESCRIPTOR结构

PIXELFORMATDESCRIPTOR中每个变量值的具体含义和设置可以参考有关资料,下面举出一个PIXELFORMATDESCRIPTOR初始化例子来简要说明相关变量的意义。定义PIXELFORMATDESCRIPTOR结构的pfd如下:

01. PIXELFORMATDESCRIPTOR pfd = {
02.     sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
03.     1,
04.     PFD_DRAW_TO_WINDOW |      // support window
05.     PFD_SUPPORT_OPENGL |      // support OpenGL
06.     PFD_DOUBLEBUFFER,        // double buffered
07.     PFD_TYPE_RGBA,         // RGBA type
08.     24,               // 24-bit color depth
09.     0, 0, 0, 0, 0, 0,        // color bits ignored
10.     0,               // no alpha buffer
11.     0,               // shift bit ignored
12.     0,               // no accumulation buff
13.     0, 0, 0, 0,           // accum bits ignored
14.     32,               // 32-bit z-buffer
15.     0,               // no stencil buffer
16.     0,               // no auxiliary buffer
17.     PFD_MAIN_PLANE,         // main layer
18.     0,               // reserved
19.     0, 0, 0             // layer masks ignored
20.   };

在这个结构里,前两个变量的含义十分明显。第三个变量dwFlags的值是PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,表明应用程序使用OpenGL函数来绘制窗口,第四个表明当前采用RGBA颜色模式,第五个采用24位真彩色,既1.67千万种颜色,如果是256色系统则自动实现颜色抖动;因为没有使用alpha缓存和累计缓存,所以从变量cAlphaBits到cAccumAlphaBits都设置为0;深度缓存设置为32位,这个缓存能解决三维场景的消隐问题;变量cAuxBuffers设置为0,在Windows 95下不支持辅助缓存;Windows 95下针对OpenGL变量ilayerType只能设置为PFD_MAIN_PLANE,但在其它平台也许支持PFD_MAIN_PLANE或PFD_MAIN_UNDERLAYPLANE;接下来bReserved变量只能设为0,而最后三个变量Windows 95都不支持,故全设置为0。

4.5 设置像素结构

当初始化PIXELFORMATDESCRIPTOR结构后,就要设置像素格式。下面举例说明如何设置像素格式。

1. CClientDC clientDC(this);
2.   int PixelFormat = ChoosePixelFormat(clientDC.m_hDC,&pfd);
3.   BOOL result=SetPixelFormat(clientDC.m_hDC,PixelFormat,&pfd);

第一行语句说明得到一个应用窗口客户区的设置描述表。第一行调用ChoosePixelFormat()选择一个像素格式,并将像素格式索引号返回给pixelFormat变量;函数中第一个参数是选择像素格式的设备描述表的句柄,第二个参数是PIXELFORMATDESCRIPTOR结构的地址。如果调用失败则返回0;否则返回像素格式索引号。第三行调用SetPixelFormat()设置像素格式,三个参数分别是设备描述表的句柄、像素格式索引号和PIXELFORMATDESCRIPTOR结构的地址。如果调用成功则返回TRUE,否则返回FALSE。

4.6 创建图形操作描述表

正如前所述,必须创建图形操作描述表并启用它后,才能调用OpenGL函数在窗口内进行各种图形操作。一般来说,利用MFC中增补的管理图形操作描述表方法来编程比较方便。即在视类(CView)的消息OnCreat()中创建图形操作描述表。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
用MFC VC++实现的时钟源代码 // MFCFrame1View.cpp : implementation of the CMFCFrame1View class // #include "stdafx.h" #include "MFCFrame1.h" #include "MFCFrame1Doc.h" #include "MFCFrame1View.h" #include "PointDialog.h" #include "math.h" GLUquadricObj *objCylinder = gluNewQuadric(); #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CMFCFrame1View IMPLEMENT_DYNCREATE(CMFCFrame1View, CView) BEGIN_MESSAGE_MAP(CMFCFrame1View, CView) //{{AFX_MSG_MAP(CMFCFrame1View) ON_WM_CREATE() ON_WM_DESTROY() ON_WM_SIZE() ON_COMMAND(IDM_ZIXUAN, OnZixuan) ON_WM_TIMER() ON_COMMAND(IDM_ChangDirect, OnChangDirect) //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMFCFrame1View construction/destruction CMFCFrame1View::CMFCFrame1View() { // TODO: add construction code here this->m_GLPixelIndex = 0; this->m_hGLContext = NULL; Angle1=0.0; Angle2=30.0; Timer=0; x=0.0; z=0.0; juli=40.0; } CMFCFrame1View::~CMFCFrame1View() { } BOOL CMFCFrame1View::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS); return CView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CMFCFrame1View drawing ///////////////////////////////////////////////////////////////////////////// // CMFCFrame1View printing BOOL CMFCFrame1View::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CMFCFrame1View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CMFCFrame1View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CMFCFrame1View diagnostics #ifdef _DEBUG void CMFCFrame1View::AssertValid() const { CView::AssertValid(); } void CMFCFrame1View::Dump(CDumpContext& dc) const { CView::Dump(dc); } CMFCFrame1Doc* CMFCFrame1View::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMFCFrame1Doc))); return (CMFCFrame1Doc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CMFCFrame1View message handlers BOOL CMFCFrame1View::SetWindowPixelFormat(HDC hDC) { PIXELFORMATDESCRIPTOR pixelDesc= { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| PFD_DOUBLEBUFFER|PFD_SUPPORT_GDI, 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 }; this->m_GLPixelIndex = ChoosePixelFormat(hDC,&pixelDesc); if(this->m_GLPixelIndex==0) { this->m_GLPixelIndex = 1; if(DescribePixelFormat(hDC,this->m_GLPixelIndex,sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0) { return FALSE; } } if(SetPixelFormat(hDC,this->m_GLPixelIndex,&pixelDesc)==FALSE) { return FALSE; } return TRUE; } int CMFCFrame1View::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) { return 0; } return 0; } BOOL CMFCFrame1View::CreateViewGLContext(HDC hDC) { this->m_hGLContext = wglCreateContext(hDC); if(this->m_hGLContext==NULL) {//创建失败 return FALSE; } if(wglMakeCurrent(hDC,this->m_hGLContext)==FALSE) {//选为当前RC失败 return FALSE; } return TRUE; } void CMFCFrame1View::OnDestroy() { CView::OnDestroy(); // TODO: Add your message handler code here if(wglGetCurrentContext()!=NULL) { wglMakeCurrent(NULL,NULL); } if(this->m_hGLContext!=NULL) { wglDeleteContext(this->m_hGLContext); this->m_hGLContext = NULL; } } void CMFCFrame1View::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); // TODO: Add your message handler code here GLsizei width,height; GLdouble aspect; width = cx; height = cy; if(cy==0) { aspect = (GLdouble)width; } else { aspect = (GLdouble)width/(GLdouble)height; } glViewport(0,0,width,height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(40.0,aspect,5.0,1000.0); } void CMFCFrame1View::OnDraw(CDC* pDC) { CMFCFrame1Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here CPaintDC dc(this); glClearColor(1.0,1.0,1.0,1.0); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0,0.0,10.0,0.0,0.0,0.0,0.0,1.0,0.0); glRotatef(-90.0,1.0,0.0,0.0);/*返回原坐标*/ glTranslatef(-3.0,0.0,0.0); SwapBuffers(dc.m_ps.hdc); glDrawBuffer (GL_BACK); glFlush(); } void CMFCFrame1View::OnZixuan() { // TODO: Add your command handler code here Timer=1; SetTimer(1,100,NULL); } void CMFCFrame1View::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default CPaintDC dc(this); if (Timer==1) { Angle1=Angle1-1; Angle2=Angle2-1; glClearColor(1.0,1.0,1.0,1.0); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW);/**/ glLoadIdentity(); gluLookAt(0.0,20.0,0.000000001,0.0,0.0,0.0,0.0,1.0,0.0); glPushMatrix(); glColor3f(0.7,0.7,0.7); glTranslatef(0.0,0.0,1.1); glRotatef(-90.0,1.0,0.0,0.0); glutSolidCone(5.0,0.0,60.0,60.0); /*底盘*/ glPopMatrix(); glPushMatrix(); glColor3f(0.0,0.0,0.0); glTranslatef(3.9,0.99,1.0); /*刻度*/ glRotatef(90.0,0.0,1.0,0.0); gluCylinder(objCylinder, 0.05, 0.05, 0.8, 9999, 9); glPopMatrix(); glPushMatrix(); glColor3f(0.0,0.0,0.0); glTranslatef(-4.7,0.99,1.0); /*刻度*/ glRotatef(90.0,0.0,1.0,0.0); gluCylinder(objCylinder,0.05, 0.05, 0.8, 9999, 9); glPopMatrix(); glPushMatrix(); glColor3f(0.0,0.0,0.0); glTranslatef(0.0,0.99,-2.9); /*刻度*/ glRotatef(180.0,0.0,1.0,0.0); gluCylinder(objCylinder,0.05, 0.05, 0.8, 9999, 9); glPopMatrix(); glPushMatrix(); glColor3f(0.0,0.0,0.0); glTranslatef(0.0,0.99,5.8); /*刻度*/ glRotatef(180.0,0.0,1.0,0.0); gluCylinder(objCylinder,0.05, 0.05,0.8, 9999, 9); glPopMatrix(); glPushMatrix(); glColor3f(0.0,1.0,0.0); glRotatef(45.0,0.0,1.0,0.0); glTranslatef(-0.67,0.99,0.7); /*时针*/ glRotatef(Angle1/129600,0.0,1.0,0.0); gluCylinder(objCylinder, 0.07, 0.02, 2.5, 9999, 9); glPopMatrix(); glPushMatrix(); glColor3f(1.0,0.0,0.0); glTranslatef(0.0,0.99,1.0); /*分针*/ glRotatef(Angle2/360,0.0,1.0,0.0); gluCylinder(objCylinder, 0.05, 0.02, 3.5, 9999, 9); glPopMatrix(); glPushMatrix(); glColor3f(0.0,0.0,0.5); glTranslatef(0.0,0.99,1.0); /*秒针*/ glRotatef(Angle1,0.0,1.0,0.0); gluCylinder(objCylinder, 0.07, 0.02, 4.5, 9999, 9); glPopMatrix(); SwapBuffers(dc.m_ps.hdc); glDrawBuffer (GL_BACK); glFlush(); } else if(Timer==2) { glClearColor(1.0,1.0,1.0,1.0); glClear(GL_COLOR_BUFFER_BIT); if (juli>12.0) { glMatrixMode(GL_MODELVIEW);/*建立了从世界坐标系到观察坐标系的转换矩阵*/ glLoadIdentity(); gluLookAt(0.0,8.0,juli,0.0,0.0,0.0,0.0,1.0,0.0); juli=juli-0.1; glPushMatrix(); glColor3f(0.0,0.0,0.0); glRotatef(-90.0,1.0,0.0,0.0); glutWireCone(40.0,0.0,30.0,30.0); /*画高度为0的圆锥*/ glPopMatrix(); glPushMatrix(); glColor3f(1.0,0.0,1.0); glLineWidth(4.0); glTranslatef(4.0,1.0,0.0); glutWireOctahedron(); /*画八面体*/ glLineWidth(1.0); glPopMatrix(); glPushMatrix(); glColor3f(1.0,0.0,1.0); glTranslatef(0.0,1.1,0.0); glRotatef(Angle2,0.0,1.0,0.0); gluCylinder(objCylinder, 1.0, 1.0, 10.0, 9999, 9); /*画壶*/ glPopMatrix(); } else if(juli<=12.0) { Angle2=Angle2+0.01; if (Angle2==360.0) Angle2=0.0; glMatrixMode(GL_MODELVIEW);/*建立了从世界坐标系到观察坐标系的转换矩阵*/ glLoadIdentity(); x=12.0*sin(Angle2); z=12.0*cos(Angle2); gluLookAt(x,5.0,z,0.0,0.0,0.0,0.0,1.0,0.0); glPushMatrix(); glColor3f(0.0,0.0,0.0); glRotatef(-90.0,1.0,0.0,0.0); glutWireCone(40.0,0.0,30.0,30.0); /*画高度为0的圆锥*/ glPopMatrix(); glPushMatrix(); glColor3f(1.0,0.0,1.0); glLineWidth(4.0); glTranslatef(4.0,1.0,0.0); glutWireOctahedron(); /*画八面体*/ glLineWidth(1.0); glPopMatrix(); glPushMatrix(); glColor3f(1.0,0.0,1.0); glTranslatef(0.0,1.1,0.0); gluCylinder(objCylinder, 1.0, 1.0, 10.0, 9999, 9); /*画壶*/ glPopMatrix(); } SwapBuffers(dc.m_ps.hdc); glDrawBuffer (GL_BACK); glFlush(); } CView::OnTimer(nIDEvent); } void CMFCFrame1View::OnChangDirect() { // TODO: Add your command handler code here Timer=2; SetTimer(1,100 ,NULL); }
好的,下面是使用MFC画出两个立方体并给它们上色的代码: 首先,我们需要定义一个立方体的顶点坐标、面和颜色。这里我们定义两个立方体,每个立方体有8个顶点和6个面,除了顶面和正面外,其余面分别用不同的颜色进行上色。 ```cpp // 定义立方体的顶点坐标 const float vertices[2][8][3] = { {{-0.5f, -0.5f, -0.5f}, {0.5f, -0.5f, -0.5f}, {0.5f, 0.5f, -0.5f}, {-0.5f, 0.5f, -0.5f}, {-0.5f, -0.5f, 0.5f}, {0.5f, -0.5f, 0.5f}, {0.5f, 0.5f, 0.5f}, {-0.5f, 0.5f, 0.5f}}, {{-1.0f, -0.5f, -0.5f}, {-0.5f, -0.5f, -0.5f}, {-0.5f, 0.5f, -0.5f}, {-1.0f, 0.5f, -0.5f}, {-1.0f, -0.5f, 0.5f}, {-0.5f, -0.5f, 0.5f}, {-0.5f, 0.5f, 0.5f}, {-1.0f, 0.5f, 0.5f}} }; // 定义立方体的面 const int faces[2][6][4] = { {{0, 1, 2, 3}, {1, 5, 6, 2}, {5, 4, 7, 6}, {4, 0, 3, 7}, {3, 2, 6, 7}, {0, 4, 5, 1}}, {{0, 1, 2, 3}, {1, 5, 6, 2}, {5, 4, 7, 6}, {4, 0, 3, 7}, {1, 0, 4, 5}, {2, 6, 7, 3}} }; // 定义立方体的颜色 const float colors[2][6][3] = { {{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 1.0f}}, {{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 1.0f}, {0.0f, 1.0f, 1.0f}} }; ``` 接下来,我们需要在MFC窗口的绘图区域中画出这两个立方体。我们可以重载MFC窗口类的OnDraw函数,在其中使用OpenGL的函数进行绘制。 ```cpp void CMyMFCOpenGLView::OnDraw(CDC* pDC) { // 获取绘图区域的大小 CRect rect; GetClientRect(&rect); // 初始化OpenGL上下文 wglMakeCurrent(pDC->GetSafeHdc(), m_hRC); // 设置视口大小 glViewport(0, 0, rect.Width(), rect.Height()); // 设置投影矩阵 glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, (float)rect.Width() / (float)rect.Height(), 0.1f, 100.0f); // 设置模型视图矩阵 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); // 绘制第一个立方体 glPushMatrix(); glTranslatef(-1.5f, 0.0f, 0.0f); glBegin(GL_QUADS); for (int i = 0; i < 6; i++) { glColor3fv(colors[0][i]); for (int j = 0; j < 4; j++) { glVertex3fv(vertices[0][faces[0][i][j]]); } } glEnd(); glPopMatrix(); // 绘制第二个立方体 glPushMatrix(); glTranslatef(1.5f, 0.0f, 0.0f); glBegin(GL_QUADS); for (int i = 0; i < 6; i++) { glColor3fv(colors[1][i]); for (int j = 0; j < 4; j++) { glVertex3fv(vertices[1][faces[1][i][j]]); } } glEnd(); glPopMatrix(); // 清除缓冲区 glFlush(); SwapBuffers(pDC->GetSafeHdc()); } ``` 最后,在MFC窗口类的OnCreate函数中,进行OpenGL的初始化和创建OpenGL渲染上下文。 ```cpp int CMyMFCOpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; // 获取设备上下文 HDC hdc = ::GetDC(m_hWnd); // 设置像素格式 PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR) }; pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; pfd.cDepthBits = 24; pfd.cStencilBits = 8; pfd.iLayerType = PFD_MAIN_PLANE; int format = ChoosePixelFormat(hdc, &pfd); SetPixelFormat(hdc, format, &pfd); // 创建渲染上下文 m_hRC = wglCreateContext(hdc); // 释放设备上下文 ::ReleaseDC(m_hWnd, hdc); return 0; } ``` 以上就是使用MFC画出两个立方体并给它们上色的完整代码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值