当前位置:网站首页>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]所创,转载请带上原文链接,感谢
边栏推荐
猜你喜欢
Flink's datasource Trilogy 3: customization
C/C++编程笔记:指针篇!从内存理解指针,让你完全搞懂指针
Test comparison of three domestic cloud databases
云计算之路-出海记-小目标:Hello World from .NET 5.0 on AWS
Installation record of SAP s / 4hana 2020
LeetCode-15:三数之和
为什么需要使用API管理平台
架构中台图
如何让脚本同时兼容Python2和Python3?
How to reduce the resource consumption of istio agent through sidecar custom resource
随机推荐
选择API管理平台之前要考虑的5个因素
国内三大云数据库测试对比
基于链表的有界阻塞队列 —— LinkedBlockingQueue
Five phases of API life cycle
程序员都应该知道的URI,一文帮你全面了解
Introduction skills of big data software learning
Are there many Python application scenarios?
Programmers should know the URI, a comprehensive understanding of the article
Mobile big data own website precise marketing and accurate customer acquisition
Python应用场景多不多?
The vowels in the inverted string of leetcode
【200人面试经验】,程序员面试,常见面试题解析
LeetCode-11:盛水最多的容器
Copy on write collection -- copyonwritearraylist
常见特征金字塔网络FPN及变体
六家公司CTO讲述曾经历的“宕机噩梦”
APReLU:跨界应用,用于机器故障检测的自适应ReLU | IEEE TIE 2020
Using containers to store table data
C + + adjacency matrix
Dynamic relu: Microsoft's refreshing device may be the best relu improvement | ECCV 2020