当前位置:网站首页>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]所创,转载请带上原文链接,感谢
边栏推荐
- Five factors to consider before choosing API management platform
- Why need to use API management platform
- leetcode之反转字符串中的元音字母
- 华为HCIA笔记
- First development of STC to stm32
- Save code
- Several common playing methods of sub database and sub table and how to solve the problem of cross database query
- Core knowledge of C + + 11-17 template (2) -- class template
- 当我们聊数据质量的时候,我们在聊些什么?
- leetcode之反转字符串中的元音字母
猜你喜欢
SAP S/4HANA 2020安装实录
Introduction to nmon
AQS 都看完了,Condition 原理可不能少!
Several common playing methods of sub database and sub table and how to solve the problem of cross database query
写时复制集合 —— CopyOnWriteArrayList
装饰器(一)
几行代码轻松实现跨系统传递 traceId,再也不用担心对不上日志了!
Octave basic syntax
基于链表的有界阻塞队列 —— LinkedBlockingQueue
Linked blocking queue based on linked list
随机推荐
23张图,带你入门推荐系统
Flink的DataSource三部曲之三:自定义
梁老师小课堂|谈谈模板方法模式
Travel notes of csp-s 2020
Python应用场景多不多?
Pipedrive如何在每天部署50+次的情况下支持质量发布?
Decorator (2)
What courses will AI programming learn?
文件拷贝的实现
Using containers to store table data
Test comparison of three domestic cloud databases
常见特征金字塔网络FPN及变体
服务器性能监控神器nmon使用介绍
c++11-17 模板核心知识(二)—— 类模板
SaaS: another manifestation of platform commercialization capability
Tips in Android Development: requires permission android.permission write_ Settings solution
Chapter 5 programming
移动大数据自有网站精准营销精准获客
Huawei HCIA notes
链表