(三)QT窗口Opengl库的实现

videoRender.h:

#pragma once

#include <QtWidgets/QWidget>
#include "ui_qtvideorender.h"


#include"Windows.h"
//#include<windows.h>
#include <QResizeEvent>
class QtVideoRender : public QWidget
{
    Q_OBJECT

public:
    QtVideoRender(QWidget *parent = nullptr);
    ~QtVideoRender();

    virtual QPaintEngine* paintEngine() const { return NULL; }

    virtual void resizeEvent(QResizeEvent* event);

    void GLUpdate();

private:
    bool createGLContext();

    void render();

    bool event(QEvent* event);

private:
    Ui::QtVideoRenderClass ui;

private:
    HDC dc;
    //设备上下文
    HGLRC rc;//opengl上下文  也是渲染上下文

    HWND hwnd;//windows窗口句柄

};

videorender.cpp:

#include "qtvideorender.h"
#include <assert.h>

#include"GL\eglew.h"
//
#pragma comment(lib,"glew32.lib")
#pragma comment(lib,"opengl32.lib")
#include"QtEvent.h"
QtVideoRender::QtVideoRender(QWidget *parent)
    : QWidget(parent,Qt::MSWindowsOwnDC)
	//Qt::MSWindowsOwnDC  使用自己的pc

{
    //1.
    setAttribute(Qt::WA_PaintOnScreen);
	//绘制到屏幕 就不能使用qt默认的了  的绘制就不能用了 ;已经手动实现paintEngine() 这个函数
    setAttribute(Qt::WA_NoSystemBackground);//无系统背景
    setAutoFillBackground(true);//自动填充
    ui.setupUi(this);

    //2.
    hwnd = (HWND)winId();
   bool sucess=createGLContext();
   //
   wglMakeCurrent(dc, rc);

    assert(glewInit() == GLEW_OK);

   QApplication::postEvent(this, new QtEvent(QtEvent::GL_Renderer));
}

QtVideoRender::~QtVideoRender()
{
   
 
	wglMakeCurrent(NULL, NULL);
	if (rc)
	{
		wglDeleteContext(rc);
	}
	if (dc)
	{
		ReleaseDC(hwnd, dc);
	}
	 
}

//2.

void QtVideoRender::resizeEvent(QResizeEvent* event)
{

	 
	glViewport(0, 0, event->size().width(), event->size().height());
	GLUpdate();
	 
}

void QtVideoRender::GLUpdate()
{
	 QApplication::postEvent(this, new QtEvent(QtEvent::GL_Renderer));
}

bool QtVideoRender::createGLContext()
{
	 
	 
	//获取设备上下文
	dc = GetDC(hwnd);

	//概念:深度缓冲  模板缓冲区位深
	PIXELFORMATDESCRIPTOR pfd;//???结构体
	ZeroMemory(&pfd, sizeof(pfd));
	pfd.nSize = sizeof(pfd);
	//指定结构体版本号,设置为1
	pfd.nVersion = 1;
	//rgba 4个字节
	pfd.cColorBits = 32;
	//设置深度缓冲 空间物体 对于眼睛有距离  记录这些点的层次
	pfd.cDepthBits = 24;
	//设置模板缓冲区位深  :屏幕上的像素点保留一个无符号的整形
	pfd.cStencilBits = 8;
	//设置像素类型
	pfd.iPixelType = PFD_TYPE_RGBA;
	//可以绘制到窗口   
	// 第三个参数设置双缓冲  机制   有两张图 一个前一个后  前面显示,后面绘画 绘画完了 放在前面  显示放在后面 开始绘画 绘画完了 放在前面 两者交替循环
	pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;

	
	int format = 0;
	format = ChoosePixelFormat(dc, &pfd);
	
	if (!format)
	{
		throw;//实际开发不是这么做
		//return false;
	}
	SetPixelFormat(dc, format, &pfd);
    //opengl上下文	 
	rc = wglCreateContext(dc);
	  
	return true;
}


bool QtVideoRender::event(QEvent* event)
{
	 
	if (event->type() == QtEvent::GL_Renderer)
	{
		//进行渲染
		render();
	}
	return QWidget::event(event);
	 
	 
}


void QtVideoRender::render()
{
	
	//glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
	//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	 
	static float redv = 0;
	redv += 0.01;
	if (redv > 1)redv = 0;
	glClearColor(redv, 0.0f, 0.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	SwapBuffers(dc);
}
/*

Qt::MSWindowsOwnDC:
一:
实验 :
  (1)显示窗口   是白色的
      1.注意  平台的字节设置  是unicode  还是多字节的 根据平台选择  不然 导致错误 
	  rc = wglCreateContext(dc);这一步会中断掉  这个问题不是错误 而是忽视  ,有时候忽视细节 会导致问题无法解决 
	  从而花一大把时间去 查找不是问题的问题  ,最后这种经验算不算一种收获 也是值得深思的
 (2)在窗口绘制颜色
 (3)改变窗口大小 发现 渲染区域不改变   
     就实现 resize事件 去更新界面 渲染颜色随窗口变动而改变 
	 
*/

实验结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值