Simple dx render example.

This commit is contained in:
jmsgrogan 2023-01-05 16:40:27 +00:00
parent 36515556b8
commit e0cad34d55
22 changed files with 339 additions and 60 deletions

View file

@ -19,12 +19,12 @@ public:
AbstractApp* getMainApplication() const override;
void run();
AbstractUIInterface* getUiInterface() const override;
void setUiInterfaceBackend(UiInterfaceFactory::Backend backend);
void run();
protected:
virtual void initializeViews();

View file

@ -48,6 +48,8 @@ void MainApplication::initialize(CommandLineArgsUPtr commandLineArgs, std::uniqu
FileLogger::GetInstance().Open();
MLOG_INFO("Launched");
if (false)
{
mDatabaseManager = DatabaseManager::Create();
mDatabaseManager->openDatabase(launch_path + "/database.db");
MLOG_INFO("Created DB");
@ -58,6 +60,7 @@ void MainApplication::initialize(CommandLineArgsUPtr commandLineArgs, std::uniqu
mAudioManager = AudioManager::Create();
MLOG_INFO("Created Audio Manager");
}
}
void MainApplication::run()
{
@ -140,9 +143,17 @@ CommandLineArgs* MainApplication::getCommandLineArgs() const
}
void MainApplication::shutDown()
{
if (mDatabaseManager)
{
mDatabaseManager->onShutDown();
}
if (mNetworkManager)
{
mNetworkManager->ShutDown();
}
MLOG_INFO("Shut down");
FileLogger::GetInstance().Close();
}

View file

@ -7,6 +7,8 @@ list(APPEND geometry_LIB_INCLUDES
Grid.h
Grid.cpp
Line.h
Linalg.h
Linalg.cpp
Line.cpp
LineSegment.cpp
Path.h
@ -18,7 +20,9 @@ list(APPEND geometry_LIB_INCLUDES
Rectangle.cpp
Triangle.h
Triangle.cpp
Transform.cpp)
Transform.cpp
Vector.h
Vector.cpp)
# add the library

11
src/geometry/Linalg.cpp Normal file
View file

@ -0,0 +1,11 @@
#include "Linalg.h"
double Linalg::dotProduct(const Vector& v0, const Vector& v1)
{
return v0.dotProduct(v1);
}
Vector Linalg::crossProduct(const Vector& v0, const Vector& v1)
{
return v0.crossProduct(v1);
}

10
src/geometry/Linalg.h Normal file
View file

@ -0,0 +1,10 @@
#pragma once
#include "Vector.h"
class Linalg
{
static double dotProduct(const Vector& v0, const Vector& v1);
static Vector crossProduct(const Vector& v0, const Vector& v1);
};

View file

@ -49,12 +49,15 @@ double Point::getZ() const
double Point::getDistance(const Point& point) const
{
return std::sqrt(mX*point.getX() + mY*point.getY() + mZ*point.getZ());
const auto deltaX = getDeltaX(point);
const auto deltaY = getDeltaY(point);
const auto deltaZ = getDeltaZ(point);
return std::sqrt(deltaX* deltaX + deltaY* deltaY + deltaZ* deltaZ);
}
double Point::getDistance(Point* point) const
Vector Point::getDelta(const Point& point) const
{
return std::sqrt(mX*point->getX() + mY*point->getY() + mZ*point->getZ());
return Vector(point.mX - mX, point.mY - mY, point.mZ - mZ);
}
double Point::getDeltaX(const Point& point) const
@ -66,3 +69,22 @@ double Point::getDeltaY(const Point& point) const
{
return point.getY() - mY;
}
double Point::getDeltaZ(const Point& point) const
{
return point.getZ() - mZ;
}
void Point::scale(double x, double y, double z)
{
mX = x * mX;
mY = y * mY;
mZ = z * mZ;
}
void Point::translate(double x, double y, double z)
{
mX += x;
mY += y;
mZ += z;
}

View file

@ -1,6 +1,7 @@
#pragma once
#include "DiscretePoint.h"
#include "Vector.h"
#include <memory>
#include <cmath>
@ -27,25 +28,17 @@ public:
double getDistance(const Point& point) const;
double getDistance(Point* point) const;
double getDeltaX(const Point& point) const;
double getDeltaY(const Point& point) const;
void scale(double x, double y, double z = 1.0)
{
mX = x*mX;
mY = y*mY;
mZ = z*mZ;
}
double getDeltaZ(const Point& point) const;
void translate(double x, double y, double z = 0.0)
{
mX += x;
mY += y;
mZ += z;
}
Vector getDelta(const Point& point) const;
void scale(double x, double y, double z = 1.0);
void translate(double x, double y, double z = 0.0);
bool operator==(const Point& rhs) const
{

61
src/geometry/Vector.cpp Normal file
View file

@ -0,0 +1,61 @@
#include "Vector.h"
Vector::Vector(double x, double y, double z)
: mX(x),
mY(y),
mZ(z)
{
updateLength();
}
Vector::~Vector()
{
};
double Vector::getX() const
{
return mX;
}
double Vector::getY() const
{
return mY;
}
double Vector::getZ() const
{
return mZ;
}
double Vector::getLength() const
{
return mLength;
}
double Vector::dotProduct(const Vector& v) const
{
return mX * v.mX + mY * v.mY + mZ * v.mZ;
}
Vector Vector::crossProduct(const Vector& v) const
{
return Vector(v.mY * mZ - v.mZ * mY, v.mZ * mX - v.mX * mZ, v.mX * mY - v.mY * mX);
}
Vector Vector::getNormalized() const
{
return Vector(mX / mLength, mY / mLength, mZ / mLength);
}
void Vector::scale(double x, double y, double z)
{
mX = x * mX;
mY = y * mY;
mZ = z * mZ;
updateLength();
}
void Vector::updateLength()
{
mLength = std::sqrt(mX * mX + mY * mY + mZ * mZ);
}

48
src/geometry/Vector.h Normal file
View file

@ -0,0 +1,48 @@
#pragma once
#include <memory>
#include <cmath>
class Vector
{
public:
Vector(double x = 0, double y = 0, double z = 0);
~Vector();
double getX() const;
double getY() const;
double getZ() const;
double getLength() const;
Vector getNormalized() const;
void scale(double x, double y, double z = 1.0);
double dotProduct(const Vector& v) const;
Vector crossProduct(const Vector& v) const;
bool operator==(const Vector& rhs) const
{
return (mX == rhs.mX)
&& (mY == rhs.mY)
&& (mZ == rhs.mZ);
}
bool operator!=(const Vector& rhs) const
{
return !operator==(rhs);
}
private:
void updateLength();
double mLength{ 0 };
double mX{ 0 };
double mY{ 0 };
double mZ{ 0 };
};

View file

@ -5,6 +5,8 @@
#include "DrawingSurface.h"
#include "TriMesh.h"
#include "TriFace.h"
#include "FileLogger.h"
#include <directx/d3dx12.h>
@ -26,18 +28,45 @@ void DirectXMesh::update(DrawingContext* context, ID3D12Device* device)
std::vector<float> 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())
for (const auto& face : dynamic_cast<TriMesh*>(mModel->getMesh())->getFaces())
{
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;
for (const auto& loc : face->getNodeLocations(AbstractFace::Orientation::CW))
{
auto x = loc.getX() * transform.getScaleX() + transform.getLocation().getX();
auto y = loc.getY() * transform.getScaleY() + transform.getLocation().getY();
x = 2 * x - 1;
y = 2 * y - 1;
Vertex vert;
vert.position = DirectX::XMFLOAT3(x, y, 0.0);
vert.color = DirectX::XMFLOAT4(color[0], color[1], color[2], color[3]);
MLOG_INFO("Adding vert: " << x << " | " << y);
mVertexBuffer.push_back(vert);
}
mIndexBuffer = dynamic_cast<TriMesh*>(mModel->getMesh())->getFaceNodeIds();
}
/*
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]);
MLOG_INFO("Adding vert: " << x << " | " << y);
mVertexBuffer.push_back(vert);
}
*/
//mIndexBuffer = dynamic_cast<TriMesh*>(mModel->getMesh())->getFaceNodeIds();
mIndexBuffer = { 0, 1, 2 };
for (auto id : mIndexBuffer)
{
MLOG_INFO("Adding id: " << id);
}
createD3dVertexBuffer(device);
createD3dIndexBuffer(device);
@ -88,6 +117,7 @@ void DirectXMesh::createD3dIndexBuffer(ID3D12Device* device)
mIndexBufferView.BufferLocation = mD3dIndexBuffer->GetGPUVirtualAddress();
mIndexBufferView.SizeInBytes = buffer_size;
mIndexBufferView.Format = DXGI_FORMAT_R16_UINT;
}
void DirectXMesh::uploadIndexBuffer(unsigned char* pBuffer) const

