QT调用OpenGL[转]
目录
Window 创建窗口
#include <windows.h> #include <tchar.h> LRESULT CALLBACK wndProc(HWND hWnd, UINT msgId, WPARAM wParam, LPARAM lParam) { switch (msgId) { case WM_CLOSE: case WM_DESTROY: { PostQuitMessage(0); } break; default: return DefWindowProc(hWnd, msgId, wParam, lParam); } return 0; } int __stdcall WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) { //1 注册窗口类 WNDCLASSEX wnd; memset(&wnd, 0, sizeof(wnd)); wnd.cbSize = sizeof(wnd); wnd.lpfnWndProc = wndProc; wnd.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); wnd.hCursor = LoadCursor(hInstance, IDC_ARROW); wnd.hIcon = 0; wnd.hIconSm = 0; wnd.hInstance = hInstance; wnd.lpszClassName = _T("Demo1"); wnd.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_OWNDC; RegisterClassEx(&wnd); //2 创建窗口 HWND hWnd = CreateWindowEx( 0 , _T("Demo1") , _T("测试窗口") , WS_OVERLAPPEDWINDOW , 100 , 100 , 480 , 320 , 0 , 0 , hInstance , 0); //!3 更新显示 if (hWnd) { UpdateWindow(hWnd); ShowWindow(hWnd, SW_SHOW); } MSG msg = { 0 }; //4 消息循环 while (WM_QUIT != msg.message) { if (GetMessage(&msg, 0, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return 0; }
- 显示:
Window 调用OpenGL
- 需要引入头文件 #include <gl/gl.h> 添加库OpenGL32.lib
- 像素格式结构-PIXELFORMATDESCRIPTOR参考:
- GLContext.h
#pragma once #include <gl/gl.h> class GLContext { protected: int _format; //! 窗口句柄 HWND _hWnd; //! 绘制设备上下文 HDC _hDC; //! OpenGL上下文 HGLRC _hRC; public: GLContext() { _format = 0; _hWnd = 0; _hDC = 0; _hRC = 0; } ~GLContext() { shutdown(); } // 初始化GL bool setup(HWND hWnd, HDC hDC) { _hWnd = hWnd; _hDC = hDC; unsigned PixelFormat; PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 8, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 }; if (_format == 0) { PixelFormat = ChoosePixelFormat(_hDC, &pfd); } else { PixelFormat = _format; } if (!SetPixelFormat(_hDC, PixelFormat, &pfd)) { return false; } _hRC = wglCreateContext(_hDC); if (!wglMakeCurrent(_hDC, _hRC)) { return false; } return true; } // 销毁EGL void shutdown() { if (_hRC != NULL) { wglMakeCurrent(NULL, NULL); wglDeleteContext(_hRC); _hRC = NULL; } if (_hDC != NULL) { ReleaseDC(_hWnd, _hDC); _hDC = NULL; } } // 交换缓冲区 void swapBuffer() { SwapBuffers(_hDC); } };
- main.cpp
#include <windows.h> #include <tchar.h> #include "GLContext.h" LRESULT CALLBACK wndProc(HWND hWnd, UINT msgId, WPARAM wParam, LPARAM lParam) { switch (msgId) { case WM_CLOSE: case WM_DESTROY: { PostQuitMessage(0); } break; default: return DefWindowProc(hWnd, msgId, wParam, lParam); } return 0; } int __stdcall WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) { //1 注册窗口类 WNDCLASSEX wnd; memset(&wnd, 0, sizeof(wnd)); wnd.cbSize = sizeof(wnd); wnd.lpfnWndProc = wndProc; wnd.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); wnd.hCursor = LoadCursor(hInstance, IDC_ARROW); wnd.hIcon = 0; wnd.hIconSm = 0; wnd.hInstance = hInstance; wnd.lpszClassName = _T("Demo2"); wnd.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_OWNDC; RegisterClassEx(&wnd); //2 创建窗口 HWND hWnd = CreateWindowEx( 0 , _T("Demo2") , _T("测试标题") , WS_OVERLAPPEDWINDOW , 100 , 100 , 480 , 320 , 0 , 0 , hInstance , 0); //!3 更新显示 if (hWnd) { UpdateWindow(hWnd); ShowWindow(hWnd, SW_SHOW); } else { return 0; } GLContext context; if (!context.setup(hWnd, GetDC(hWnd))) { return 0; } MSG msg = { 0 }; //4 消息循环 while (WM_QUIT != msg.message) { if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { /** * 调用绘制函数进行绘制 */ glClearColor(0, 1, 0, 1); glClear(GL_COLOR_BUFFER_BIT); context.swapBuffer(); } } context.shutdown(); return 0; }
- 显示:
QT调用
- QT_Opengl.h
#pragma once #include "GLContext.h" #include <QtWidgets/QWidget> #include <QTimer> #include "ui_QT_Opengl.h" class QT_Opengl : public QWidget { Q_OBJECT public: QT_Opengl(QWidget *parent = Q_NULLPTR); GLContext m_context; QTimer m_renderTimer; void render(); ~QT_Opengl(); private: Ui::QT_OpenglClass ui; };
- QT_Opengl.cpp
#include "QT_Opengl.h" QT_Opengl::QT_Opengl(QWidget *parent) : QWidget(parent) { ui.setupUi(this); HWND hWnd = (HWND)winId(); HDC hdc = GetDC(hWnd); m_context.setup(hWnd, hdc); QObject::connect(&m_renderTimer, &QTimer::timeout, this, &QT_Opengl::render); m_renderTimer.setInterval(16); m_renderTimer.start(); } void QT_Opengl::render() { glClearColor(0, 1, 0, 1); glClear(GL_COLOR_BUFFER_BIT); m_context.swapBuffer(); } QT_Opengl::~QT_Opengl() { m_context.shutdown(); }
- 显示:
QT封装并调用
- OpenGLWgt.h
#pragma once #include "GLContext.h" #include <QWidget> #include <QTimer> class OpenGLWgt :public QWidget { public: OpenGLWgt(QWidget* parent = 0); ~OpenGLWgt(); GLContext m_context; QTimer m_renderTimer; inline void setColor(float* colorArry) { for (int i = 0; i < 3; ++i) { m_colorArry[i] = colorArry[i]; } } inline void startOpenGL(HWND hWnd, HDC hdc) { m_context.setup(hWnd, hdc); } inline void startTimer() { m_renderTimer.setInterval(10); m_renderTimer.start(); } void render(); private: float m_colorArry[3]; };
- OpenGLWgt.cpp
#include "OpenGLWgt.h" OpenGLWgt::OpenGLWgt(QWidget* parent) :QWidget(parent) { QObject::connect(&m_renderTimer, &QTimer::timeout, this, &OpenGLWgt::render); } OpenGLWgt::~OpenGLWgt() { QObject::disconnect(&m_renderTimer, &QTimer::timeout, this, &OpenGLWgt::render); m_context.shutdown(); } void OpenGLWgt::render() { glClearColor(m_colorArry[0], m_colorArry[1], m_colorArry[2], 1); glClear(GL_COLOR_BUFFER_BIT); m_context.swapBuffer(); }
- OpenGLWgt.cpp
#pragma once #include <QtWidgets/QWidget> #include <QTimer> #include "ui_QT_Opengl.h" class OpenGLWgt; class QT_Opengl : public QWidget { Q_OBJECT public: QT_Opengl(QWidget *parent = Q_NULLPTR); OpenGLWgt *pWdg = nullptr; ~QT_Opengl(); private: Ui::QT_OpenglClass ui; };
- QT_Opengl.cpp
#include "QT_Opengl.h" #include "OpenGLWgt.h" QT_Opengl::QT_Opengl(QWidget *parent) : QWidget(parent) { ui.setupUi(this); HWND hWnd = (HWND)winId(); HDC hdc = GetDC(hWnd); pWdg = new OpenGLWgt(this); float color[3] = { 0,1,1 }; pWdg->setColor(color); pWdg->startOpenGL(hWnd, hdc); pWdg->startTimer(); } QT_Opengl::~QT_Opengl() { if (pWdg) { delete pWdg; pWdg = nullptr; } }
- 显示: