[c++ / SFML] [µPaint] A simple drawing program
German version: here
A video demonstration: here
This project shows how easy it is to create your own minimalistic drawing program and therefore its aim is to encourage you to further develop it. You could for instance try to add support for drawing circles, rectangles, zoom in / out etc.
You are welcome to post your code in the comments and ask if you have any questions or suggestions.
There will probably be a follow up, that shows a way on how to implement the above ideas.
Setup
First of all c++ and the SimpleFastMultimediaLibrary (SFML) are used to create this minimalistic program. Install guide of SFML for Visual Studio: here
Since steemit doesn't support syntax highlighting (yet), I suggest copying the below code to a program of your choice, that supports it. Like Notepad++.
Code
In order to understand how vertexArrays work see: VertexArray
Basically what is being done is to add a new vertexArray to a vector every time the user releases a mouse button and therefore must have pressed it before. When the user presses a mouse button we add vertices to the current vertexArray with the current mouse_position as its coordinates for as long as the user releases a mouse button.
Peculiarities
Since the mouse_position is referenced to the monitors coordinate system, we have to compensate for it by subtracting the windows position (left upper corner) from it.
We also have to compensate for the windows border thickness and the title bar thickness in order to draw a line from the actual mouse point (See Border_Offset).
If you want to know how the "µPaint" imgage at the top was created: Play around with the code.
Hint: It only needs 3 changes to be able to recreate it.
Small enhancements
To prevent the number of vertices going to infinity a new vertex is only added, when the mouse has moved
#include "SFML\Graphics.hpp"
#include <iostream>
#include <vector>
int main()
{
std::vector<sf::VertexArray> vertices; // vector in wich all vertexArrays will be stored
vertices.push_back(sf::VertexArray()); // The 1. Line
vertices[0].setPrimitiveType(sf::LinesStrip); // The 1. Line's PrimitiveType: see https://www.sfml-dev.org/tutorials/2.4/graphics-vertex-array.php
int lines_number = 0; // The index of the current_line
int locked = false; // When a mouse button is pressed this will change to true until a mouse button is released again
sf::Color curr_col = sf::Color::Black;
sf::Vector2i last_Mouse_pos(0,0);
sf::RenderWindow window(sf::VideoMode(1280, 720), "µPaint", sf::Style::Close, sf::ContextSettings(0,0, 0)); // The window everything is rendered to
window.setFramerateLimit(60);
sf::Vector2f Border_Offset(-5, -25); // Compensate for the Window frame when calling window.getPosition()
while (window.isOpen())
{
// Event processing
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::KeyPressed) // Handling the closure of the renderwindow
if(event.key.code == sf::Keyboard::Key::Escape)
window.close();
if (event.type == sf::Event::Closed) // Handling the closure of the renderwindow
window.close();
if (event.type == sf::Event::MouseButtonPressed) // See "locked" definition
{
locked = true;
}
if (event.type == sf::Event::MouseButtonReleased) // See "locked" definition
{
// Add a new Line
lines_number++;
vertices.push_back(sf::VertexArray());
vertices[lines_number].setPrimitiveType(sf::LinesStrip);
locked = false; // Reset
}
}
if (locked) // See "locked" definition
{
if (last_Mouse_pos != sf::Mouse::getPosition()) // When the Mouse hasn't moved don't add any new Vertex (save memory)
{
//.append(Position, Color) : .append(MousePos - WindowPos + MouseOffset, curr_col)
vertices[lines_number].append(sf::Vertex(sf::Vector2f(sf::Mouse::getPosition().x - window.getPosition().x + Border_Offset.x, sf::Mouse::getPosition().y - window.getPosition().y + Border_Offset.y), curr_col));
last_Mouse_pos = sf::Mouse::getPosition();
}
}
//curr_col = sf::Color::Color(rand() % 255, rand() % 255, rand() % 255);
std::cout << "vertices in line " << lines_number << ": " << vertices[lines_number].getVertexCount() << std::endl;
window.clear(sf::Color::White); //Clear the window with a specific color
//Draw everything (vertices)
for (int i = 0; i < vertices.size(); i++)
{
window.draw(vertices[i]);
}
window.display();
}
return 0;
}