View file

@ -89,9 +89,10 @@ void DirectXMeshPainter::updateCommandList(ID3D12GraphicsCommandList* commandLis
for (const auto& mesh : mDxMeshes)
{
commandList->IASetVertexBuffers(0, 1, &mesh->getVertBufferView());
commandList->IASetIndexBuffer(&mesh->getIndexBufferView());
commandList->DrawInstanced(3, 1, 0, 0);
commandList->IASetVertexBuffers(0, 1, &mesh->getVertBufferView());
commandList->DrawInstanced(mesh->getVertBufferView().SizeInBytes/ mesh->getVertBufferView().StrideInBytes, 1, 0, 0);
//commandList->DrawIndexedInstanced(3, 1, 0, 0, 0);
}
}

View file

@ -12,6 +12,13 @@ class Edge;
class AbstractFace
{
public:
enum class Orientation
{
CW,
CCW
};
AbstractFace(unsigned id=0);
virtual ~AbstractFace();
@ -32,7 +39,7 @@ public:
virtual std::vector<unsigned> getEdgeIds() const = 0;
virtual std::vector<Point> getNodeLocations() const = 0;
virtual std::vector<Point> getNodeLocations(Orientation orientation = Orientation::CCW) const = 0;
protected:
unsigned mId{0};

View file

@ -1,16 +1,29 @@
list(APPEND mesh_LIB_INCLUDES
AbstractMesh.cpp
AbstractMesh.h
Edge.cpp
Edge.h
AbstractFace.cpp
AbstractFace.h
QuadFace.cpp
QuadFace.h
TriFace.cpp
TriFace.h
Node.cpp
Node.h
QuadMesh.cpp
QuadMesh.h
TriMesh.cpp
TriMesh.h
FaceMesh.cpp
FaceMesh.h
LineMesh.cpp
LineMesh.h
MeshPrimitives.cpp
MeshBuilder.cpp)
MeshPrimitives.h
MeshBuilder.cpp
MeshBuilder.h
)
# add the library

