First opengl/x11/window integration.

This commit is contained in:
James Grogan 2022-11-14 13:07:11 +00:00
parent 7c6a92f4ec
commit cea3d2c39f
30 changed files with 254 additions and 72 deletions

View file

@ -29,7 +29,7 @@ AbstractApp* GuiApplication::getMainApplication() const
void GuiApplication::initializeViews() void GuiApplication::initializeViews()
{ {
mDesktopManager->getWindowManager()->getMainWindow()->setSize(800, 600);
} }
void GuiApplication::setUiInterfaceBackend(UiInterfaceFactory::Backend backend) void GuiApplication::setUiInterfaceBackend(UiInterfaceFactory::Backend backend)

View file

@ -6,9 +6,16 @@ Point::Point(double x, double y)
{ {
} }
Point::Point(const DiscretePoint& point)
: mX(point.GetX()),
mY(point.GetY())
{
}
Point::Point(const Point& reference, double offSetX, double offSetY) Point::Point(const Point& reference, double offSetX, double offSetY)
: mX(reference.getX() + offSetX), : mX(reference.getX() + offSetX),
mY(reference.getX() + offSetY) mY(reference.getY() + offSetY)
{ {
} }

View file

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "DiscretePoint.h"
#include <memory> #include <memory>
#include <cmath> #include <cmath>
@ -9,6 +11,8 @@ public:
Point(double x, double y); Point(double x, double y);
Point(const DiscretePoint& point);
Point(const Point& reference, double offSetX, double offSetY); Point(const Point& reference, double offSetX, double offSetY);
~Point(); ~Point();

View file

