从零开始开发3D游戏引擎 - 在QtWidget中进行Direct3D11渲染,并捕捉Windows消息

DirectX 渲染

创建一个继承QWidget的类,重写paintEvent,resizeEvent
但是仅仅这样还不够,画面会一直闪烁,需要重写以下函数
virtual QPaintEngine paintEngine() const { return NULL; }*
并设置窗口属性
this->setAttribute(Qt::WA_PaintOnScreen, true);
this->setAttribute(Qt::WA_NativeWindow, true);

捕捉Windows的消息

重写nativeEventFilter,继承 public QAbstractNativeEventFilter 接口
并砸application里面install

QApplication a(argc, argv);
BugattiEngine w;
w.show();
a.installNativeEventFilter(&w);
a.installNativeEventFilter(w.GetRenderWidget());
#pragma once
#include <qwidget.h>
#include "Render/D3DX11Entry.h"
class RenderWidget :
	public QWidget, public QAbstractNativeEventFilter
{
public:
	RenderWidget(QWidget* parent = nullptr);
	virtual ~RenderWidget();
	D3DX11Entry d3d11_entry;
	QWidget* main_window;
	HWND hwnd;
	bool has_init;
	virtual QPaintEngine* paintEngine() const { return NULL; }
	void Init(UINT width = 800, UINT height = 600);
protected:
	//virtual void resizeEvent(QResizeEvent* evt);
	virtual void paintEvent(QPaintEvent* evt); 
	virtual void timerEvent(QTimerEvent *event);
	virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE;
};


RenderWidget::RenderWidget(QWidget* parent) :QWidget(parent)
, d3d11_entry((HWND)this->winId())
, has_init(false)
{
	hwnd = (HWND)this->winId();
	this->setAttribute(Qt::WA_PaintOnScreen, true);
	this->setAttribute(Qt::WA_NativeWindow, true);
	startTimer(1000);
	main_window = parentWidget()->parentWidget();
}


RenderWidget::~RenderWidget()
{
	d3d11_entry.CleanupDevice();
}

void RenderWidget::Init(UINT width, UINT height)
{
	setFixedSize(width, height);
	d3d11_entry.SetSize(width, height);
	d3d11_entry.InitDevice();
}

//QPainter painter(this);
//painter.drawLine(80, 100, 650, 500);
void RenderWidget::paintEvent(QPaintEvent * event)
{
	d3d11_entry.Render();
	update();
}

void RenderWidget::timerEvent(QTimerEvent * event)
{
	main_window->setWindowTitle("FPS = " + QString::number(d3d11_entry.fps));
}

bool RenderWidget::nativeEventFilter(const QByteArray &eventType, void *message, long *)
{
	if (eventType == "windows_generic_MSG" || eventType == "windows_dispatcher_MSG")
	{
		MSG* pMsg = reinterpret_cast<MSG*>(message);
		if (pMsg->message == WM_KEYDOWN)
		{
			qDebug() << "RenderWidget windows system message WM_KEYDOWN";
		}
	}
	return false;
}

猜你喜欢

转载自blog.csdn.net/shujianlove0/article/details/84142396
今日推荐