View file

@ -75,7 +75,34 @@ void TriFace::associateWidthEdges()
mEdge2->associateFace(mId);
}
std::vector<Point> TriFace::getNodeLocations() const
std::vector<Point> TriFace::getNodeLocations(Orientation orientation) const
{
if (orientation != getOrientation())
{
return { mEdge0->getNode0()->getPoint(), mEdge0->getNode1()->getPoint(), mEdge1->getNode1()->getPoint() };
}
else
{
return { mEdge0->getNode0()->getPoint(), mEdge1->getNode1()->getPoint(), mEdge0->getNode1()->getPoint() };
}
}
Vector TriFace::getNormal() const
{
auto v0 = mEdge0->getNode0()->getPoint().getDelta(mEdge0->getNode1()->getPoint());
auto v1 = mEdge0->getNode0()->getPoint().getDelta(mEdge1->getNode1()->getPoint());
return v0.crossProduct(v1).getNormalized();
}
AbstractFace::Orientation TriFace::getOrientation() const
{
Vector z_norm(0, 0, 1);
if (z_norm.dotProduct(getNormal()) < 0.0)
{
return Orientation::CW;
}
else
{
return Orientation::CCW;
}
}

View file

@ -1,6 +1,7 @@
#pragma once
#include "AbstractFace.h"
#include "Vector.h"
class Edge;
@ -26,7 +27,11 @@ public:
unsigned getEdge2Id () const;
std::vector<unsigned> getEdgeIds() const override;
std::vector<Point> getNodeLocations() const override;
std::vector<Point> getNodeLocations(Orientation orientation = Orientation::CCW) const override;
Vector getNormal() const;
AbstractFace::Orientation getOrientation() const;
private:
Edge* mEdge0{nullptr};

View file