@ -7,6 +7,14 @@ Rectangle::Rectangle(const Point& bottomLeft, const Point& topRight)
mWidth = mBottomLeft.getDeltaX(topRight); mWidth = mBottomLeft.getDeltaX(topRight);
} }
Rectangle::Rectangle(const Point& bottomLeft, double width, double height)
: mBottomLeft(bottomLeft),
mHeight(height),
mWidth(width)
{
}
Rectangle Rectangle::getBounds() const Rectangle Rectangle::getBounds() const
{ {
return Rectangle(mBottomLeft, Point(mBottomLeft, mWidth, mHeight)); return Rectangle(mBottomLeft, Point(mBottomLeft, mWidth, mHeight));

View file

@ -11,6 +11,7 @@ class Rectangle : public AbstractGeometricItem
public: public:
Rectangle(const Point& bottomLeft, const Point& topRight); Rectangle(const Point& bottomLeft, const Point& topRight);
Rectangle(const Point& bottomLeft, double width, double height);
double getHeight() const; double getHeight() const;

View file

@ -1,16 +1,13 @@
#include "DrawingContext.h" #include "DrawingContext.h"
#include "AbstractGeometricItem.h"
#include "AbstractPainter.h" #include "AbstractPainter.h"
#include "OpenGlPainter.h" #include "OpenGlPainter.h"
#include "RasterPainter.h" #include "RasterPainter.h"
#include "Grid.h"
#include "TriMesh.h"
#include "DrawingSurface.h" #include "DrawingSurface.h"
#include "Scene.h" #include "Scene.h"
#include "Grid.h"
#include "MeshBuilder.h"
#include "TriMesh.h"
DrawingContext::DrawingContext(DrawingSurface* surface, DrawingMode requestedDrawingMode) DrawingContext::DrawingContext(DrawingSurface* surface, DrawingMode requestedDrawingMode)
: mSurface(surface), : mSurface(surface),
@ -32,11 +29,6 @@ std::unique_ptr<DrawingContext> DrawingContext::Create(DrawingSurface* surface,
return std::make_unique<DrawingContext>(surface, requestedDrawingMode); return std::make_unique<DrawingContext>(surface, requestedDrawingMode);
} }
void DrawingContext::updateMesh()
{
}
Scene* DrawingContext::getScene() const Scene* DrawingContext::getScene() const
{ {
return mScene.get(); return mScene.get();
@ -49,5 +41,6 @@ DrawingSurface* DrawingContext::getSurface() const
void DrawingContext::paint() void DrawingContext::paint()
{ {
mScene->update(mDrawingMode == DrawingMode::RASTER ? mSurface->getImage() : nullptr);
mPainter->paint(this);
} }

View file

@ -6,7 +6,6 @@
class Scene; class Scene;
class AbstractPainter; class AbstractPainter;
class DrawingSurface; class DrawingSurface;
class TriMesh;
enum class DrawingMode enum class DrawingMode
{ {
@ -28,12 +27,10 @@ public:
void paint(); void paint();
private: private:
void updateMesh();
DrawingMode mDrawingMode; DrawingMode mDrawingMode;
std::unique_ptr<TriMesh> mMesh;
std::unique_ptr<Scene> mScene;
DrawingSurface* mSurface{nullptr}; DrawingSurface* mSurface{nullptr};
std::unique_ptr<Scene> mScene;
std::unique_ptr<AbstractPainter> mPainter; std::unique_ptr<AbstractPainter> mPainter;
}; };

View file

@ -1,6 +1,9 @@
#include "OpenGlPainter.h" #include "OpenGlPainter.h"
#include "DrawingContext.h" #include "DrawingContext.h"
#include "DrawingSurface.h"
#include "Scene.h"
#include "TriMesh.h"
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
@ -8,19 +11,47 @@
#include <GL/gl.h> #include <GL/gl.h>
#include <iostream>
void OpenGlPainter::paint(DrawingContext* context) void OpenGlPainter::paint(DrawingContext* context)
{ {
auto surface = context->getSurface();
const auto width = double(surface->getWidth());
const auto height = double(surface->getHeight());
const auto num_mesh = context->getScene()->getNumMeshes();
glClearColor(0.4, 0.4, 0.4, 0.4); glClearColor(0.4, 0.4, 0.4, 0.4);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glBegin(GL_TRIANGLES); for (std::size_t idx=0; idx<num_mesh; idx++)
glVertex3f(-0.7, 0.7, 0); {
glVertex3f(0.7, 0.7, 0); auto mesh = context->getScene()->getMesh(idx);
glVertex3f(0, -1, 0); const auto faces = mesh->getFaceVertices();
glEnd();
glColor3f(1.0, 0.0, 1.0);
for (const auto& face : faces)
{
glBegin(GL_TRIANGLES);
double x0 = 2.0*face[0].getX() / width - 1.0;
double y0 = 2.0*face[0].getY() / height - 1.0;
double x1 = 2.0*face[1].getX() / width - 1.0;
double y1 = 2.0*face[1].getY() / height - 1.0;
double x2 = 2.0*face[2].getX() / width - 1.0;
double y2 = 2.0*face[2].getY() / height - 1.0;
glVertex3f(x0, y0, 0);
glVertex3f(x1, y1, 0);
glVertex3f(x2, y2, 0);
glEnd();
}
}
glFlush(); glFlush();
} }

View file

@ -1,8 +1,7 @@
#pragma once #pragma once
class AbstractGeometricItem;
class AbstractMesh class AbstractMesh
{ {
public:
virtual ~AbstractMesh() = default;
}; };

View file

@ -18,3 +18,13 @@ Edge::~Edge()
{ {
} }
unsigned Edge::getNode0Id() const
{
return mNode0->getIndex();
}
unsigned Edge::getNode1Id() const
{
return mNode1->getIndex();
}

View file

@ -12,6 +12,10 @@ public:
static std::unique_ptr<Edge> Create(Node* node0, Node* node1, unsigned id = 0); static std::unique_ptr<Edge> Create(Node* node0, Node* node1, unsigned id = 0);
unsigned getNode0Id() const;
unsigned getNode1Id() const;
private: private:
unsigned mId{0}; unsigned mId{0};
Node* mNode0{nullptr}; Node* mNode0{nullptr};

View file

@ -16,16 +16,11 @@ class MeshPrimitives
{ {
public: public:
static std::unique_ptr<TriMesh> build(AbstractGeometricItem* item)
{
}
static std::unique_ptr<TriMesh> build(const Rectangle& rectangle) static std::unique_ptr<TriMesh> build(const Rectangle& rectangle)
{ {
const auto bottom_left = rectangle.getBottomLeft(); const auto bottom_left = rectangle.getLocation();
const auto width = rectangle.GetWidth(); const auto width = rectangle.getWidth();
const auto height = rectangle.GetHeight(); const auto height = rectangle.getHeight();
VecPoints locations = { VecPoints locations = {
bottom_left, bottom_left,

View file

@ -15,6 +15,11 @@ public:
void updateIndex(unsigned index); void updateIndex(unsigned index);
const Point& getPoint() const
{
return mPoint;
}
private: private:
unsigned mIndex{0}; unsigned mIndex{0};
Point mPoint; Point mPoint;

View file

@ -1,5 +1,7 @@
#include "TriFace.h" #include "TriFace.h"
#include "Edge.h"
TriFace::TriFace(Edge* edge0, Edge* edge1, Edge* edge2, unsigned id) TriFace::TriFace(Edge* edge0, Edge* edge1, Edge* edge2, unsigned id)
: mEdge0(edge0), : mEdge0(edge0),
mEdge1(edge1), mEdge1(edge1),
@ -18,3 +20,8 @@ TriFace::~TriFace()
{ {
} }
std::vector<unsigned> TriFace::getNodeIds() const
{
return {mEdge0->getNode0Id(), mEdge0->getNode1Id(), mEdge1->getNode1Id()};
}

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <vector>
class Edge; class Edge;
@ -11,6 +12,8 @@ public:
~TriFace(); ~TriFace();
static std::unique_ptr<TriFace> Create(Edge* edge0, Edge* edge1, Edge* edge2, unsigned id=0); static std::unique_ptr<TriFace> Create(Edge* edge0, Edge* edge1, Edge* edge2, unsigned id=0);
std::vector<unsigned> getNodeIds() const;
private: private:
unsigned mId{0}; unsigned mId{0};
Edge* mEdge0{nullptr}; Edge* mEdge0{nullptr};

View file

@ -15,3 +15,15 @@ void TriMesh::populate(VecNodes& nodes, VecEdges& edges, VecFaces& faces)
mEdges = std::move(edges); mEdges = std::move(edges);
mFaces = std::move(faces); mFaces = std::move(faces);
} }
std::vector<std::vector<Point> > TriMesh::getFaceVertices() const
{
std::vector<std::vector<Point> > verts(mFaces.size());
for(std::size_t idx=0; idx<mFaces.size(); idx++)
{
const auto nodeIds = mFaces[idx]->getNodeIds();
verts[idx] = {mNodes[nodeIds[0]]->getPoint(), mNodes[nodeIds[1]]->getPoint(), mNodes[nodeIds[2]]->getPoint()};
}
return verts;
}

View file

@ -1,5 +1,8 @@
#pragma once #pragma once
#include "AbstractMesh.h"
#include "Point.h"
#include <vector> #include <vector>
#include <memory> #include <memory>
@ -15,7 +18,7 @@ using VecNodes = std::vector<NodePtr>;
using VecEdges = std::vector<EdgePtr>; using VecEdges = std::vector<EdgePtr>;
using VecFaces = std::vector<TriFacePtr>; using VecFaces = std::vector<TriFacePtr>;
class TriMesh class TriMesh : public AbstractMesh
{ {
public: public:
TriMesh() = default; TriMesh() = default;
@ -24,6 +27,8 @@ public:
void populate(VecNodes& nodes, VecEdges& edges, VecFaces& faces); void populate(VecNodes& nodes, VecEdges& edges, VecFaces& faces);
std::vector<std::vector<Point> > getFaceVertices() const;
private: private:
VecNodes mNodes; VecNodes mNodes;
VecEdges mEdges; VecEdges mEdges;

View file

@ -22,9 +22,9 @@ Window::Window()
: DrawingSurface(), : DrawingSurface(),
mWidget(Widget::Create()) mWidget(Widget::Create())
{ {
mWidget->setBounds(mWidth, mHeight);
mWidth = 800; mWidth = 800;
mHeight = 600; mHeight = 600;
mWidget->setBounds(mWidth, mHeight);
} }
Window::~Window() Window::~Window()
@ -104,7 +104,7 @@ void Window::doPaint(mt::Screen* screen)
{ {
mPlatformWindow->beforePaint(screen); mPlatformWindow->beforePaint(screen);
mDrawingContext->getScene()->setLayers(mWidget->getLayers()); mDrawingContext->getScene()->syncLayers(mWidget->getLayers());
mDrawingContext->paint(); mDrawingContext->paint();

View file

@ -74,10 +74,11 @@ void Button::onPaintEvent(const PaintEvent* event)
{ {
unsigned fontOffset = unsigned(mLabel.size()) * 4; unsigned fontOffset = unsigned(mLabel.size()) * 4;
auto middle = DiscretePoint(mLocation.GetX() + mSize.mWidth/2 - fontOffset, mLocation.GetY() + mSize.mHeight/2 + 4); auto middle = DiscretePoint(mLocation.GetX() + mSize.mWidth/2 - fontOffset, mLocation.GetY() + mSize.mHeight/2 + 4);
auto textLayer = VisualLayer::Create(); auto textLayer = VisualLayer::Create();
auto textElement = TextNode::Create(mLabel, middle); auto node = TextNode::Create(mLabel, middle);
textElement->setFillColor(mBackgroundColor); node->setFillColor(mBackgroundColor);
textLayer->setText(std::move(textElement)); textLayer->setTextNode(std::move(node));
mMyLayers.push_back(std::move(textLayer)); mMyLayers.push_back(std::move(textLayer));
} }
mDirty = false; mDirty = false;

View file

@ -48,7 +48,7 @@ void Label::onPaintEvent(const PaintEvent* event)
auto textLayer = VisualLayer::Create(); auto textLayer = VisualLayer::Create();
auto textElement = TextNode::Create(mLabel, middle); auto textElement = TextNode::Create(mLabel, middle);
textElement->setFillColor(mBackgroundColor); textElement->setFillColor(mBackgroundColor);
textLayer->setText(std::move(textElement)); textLayer->setTextNode(std::move(textElement));
mMyLayers.push_back(std::move(textLayer)); mMyLayers.push_back(std::move(textLayer));
} }
addMyLayers(); addMyLayers();

View file

@ -94,7 +94,7 @@ void TextBox::onPaintEvent(const PaintEvent* event)
auto textLayer = VisualLayer::Create(); auto textLayer = VisualLayer::Create();
auto textElement = TextNode::Create(line, loc); auto textElement = TextNode::Create(line, loc);
textElement->setFillColor(mBackgroundColor); textElement->setFillColor(mBackgroundColor);
textLayer->setText(std::move(textElement)); textLayer->setTextNode(std::move(textElement));
mMyLayers.push_back(std::move(textLayer)); mMyLayers.push_back(std::move(textLayer));
offset += 20; offset += 20;
} }

View file

@ -10,6 +10,7 @@
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
#include <iostream>
Widget::Widget() Widget::Widget()
: mLocation(DiscretePoint(0, 0)), : mLocation(DiscretePoint(0, 0)),
@ -99,9 +100,9 @@ void Widget::setBounds(unsigned width, unsigned height)
if (width != mSize.mWidth || height != mSize.mHeight) if (width != mSize.mWidth || height != mSize.mHeight)
{ {
mDirty = true; mDirty = true;
mSize.mWidth = width;
mSize.mHeight = height;
} }
mSize.mWidth = width;
mSize.mHeight = height;
} }
void Widget::setBackgroundColor(const Color& color) void Widget::setBackgroundColor(const Color& color)
@ -273,9 +274,9 @@ void Widget::addBackground(const PaintEvent* event)
unsigned deltaX = mSize.mWidth - mMargin.mLeft - mMargin.mRight; unsigned deltaX = mSize.mWidth - mMargin.mLeft - mMargin.mRight;
unsigned deltaY = mSize.mHeight - mMargin.mTop - mMargin.mBottom; unsigned deltaY = mSize.mHeight - mMargin.mTop - mMargin.mBottom;
auto shape = RectangleNode::Create(DiscretePoint(locX, locY), deltaX, deltaY); auto node = RectangleNode::Create(DiscretePoint(locX, locY), deltaX, deltaY);
shape->setFillColor(mBackgroundColor); node->setFillColor(mBackgroundColor);
auto shapeLayer = VisualLayer::Create(); auto layer = VisualLayer::Create();
shapeLayer->setShape(std::move(shape)); layer->setShapeNode(std::move(node));
mMyLayers.push_back(std::move(shapeLayer)); mMyLayers.push_back(std::move(layer));
} }

View file

@ -14,11 +14,18 @@ public:
} }
virtual ~AbstractVisualNode() = default;
AbstractMesh* getMesh() const AbstractMesh* getMesh() const
{ {
return mMesh.get(); return mMesh.get();
} }
virtual void updateMesh()
{
}
Image<unsigned char>* getImage() const Image<unsigned char>* getImage() const
{ {
return mImage.get(); return mImage.get();
@ -29,7 +36,7 @@ public:
return mLocation; return mLocation;
} }
private: protected:
DiscretePoint mLocation; DiscretePoint mLocation;
std::unique_ptr<AbstractMesh> mMesh; std::unique_ptr<AbstractMesh> mMesh;
std::unique_ptr<Image<unsigned char> > mImage; std::unique_ptr<Image<unsigned char> > mImage;

View file

@ -1,5 +1,10 @@
#include "RectangleNode.h" #include "RectangleNode.h"
#include "Rectangle.h"
#include "MeshPrimitives.h"
#include <iostream>
RectangleNode::RectangleNode(const DiscretePoint& loc, unsigned width, unsigned height) RectangleNode::RectangleNode(const DiscretePoint& loc, unsigned width, unsigned height)
: GeometryNode(loc), : GeometryNode(loc),
mWidth(width), mWidth(width),
@ -27,3 +32,11 @@ unsigned RectangleNode::getHeight() const
{ {
return mHeight; return mHeight;
} }
void RectangleNode::updateMesh()
{
const auto rect = Rectangle(mLocation, mWidth, mHeight);
auto mesh = MeshPrimitives::build(rect);
mMesh = std::move(mesh);
}

View file

@ -15,6 +15,8 @@ public:
unsigned getWidth() const; unsigned getWidth() const;
unsigned getHeight() const; unsigned getHeight() const;
void updateMesh() override;
private: private:
unsigned mWidth{1}; unsigned mWidth{1};
unsigned mHeight{1}; unsigned mHeight{1};

View file

@ -0,0 +1,54 @@
#include "Scene.h"
#include "VisualLayer.h"
#include "GeometryNode.h"
#include "RectangleNode.h"
#include "MeshBuilder.h"
#include "TriMesh.h"
void Scene::syncLayers(const std::vector<VisualLayer*>& layers)
{
mLayers = layers;
}
void Scene::update(Image<unsigned char>* image)
{
if (image)
{
//
}
else
{
mWorkingMeshs.clear();
for(auto layer : mLayers)
{
if (layer->hasShapeNode())
{
auto node = layer->getShapeNode();
if (layer->getIsDirty())
{
node->updateMesh();
layer->setIsDirty(false);
}
mWorkingMeshs.push_back(dynamic_cast<TriMesh*>(node->getMesh()));
}
}
}
}
void Scene::processRectangleNode(RectangleNode* node)
{
}
unsigned Scene::getNumMeshes() const
{
return mWorkingMeshs.size();
}
TriMesh* Scene::getMesh(std::size_t idx) const
{
return mWorkingMeshs[idx];
}

View file

@ -1,23 +1,33 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include <memory>
class VisualLayer; class VisualLayer;
class TriMesh;
class RectangleNode;
template <typename T>
class Image;
class Scene class Scene
{ {
public: public:
Scene() = default; Scene() = default;
void setLayers(const std::vector<VisualLayer*>& layers) void syncLayers(const std::vector<VisualLayer*>& layers);
{
mLayers = layers; void update(Image<unsigned char>* image = nullptr);
}
unsigned getNumMeshes() const;
TriMesh* getMesh(std::size_t idx) const;
const std::vector<VisualLayer*>& getLayers() const
{
return mLayers;
}
private: private:
void processRectangleNode(RectangleNode* node);
std::vector<TriMesh*> mWorkingMeshs;
std::vector<VisualLayer*> mLayers; std::vector<VisualLayer*> mLayers;
}; };

View file

@ -15,32 +15,32 @@ std::unique_ptr<VisualLayer> VisualLayer::Create()
return std::make_unique<VisualLayer>(); return std::make_unique<VisualLayer>();
} }
bool VisualLayer::hasShape() const bool VisualLayer::hasShapeNode() const
{ {
return bool(mShape); return bool(mShape);
} }
bool VisualLayer::hasText() const bool VisualLayer::hasTextNode() const
{ {
return bool(mText); return bool(mText);
} }
GeometryNode* VisualLayer::getShape() const GeometryNode* VisualLayer::getShapeNode() const
{ {
return mShape.get(); return mShape.get();
} }
TextNode* VisualLayer::getText() const TextNode* VisualLayer::getTextNode() const
{ {
return mText.get(); return mText.get();
} }
void VisualLayer::setShape(GeometryNodePtr shape) void VisualLayer::setShapeNode(GeometryNodePtr shape)
{ {
mShape = std::move(shape); mShape = std::move(shape);
} }
void VisualLayer::setText(std::unique_ptr<TextNode> text) void VisualLayer::setTextNode(std::unique_ptr<TextNode> text)
{ {
mText = std::move(text); mText = std::move(text);
} }

