Refactor the rendernode example
By removing the Renderer abstraction it becomes easier to follow and understand. Change-Id: Iddacb461d51a75864983850660c5480985b3524f Reviewed-by: Andy Nichols <andy.nichols@qt.io>
This commit is contained in:
parent
519032e9e0
commit
e1682b84bb
|
@ -45,51 +45,6 @@
|
|||
#include "openglrenderer.h"
|
||||
#include "d3d12renderer.h"
|
||||
|
||||
CustomRenderNode::~CustomRenderNode()
|
||||
{
|
||||
releaseResources();
|
||||
}
|
||||
|
||||
void CustomRenderNode::render(const RenderState *state)
|
||||
{
|
||||
QSGRendererInterface *ri = m_item->window()->rendererInterface();
|
||||
if (!ri)
|
||||
return;
|
||||
|
||||
if (!m_renderer) {
|
||||
switch (ri->graphicsAPI()) {
|
||||
case QSGRendererInterface::OpenGL:
|
||||
#ifndef QT_NO_OPENGL
|
||||
m_renderer = new OpenGLRenderer(m_item, this);
|
||||
#endif
|
||||
break;
|
||||
case QSGRendererInterface::Direct3D12:
|
||||
#ifdef HAS_D3D12
|
||||
m_renderer = new D3D12Renderer(m_item, this);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Q_ASSERT(m_renderer);
|
||||
m_renderer->init();
|
||||
}
|
||||
|
||||
m_renderer->render(state);
|
||||
}
|
||||
|
||||
// No need to reimplement changedStates() since our rendering is so simple,
|
||||
// without involving any state changes.
|
||||
|
||||
void CustomRenderNode::releaseResources()
|
||||
{
|
||||
if (!m_renderer)
|
||||
return;
|
||||
|
||||
delete m_renderer;
|
||||
m_renderer = nullptr;
|
||||
}
|
||||
|
||||
CustomRenderItem::CustomRenderItem(QQuickItem *parent)
|
||||
: QQuickItem(parent)
|
||||
{
|
||||
|
@ -99,9 +54,26 @@ CustomRenderItem::CustomRenderItem(QQuickItem *parent)
|
|||
|
||||
QSGNode *CustomRenderItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
|
||||
{
|
||||
CustomRenderNode *n = static_cast<CustomRenderNode *>(node);
|
||||
if (!node)
|
||||
n = new CustomRenderNode(this);
|
||||
QSGRenderNode *n = static_cast<QSGRenderNode *>(node);
|
||||
if (!n) {
|
||||
QSGRendererInterface *ri = window()->rendererInterface();
|
||||
if (!ri)
|
||||
return nullptr;
|
||||
switch (ri->graphicsAPI()) {
|
||||
case QSGRendererInterface::OpenGL:
|
||||
#ifndef QT_NO_OPENGL
|
||||
n = new OpenGLRenderNode(this);
|
||||
break;
|
||||
#endif
|
||||
case QSGRendererInterface::Direct3D12:
|
||||
#ifdef HAS_D3D12
|
||||
n = new D3D12RenderNode(this);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
|
|
@ -42,29 +42,6 @@
|
|||
#define CUSTOMRENDERITEM_H
|
||||
|
||||
#include <QQuickItem>
|
||||
#include <QSGRenderNode>
|
||||
|
||||
class CustomRenderer
|
||||
{
|
||||
public:
|
||||
virtual ~CustomRenderer() { }
|
||||
virtual void init() = 0;
|
||||
virtual void render(const QSGRenderNode::RenderState *state) = 0;
|
||||
};
|
||||
|
||||
class CustomRenderNode : public QSGRenderNode
|
||||
{
|
||||
public:
|
||||
CustomRenderNode(QQuickItem *item) : m_item(item) { }
|
||||
~CustomRenderNode();
|
||||
|
||||
void render(const RenderState *state) override;
|
||||
void releaseResources() override;
|
||||
|
||||
private:
|
||||
QQuickItem *m_item;
|
||||
CustomRenderer *m_renderer = nullptr;
|
||||
};
|
||||
|
||||
class CustomRenderItem : public QQuickItem
|
||||
{
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "d3d12renderer.h"
|
||||
#include <QQuickItem>
|
||||
#include <QQuickWindow>
|
||||
#include <QSGRendererInterface>
|
||||
|
||||
|
@ -47,15 +48,34 @@
|
|||
#include "vs_shader.hlslh"
|
||||
#include "ps_shader.hlslh"
|
||||
|
||||
D3D12Renderer::D3D12Renderer(QQuickItem *item, QSGRenderNode *node)
|
||||
: m_item(item),
|
||||
m_node(node),
|
||||
vbPtr(nullptr),
|
||||
cbPtr(nullptr)
|
||||
D3D12RenderNode::D3D12RenderNode(QQuickItem *item)
|
||||
: m_item(item)
|
||||
{
|
||||
}
|
||||
|
||||
void D3D12Renderer::init()
|
||||
D3D12RenderNode::~D3D12RenderNode()
|
||||
{
|
||||
releaseResources();
|
||||
}
|
||||
|
||||
void D3D12RenderNode::releaseResources()
|
||||
{
|
||||
if (vbPtr) {
|
||||
vertexBuffer->Unmap(0, nullptr);
|
||||
vbPtr = nullptr;
|
||||
}
|
||||
if (cbPtr) {
|
||||
constantBuffer->Unmap(0, nullptr);
|
||||
cbPtr = nullptr;
|
||||
}
|
||||
constantBuffer = nullptr;
|
||||
vertexBuffer = nullptr;
|
||||
rootSignature = nullptr;
|
||||
pipelineState = nullptr;
|
||||
m_device = nullptr;
|
||||
}
|
||||
|
||||
void D3D12RenderNode::init()
|
||||
{
|
||||
QSGRendererInterface *rif = m_item->window()->rendererInterface();
|
||||
m_device = static_cast<ID3D12Device *>(rif->getResource(QSGRendererInterface::Device));
|
||||
|
@ -180,22 +200,17 @@ void D3D12Renderer::init()
|
|||
}
|
||||
}
|
||||
|
||||
D3D12Renderer::~D3D12Renderer()
|
||||
void D3D12RenderNode::render(const RenderState *state)
|
||||
{
|
||||
if (vbPtr)
|
||||
vertexBuffer->Unmap(0, nullptr);
|
||||
if (cbPtr)
|
||||
constantBuffer->Unmap(0, nullptr);
|
||||
}
|
||||
if (!m_device)
|
||||
init();
|
||||
|
||||
void D3D12Renderer::render(const QSGRenderNode::RenderState *state)
|
||||
{
|
||||
QSGRendererInterface *rif = m_item->window()->rendererInterface();
|
||||
ID3D12GraphicsCommandList *commandList = static_cast<ID3D12GraphicsCommandList *>(rif->getResource(QSGRendererInterface::CommandList));
|
||||
Q_ASSERT(commandList);
|
||||
|
||||
const int msize = 16 * sizeof(float);
|
||||
memcpy(cbPtr, m_node->matrix()->constData(), msize);
|
||||
memcpy(cbPtr, matrix()->constData(), msize);
|
||||
memcpy(cbPtr + msize, state->projectionMatrix()->constData(), msize);
|
||||
|
||||
const QPointF p0(m_item->width() - 1, m_item->height() - 1);
|
||||
|
|
|
@ -41,35 +41,38 @@
|
|||
#ifndef D3D12RENDERER_H
|
||||
#define D3D12RENDERER_H
|
||||
|
||||
#include "customrenderitem.h"
|
||||
#include <qsgrendernode.h>
|
||||
|
||||
#ifdef HAS_D3D12
|
||||
|
||||
class QQuickItem;
|
||||
|
||||
#include <d3d12.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
class D3D12Renderer : public CustomRenderer
|
||||
class D3D12RenderNode : public QSGRenderNode
|
||||
{
|
||||
public:
|
||||
D3D12Renderer(QQuickItem *item, QSGRenderNode *node);
|
||||
~D3D12Renderer();
|
||||
void init() override;
|
||||
void render(const QSGRenderNode::RenderState *state) override;
|
||||
D3D12RenderNode(QQuickItem *item);
|
||||
~D3D12RenderNode();
|
||||
|
||||
void render(const RenderState *state) override;
|
||||
void releaseResources() override;
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
QQuickItem *m_item;
|
||||
QSGRenderNode *m_node;
|
||||
ID3D12Device *m_device;
|
||||
ID3D12Device *m_device = nullptr;
|
||||
ComPtr<ID3D12PipelineState> pipelineState;
|
||||
ComPtr<ID3D12RootSignature> rootSignature;
|
||||
ComPtr<ID3D12Resource> vertexBuffer;
|
||||
ComPtr<ID3D12Resource> constantBuffer;
|
||||
D3D12_VERTEX_BUFFER_VIEW vertexBufferView;
|
||||
quint8 *vbPtr;
|
||||
quint8 *cbPtr;
|
||||
quint8 *vbPtr = nullptr;
|
||||
quint8 *cbPtr = nullptr;
|
||||
};
|
||||
|
||||
#endif // HAS_D3D12
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "openglrenderer.h"
|
||||
#include <QQuickItem>
|
||||
|
||||
#ifndef QT_NO_OPENGL
|
||||
|
||||
|
@ -46,13 +47,28 @@
|
|||
#include <QOpenGLBuffer>
|
||||
#include <QOpenGLFunctions>
|
||||
|
||||
OpenGLRenderer::OpenGLRenderer(QQuickItem *item, QSGRenderNode *node)
|
||||
: m_item(item),
|
||||
m_node(node)
|
||||
OpenGLRenderNode::OpenGLRenderNode(QQuickItem *item)
|
||||
: m_item(item)
|
||||
{
|
||||
}
|
||||
|
||||
void OpenGLRenderer::init()
|
||||
OpenGLRenderNode::~OpenGLRenderNode()
|
||||
{
|
||||
releaseResources();
|
||||
}
|
||||
|
||||
// No need to reimplement changedStates() since our rendering is so simple,
|
||||
// without involving any state changes.
|
||||
|
||||
void OpenGLRenderNode::releaseResources()
|
||||
{
|
||||
delete m_program;
|
||||
m_program = nullptr;
|
||||
delete m_vbo;
|
||||
m_vbo = nullptr;
|
||||
}
|
||||
|
||||
void OpenGLRenderNode::init()
|
||||
{
|
||||
m_program = new QOpenGLShaderProgram;
|
||||
|
||||
|
@ -98,18 +114,15 @@ void OpenGLRenderer::init()
|
|||
m_vbo->release();
|
||||
}
|
||||
|
||||
OpenGLRenderer::~OpenGLRenderer()
|
||||
void OpenGLRenderNode::render(const RenderState *state)
|
||||
{
|
||||
delete m_program;
|
||||
delete m_vbo;
|
||||
}
|
||||
if (!m_program)
|
||||
init();
|
||||
|
||||
void OpenGLRenderer::render(const QSGRenderNode::RenderState *state)
|
||||
{
|
||||
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
||||
|
||||
m_program->bind();
|
||||
m_program->setUniformValue(m_matrixUniform, *state->projectionMatrix() * *m_node->matrix());
|
||||
m_program->setUniformValue(m_matrixUniform, *state->projectionMatrix() * *matrix());
|
||||
|
||||
m_vbo->bind();
|
||||
|
||||
|
|
|
@ -41,25 +41,27 @@
|
|||
#ifndef OPENGLRENDERER_H
|
||||
#define OPENGLRENDERER_H
|
||||
|
||||
#include "customrenderitem.h"
|
||||
#include <qsgrendernode.h>
|
||||
|
||||
#ifndef QT_NO_OPENGL
|
||||
|
||||
class QQuickItem;
|
||||
class QOpenGLShaderProgram;
|
||||
class QOpenGLBuffer;
|
||||
|
||||
class OpenGLRenderer : public CustomRenderer
|
||||
class OpenGLRenderNode : public QSGRenderNode
|
||||
{
|
||||
public:
|
||||
OpenGLRenderer(QQuickItem *item, QSGRenderNode *node);
|
||||
~OpenGLRenderer();
|
||||
void init() override;
|
||||
void render(const QSGRenderNode::RenderState *state) override;
|
||||
OpenGLRenderNode(QQuickItem *item);
|
||||
~OpenGLRenderNode();
|
||||
|
||||
void render(const RenderState *state) override;
|
||||
void releaseResources() override;
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
QQuickItem *m_item;
|
||||
QSGRenderNode *m_node;
|
||||
QOpenGLShaderProgram *m_program = nullptr;
|
||||
int m_matrixUniform;
|
||||
QOpenGLBuffer *m_vbo = nullptr;
|
||||
|
|
Loading…
Reference in New Issue