add: VirtualDisplay
This commit is contained in:
@@ -1,14 +1,34 @@
|
|||||||
cmake_minimum_required(VERSION 3.18)
|
cmake_minimum_required(VERSION 3.18)
|
||||||
|
|
||||||
|
if (BUILD_VIRTUAL_DISPLAY)
|
||||||
|
set(VCPKG_MANIFEST_FEATURES virtual)
|
||||||
|
endif(BUILD_VIRTUAL_DISPLAY)
|
||||||
|
|
||||||
|
|
||||||
project(Frame)
|
project(Frame)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
|
option(BUILD_EPD
|
||||||
|
"Build EPD Display"
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
|
||||||
#if (UNIX)
|
find_package(fmt CONFIG REQUIRED)
|
||||||
|
|
||||||
|
option(BUILD_VIRTUAL_DISPLAY
|
||||||
|
"Build virtual sfml based display"
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
|
||||||
|
if (BUILD_EPD)
|
||||||
add_subdirectory(bcm2835)
|
add_subdirectory(bcm2835)
|
||||||
add_subdirectory(waveshare)
|
add_subdirectory(waveshare)
|
||||||
#endif (UNIX)
|
endif (BUILD_EPD)
|
||||||
|
|
||||||
|
if (BUILD_VIRTUAL_DISPLAY)
|
||||||
|
find_package(SFML COMPONENTS system window graphics CONFIG REQUIRED)
|
||||||
|
endif(BUILD_VIRTUAL_DISPLAY)
|
||||||
|
|
||||||
add_subdirectory(frame)
|
add_subdirectory(frame)
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,44 @@
|
|||||||
|
|
||||||
set(target frame)
|
set(target frame)
|
||||||
|
|
||||||
|
configure_file (
|
||||||
|
"${PROJECT_SOURCE_DIR}/frame/src/Config.h.in"
|
||||||
|
"${PROJECT_SOURCE_DIR}/frame/src/Config.h"
|
||||||
|
)
|
||||||
|
|
||||||
set(src
|
set(src
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
src/Image.hpp
|
src/Image.hpp
|
||||||
src/Image.cpp
|
src/Image.cpp
|
||||||
src/display/IDisplay.hpp
|
src/display/IDisplay.hpp
|
||||||
src/display/EPD_7in5_V2.hpp
|
src/display/Display.hpp
|
||||||
src/display/EPD_7in5_V2.cpp
|
src/display/Display.cpp
|
||||||
src/render/RenderTarget.hpp
|
src/render/RenderTarget.hpp
|
||||||
src/render/RenderTarget.cpp
|
src/render/RenderTarget.cpp
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (BUILD_EPD)
|
||||||
|
set(src ${src}
|
||||||
|
src/display/EPD_7in5_V2.hpp
|
||||||
|
src/display/EPD_7in5_V2.cpp
|
||||||
|
)
|
||||||
|
endif (BUILD_EPD)
|
||||||
|
|
||||||
|
if (BUILD_VIRTUAL_DISPLAY)
|
||||||
|
set(src ${src}
|
||||||
|
src/display/VirtualDisplay.hpp
|
||||||
|
src/display/VirtualDisplay.cpp
|
||||||
|
)
|
||||||
|
endif (BUILD_VIRTUAL_DISPLAY)
|
||||||
|
|
||||||
add_executable(${target} ${src})
|
add_executable(${target} ${src})
|
||||||
target_link_libraries(${target} PRIVATE waveshare)
|
target_link_libraries(${target} PRIVATE fmt::fmt)
|
||||||
|
|
||||||
|
if (BUILD_EPD)
|
||||||
|
target_link_libraries(${target} PRIVATE waveshare)
|
||||||
|
endif (BUILD_EPD)
|
||||||
|
|
||||||
|
if (BUILD_VIRTUAL_DISPLAY)
|
||||||
|
target_link_libraries(${target} PRIVATE sfml-system sfml-window sfml-graphics)
|
||||||
|
endif(BUILD_VIRTUAL_DISPLAY)
|
||||||
2
frame/src/Config.h
Normal file
2
frame/src/Config.h
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#define BUILD_VIRTUAL_DISPLAY
|
||||||
|
/* #undef BUILD_EPD */
|
||||||
2
frame/src/Config.h.in
Normal file
2
frame/src/Config.h.in
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#cmakedefine BUILD_VIRTUAL_DISPLAY
|
||||||
|
#cmakedefine BUILD_EPD
|
||||||
27
frame/src/display/Display.cpp
Normal file
27
frame/src/display/Display.cpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#include "Display.hpp"
|
||||||
|
|
||||||
|
#include "../Config.h"
|
||||||
|
|
||||||
|
#ifdef BUILD_EPD
|
||||||
|
# include "EPD_7in5_V2.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BUILD_VIRTUAL_DISPLAY
|
||||||
|
# include "VirtualDisplay.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace frame::display
|
||||||
|
{
|
||||||
|
std::unique_ptr<IDisplay> Create()
|
||||||
|
{
|
||||||
|
#ifdef BUILD_EPD
|
||||||
|
return std::make_unique<EPD_7in5_V2>();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BUILD_VIRTUAL_DISPLAY
|
||||||
|
return std::make_unique<VirtualDisplay>();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
} // namespace frame::display
|
||||||
13
frame/src/display/Display.hpp
Normal file
13
frame/src/display/Display.hpp
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IDisplay.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
|
namespace frame::display
|
||||||
|
{
|
||||||
|
|
||||||
|
std::unique_ptr<IDisplay> Create();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -26,6 +26,8 @@ namespace frame::display
|
|||||||
|
|
||||||
virtual void Sleep() = 0;
|
virtual void Sleep() = 0;
|
||||||
|
|
||||||
|
virtual void Update() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Size const& getSize()
|
Size const& getSize()
|
||||||
{
|
{
|
||||||
|
|||||||
73
frame/src/display/VirtualDisplay.cpp
Normal file
73
frame/src/display/VirtualDisplay.cpp
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#include "VirtualDisplay.hpp"
|
||||||
|
|
||||||
|
#include "../size.hpp"
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace frame::display
|
||||||
|
{
|
||||||
|
constexpr std::string_view title = "Virtual Display";
|
||||||
|
|
||||||
|
VirtualDisplay::VirtualDisplay()
|
||||||
|
: IDisplay(title, {800, 480})
|
||||||
|
, size(getSize())
|
||||||
|
, window(sf::VideoMode(size.width, size.height), std::string(title))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualDisplay::Init()
|
||||||
|
{
|
||||||
|
renderTarget.create(size.width, size.height, sf::Color::White);
|
||||||
|
Draw();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualDisplay::Clear(Color color)
|
||||||
|
{
|
||||||
|
renderTarget.create(size.width,
|
||||||
|
size.height,
|
||||||
|
color == Color::WHITE ? sf::Color::White
|
||||||
|
: sf::Color::Black);
|
||||||
|
Draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualDisplay::Display(Image const& image, bool invert)
|
||||||
|
{
|
||||||
|
|
||||||
|
for(auto y = 0; y < size.height; ++y)
|
||||||
|
{
|
||||||
|
for(auto x = 0; x < size.width; ++x)
|
||||||
|
{
|
||||||
|
renderTarget.setPixel(x,
|
||||||
|
y,
|
||||||
|
(image.at(x, y) > 265 / 2)
|
||||||
|
? sf::Color::Black
|
||||||
|
: sf::Color::White);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualDisplay::Sleep() {}
|
||||||
|
|
||||||
|
void VirtualDisplay::Update()
|
||||||
|
{
|
||||||
|
sf::Event ev;
|
||||||
|
while(window.pollEvent(ev))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualDisplay::Draw()
|
||||||
|
{
|
||||||
|
sf::Sprite sprite;
|
||||||
|
sf::Texture texture;
|
||||||
|
texture.loadFromImage(renderTarget);
|
||||||
|
sprite.setTexture(texture);
|
||||||
|
|
||||||
|
window.clear(sf::Color::White);
|
||||||
|
window.draw(sprite);
|
||||||
|
window.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace frame::display
|
||||||
33
frame/src/display/VirtualDisplay.hpp
Normal file
33
frame/src/display/VirtualDisplay.hpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "IDisplay.hpp"
|
||||||
|
|
||||||
|
#include <sfml/Graphics.hpp>
|
||||||
|
|
||||||
|
namespace frame::display
|
||||||
|
{
|
||||||
|
|
||||||
|
class VirtualDisplay : public IDisplay
|
||||||
|
{
|
||||||
|
Size size;
|
||||||
|
sf::RenderWindow window;
|
||||||
|
sf::Image renderTarget;
|
||||||
|
|
||||||
|
public:
|
||||||
|
VirtualDisplay();
|
||||||
|
~VirtualDisplay() = default;
|
||||||
|
|
||||||
|
bool Init() override;
|
||||||
|
|
||||||
|
void Clear(Color color) override;
|
||||||
|
|
||||||
|
void Display(Image const& image, bool invert = false) override;
|
||||||
|
|
||||||
|
void Sleep() override;
|
||||||
|
|
||||||
|
void Update() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Draw();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace frame::display
|
||||||
@@ -4,25 +4,29 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
#include "display/EPD_7in5_V2.hpp"
|
#include "display/Display.hpp"
|
||||||
#include "render/RenderTarget.hpp"
|
#include "render/RenderTarget.hpp"
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
constexpr double pi = 3.14159;
|
constexpr double pi = 3.14159;
|
||||||
|
|
||||||
frame::display::EPD_7in5_V2 display{};
|
auto display = frame::display::Create();
|
||||||
|
|
||||||
display.Init();
|
if(!display)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
display.Clear(frame::display::Color::WHITE);
|
display->Init();
|
||||||
|
|
||||||
frame::render::RenderTarget target(display.getSize());
|
display->Clear(frame::display::Color::WHITE);
|
||||||
|
|
||||||
frame::Vector const center = (display.getSize() / 2);
|
frame::render::RenderTarget target(display->getSize());
|
||||||
|
|
||||||
|
frame::Vector const center = (display->getSize() / 2);
|
||||||
|
|
||||||
target.DrawPixel({10, 10}, frame::BLACK);
|
target.DrawPixel({10, 10}, frame::BLACK);
|
||||||
target.DrawLine({10, 12}, {100, 12}, frame::BLACK);
|
target.DrawLine({10, 12}, {100, 12}, frame::BLACK);
|
||||||
@@ -54,13 +58,15 @@ int main()
|
|||||||
target.DrawCircle({151, 151}, 10, frame::WHITE);
|
target.DrawCircle({151, 151}, 10, frame::WHITE);
|
||||||
target.DrawCircle({151, 151}, 1, frame::WHITE);
|
target.DrawCircle({151, 151}, 1, frame::WHITE);
|
||||||
|
|
||||||
target.DrawRect({10, (int)display.getSize().height - 110}, {110, (int)display.getSize().height - 10}, 5);
|
target.DrawRect({10, (int)display->getSize().height - 110},
|
||||||
|
{110, (int)display->getSize().height - 10},
|
||||||
|
5);
|
||||||
|
|
||||||
display.Display(target.getImage());
|
display->Display(target.getImage());
|
||||||
|
|
||||||
std::this_thread::sleep_for(10s);
|
std::this_thread::sleep_for(10s);
|
||||||
|
|
||||||
display.Clear(frame::display::Color::WHITE);
|
display->Clear(frame::display::Color::WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ namespace frame::render
|
|||||||
|
|
||||||
void RenderTarget::DrawPixel(Vector const& position, Color color)
|
void RenderTarget::DrawPixel(Vector const& position, Color color)
|
||||||
{
|
{
|
||||||
if(position.x < 0 || position.y < 0 || position.x >= image.getWidth() || position.y > image.getHeight())
|
if(position.x < 0 || position.y < 0 || position.x >= image.getWidth()
|
||||||
|
|| position.y >= image.getHeight())
|
||||||
return;
|
return;
|
||||||
image.at(position.x, position.y) = color;
|
image.at(position.x, position.y) = color;
|
||||||
}
|
}
|
||||||
@@ -85,7 +86,8 @@ namespace frame::render
|
|||||||
|
|
||||||
while(pos.x <= radius / std::sqrt(2.f))
|
while(pos.x <= radius / std::sqrt(2.f))
|
||||||
{
|
{
|
||||||
float E = pos.x * pos.x + ((float)pos.y + 0.5f) * ((float)pos.y + 0.5f) - r_2;
|
float E = pos.x * pos.x
|
||||||
|
+ ((float)pos.y + 0.5f) * ((float)pos.y + 0.5f) - r_2;
|
||||||
|
|
||||||
if(E <= 0)
|
if(E <= 0)
|
||||||
{
|
{
|
||||||
@@ -104,7 +106,9 @@ namespace frame::render
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderTarget::DrawRectFilled(Vector const& LeftTop, Vector const& BottomRight, Color color)
|
void RenderTarget::DrawRectFilled(Vector const& LeftTop,
|
||||||
|
Vector const& BottomRight,
|
||||||
|
Color color)
|
||||||
{
|
{
|
||||||
auto pos = LeftTop;
|
auto pos = LeftTop;
|
||||||
|
|
||||||
@@ -120,7 +124,10 @@ namespace frame::render
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderTarget::DrawRect(Vector const& TopLeft, Vector const& BottomRight, uint8_t LineWidth, Color color)
|
void RenderTarget::DrawRect(Vector const& TopLeft,
|
||||||
|
Vector const& BottomRight,
|
||||||
|
uint8_t LineWidth,
|
||||||
|
Color color)
|
||||||
{
|
{
|
||||||
auto pos = TopLeft;
|
auto pos = TopLeft;
|
||||||
|
|
||||||
@@ -129,13 +136,15 @@ namespace frame::render
|
|||||||
DrawRectFilled(TopLeft, {BottomRight.x, TopLeft.y + lw}, color);
|
DrawRectFilled(TopLeft, {BottomRight.x, TopLeft.y + lw}, color);
|
||||||
DrawRectFilled({TopLeft.x, BottomRight.y - lw}, BottomRight);
|
DrawRectFilled({TopLeft.x, BottomRight.y - lw}, BottomRight);
|
||||||
|
|
||||||
DrawRectFilled({TopLeft.x , TopLeft.y + lw},
|
DrawRectFilled({TopLeft.x, TopLeft.y + lw},
|
||||||
{TopLeft.x + lw, BottomRight.y - lw});
|
{TopLeft.x + lw, BottomRight.y - lw});
|
||||||
DrawRectFilled({BottomRight.x - lw, TopLeft.y + lw},
|
DrawRectFilled({BottomRight.x - lw, TopLeft.y + lw},
|
||||||
{BottomRight.x , BottomRight.y - lw});
|
{BottomRight.x, BottomRight.y - lw});
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderTarget::DrawPointsMirrorCircle(Vector const& center, Vector const& pos, Color color)
|
void RenderTarget::DrawPointsMirrorCircle(Vector const& center,
|
||||||
|
Vector const& pos,
|
||||||
|
Color color)
|
||||||
{
|
{
|
||||||
DrawPixel(center + pos, color);
|
DrawPixel(center + pos, color);
|
||||||
DrawPixel(center + Vector{pos.x, pos.y * -1}, color);
|
DrawPixel(center + Vector{pos.x, pos.y * -1}, color);
|
||||||
|
|||||||
11
vcpkg.json
Normal file
11
vcpkg.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "frame",
|
||||||
|
"version": "1.0",
|
||||||
|
"dependencies": ["fmt"],
|
||||||
|
"features": {
|
||||||
|
"virtual": {
|
||||||
|
"description": "Build Virtual Display",
|
||||||
|
"dependencies": ["sfml"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user