-
I made a little project that is supposed to merge with my main one when it is finished, tho I am having problems. Basically the code is supposed to create a window on which you can freely draw. That being said when I click to draw the whole sprite gets moved down a couple of pixels or so.(the line vertexes get saved as a texture which is applied to a sprite and then drawn). The thing is if VideoMode and the texture size are something like 800x600 this doesn't happen, but the moment they are set to 1080p(monitors native resolution) it happens. This is the code :
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
int main()
{
// create the window
sf::RenderWindow window(sf::VideoMode(800, 600), "My window");
std::vector <sf::Vertex> lines;
sf::Texture texture;
sf::Sprite sprite;
sprite.setPosition(0, 0);
texture.create(800, 600);
sf::Event event;
int mousedown = 0;
// run the program as long as the window is open
window.setFramerateLimit(60);
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
else if ((event.type == sf::Event::MouseMoved) && (mousedown == 1))
{
sf::Vertex point;
point.color = sf::Color::Black;
point.position = sf::Vector2f(sf::Mouse::getPosition(window));
lines.push_back(point);
}
else if (event.type == sf::Event::MouseButtonPressed)
{
mousedown = 1;
}
else if (event.type == sf::Event::MouseButtonReleased)
{
mousedown = 0;
texture.update(window);
lines.clear();
}
}
window.clear(sf::Color::White);
sprite.setTexture(texture);
window.draw(sprite);
window.draw(&lines[0], lines.size(), sf::LinesStrip);
window.display();
}
return 0;
}
-
Non-fullscreen windows of max resolution are known to produce issues (at least on Windows), because with decorations, they end up being bigger than the screen. You can confirm if this is causing your problem, by reducing the window size just a little bit, or by making it fullscreen.
-
I tried a couple of things : Setting it to 1900x1000 - this allowed me to draw but as soon as I released the button the lines disappeared.
Setting it 1600x900 - This works tho making it fullscreen draws lines a little to the right of my cursor, and like the above one when the button is released the lines disappear(when in fullscreen)
-
Btw will 2 LineStrips from different vectors connect? And if so what can I do to prevent it?
-
Btw will 2 LineStrips from different vectors connect?
No.
-
Asking this because I modified my code so it doesn't save the lines as a texture, but rather it saves the lines on an another sf::Vertex vector. Tho it seems that the lines still seem to connect.
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
int main()
{
// create the window
sf::RenderWindow window(sf::VideoMode(1920, 1080), "My window");
std::vector <sf::Vertex> lines;
std::vector <sf::Vertex> archivedLines;
sf::Event event;
int mousedown = 0;
// run the program as long as the window is open
window.setFramerateLimit(60);
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::MouseButtonPressed)
{
mousedown = 1;
}
if (event.type == sf::Event::MouseButtonReleased)
{
mousedown = 0;
lines.clear();
}
if ((event.type == sf::Event::MouseMoved) && (mousedown == 1))
{
sf::Vertex line;
line.color = sf::Color::Black;
line.position = sf::Vector2f(sf::Mouse::getPosition(window));
lines.push_back(line);
archivedLines.push_back(line);
}
}
window.clear(sf::Color::White);
window.draw(&lines[0], lines.size(), sf::LineStrip);
window.draw(&archivedLines[0], archivedLines.size(), sf::LineStrip);
window.display();
}
return 0;
}
-
Nevermind, figured it out.
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
int main()
{
// create the window
sf::RenderWindow window(sf::VideoMode(1920, 1080), "My window");
std::vector <sf::Vertex> lines;
std::vector <sf::Vertex> archivedLines;
sf::Event event;
int mousedown = 0;
// run the program as long as the window is open
window.setFramerateLimit(60);
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::MouseButtonPressed)
{
mousedown = 1;
}
if (event.type == sf::Event::MouseButtonReleased)
{
mousedown = 0;
for(auto i : lines)
{
archivedLines.push_back(i);
}
lines.clear();
}
if ((event.type == sf::Event::MouseMoved) && (mousedown == 1))
{
sf::Vertex line;
line.color = sf::Color::Black;
line.position = sf::Vector2f(sf::Mouse::getPosition(window));
lines.push_back(line);
//archivedLines.push_back(line);
}
}
std::cout<<archivedLines.size()<<std::endl;
window.clear(sf::Color::White);
window.draw(&lines[0], lines.size(), sf::LineStrip);
window.draw(&archivedLines[0], archivedLines.size(), sf::LineStrip);
window.display();
}
return 0;
}
-
So after being happy for a couple of seconds thinking that I solved the problem I realised that once lines are put into the archivedLines vector they would connect. For now at least I have no idea how to fix this. I have some unrealistic ideas like a vector of vectors. I tried removing the line that connects them, but it doesn't work.
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
int main()
{
// create the window
sf::RenderWindow window(sf::VideoMode(1920, 1080), "My window");
std::vector <sf::Vertex> lines;
std::vector <sf::Vertex> archivedLines;
sf::Event event;
int mousedown = 0;
// run the program as long as the window is open
window.setFramerateLimit(10000);
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::MouseButtonPressed)
{
mousedown = 1;
}
if (event.type == sf::Event::MouseButtonReleased)
{
mousedown = 0;
int removeLine = archivedLines.size();
std::cout<<"RemoveLine- "<<removeLine<<std::endl;
for(auto i : lines)
{
archivedLines.push_back(i);
}
if(removeLine > 0)
{
std::cout<<"Vector Size- "<<archivedLines.size()<<std::endl;
archivedLines.erase(archivedLines.begin()+removeLine);
}
lines.clear();
}
if ((event.type == sf::Event::MouseMoved) && (mousedown == 1))
{
sf::Vertex line;
line.color = sf::Color::Black;
line.position = sf::Vector2f(sf::Mouse::getPosition(window));
lines.push_back(line);
}
}
window.clear(sf::Color::White);
window.draw(&lines[0], lines.size(), sf::LineStrip);
window.draw(&archivedLines[0], archivedLines.size(), sf::LineStrip);
window.display();
}
return 0;
}
-
I have some unrealistic ideas like a vector of vectors
Why "unrealistic"? You want to store a list of separate line strips that don't connect to each other, don't you? So that's exactly a vector of vectors.
-
Unrealistic, because I tried it and after spamming lines the performance was down to a craw. Also maybe it was me that did something wrong since lines would snap to the top left corner of the window. It sometimes also crashes.
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
int main()
{
// create the window
sf::RenderWindow window(sf::VideoMode(1920, 1080), "My window");
std::vector <sf::Vertex> lines;
std::vector <std::vector<sf::Vertex>> archivedLines;
sf::Event event;
int mousedown = 0;
// run the program as long as the window is open
window.setFramerateLimit(1000);
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::MouseButtonPressed)
{
mousedown = 1;
}
if (event.type == sf::Event::MouseButtonReleased)
{
mousedown = 0;
archivedLines.push_back(lines);
lines.clear();
}
if ((event.type == sf::Event::MouseMoved) && (mousedown == 1))
{
sf::Vertex line;
line.color = sf::Color::Black;
line.position = sf::Vector2f(sf::Mouse::getPosition(window));
lines.push_back(line);
}
}
window.clear(sf::Color::White);
if(archivedLines.size() > 0)
{
for(int i = 0; i < archivedLines.size(); ++i)
{
for(int t = 0; t < archivedLines[i].size(); ++t)
{
window.draw(&archivedLines[i][t], archivedLines[i].size(), sf::LineStrip);
}
}
}
window.draw(&lines[0], lines.size(), sf::LineStrip);
window.display();
}
return 0;
}
-
Take 5 minutes to really think about your code. What you wrote doesn't make sense.
for(const auto& line : archivesLines) // iterate on all archived line strips
window.draw(&line[0], line.size(), sf::LineStrip); // draw them
You can also use sf::VertexArray to simplify things a little bit.
-
:-[ My mistake was quite silly - I've got it running now. Btw is there any way to make the placement of a line match the position of the mouse when the window is resized?
-
Yes, see https://www.sfml-dev.org/documentation/2.5.1/classsf_1_1RenderTarget.php#a2d3e9d7c4a1f5ea7e52b06f53e3011f9
-
Wow that was simple. I didn't know that there was an overloaded version of the mapPixelsToCoords that accepted the current view.
-
I am trying to add a rectangle shape over the screen and for some reason lines that are under it(the rectangle is transparent) don't show up. size() show that the vector is getting bigger so lines are being put inside, but they don't show up.
Edit - opaqueness is supposed to be 0, not 255.
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
int main()
{
// create the window
sf::VideoMode mode = sf::VideoMode::getDesktopMode();
sf::RenderWindow window(sf::VideoMode(mode.width / 2, mode.height), "My window");
std::vector <sf::Vertex> lines;
std::vector <std::vector<sf::Vertex>> archivedLines;
sf::RectangleShape screen;
screen.setSize(sf::Vector2f(1600, 900));
screen.setPosition(sf::Vector2f(160, 90));
screen.setFillColor(sf::Color(255, 255, 255, 255));
screen.setOutlineThickness(160);
screen.setOutlineColor(sf::Color(102, 102, 102));
sf::Event event;
int mousedown = 0;
// run the program as long as the window is open
window.setFramerateLimit(1000);
sf::Vector2i smth = sf::Mouse::getPosition(window);
sf::Vector2f mousePosition = window.mapPixelToCoords(smth);
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
smth = sf::Mouse::getPosition(window);
mousePosition = window.mapPixelToCoords(smth, window.getView());
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::MouseButtonPressed)
{
mousedown = 1;
}
if (event.type == sf::Event::MouseButtonReleased)
{
mousedown = 0;
archivedLines.push_back(lines);
lines.clear();
}
if ((event.type == sf::Event::MouseMoved) && (mousedown == 1))
{
sf::Vertex line;
line.color = sf::Color::Black;
line.position = sf::Vector2f(mousePosition);
lines.push_back(line);
}
}
std::cout<<archivedLines.size()<<std::endl;
window.clear(sf::Color::White);
if(archivedLines.size() > 0)
{
for(int i = 0; i < archivedLines.size(); ++i)
{
window.draw(&archivedLines[i][0], archivedLines[i].size(), sf::LineStrip);
}
}
window.draw(&lines[0], lines.size(), sf::LineStrip);
window.draw(screen);
window.display();
}
return 0;
}