add: VirtualDisplay
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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 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 Update() {}
|
||||
|
||||
public:
|
||||
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 <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);
|
||||
@@ -52,15 +56,17 @@ int main()
|
||||
target.DrawCircle({151, 151}, 30, frame::WHITE);
|
||||
target.DrawCircle({151, 151}, 20, 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);
|
||||
|
||||
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)
|
||||
{
|
||||
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,23 +106,28 @@ 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;
|
||||
|
||||
while(pos.y <= BottomRight.y)
|
||||
{
|
||||
while(pos.x <= BottomRight.x)
|
||||
{
|
||||
DrawPixel(pos, color);
|
||||
pos.x++;
|
||||
}
|
||||
pos.x = LeftTop.x;
|
||||
pos.y++;
|
||||
}
|
||||
while(pos.y <= BottomRight.y)
|
||||
{
|
||||
while(pos.x <= BottomRight.x)
|
||||
{
|
||||
DrawPixel(pos, color);
|
||||
pos.x++;
|
||||
}
|
||||
pos.x = LeftTop.x;
|
||||
pos.y++;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -129,13 +136,15 @@ namespace frame::render
|
||||
DrawRectFilled(TopLeft, {BottomRight.x, TopLeft.y + lw}, color);
|
||||
DrawRectFilled({TopLeft.x, BottomRight.y - lw}, BottomRight);
|
||||
|
||||
DrawRectFilled({TopLeft.x , TopLeft.y + lw},
|
||||
{TopLeft.x + lw, BottomRight.y - lw});
|
||||
DrawRectFilled({BottomRight.x - lw, TopLeft.y + lw},
|
||||
{BottomRight.x , BottomRight.y - lw});
|
||||
DrawRectFilled({TopLeft.x, TopLeft.y + lw},
|
||||
{TopLeft.x + lw, BottomRight.y - lw});
|
||||
DrawRectFilled({BottomRight.x - lw, TopLeft.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 + 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