From 7fcc8e43ae37fd1566bcdc82ea16a725b32a229c Mon Sep 17 00:00:00 2001 From: jmsgrogan Date: Thu, 5 Jan 2023 12:06:17 +0000 Subject: [PATCH] Further directx cleaning. --- src/core/StringUtils.cpp | 17 ++ src/core/StringUtils.h | 2 + src/graphics/AbstractPainter.h | 11 +- src/graphics/CMakeLists.txt | 4 + src/graphics/DrawingContext.cpp | 5 +- src/graphics/PainterFactory.cpp | 29 ++- src/graphics/PainterFactory.h | 3 +- src/graphics/RasterPainter.cpp | 11 +- src/graphics/RasterPainter.h | 4 +- src/graphics/directx/DirectXMesh.cpp | 111 +++++++++ src/graphics/directx/DirectXMesh.h | 48 ++++ src/graphics/directx/DirectXMeshPainter.cpp | 218 ++++-------------- src/graphics/directx/DirectXMeshPainter.h | 38 +-- src/graphics/directx/DirectXPainter.cpp | 63 +++-- src/graphics/directx/DirectXPainter.h | 24 +- src/graphics/directx/DirectXTextPainter.cpp | 34 +-- src/graphics/directx/DirectXTextPainter.h | 12 +- src/graphics/opengl/OpenGlPainter.cpp | 19 +- src/graphics/opengl/OpenGlPainter.h | 4 +- src/mesh/AbstractMesh.cpp | 10 + src/mesh/AbstractMesh.h | 7 +- .../win32/Win32DxWindowInterface.cpp | 29 ++- .../win32/Win32DxWindowInterface.h | 2 + 23 files changed, 401 insertions(+), 304 deletions(-) create mode 100644 src/graphics/directx/DirectXMesh.cpp create mode 100644 src/graphics/directx/DirectXMesh.h diff --git a/src/core/StringUtils.cpp b/src/core/StringUtils.cpp index ff0457a..64aecd1 100644 --- a/src/core/StringUtils.cpp +++ b/src/core/StringUtils.cpp @@ -173,6 +173,23 @@ std::string StringUtils::convert(const std::wstring& input) #endif } +std::wstring StringUtils::convert(const std::string& input) +{ + if (input.empty()) + { + return std::wstring(); + } + +#ifdef _WIN32 + const auto charsNeeded = ::MultiByteToWideChar(CP_UTF8, 0, input.data(), (int)input.size(), NULL, 0); + std::vector buffer(charsNeeded); + const auto charsConverted = ::MultiByteToWideChar(CP_UTF8, 0, input.data(), (int)input.size(), &buffer[0], buffer.size()); + return std::wstring(&buffer[0], charsConverted); +#else + throw std::logic_error("Not implemented"); +#endif +} + std::string StringUtils::toPaddedString(unsigned numBytes, unsigned entry) { std::stringstream sstr; diff --git a/src/core/StringUtils.h b/src/core/StringUtils.h index 2c8fca5..ba7ce52 100644 --- a/src/core/StringUtils.h +++ b/src/core/StringUtils.h @@ -20,6 +20,8 @@ public: static std::string convert(const std::wstring& input); + static std::wstring convert(const std::string& input); + static bool isAlphaNumeric(char c); static bool isAlphabetical(char c); diff --git a/src/graphics/AbstractPainter.h b/src/graphics/AbstractPainter.h index 78666d7..31f818c 100644 --- a/src/graphics/AbstractPainter.h +++ b/src/graphics/AbstractPainter.h @@ -5,6 +5,15 @@ class DrawingContext; class AbstractPainter { public: + AbstractPainter(DrawingContext* context) + : mDrawingContext(context) + { + + } + virtual ~AbstractPainter() = default; - virtual void paint(DrawingContext* context) = 0; + virtual void paint() = 0; + +protected: + DrawingContext* mDrawingContext{ nullptr }; }; diff --git a/src/graphics/CMakeLists.txt b/src/graphics/CMakeLists.txt index 52e20da..73f13e2 100644 --- a/src/graphics/CMakeLists.txt +++ b/src/graphics/CMakeLists.txt @@ -18,7 +18,9 @@ list(APPEND graphics_LIB_INCLUDES list(APPEND graphics_HEADERS ${platform_HEADERS} RasterPainter.h + DrawingContext.h PainterFactory.h + AbstractPainter.h ) if(UNIX) set(OpenGL_GL_PREFERENCE "GLVND") @@ -44,12 +46,14 @@ if(UNIX) endif() else() list(APPEND graphics_LIB_INCLUDES + directx/DirectXMesh.cpp directx/DirectXPainter.cpp directx/DirectXTextPainter.cpp directx/DirectXMeshPainter.cpp directx/DirectXShaderProgram.cpp ) list(APPEND graphics_HEADERS + directx/DirectXMesh.h directx/DirectXPainter.h directx/DirectXTextPainter.h directx/DirectXMeshPainter.h diff --git a/src/graphics/DrawingContext.cpp b/src/graphics/DrawingContext.cpp index 3e7285b..529d0c5 100644 --- a/src/graphics/DrawingContext.cpp +++ b/src/graphics/DrawingContext.cpp @@ -14,7 +14,7 @@ DrawingContext::DrawingContext(DrawingSurface* surface, FontsManager* fontsManag mDrawingMode(requestedDrawingMode), mFontsManager(fontsManager) { - mPainter = PainterFactory::Create(mDrawingMode); + mPainter = PainterFactory::Create(this, mDrawingMode); } std::unique_ptr DrawingContext::Create(DrawingSurface* surface, FontsManager* fontsManager, DrawingMode requestedDrawingMode) @@ -38,8 +38,7 @@ void DrawingContext::paint() { mSurface->getScene()->update(mFontsManager); } - - mPainter->paint(this); + mPainter->paint(); } AbstractPainter* DrawingContext::getPainter() const diff --git a/src/graphics/PainterFactory.cpp b/src/graphics/PainterFactory.cpp index 76cc16c..8fe43fd 100644 --- a/src/graphics/PainterFactory.cpp +++ b/src/graphics/PainterFactory.cpp @@ -8,42 +8,41 @@ #include "OpenGlFontTexture.h" #endif -#ifdef _WIN32 -#include "DirectXPainter.h" -//#include "DirectXMeshPainter.h" -//#include "DirectXTextPainter.h" -//#include "DirectXShaderProgram.h" -#endif - #include "Grid.h" - #include "RasterPainter.h" - #include "DrawingContext.h" -std::unique_ptr PainterFactory::Create(DrawingMode drawMode) +#ifdef _WIN32 +#include "DirectXPainter.h" +#include "DirectXMesh.h" +#include "DirectXMeshPainter.h" +#include "DirectXTextPainter.h" +#endif + + +std::unique_ptr PainterFactory::Create(DrawingContext* context, DrawingMode drawMode) { #ifdef _WIN32 if (drawMode == DrawingMode::GRAPH) { - return std::make_unique(); + return std::make_unique(context); } else { - return std::make_unique(); + return std::make_unique(context); } #else #ifdef HAS_OPENGL if (drawMode == DrawingMode::GRAPH) { - return std::make_unique(); + return std::make_unique(context); } else { - return std::make_unique(); + return std::make_unique(context); } #else - return std::make_unique(); + return std::make_unique(context); #endif #endif } diff --git a/src/graphics/PainterFactory.h b/src/graphics/PainterFactory.h index 9204a0b..ee7e113 100644 --- a/src/graphics/PainterFactory.h +++ b/src/graphics/PainterFactory.h @@ -5,9 +5,10 @@ #include enum class DrawingMode; +class DrawingContext; class PainterFactory { public: - static std::unique_ptr Create(DrawingMode drawMode); + static std::unique_ptr Create(DrawingContext* context, DrawingMode drawMode); }; diff --git a/src/graphics/RasterPainter.cpp b/src/graphics/RasterPainter.cpp index b8a58c9..2ad5ea4 100644 --- a/src/graphics/RasterPainter.cpp +++ b/src/graphics/RasterPainter.cpp @@ -4,16 +4,17 @@ #include "DrawingContext.h" #include "Grid.h" -RasterPainter::RasterPainter() - : mGrid(std::make_unique >(Rectangle(Point(0, 0), Point(100, 100)))) +RasterPainter::RasterPainter(DrawingContext* context) + : AbstractPainter(context), + mGrid(std::make_unique >(Rectangle(Point(0, 0), Point(100, 100)))) { } -void RasterPainter::paint(DrawingContext* context) +void RasterPainter::paint() { - const auto width = context->getSurface()->getWidth(); - const auto height = context->getSurface()->getHeight(); + const auto width = mDrawingContext->getSurface()->getWidth(); + const auto height = mDrawingContext->getSurface()->getHeight(); mGrid->resetBounds(Rectangle(Point(0, 0), Point(width, height))); /* diff --git a/src/graphics/RasterPainter.h b/src/graphics/RasterPainter.h index df40d33..7ebfefb 100644 --- a/src/graphics/RasterPainter.h +++ b/src/graphics/RasterPainter.h @@ -11,9 +11,9 @@ class Grid; class RasterPainter : public AbstractPainter { public: - RasterPainter(); + RasterPainter(DrawingContext* context); - void paint(DrawingContext* context) override; + void paint() override; private: std::unique_ptr > mGrid; diff --git a/src/graphics/directx/DirectXMesh.cpp b/src/graphics/directx/DirectXMesh.cpp new file mode 100644 index 0000000..c622489 --- /dev/null +++ b/src/graphics/directx/DirectXMesh.cpp @@ -0,0 +1,111 @@ +#include "DirectXMesh.h" + +#include "SceneModel.h" +#include "DrawingContext.h" +#include "DrawingSurface.h" + +#include "TriMesh.h" + +#include + +DirectXMesh::DirectXMesh(SceneModel* model) + : mModel(model) +{ + +} + +void DirectXMesh::update(DrawingContext* context, ID3D12Device* device) +{ + mVertexBuffer.clear(); + mIndexBuffer.clear(); + + const auto width = float(context->getSurface()->getWidth()); + const auto height = float(context->getSurface()->getHeight()); + + auto model_color = mModel->getColor().getAsVectorDouble(); + std::vector color = { float(model_color[0]), float(model_color[1]), float(model_color[2]), float(model_color[3]) }; + + auto transform = mModel->getTransform(); + for (const auto& node : mModel->getMesh()->getNodes()) + { + auto x = node->getPoint().getX() * transform.getScaleX() + transform.getLocation().getX(); + x = 2 * x / width - 1.0; + auto y = node->getPoint().getY() * transform.getScaleY() + transform.getLocation().getY(); + y = 2 * y / height; + Vertex vert; + vert.position = DirectX::XMFLOAT3(x, y, 0.0); + vert.color = DirectX::XMFLOAT4(color[0], color[1], color[2], color[3]); + mVertexBuffer.push_back(vert); + } + mIndexBuffer = dynamic_cast(mModel->getMesh())->getFaceNodeIds(); + + createD3dVertexBuffer(device); + createD3dIndexBuffer(device); + + mVertexBuffer.clear(); + mIndexBuffer.clear(); +} + +void DirectXMesh::createD3dVertexBuffer(ID3D12Device* device) +{ + // Note: using upload heaps to transfer static data like vert buffers is not + // recommended. Every time the GPU needs it, the upload heap will be marshalled + // over. Please read up on Default Heap usage. An upload heap is used here for + // code simplicity and because there are very few verts to actually transfer. + CD3DX12_HEAP_PROPERTIES heapProps(D3D12_HEAP_TYPE_UPLOAD); + const auto buffer_size = mVertexBuffer.size() * sizeof(Vertex); + auto desc = CD3DX12_RESOURCE_DESC::Buffer(buffer_size); + device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&mD3dVertexBuffer)); + + UINT8* pDataBegin; + CD3DX12_RANGE readRange(0, 0); + mD3dVertexBuffer->Map(0, &readRange, reinterpret_cast(&pDataBegin)); + uploadVertexBuffer(pDataBegin); + mD3dVertexBuffer->Unmap(0, nullptr); + + mVertexBufferView.BufferLocation = mD3dVertexBuffer->GetGPUVirtualAddress(); + mVertexBufferView.StrideInBytes = sizeof(Vertex); + mVertexBufferView.SizeInBytes = buffer_size; +} + +void DirectXMesh::uploadVertexBuffer(unsigned char* pBuffer) const +{ + memcpy(pBuffer, mVertexBuffer.data(), mVertexBuffer.size() * sizeof(Vertex)); +} + +void DirectXMesh::createD3dIndexBuffer(ID3D12Device* device) +{ + CD3DX12_HEAP_PROPERTIES heapProps(D3D12_HEAP_TYPE_UPLOAD); + const auto buffer_size = mIndexBuffer.size() * sizeof(unsigned); + auto desc = CD3DX12_RESOURCE_DESC::Buffer(buffer_size); + device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&mD3dIndexBuffer)); + + UINT8* pDataBegin; + CD3DX12_RANGE readRange(0, 0); + mD3dIndexBuffer->Map(0, &readRange, reinterpret_cast(&pDataBegin)); + uploadIndexBuffer(pDataBegin); + mD3dIndexBuffer->Unmap(0, nullptr); + + mIndexBufferView.BufferLocation = mD3dIndexBuffer->GetGPUVirtualAddress(); + mIndexBufferView.SizeInBytes = buffer_size; +} + +void DirectXMesh::uploadIndexBuffer(unsigned char* pBuffer) const +{ + memcpy(pBuffer, mIndexBuffer.data(), mIndexBuffer.size() * sizeof(unsigned)); +} + +const D3D12_VERTEX_BUFFER_VIEW& DirectXMesh::getVertBufferView() const +{ + return mVertexBufferView; +} + +const D3D12_INDEX_BUFFER_VIEW& DirectXMesh::getIndexBufferView() const +{ + return mIndexBufferView; +} + +SceneModel* DirectXMesh::getModel() const +{ + return mModel; +} \ No newline at end of file diff --git a/src/graphics/directx/DirectXMesh.h b/src/graphics/directx/DirectXMesh.h new file mode 100644 index 0000000..f4ca5d8 --- /dev/null +++ b/src/graphics/directx/DirectXMesh.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include +#include + +#include +#include + +class SceneModel; +class DrawingContext; + +class DirectXMesh +{ +public: + DirectXMesh(SceneModel* model); + + const D3D12_VERTEX_BUFFER_VIEW& getVertBufferView() const; + + const D3D12_INDEX_BUFFER_VIEW& getIndexBufferView() const; + + SceneModel* getModel() const; + + void update(DrawingContext* context, ID3D12Device* device); + +private: + struct Vertex + { + DirectX::XMFLOAT3 position; + DirectX::XMFLOAT4 color; + }; + + void createD3dVertexBuffer(ID3D12Device* device); + void uploadVertexBuffer(unsigned char* pBuffer) const; + + void createD3dIndexBuffer(ID3D12Device* device); + void uploadIndexBuffer(unsigned char* pBuffer) const; + + SceneModel* mModel{ nullptr }; + + std::vector mVertexBuffer; + Microsoft::WRL::ComPtr mD3dVertexBuffer; + D3D12_VERTEX_BUFFER_VIEW mVertexBufferView{}; + + std::vector mIndexBuffer; + Microsoft::WRL::ComPtr mD3dIndexBuffer; + D3D12_INDEX_BUFFER_VIEW mIndexBufferView{}; +}; \ No newline at end of file diff --git a/src/graphics/directx/DirectXMeshPainter.cpp b/src/graphics/directx/DirectXMeshPainter.cpp index 4d1dd9b..c8b0aaf 100644 --- a/src/graphics/directx/DirectXMeshPainter.cpp +++ b/src/graphics/directx/DirectXMeshPainter.cpp @@ -2,12 +2,14 @@ #include "DrawingContext.h" #include "DrawingSurface.h" +#include "Scene.h" #include "SceneModel.h" #include "TriMesh.h" #include "LineMesh.h" #include "DirectXShaderProgram.h" +#include "DirectXMesh.h" #include #include @@ -17,14 +19,6 @@ DirectXMeshPainter::DirectXMeshPainter() { - const float aspectRatio = 1.0; - mVertexBuffer = - { - { { 0.0f, 0.25f * aspectRatio, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } }, - { { 0.25f, -0.25f * aspectRatio, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, - { { -0.25f, -0.25f * aspectRatio, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } } - }; - auto shader_path = std::filesystem::path(__FILE__).parent_path() / "shaders.hlsl"; mShaderProgram = std::make_unique(shader_path, shader_path); } @@ -34,172 +28,10 @@ void DirectXMeshPainter::initializeShader() } -DirectXShaderProgram* DirectXMeshPainter::getShaderProgram() const +void DirectXMeshPainter::initializeD3d(ID3D12Device* device) { - return mShaderProgram.get(); -} - -unsigned int DirectXMeshPainter::getVertexBufferSize() const -{ - return mVertexBuffer.size()*sizeof(Vertex); -} - -unsigned int DirectXMeshPainter::getVertexSize() const -{ - return sizeof(Vertex); -} - -ID3D12PipelineState* DirectXMeshPainter::getPipelineState() const -{ - return mPipelineState.Get(); -} - -ID3D12RootSignature* DirectXMeshPainter::getRootSignature() const -{ - return mRootSignature.Get(); -} - -void DirectXMeshPainter::updateVertexBuffer(unsigned char* pBuffer) const -{ - memcpy(pBuffer, mVertexBuffer.data(), getVertexBufferSize()); -} - -void DirectXMeshPainter::updateCommandList(const CD3DX12_CPU_DESCRIPTOR_HANDLE& rtvHandle, ID3D12GraphicsCommandList* commandList) -{ - const float clearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f }; - commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr); - commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - commandList->IASetVertexBuffers(0, 1, &mVertexBufferView); - commandList->DrawInstanced(3, 1, 0, 0); -} - -void DirectXMeshPainter::initializeBuffers() -{ - /* - glGenBuffers(1, &mVertexBuffer); - - glGenBuffers(1, &mElementBuffer); - - glGenVertexArrays(1, &mVertexArray); - */ -} - -void DirectXMeshPainter::paint(const std::vector& verts, const std::vector& elements, const std::vector& color, bool lines) -{ - /* - glBindVertexArray(mVertexArray); - - glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); - glBufferData(GL_ARRAY_BUFFER, verts.size() * sizeof(float), verts.data(), GL_STATIC_DRAW); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mElementBuffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, elements.size() * sizeof(unsigned), elements.data(), GL_STATIC_DRAW); - - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); - glEnableVertexAttribArray(0); - - //glm::mat4 projection = glm::ortho(0.0f, width, 0.0f, height); - //glUniformMatrix4fv(glGetUniformLocation(mShaderProgram->getHandle(), "projection"), 1, GL_FALSE, glm::value_ptr(projection)); - - glUseProgram(mShaderProgram->getHandle()); - glBindVertexArray(mVertexArray); - - int vertexColorLocation = glGetUniformLocation(mShaderProgram->getHandle(), "ourColor"); - glUniform4f(vertexColorLocation, float(color[0]), float(color[1]), float(color[2]), float(color[3])); - - //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - if (lines) - { - glDrawElements(GL_LINES, elements.size(), GL_UNSIGNED_INT, 0); - } - else - { - glDrawElements(GL_TRIANGLES, elements.size(), GL_UNSIGNED_INT, 0); - } - glBindVertexArray(0); - */ -} - -void DirectXMeshPainter::paint(SceneModel* model, DrawingContext* context) -{ - return; - /* - if (!mShaderProgram) - { - initializeShader(); - } - - if (mVertexArray == 0) - { - initializeBuffers(); - } - - auto surface = context->getSurface(); - const auto width = float(surface->getWidth()); - const auto height = float(surface->getHeight()); - - auto transform = model->getTransform(); - auto vertices = model->getMesh()->getVerticesFlat(); - for (std::size_t idx = 0; idx < vertices.size(); idx++) - { - if (idx % 3 == 0) - { - auto x = vertices[idx] * transform.getScaleX() + transform.getLocation().getX(); - vertices[idx] = 2 * x / width - 1.0; - } - else if (idx % 3 == 1) - { - auto y = vertices[idx] * transform.getScaleY() + transform.getLocation().getY(); - vertices[idx] = 1.0 - 2 * y / height; - } - } - - std::vector indices; - const bool line_mesh = model->getMesh()->getType() == AbstractMesh::MeshType::LINE; - if (line_mesh) - { - indices = dynamic_cast(model->getMesh())->getEdgeNodeIds(); - } - else - { - indices = dynamic_cast(model->getMesh())->getFaceNodeIds(); - } - - auto model_color = model->getColor().getAsVectorDouble(); - std::vector color = { float(model_color[0]), float(model_color[1]), float(model_color[2]), float(model_color[3]) }; - - paint(vertices, indices, color, line_mesh); - - if (model->getShowOutline()) - { - auto edge_indices = dynamic_cast(model->getMesh())->getEdgeNodeIds(); - paint(vertices, edge_indices, { 0, 0, 0, 1 }, true); - } - */ -} - -void DirectXMeshPainter::createVertexBuffer(ID3D12Device* device) -{ - // Note: using upload heaps to transfer static data like vert buffers is not - // recommended. Every time the GPU needs it, the upload heap will be marshalled - // over. Please read up on Default Heap usage. An upload heap is used here for - // code simplicity and because there are very few verts to actually transfer. - CD3DX12_HEAP_PROPERTIES heapProps(D3D12_HEAP_TYPE_UPLOAD); - auto desc = CD3DX12_RESOURCE_DESC::Buffer(getVertexBufferSize()); - device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&mD3dVertexBuffer)); - - // Copy the mesh data to the vertex buffer. - UINT8* pVertexDataBegin; - CD3DX12_RANGE readRange(0, 0); // We do not intend to read from this resource on the CPU. - mD3dVertexBuffer->Map(0, &readRange, reinterpret_cast(&pVertexDataBegin)); - updateVertexBuffer(pVertexDataBegin); - mD3dVertexBuffer->Unmap(0, nullptr); - - // Initialize the vertex buffer view. - mVertexBufferView.BufferLocation = mD3dVertexBuffer->GetGPUVirtualAddress(); - mVertexBufferView.StrideInBytes = getVertexSize(); - mVertexBufferView.SizeInBytes = getVertexBufferSize(); + createRootSignature(device); + createPipelineStateObject(device); } void DirectXMeshPainter::createRootSignature(ID3D12Device* device) @@ -240,3 +72,43 @@ void DirectXMeshPainter::createPipelineStateObject(ID3D12Device* device) psoDesc.SampleDesc.Count = 1; device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&mPipelineState)); } + +ID3D12PipelineState* DirectXMeshPainter::getPipelineState() const +{ + return mPipelineState.Get(); +} + +ID3D12RootSignature* DirectXMeshPainter::getRootSignature() const +{ + return mRootSignature.Get(); +} + +void DirectXMeshPainter::updateCommandList(ID3D12GraphicsCommandList* commandList) +{ + commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + for (const auto& mesh : mDxMeshes) + { + commandList->IASetVertexBuffers(0, 1, &mesh->getVertBufferView()); + commandList->IASetIndexBuffer(&mesh->getIndexBufferView()); + commandList->DrawInstanced(3, 1, 0, 0); + } +} + +void DirectXMeshPainter::updateBuffers(DrawingContext* context, ID3D12Device* device) +{ + mDxMeshes.clear(); + auto scene = context->getSurface()->getScene(); + for (const auto item : scene->getItems()) + { + if (item->getType() == SceneItem::Type::MODEL && item->isVisible()) + { + auto model = dynamic_cast(item); + auto dx_mesh = std::make_unique(model); + dx_mesh->update(context, device); + mDxMeshes.push_back(std::move(dx_mesh)); + } + } +} + + diff --git a/src/graphics/directx/DirectXMeshPainter.h b/src/graphics/directx/DirectXMeshPainter.h index 1297f69..956f9af 100644 --- a/src/graphics/directx/DirectXMeshPainter.h +++ b/src/graphics/directx/DirectXMeshPainter.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include @@ -9,49 +8,26 @@ class DrawingContext; class DirectXShaderProgram; -class SceneModel; - -struct CD3DX12_CPU_DESCRIPTOR_HANDLE; +class DirectXMesh; class DirectXMeshPainter { public: DirectXMeshPainter(); - void paint(SceneModel* model, DrawingContext* context); - - DirectXShaderProgram* getShaderProgram() const; - - void createVertexBuffer(ID3D12Device* device); - void createRootSignature(ID3D12Device* device); - void createPipelineStateObject(ID3D12Device* device); - ID3D12PipelineState* getPipelineState() const; ID3D12RootSignature* getRootSignature() const; - void updateCommandList(const CD3DX12_CPU_DESCRIPTOR_HANDLE& rtvHandle, ID3D12GraphicsCommandList* commandList); + void initializeD3d(ID3D12Device* device); + void updateBuffers(DrawingContext* context, ID3D12Device* device); + void updateCommandList(ID3D12GraphicsCommandList* commandList); private: - struct Vertex - { - DirectX::XMFLOAT3 position; - DirectX::XMFLOAT4 color; - }; - void initializeShader(); - void initializeBuffers(); + void createRootSignature(ID3D12Device* device); + void createPipelineStateObject(ID3D12Device* device); - unsigned int getVertexBufferSize() const; - unsigned int getVertexSize() const; - void updateVertexBuffer(unsigned char* pBuffer) const; - - void paint(const std::vector& verts, const std::vector& elements, const std::vector& color, bool lines = false); - - unsigned int mVertexBufferSize{ 0 }; - std::vector mVertexBuffer; - - Microsoft::WRL::ComPtr mD3dVertexBuffer; - D3D12_VERTEX_BUFFER_VIEW mVertexBufferView{}; + std::vector > mDxMeshes; Microsoft::WRL::ComPtr mRootSignature; Microsoft::WRL::ComPtr mPipelineState; diff --git a/src/graphics/directx/DirectXPainter.cpp b/src/graphics/directx/DirectXPainter.cpp index 12d1519..cd7be78 100644 --- a/src/graphics/directx/DirectXPainter.cpp +++ b/src/graphics/directx/DirectXPainter.cpp @@ -16,15 +16,18 @@ #include "DirectXShaderProgram.h" #include "DirectXMeshPainter.h" #include "DirectXTextPainter.h" +#include "DirectXMesh.h" #include "File.h" #include +#include #include -DirectXPainter::DirectXPainter() - : mMeshPainter(std::make_unique()), +DirectXPainter::DirectXPainter(DrawingContext* context) + : AbstractPainter(context), + mMeshPainter(std::make_unique()), mTextPainter(std::make_unique()) { @@ -40,34 +43,48 @@ DirectXTextPainter* DirectXPainter::getTextPainter() const return mTextPainter.get(); } -void DirectXPainter::paint(DrawingContext* context) +void DirectXPainter::initializeMesh(ID3D12Device* device) { - auto surface = context->getSurface(); - const auto width = double(surface->getWidth()); - const auto height = double(surface->getHeight()); + mMeshPainter->initializeD3d(device); +} - /* - glViewport(0, 0, width, height); - glOrtho(0, width, 0, height, -1.0, 1.0); +void DirectXPainter::initializeText(ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory) +{ + mTextPainter->initialize(d2dContext, directWriteFactory); +} - glClearColor(0.5, 0.5, 1.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT); - */ +void DirectXPainter::updateMesh(ID3D12Device* device) +{ + mMeshPainter->updateBuffers(mDrawingContext, device); +} - auto scene = context->getSurface()->getScene(); +void DirectXPainter::paint() +{ +} + +void DirectXPainter::paintBackground(const CD3DX12_CPU_DESCRIPTOR_HANDLE& rtvHandle, ID3D12GraphicsCommandList* commandList) +{ + const float clearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f }; + commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr); +} + +void DirectXPainter::paintMesh(ID3D12GraphicsCommandList* commandList) +{ + mMeshPainter->updateCommandList(commandList); +} + +void DirectXPainter::paintText(ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory) +{ + auto scene = mDrawingContext->getSurface()->getScene(); + + auto width = mDrawingContext->getSurface()->getWidth(); + auto height = mDrawingContext->getSurface()->getHeight(); for (const auto item : scene->getItems()) { - if (item->getType() == SceneItem::Type::MODEL) + if (item->getType() == SceneItem::Type::TEXT && item->isVisible()) { - mMeshPainter->paint(dynamic_cast(item), context); - } - else if (item->getType() == SceneItem::Type::TEXT) - { - mTextPainter->paint(dynamic_cast(item), context); + auto text = dynamic_cast(item); + mTextPainter->paint(text, mDrawingContext, d2dContext, width, height); } } - - /* - glFlush(); - */ } diff --git a/src/graphics/directx/DirectXPainter.h b/src/graphics/directx/DirectXPainter.h index 9027e3d..ea455f2 100644 --- a/src/graphics/directx/DirectXPainter.h +++ b/src/graphics/directx/DirectXPainter.h @@ -1,21 +1,41 @@ #pragma once #include "AbstractPainter.h" + +#include +#include +#include +#include + #include class DrawingContext; class DirectXMeshPainter; class DirectXTextPainter; +struct CD3DX12_CPU_DESCRIPTOR_HANDLE; + class DirectXPainter : public AbstractPainter { public: - DirectXPainter(); - void paint(DrawingContext* context) override; + DirectXPainter(DrawingContext* context); + void paint() override; DirectXMeshPainter* getMeshPainter() const; DirectXTextPainter* getTextPainter() const; + void initializeMesh(ID3D12Device* device); + + void initializeText(ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory); + + void paintBackground(const CD3DX12_CPU_DESCRIPTOR_HANDLE& rtvHandle, ID3D12GraphicsCommandList* commandList); + + void paintMesh(ID3D12GraphicsCommandList* commandList); + + void paintText(ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory); + + void updateMesh(ID3D12Device* device); + private: std::unique_ptr mMeshPainter; std::unique_ptr mTextPainter; diff --git a/src/graphics/directx/DirectXTextPainter.cpp b/src/graphics/directx/DirectXTextPainter.cpp index 0c77407..3ac122b 100644 --- a/src/graphics/directx/DirectXTextPainter.cpp +++ b/src/graphics/directx/DirectXTextPainter.cpp @@ -11,6 +11,7 @@ #include "SceneText.h" +#include "StringUtils.h" #include "File.h" #include @@ -24,26 +25,15 @@ DirectXTextPainter::DirectXTextPainter() } - -void DirectXTextPainter::paint(SceneText* text, DrawingContext* context) +void DirectXTextPainter::initialize(ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory) { - -} - -void DirectXTextPainter::paint(ID2D1DeviceContext2* d2dContext, float width, float height) -{ - D2D1_RECT_F textRect = D2D1::RectF(0, 0, width, height); - static const WCHAR text[] = L"11On12"; - - d2dContext->BeginDraw(); - d2dContext->SetTransform(D2D1::Matrix3x2F::Identity()); - d2dContext->DrawText(text, _countof(text) - 1, mTextFormat.Get(), &textRect, mTextBrush.Get()); - d2dContext->EndDraw(); + initializeBrush(d2dContext); + initializeTextFormat(directWriteFactory); } void DirectXTextPainter::initializeBrush(ID2D1DeviceContext2* d2dContext) { - d2dContext->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &mTextBrush); + d2dContext->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &mTextBrush); } void DirectXTextPainter::initializeTextFormat(IDWriteFactory* directWriteFactory) @@ -62,3 +52,17 @@ void DirectXTextPainter::initializeTextFormat(IDWriteFactory* directWriteFactory mTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER); } +void DirectXTextPainter::paint(SceneText* text, DrawingContext* context, ID2D1DeviceContext2* d2dContext, float width, float height) +{ + D2D1_RECT_F textRect = D2D1::RectF(0, 0, width, height); + + auto content = StringUtils::convert(text->getTextData().mContent); + + d2dContext->BeginDraw(); + d2dContext->SetTransform(D2D1::Matrix3x2F::Identity()); + d2dContext->DrawText(content.c_str(), static_cast(content.size()) - 1, mTextFormat.Get(), &textRect, mTextBrush.Get()); + d2dContext->EndDraw(); +} + + + diff --git a/src/graphics/directx/DirectXTextPainter.h b/src/graphics/directx/DirectXTextPainter.h index a2585ea..e64376b 100644 --- a/src/graphics/directx/DirectXTextPainter.h +++ b/src/graphics/directx/DirectXTextPainter.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -23,15 +24,14 @@ class DirectXTextPainter public: DirectXTextPainter(); - void paint(SceneText* text, DrawingContext* context); + void initialize(ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory); - void paint(ID2D1DeviceContext2* d2dContext, float width, float height); - - void initializeBrush(ID2D1DeviceContext2* d2dContext); - - void initializeTextFormat(IDWriteFactory* directWriteFactory); + void paint(SceneText* text, DrawingContext* context, ID2D1DeviceContext2* d2dContext, float width, float height); private: + void initializeBrush(ID2D1DeviceContext2* d2dContext); + void initializeTextFormat(IDWriteFactory* directWriteFactory); + Microsoft::WRL::ComPtr mTextBrush; Microsoft::WRL::ComPtr mTextFormat; }; diff --git a/src/graphics/opengl/OpenGlPainter.cpp b/src/graphics/opengl/OpenGlPainter.cpp index 773a2dc..d6110f3 100644 --- a/src/graphics/opengl/OpenGlPainter.cpp +++ b/src/graphics/opengl/OpenGlPainter.cpp @@ -20,10 +20,6 @@ #include "File.h" -#ifdef _WIN32 -#include -#endif - #define GL_GLEXT_PROTOTYPES #include #include @@ -35,14 +31,15 @@ #include -OpenGlPainter::OpenGlPainter() - : mMeshPainter(std::make_unique()), - mTextPainter(std::make_unique()) +OpenGlPainter::OpenGlPainter(DrawingContext* context) + : AbstractPainter(context) + mMeshPainter(std::make_unique()), + mTextPainter(std::make_unique()) { } -void OpenGlPainter::paint(DrawingContext* context) +void OpenGlPainter::paint() { auto surface = context->getSurface(); const auto width = double(surface->getWidth()); @@ -54,16 +51,16 @@ void OpenGlPainter::paint(DrawingContext* context) glClearColor(0.5, 0.5, 1.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); - auto scene = context->getSurface()->getScene(); + auto scene = mDrawingContext->getSurface()->getScene(); for (const auto item : scene->getItems()) { if (item->getType() == SceneItem::Type::MODEL) { - mMeshPainter->paint(dynamic_cast(item), context); + mMeshPainter->paint(dynamic_cast(item), mDrawingContext); } else if (item->getType() == SceneItem::Type::TEXT) { - mTextPainter->paint(dynamic_cast(item), context); + mTextPainter->paint(dynamic_cast(item), mDrawingContext); } } diff --git a/src/graphics/opengl/OpenGlPainter.h b/src/graphics/opengl/OpenGlPainter.h index e5a362a..776526f 100644 --- a/src/graphics/opengl/OpenGlPainter.h +++ b/src/graphics/opengl/OpenGlPainter.h @@ -14,8 +14,8 @@ class TriMesh; class OpenGlPainter : public AbstractPainter { public: - OpenGlPainter(); - void paint(DrawingContext* context) override; + OpenGlPainter(DrawingContext* context); + void paint() override; private: std::unique_ptr mMeshPainter; diff --git a/src/mesh/AbstractMesh.cpp b/src/mesh/AbstractMesh.cpp index b9340f0..d2eef54 100644 --- a/src/mesh/AbstractMesh.cpp +++ b/src/mesh/AbstractMesh.cpp @@ -21,6 +21,16 @@ bool AbstractMesh::hasVectorAttribute(const std::string& tag) const return mVectorAttributes.find(tag) != mVectorAttributes.end(); } +unsigned AbstractMesh::getNumNodes() const +{ + return unsigned(mNodes.size()); +} + +const VecNodes& AbstractMesh::getNodes() const +{ + return mNodes; +} + std::vector AbstractMesh::getVectorAttribute(const std::string& tag) const { auto iter = mVectorAttributes.find(tag); diff --git a/src/mesh/AbstractMesh.h b/src/mesh/AbstractMesh.h index e0ad9a2..be8a22e 100644 --- a/src/mesh/AbstractMesh.h +++ b/src/mesh/AbstractMesh.h @@ -58,10 +58,9 @@ public: void transform(const Transform& transform); - unsigned getNumNodes() const - { - return unsigned(mNodes.size()); - } + unsigned getNumNodes() const; + + const VecNodes& getNodes() const; protected: std::unordered_map > mVectorAttributes; diff --git a/src/windows/ui_interfaces/win32/Win32DxWindowInterface.cpp b/src/windows/ui_interfaces/win32/Win32DxWindowInterface.cpp index 141f4a3..fbbce69 100644 --- a/src/windows/ui_interfaces/win32/Win32DxWindowInterface.cpp +++ b/src/windows/ui_interfaces/win32/Win32DxWindowInterface.cpp @@ -92,7 +92,8 @@ void Win32DxWindowInterface::populateCommandList() CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(mRtvHeap->GetCPUDescriptorHandleForHeapStart(), static_cast(mFrameIndex), mRtvDescriptorSize); mCommandList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr); - painter->getMeshPainter()->updateCommandList(rtvHandle, mCommandList.Get()); + painter->paintBackground(rtvHandle, mCommandList.Get()); + painter->paintMesh(mCommandList.Get()); // Indicate that the back buffer will now be used to present. //barrier = CD3DX12_RESOURCE_BARRIER::Transition(mRenderTargets[mFrameIndex].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); @@ -110,8 +111,7 @@ void Win32DxWindowInterface::renderD2d() mDxInterface->getD2dContext()->SetTarget(mD2dRenderTargets[mFrameIndex].Get()); auto painter = dynamic_cast(mWindow->getDrawingContent()->getPainter()); - D2D1_SIZE_F rtSize = mD2dRenderTargets[mFrameIndex]->GetSize(); - painter->getTextPainter()->paint(mDxInterface->getD2dContext(), rtSize.width, rtSize.height); + painter->paintText(mDxInterface->getD2dContext(), mDxInterface->getDirectWriteFactory()); // Release our wrapped render target resource. Releasing // transitions the back buffer resource to the state specified @@ -205,6 +205,19 @@ void Win32DxWindowInterface::setupDescriptorHeaps() rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; mDxInterface->getDevice()->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&mRtvHeap)); + + D3D12_DESCRIPTOR_HEAP_DESC srvHeapDesc = {}; + srvHeapDesc.NumDescriptors = 1; + srvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + srvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + mDxInterface->getDevice()->CreateDescriptorHeap(&srvHeapDesc, IID_PPV_ARGS(&mSrvHeap)); + + D3D12_DESCRIPTOR_HEAP_DESC cbvHeapDesc = {}; + cbvHeapDesc.NumDescriptors = 1; + cbvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + cbvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + mDxInterface->getDevice()->CreateDescriptorHeap(&cbvHeapDesc, IID_PPV_ARGS(&mCbvHeap)); + mRtvDescriptorSize = mDxInterface->getDevice()->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); } @@ -253,25 +266,22 @@ bool Win32DxWindowInterface::loadAssets() { auto painter = dynamic_cast(mWindow->getDrawingContent()->getPainter()); - painter->getMeshPainter()->createRootSignature(mDxInterface->getDevice()); - painter->getMeshPainter()->createPipelineStateObject(mDxInterface->getDevice()); + painter->initializeMesh(mDxInterface->getDevice()); // Create the command list. mDxInterface->getDevice()->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, mCommandAllocator.Get(), painter->getMeshPainter()->getPipelineState(), IID_PPV_ARGS(&mCommandList)); // Create D2D/DWrite objects for rendering text. - painter->getTextPainter()->initializeBrush(mDxInterface->getD2dContext()); - painter->getTextPainter()->initializeTextFormat(mDxInterface->getDirectWriteFactory()); + painter->initializeText(mDxInterface->getD2dContext(), mDxInterface->getDirectWriteFactory()); // Command lists are created in the recording state, but there is nothing // to record yet. The main loop expects it to be closed, so close it now. mCommandList->Close(); - painter->getMeshPainter()->createVertexBuffer(mDxInterface->getDevice()); + painter->updateMesh(mDxInterface->getDevice()); createSyncObjects(); - return true; } @@ -306,6 +316,5 @@ void Win32DxWindowInterface::waitForPreviousFrame() mFence->SetEventOnCompletion(fence, mFenceEvent); ::WaitForSingleObject(mFenceEvent, INFINITE); } - mFrameIndex = mSwapChain->GetCurrentBackBufferIndex(); } \ No newline at end of file diff --git a/src/windows/ui_interfaces/win32/Win32DxWindowInterface.h b/src/windows/ui_interfaces/win32/Win32DxWindowInterface.h index 7d598f6..cbf1a3c 100644 --- a/src/windows/ui_interfaces/win32/Win32DxWindowInterface.h +++ b/src/windows/ui_interfaces/win32/Win32DxWindowInterface.h @@ -72,6 +72,8 @@ private: Microsoft::WRL::ComPtr mSwapChain; Microsoft::WRL::ComPtr mRtvHeap; + Microsoft::WRL::ComPtr mSrvHeap; + Microsoft::WRL::ComPtr mCbvHeap; UINT mRtvDescriptorSize{ 0 }; Microsoft::WRL::ComPtr mRenderTargets[FrameCount];