@ -1,11 +1,16 @@
#include "TestCase.h"
#include "TestCaseRunner.h"
#include "MainApplication.h"
#include "GuiApplication.h"
#include "TestUiApplication.h"
#include "TestFramework.h"
#include "DesktopManager.h"
#include "MeshPrimitives.h"
#include "MeshNode.h"
#include "Scene.h"
#include "Widget.h"
#include <memory>
#include <string>
#include <iostream>
@ -14,5 +19,16 @@ TEST_CASE(TestDirectXRendering, "graphics")
{
auto gui_app = TestCaseRunner::getInstance().getTestApplication();
auto drawing_context = gui_app->getDesktopManager()->getWindowManager()->getMainWindow();
auto scene = drawing_context->getScene();
auto mesh = MeshPrimitives::buildRectangleAsTriMesh();
auto mesh_node = std::make_unique<MeshNode>(DiscretePoint(0, 0));
mesh_node->setMesh(mesh.get());
scene->addNode(mesh_node.get());
scene->update(nullptr);
gui_app->run();
};

View file

@ -4,10 +4,12 @@ add_library(test_utils STATIC
TestCaseRunner.h
TestFramework.h
TestCaseRunner.cpp
TestUiApplication.h
TestUiApplication.cpp
)
target_include_directories(test_utils PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(test_utils core)
target_link_libraries(test_utils core client)
set_property(TARGET test_utils PROPERTY FOLDER test)
configure_file(TestDataLocations.h.in TestDataLocations.h)

View file

@ -1,6 +1,7 @@
#include "TestCaseRunner.h"
#include "FileLogger.h"
#include "TestUiApplication.h"
#include <vector>
#include <iostream>
@ -18,12 +19,12 @@ TestCaseRunner::~TestCaseRunner()
}
GuiApplication* TestCaseRunner::getTestApplication()
TestUiApplication* TestCaseRunner::getTestApplication()
{
return mTestApplication;
}
void TestCaseRunner::setTestApplication(GuiApplication* app)
void TestCaseRunner::setTestApplication(TestUiApplication* app)
{
mTestApplication = app;
}

View file

@ -5,7 +5,7 @@
#include <vector>
#include <string>
class GuiApplication;
class TestUiApplication;
class TestCaseRunner
{
@ -16,7 +16,7 @@ public:
~TestCaseRunner();
GuiApplication* getTestApplication();
TestUiApplication* getTestApplication();
void addTestCase(const std::string& label, const std::string& tag, TestCase::TestCaseFunction func);
@ -24,10 +24,10 @@ public:
bool run(const std::vector<std::string>& args);
void setTestApplication(GuiApplication* app);
void setTestApplication(TestUiApplication* app);
private:
GuiApplication* mTestApplication{ nullptr };
TestUiApplication* mTestApplication{ nullptr };
std::vector<std::string> mFailingTests;
static bool sLastTestFailed;
static std::string sFailureLine;

View file

@ -0,0 +1,14 @@
#include "TestUiApplication.h"
#include "MainApplication.h"
TestUiApplication::TestUiApplication(std::unique_ptr<CommandLineArgs> args, std::unique_ptr<MainApplication> mainApp)
: GuiApplication(std::move(args), std::move(mainApp))
{
}
DesktopManager* TestUiApplication::getDesktopManager() const
{
return mDesktopManager.get();
}

View file

@ -0,0 +1,13 @@
#pragma once
#include "GuiApplication.h"
#include <memory>
class TestUiApplication : public GuiApplication
{
public:
TestUiApplication(std::unique_ptr<CommandLineArgs> args = nullptr, std::unique_ptr<MainApplication> mainApp = nullptr);
DesktopManager* getDesktopManager() const;
};

View file

@ -2,7 +2,7 @@
#include "CommandLineArgs.h"
#include "MainApplication.h"
#include "GuiApplication.h"
#include "TestUiApplication.h"
#include "Widget.h"
#ifdef _WIN32
@ -12,16 +12,6 @@
#include <iostream>
class TestApp : public GuiApplication
{
public:
TestApp(std::unique_ptr<CommandLineArgs> args = nullptr, std::unique_ptr<MainApplication> mainApp = nullptr)
: GuiApplication(std::move(args), std::move(mainApp))
{
}
};
#ifdef _WIN32
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
@ -41,7 +31,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine
main_app->initialize(std::move(args), std::move(applicationContext));
auto gui_app = std::make_unique<TestApp>(nullptr, std::move(main_app));
auto gui_app = std::make_unique<TestUiApplication>(nullptr, std::move(main_app));
#else
int main(int argc, char *argv[])