add: VirtualDisplay

This commit is contained in:
Simon Hardt
2022-03-04 21:44:18 +01:00
parent 10c8a1fbf7
commit ae18232853
12 changed files with 261 additions and 36 deletions

View File

@@ -1,14 +1,34 @@
cmake_minimum_required(VERSION 3.18)
if (BUILD_VIRTUAL_DISPLAY)
set(VCPKG_MANIFEST_FEATURES virtual)
endif(BUILD_VIRTUAL_DISPLAY)
project(Frame)
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(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)

View File

@@ -1,17 +1,44 @@
set(target frame)
configure_file (
"${PROJECT_SOURCE_DIR}/frame/src/Config.h.in"
"${PROJECT_SOURCE_DIR}/frame/src/Config.h"
)
set(src
src/main.cpp
src/Image.hpp
src/Image.cpp
src/display/IDisplay.hpp
src/display/EPD_7in5_V2.hpp
src/display/EPD_7in5_V2.cpp
src/display/Display.hpp
src/display/Display.cpp
src/render/RenderTarget.hpp
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})
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
View File

@@ -0,0 +1,2 @@
#define BUILD_VIRTUAL_DISPLAY
/* #undef BUILD_EPD */

2
frame/src/Config.h.in Normal file
View File

@@ -0,0 +1,2 @@
#cmakedefine BUILD_VIRTUAL_DISPLAY
#cmakedefine BUILD_EPD

View 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

View File

@@ -0,0 +1,13 @@
#pragma once
#include "IDisplay.hpp"
#include <memory>
namespace frame::display
{
std::unique_ptr<IDisplay> Create();
}

View File

@@ -26,6 +26,8 @@ namespace frame::display
virtual void Sleep() = 0;
virtual void Update() {}
public:
Size const& getSize()
{

View 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

View 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

View File

@@ -4,25 +4,29 @@
#include <thread>
#include <vector>
using namespace std::chrono_literals;
#include "display/EPD_7in5_V2.hpp"
#include "display/Display.hpp"
#include "render/RenderTarget.hpp"
int main()
{
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.DrawLine({10, 12}, {100, 12}, frame::BLACK);
@@ -54,13 +58,15 @@ int main()
target.DrawCircle({151, 151}, 10, 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);
display.Clear(frame::display::Color::WHITE);
display->Clear(frame::display::Color::WHITE);
}
/*

View File

@@ -12,7 +12,8 @@ namespace frame::render
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;
image.at(position.x, position.y) = color;
}
@@ -85,7 +86,8 @@ namespace frame::render
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)
{
@@ -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;
@@ -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;
@@ -135,7 +142,9 @@ namespace frame::render
{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 + Vector{pos.x, pos.y * -1}, color);

11
vcpkg.json Normal file
View File

@@ -0,0 +1,11 @@
{
"name": "frame",
"version": "1.0",
"dependencies": ["fmt"],
"features": {
"virtual": {
"description": "Build Virtual Display",
"dependencies": ["sfml"]
}
}
}