当前位置:网站首页>Adding OpenGL form to MFC dialog
Adding OpenGL form to MFC dialog
2020-11-09 00:28:00 【shzwork】
《MFC dialog Add OpenGL forms 》
Recently I learned how to work in MFC Add... To the dialog program OpenGL Form method , Here, I will summarize my own implementation process .
Step zero : Join in PictureControl Control
newly build MFC Dialog program , Delete the button control on the dialog box Label Control , Then add... To the form PictureControl Control , As a drawing form .
Set the control's ID Set to :IDC_RENDER
Step one : Join in OpenGL Of lib Files and header files
Right click on the project , add to OpenGL Of lib file ,freeglut_static.lib and gltools.lib, as follows .

And then in stdafx.h The related header files are as follows :

Step two : Set the header file of the dialog box ***Dlg.h
Declare the relevant variables in the dialog header file :
1 HDC hrenderDC; // Device context
2 HGLRC hrenderRC; // Rendering context
3 float m_yRotate; // speed
4 int PixelFormat; // Pixel format
Declare the relevant methods in the dialog header file :
1 BOOL SetWindowPixelFormat(HDC hDC); // Set pixel format
2 BOOL CreateViewGLContext(HDC hDC); //view GL Context
3 void RenderScene(); // Drawing the scene
Add message mapping function :
1 afx_msg void OnTimer(UINT nIDEvent);
The specific dialog header file is as follows :
1 // OpenGLTest1Dlg.h : The header file
2 //
3
4 #pragma once
5
6
7 // COpenGLTest1Dlg Dialog box
8 class COpenGLTest1Dlg : public CDialogEx
9 {
10 // structure
11 public:
12 COpenGLTest1Dlg(CWnd* pParent = NULL); // Standard constructors
13
14 BOOL SetWindowPixelFormat(HDC hDC); // Set pixel format
15 BOOL CreateViewGLContext(HDC hDC); //view GL Context
16 void RenderScene(); // Drawing the scene
17
18 HDC hrenderDC; // Device context
19 HGLRC hrenderRC; // Rendering context
20 float m_yRotate; // speed
21 int PixelFormat; // Pixel format
22
23 // Dialog data
24 enum { IDD = IDD_OPENGLTEST1_DIALOG };
25
26 protected:
27 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV Support
28
29
30 // Realization
31 protected:
32 HICON m_hIcon;
33
34
35 // Generated message mapping function
36 virtual BOOL OnInitDialog();
37 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
38 afx_msg void OnPaint();
39 afx_msg HCURSOR OnQueryDragIcon();
40 afx_msg void OnTimer(UINT nIDEvent);
41 DECLARE_MESSAGE_MAP()
42 };
Step three : Set the source file of the dialog box ***Dlg.cpp
a. Turn on timer message loop
Add... To the code block of the message loop ON_WM_TIMER() Message loop :
1 BEGIN_MESSAGE_MAP(COpenGLTest1Dlg, CDialogEx)
2 ON_WM_SYSCOMMAND()
3 ON_WM_PAINT()
4 ON_WM_QUERYDRAGICON()
5 ON_WM_TIMER()
6 END_MESSAGE_MAP()
there OnTimer Function is used to correspond to SetTimer news . When SetTimer It's time to set up , Will automatically call OnTimer() function .
Write OnTimer The body of a function , As shown below :
1 void COpenGLTest1Dlg::OnTimer(UINT nIDEvent) // Drawing scenes in real time
2 {
3 // TODO: Add your message handler code here and/or call default
4 RenderScene();
5 m_yRotate +=3;
6 CDialog::OnTimer(nIDEvent);
7 }
b. Write function SetWindowPixelFormat, Used to generate pixel formats
The body of the function is shown below :
1 BOOL COpenGLTest1Dlg::SetWindowPixelFormat(HDC hDC)
2 {
3 PIXELFORMATDESCRIPTOR pixelDesc;
4
5 pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
6 pixelDesc.nVersion = 1;
7
8 pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW |
9 PFD_SUPPORT_OPENGL |
10 PFD_DOUBLEBUFFER |
11 PFD_TYPE_RGBA;
12
13 pixelDesc.iPixelType = PFD_TYPE_RGBA;
14 pixelDesc.cColorBits = 32;
15 pixelDesc.cRedBits = 0;
16 pixelDesc.cRedShift = 0;
17 pixelDesc.cGreenBits = 0;
18 pixelDesc.cGreenShift = 0;
19 pixelDesc.cBlueBits = 0;
20 pixelDesc.cBlueShift = 0;
21 pixelDesc.cAlphaBits = 0;
22 pixelDesc.cAlphaShift = 0;
23 pixelDesc.cAccumBits = 0;
24 pixelDesc.cAccumRedBits = 0;
25 pixelDesc.cAccumGreenBits = 0;
26 pixelDesc.cAccumBlueBits = 0;
27 pixelDesc.cAccumAlphaBits = 0;
28 pixelDesc.cDepthBits = 0;
29 pixelDesc.cStencilBits = 1;
30 pixelDesc.cAuxBuffers = 0;
31 pixelDesc.iLayerType = PFD_MAIN_PLANE;
32 pixelDesc.bReserved = 0;
33 pixelDesc.dwLayerMask = 0;
34 pixelDesc.dwVisibleMask = 0;
35 pixelDesc.dwDamageMask = 0;
36
37 PixelFormat = ChoosePixelFormat(hDC,&pixelDesc);
38 if(PixelFormat==0) // Choose default
39 {
40 PixelFormat = 1;
41 if(DescribePixelFormat(hDC,PixelFormat,
42 sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)
43 {
44 return FALSE;
45 }
46 }
47
48 if(SetPixelFormat(hDC,PixelFormat,&pixelDesc)==FALSE)
49
50 {
51 return FALSE;
52 }
53
54 return TRUE;
55 }
c. Write function CreateViewGLContext, Used to generate rendering context
The specific function body is as follows :
1 BOOL COpenGLTest1Dlg::CreateViewGLContext(HDC hDC)
2 {
3 hrenderRC = wglCreateContext(hDC);
4
5 if(hrenderRC==NULL)
6 return FALSE;
7
8 if(wglMakeCurrent(hDC,hrenderRC)==FALSE)
9 return FALSE;
10
11
12
13 return TRUE;
14 }
d. Write function RenderScene, For drawing scenes
The specific function body is as follows :
1 void COpenGLTest1Dlg::RenderScene()
2 {
3
4
5 /////////////////////////////////////////////////
6 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
7
8
9 glLoadIdentity();
10 glTranslatef(0.0f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0
11 glRotated(m_yRotate, 0.0, 1.0, 0.0);
12 glBegin(GL_TRIANGLES); // Drawing Using Triangles
13
14 glVertex3f( 0.0f, 1.0f, 0.0f); // Top
15 glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
16 glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
17 glEnd(); // Finished Drawing The Triangle
18 SwapBuffers(hrenderDC);
19 }
e. In the dialog initialization program OnInitDialog Add initialization code
The specific code is as follows :
1 ///////////////////////OPENGL INIT/////////////////////////
2 CWnd *wnd=GetDlgItem(IDC_RENDER);
3 hrenderDC=::GetDC(wnd->m_hWnd);
4 if(SetWindowPixelFormat(hrenderDC)==FALSE)
5 return 0;
6
7 if(CreateViewGLContext(hrenderDC)==FALSE)
8 return 0;
9
10 glPolygonMode(GL_FRONT,GL_FILL);
11 glPolygonMode(GL_BACK,GL_FILL);
12 ///////////////////////////////////////////
13 glEnable(GL_TEXTURE_2D);
14 glShadeModel(GL_SMOOTH);
15 glViewport(0,0,259,231);
16 glMatrixMode(GL_PROJECTION);
17 glLoadIdentity();
18 gluPerspective(45,1,0.1,100.0);
19 glMatrixMode(GL_MODELVIEW);
20 glLoadIdentity();
21 glShadeModel(GL_SMOOTH); // Enable Smooth Shading
22 glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
23 glClearDepth(1.0f); // Depth Buffer Setup
24 glEnable(GL_DEPTH_TEST); // Enables Depth Testing
25 glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
26 /////////////////////////////////////////////////////////////////////////
27 glEnableClientState(GL_VERTEX_ARRAY);
28 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
29
30 SetTimer(1,10,0);
31
32 ////////////////////////////////////////////////////////////////
f. Whole .cpp Source code
1 // OpenGLTest1Dlg.cpp : Implementation file
2 //
3
4 #include "stdafx.h"
5 #include "OpenGLTest1.h"
6 #include "OpenGLTest1Dlg.h"
7 #include "afxdialogex.h"
8
9
10 #ifdef _DEBUG
11 #define new DEBUG_NEW
12 #endif
13
14
15 // For applications “ About ” Menu items CAboutDlg Dialog box
16
17 class CAboutDlg : public CDialogEx
18 {
19 public:
20 CAboutDlg();
21
22 // Dialog data
23 enum { IDD = IDD_ABOUTBOX };
24
25 protected:
26 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV Support
27
28 // Realization
29 protected:
30 DECLARE_MESSAGE_MAP()
31 };
32
33 CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
34 {
35 }
36
37 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
38 {
39 CDialogEx::DoDataExchange(pDX);
40 }
41
42 BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
43 END_MESSAGE_MAP()
44
45
46 // COpenGLTest1Dlg Dialog box
47
48
49
50
51 COpenGLTest1Dlg::COpenGLTest1Dlg(CWnd* pParent /*=NULL*/)
52 : CDialogEx(COpenGLTest1Dlg::IDD, pParent)
53 {
54 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
55 }
56
57 void COpenGLTest1Dlg::DoDataExchange(CDataExchange* pDX)
58 {
59 CDialogEx::DoDataExchange(pDX);
60 }
61
62 BEGIN_MESSAGE_MAP(COpenGLTest1Dlg, CDialogEx)
63 ON_WM_SYSCOMMAND()
64 ON_WM_PAINT()
65 ON_WM_QUERYDRAGICON()
66 ON_WM_TIMER()
67 END_MESSAGE_MAP()
68
69
70 // COpenGLTest1Dlg Message handler
71
72 BOOL COpenGLTest1Dlg::OnInitDialog()
73 {
74 CDialogEx::OnInitDialog();
75
76 // take “ About ...” Menu items are added to the system menu .
77
78 // IDM_ABOUTBOX Must be within the scope of the system command .
79 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
80 ASSERT(IDM_ABOUTBOX < 0xF000);
81
82 CMenu* pSysMenu = GetSystemMenu(FALSE);
83 if (pSysMenu != NULL)
84 {
85 BOOL bNameValid;
86 CString strAboutMenu;
87 bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
88 ASSERT(bNameValid);
89 if (!strAboutMenu.IsEmpty())
90 {
91 pSysMenu->AppendMenu(MF_SEPARATOR);
92 pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
93 }
94 }
95
96 // Set the icon for this dialog . When the application's main window is not a dialog box , The frame will automatically
97 // Do this
98 SetIcon(m_hIcon, TRUE); // Set the big icon
99 SetIcon(m_hIcon, FALSE); // Set up small icons
100
101 // TODO: Add additional initialization code here
102 ///////////////////////OPENGL INIT/////////////////////////
103 CWnd *wnd=GetDlgItem(IDC_RENDER);
104 hrenderDC=::GetDC(wnd->m_hWnd);
105 if(SetWindowPixelFormat(hrenderDC)==FALSE)
106 return 0;
107
108 if(CreateViewGLContext(hrenderDC)==FALSE)
109 return 0;
110
111 glPolygonMode(GL_FRONT,GL_FILL);
112 glPolygonMode(GL_BACK,GL_FILL);
113 ///////////////////////////////////////////
114 glEnable(GL_TEXTURE_2D);
115 glShadeModel(GL_SMOOTH);
116 glViewport(0,0,259,231);
117 glMatrixMode(GL_PROJECTION);
118 glLoadIdentity();
119 gluPerspective(45,1,0.1,100.0);
120 glMatrixMode(GL_MODELVIEW);
121 glLoadIdentity();
122 glShadeModel(GL_SMOOTH); // Enable Smooth Shading
123 glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
124 glClearDepth(1.0f); // Depth Buffer Setup
125 glEnable(GL_DEPTH_TEST); // Enables Depth Testing
126 glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
127 /////////////////////////////////////////////////////////////////////////
128 glEnableClientState(GL_VERTEX_ARRAY);
129 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
130
131 SetTimer(1,10,0);
132
133 ////////////////////////////////////////////////////////////////
134 return TRUE; // Unless you set the focus to the control , Otherwise return to TRUE
135 }
136
137 void COpenGLTest1Dlg::OnSysCommand(UINT nID, LPARAM lParam)
138 {
139 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
140 {
141 CAboutDlg dlgAbout;
142 dlgAbout.DoModal();
143 }
144 else
145 {
146 CDialogEx::OnSysCommand(nID, lParam);
147 }
148 }
149
150 // If you add a minimize button to the dialog , You need the following code
151 // To draw the icon . For using documents / View model MFC Applications ,
152 // This will be done automatically by the framework .
153
154 void COpenGLTest1Dlg::OnPaint()
155 {
156 if (IsIconic())
157 {
158 CPaintDC dc(this); // Device context for drawing
159
160 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
161
162 // Center the icon in the workspace rectangle
163 int cxIcon = GetSystemMetrics(SM_CXICON);
164 int cyIcon = GetSystemMetrics(SM_CYICON);
165 CRect rect;
166 GetClientRect(&rect);
167 int x = (rect.Width() - cxIcon + 1) / 2;
168 int y = (rect.Height() - cyIcon + 1) / 2;
169
170 // draw icon
171 dc.DrawIcon(x, y, m_hIcon);
172 }
173 else
174 {
175 CDialogEx::OnPaint();
176 }
177 }
178
179 // When the user drags the minimized window, the system calls this function to get the cursor
180 // Show .
181 HCURSOR COpenGLTest1Dlg::OnQueryDragIcon()
182 {
183 return static_cast<HCURSOR>(m_hIcon);
184 }
185
186 BOOL COpenGLTest1Dlg::SetWindowPixelFormat(HDC hDC)
187 {
188 PIXELFORMATDESCRIPTOR pixelDesc;
189
190 pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
191 pixelDesc.nVersion = 1;
192
193 pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW |
194 PFD_SUPPORT_OPENGL |
195 PFD_DOUBLEBUFFER |
196 PFD_TYPE_RGBA;
197
198 pixelDesc.iPixelType = PFD_TYPE_RGBA;
199 pixelDesc.cColorBits = 32;
200 pixelDesc.cRedBits = 0;
201 pixelDesc.cRedShift = 0;
202 pixelDesc.cGreenBits = 0;
203 pixelDesc.cGreenShift = 0;
204 pixelDesc.cBlueBits = 0;
205 pixelDesc.cBlueShift = 0;
206 pixelDesc.cAlphaBits = 0;
207 pixelDesc.cAlphaShift = 0;
208 pixelDesc.cAccumBits = 0;
209 pixelDesc.cAccumRedBits = 0;
210 pixelDesc.cAccumGreenBits = 0;
211 pixelDesc.cAccumBlueBits = 0;
212 pixelDesc.cAccumAlphaBits = 0;
213 pixelDesc.cDepthBits = 0;
214 pixelDesc.cStencilBits = 1;
215 pixelDesc.cAuxBuffers = 0;
216 pixelDesc.iLayerType = PFD_MAIN_PLANE;
217 pixelDesc.bReserved = 0;
218 pixelDesc.dwLayerMask = 0;
219 pixelDesc.dwVisibleMask = 0;
220 pixelDesc.dwDamageMask = 0;
221
222 PixelFormat = ChoosePixelFormat(hDC,&pixelDesc);
223 if(PixelFormat==0) // Choose default
224 {
225 PixelFormat = 1;
226 if(DescribePixelFormat(hDC,PixelFormat,
227 sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)
228 {
229 return FALSE;
230 }
231 }
232
233 if(SetPixelFormat(hDC,PixelFormat,&pixelDesc)==FALSE)
234
235 {
236 return FALSE;
237 }
238
239 return TRUE;
240 }
241
242
243 BOOL COpenGLTest1Dlg::CreateViewGLContext(HDC hDC)
244 {
245 hrenderRC = wglCreateContext(hDC);
246
247 if(hrenderRC==NULL)
248 return FALSE;
249
250 if(wglMakeCurrent(hDC,hrenderRC)==FALSE)
251 return FALSE;
252
253
254
255 return TRUE;
256 }
257
258 void COpenGLTest1Dlg::RenderScene()
259 {
260
261
262 /////////////////////////////////////////////////
263 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
264
265
266 glLoadIdentity();
267 glTranslatef(0.0f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0
268 glRotated(m_yRotate, 0.0, 1.0, 0.0);
269 glBegin(GL_TRIANGLES); // Drawing Using Triangles
270
271 glVertex3f( 0.0f, 1.0f, 0.0f); // Top
272 glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
273 glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
274 glEnd(); // Finished Drawing The Triangle
275 SwapBuffers(hrenderDC);
276 }
277
278 void COpenGLTest1Dlg::OnTimer(UINT nIDEvent) // Drawing scenes in real time
279 {
280 // TODO: Add your message handler code here and/or call default
281 RenderScene();
282 m_yRotate +=3;
283 CDialog::OnTimer(nIDEvent);
284 }
Step four : Operation and debugging
The running results are as follows :

版权声明
本文为[shzwork]所创,转载请带上原文链接,感谢
边栏推荐
猜你喜欢

Python features and building environment

Five design patterns frequently used in development

Copy on write collection -- copyonwritearraylist

android开发中提示:requires permission android.permission write_settings解决方法

Fiddler无法正常抓取谷歌等浏览器的请求_解决方案

使用递增计数器的线程同步工具 —— 信号量,它的原理是什么样子的?

梁老师小课堂|谈谈模板方法模式

Esockettimeout solution in request in nodejs

教你如何 分析 Android ANR 问题

理论与实践相结合彻底理解CORS
随机推荐
Introduction skills of big data software learning
VIM 入门手册, (VS Code)
链表
23张图,带你入门推荐系统
C / C + + Programming Notes: pointer! Understand pointer from memory, let you understand pointer completely
使用递增计数器的线程同步工具 —— 信号量,它的原理是什么样子的?
How to make scripts compatible with both Python 2 and python 3?
Execution of SQL statement
Teacher Liang's small class
SaaS: another manifestation of platform commercialization capability
Are there many Python application scenarios?
centos7下安装iperf时出现 make: *** No targets specified and no makefile found. Stop.的解决方案
What courses will AI programming learn?
你有没有想过为什么交易和退款要拆开不同的表
几行代码轻松实现跨系统传递 traceId,再也不用担心对不上日志了!
Octave basic syntax
APP 莫名崩溃,开始以为是 Header 中 name 大小写的锅,最后发现原来是容器的错!
表连接
Nodejs中request出现ESOCKETTIMEDOUT解决方案
Python features and building environment