View file

@ -12,14 +12,25 @@ public:
static std::unique_ptr<VisualLayer> Create(); static std::unique_ptr<VisualLayer> Create();
GeometryNode* getShape() const; GeometryNode* getShapeNode() const;
TextNode* getText() const; TextNode* getTextNode() const;
bool hasShape() const; bool hasShapeNode() const;
bool hasText() const; bool hasTextNode() const;
void setShape(std::unique_ptr<GeometryNode> shape); void setShapeNode(std::unique_ptr<GeometryNode> shape);
void setText(std::unique_ptr<TextNode> text); void setTextNode(std::unique_ptr<TextNode> text);
bool getIsDirty() const
{
return mIsDirty;
}
void setIsDirty(bool isDirty)
{
mIsDirty = isDirty;
}
private: private:
bool mIsDirty{true};
std::unique_ptr<GeometryNode> mShape; std::unique_ptr<GeometryNode> mShape;
std::unique_ptr<TextNode> mText; std::unique_ptr<TextNode> mText;
}; };

View file

@ -26,6 +26,7 @@ void XcbLayerInterface::modifyGcColor(xcb_connection_t* connection, xcb_gcontext
void XcbLayerInterface::addLayer(xcb_connection_t* connection, xcb_screen_t* screen, xcb_window_t window, xcb_gcontext_t gc, VisualLayer* layer) void XcbLayerInterface::addLayer(xcb_connection_t* connection, xcb_screen_t* screen, xcb_window_t window, xcb_gcontext_t gc, VisualLayer* layer)
{ {
/*
if(layer->hasText()) if(layer->hasText())
{ {
XcbTextInterface::AddTextElement(connection, screen, window, layer->getText()); XcbTextInterface::AddTextElement(connection, screen, window, layer->getText());
@ -45,5 +46,6 @@ void XcbLayerInterface::addLayer(xcb_connection_t* connection, xcb_screen_t* scr
xcb_poly_fill_rectangle(connection, window, gc, 1, rectangles); xcb_poly_fill_rectangle(connection, window, gc, 1, rectangles);
} }
} }
*/
} }