I'm learning how to use SFML, and after completing the RenderWindow tutorial with no problems, I've begun trying to use sf::Text and sf::Font with the next tutorial on the page.
Here is my code:
#include <iostream>
#include <SFML/Graphics.hpp>
#include <SFML/Graphics/Font.hpp>
#include <SFML/Graphics/Text.hpp>
int main() {
// initialise font
sf::Font ubuntu_r;
if(!ubuntu_r.loadFromFile("Ubuntu-R.ttf")) {
// unable to load font
std::cout << "Cannot load font." << std::endl;
}
// initialise text
sf::Text text;
text.setFont(ubuntu_r);
text.setString("Hello, world!");
text.setCharacterSize(50);
text.setColor(sf::Color(0x555555ff));
// initialise window
sf::RenderWindow win(sf::VideoMode(800,600),"Hello, world!");
// main loop
while(win.isOpen()) {
// check for closure
sf::Event e;
while(win.pollEvent(e)) {
if(e.type == sf::Event::Closed) {
win.close();
}
}
// draw text to screen
win.clear(sf::Color::White);
win.draw(text);
win.display();
}
return 0;
}
resulting in the following on compile:
$ g++ -c text.cpp
$ g++ text.o -o text -lsfml-graphics -lsfml-system -lsfml-window
text.o: In function `main':
text.cpp:(.text+0x10d): undefined reference to `sf::Font::loadFromFile(std::string const&)'
collect2: error: ld returned 1 exit status
This is very confusing, as I've checked in Font.hpp and loadFromFile() is definitely defined.
Commenting out all the text and font related code results in a perfectly compiled program that creates a white window that closes normally.
Probably the weirdest thing of all, however, is that if I selectively comment just the loadFromFile() bit:
#include <iostream>
#include <SFML/Graphics.hpp>
#include <SFML/Graphics/Font.hpp>
#include <SFML/Graphics/Text.hpp>
int main() {
// initialise font
sf::Font ubuntu_r;
/*
if(!ubuntu_r.loadFromFile("Ubuntu-R.ttf")) {
// unable to load font
std::cout << "Cannot load font." << std::endl;
}
*/
// initialise text
sf::Text text;
text.setFont(ubuntu_r);
text.setString("Hello, world!");
text.setCharacterSize(50);
text.setColor(sf::Color(0x555555ff));
// initialise window
sf::RenderWindow win(sf::VideoMode(800,600),"Hello, world!");
// main loop
while(win.isOpen()) {
// check for closure
sf::Event e;
while(win.pollEvent(e)) {
if(e.type == sf::Event::Closed) {
win.close();
}
}
// draw text to screen
win.clear(sf::Color::White);
//win.draw(text);
win.display();
}
return 0;
}
this program compiles, runs with a white screen as before, but gives a segfault on close!
$ g++ -c text.cpp
$ g++ text.o -o text -lsfml-window -lsfml-system -lsfml-graphics
$ ./text
(I click close on the window)
Segmentation fault (core dumped)
What on earth is going on? Clearly the sf::Font isn't a problem as it compiles and runs fine with everything except loadFromFile().
I'm unsure about the segfault, because on this post the problems seem ever so slightly different to my own (it doesn't occur every time, for example). My initial thought is that the segfault is caused by the program trying to draw with an undefined font, but shouldn't that result in a runtime error as soon as the program is launched, and not only on closing the window?
Also, could this be related to this problem? My error message looks pretty different.
I'm using Ubuntu 16.04, compiling with gcc in terminal and writing the code in jEdit.
Related
I am trying to embed the gnuplot window into my application using the socket/plug concept in gtkmm 3 library. I have followed the example in the official page here and everything works as expected.
Then I moved to embedding gnuplot window. I modified the socket.cpp as follows:
#include <iostream>
#include <fstream>
#include <gtkmm.h>
#include <gtkmm/socket.h>
using namespace std;
class MySocketWindow : public Gtk::Window
{
public:
MySocketWindow()
{
auto socket = Gtk::manage(new Gtk::Socket());
add(*socket);
cout << "Socket id is: " << hex << socket->get_id() << endl;
show_all();
}
};
int main(int argc, char** argv)
{
auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example.socket");
MySocketWindow win;
app->run(win);
return 0;
}
I compile/build the code with:
g++ --std=c++11 socket.cpp -o socket `pkg-config gtkmm-3.0 --cflags --libs`
And run it. A black socket window appears with Socket id is 3e0000b message printed on the terminal.
.\socket
Then I run gnuplot in x11 terminal with the corresponding window id above:
Now when I plot sin(x) in gnuplot, I am expecting the socket window to show the plot, but nothing happens. What I am doing wrong here?
I am running Ubuntu 16.04, 64-bit.
I found the cause of the problem on gnuplot's site - see my original question. Now it's left to find how to fix it on the socket's site.
So, I'm making a game using SFML in C++, but when I tried adding a image a really weird OpenGL(i think) error popped up. Doesn't make any sense at all.
First my console was spammed with random text and symbols, then the application crashed and visual studio told me this :
Exception thrown at 0x618EDBF4 (vcruntime140.dll) in SFML_Game.exe: 0xC0000005: Access violation reading location 0x00C54000.
It sounds like it has something to do with not being able to read my picture file I added, though i don't know whats wring with it.
The location of the image is in the same folder my "SFML_Game.vcxproj" is.
I also have no chance of seeing if "Could not load player image" was printed in console since the spam is too quick.
Edit I can see that the picture failed to load now, here's a picture... :
Console Picture
Here's my current code :
#include<iostream>
#include<SFML/Graphics.hpp>
#include <string>
int main(int argc, char* argv[])
{
// Creates a window
sf::RenderWindow Window(sf::VideoMode(800, 600), "SFML Game Engine");
sf::Texture pTexture;
sf::Sprite playerImage;
if (!pTexture.loadFromFile("Player.png"))
{
std::cout << "Could not load player image" << std::endl;
}
playerImage.setTexture(pTexture);
while (Window.isOpen())
{
sf::Event Event;
while (Window.pollEvent(Event) && Window.hasFocus())
{
switch (Event.type)
{
case sf::Event::Closed:
Window.close();
break;
}
}
Window.draw(playerImage);
Window.display();
}
}
So, it seems that my code was fine and it was a linker error.
I didn't know the difference between static-dynamic, static and dynamic libraries, so I just put them all in there, after removing some of them it started working.
At least in debugging mode.
Pretty much, if someone else has this problem, look up how to set SFML up on their website instead of a video tutorial. ^^
hy,
I found out, that gtkmm is delaying the output I wrote to std::cerr/std::cout until the Gtk::Window is closed.
But after a bit of researching I found out, that this is not always true. For example, if I add a Button to the Window, and I show the button, outputs on STDOUT and STDERR are working as exepcted.
To test this, I have written an MWE: (If you uncomment the line _button.show();, you would see, that output is not delayed. But if you don't show the button, the output is delayed, until the window is closed.)
Also I have addedd a ofstream, which outputs the contents in both cases directly to /tmp/test.
#include <gtkmm/window.h>
#include <gtkmm/button.h>
#include <gtkmm/application.h>
#include <fstream>
#include <iostream>
class window_t : public Gtk::Window {
public:
window_t(void);
private:
Gtk::Button _button;
};
window_t::window_t(void): _button("Click ME") {
add(_button);
//_button.show();
std::cerr << "construct-cerr" << std::endl;
std::cout << "construct-cout" << std::endl;
std::cout.flush();
std::cerr.flush();
std::ofstream file("/tmp/test");
file << "construct-file" << std::endl;
file.close();
}
int main(int argc, char* argv[]) {
auto app = Gtk::Application::create(argc, argv, "com.example.test");
window_t gtkmm_window;
return app->run(gtkmm_window);
}
You can compile this code by:
g++ main.cpp -o main `pkg-config --cflags --libs gtkmm-3.0` -Wall -pedantic -Wextra -Werror -Wcast-qual -Wcast-align -Wconversion -fdiagnostics-color=auto -g -O2 -std=c++11
Why does gtkmm delay outputs to STD(OUT|ERR) and how can I prevent this?
I am using gcc version 4.9.2 and gtkmm 3.14.
I am trying to output an image onto the screen using SFML 2.1, C++, and MS Visual Studio Professional 2013. I am getting an unexpected error when trying to load a file into a texture. It outputs a whole bunch of random characters. I'm sure if its how I configured the SFML library with Visual Studio or a problem with the code. Can anyone solve this problem? Thanks.
Here is a screenshot of what it looks like when I run the program (http://i.stack.imgur.com/uMdLT.png):
This is my code:
#include <SFML/Graphics.hpp>
#include <iostream>
#include <string>
using namespace std;
int main() {
sf::RenderWindow window;
window.create(sf::VideoMode(800, 600), "My First SFML Game!"); // initializing
sf::Texture jetTexture;
sf::Sprite jetImage;
// Getting Error here!
if (!jetTexture.loadFromFile("fighter jet.png"))
throw std::runtime_error("Could not load fighter jet.png");
jetImage.setTexture(jetTexture);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.draw(jetImage);
window.display();
}
return 0;
}
For all configuration properties, they look like this:
Linker -> General (http://i.stack.imgur.com/NZg7P.png):
Linker -> Input (http://i.stack.imgur.com/1tPaB.png):
**Please note that if I did not configured the SFML library as I did, then I would be getting an error from my system saying msvcr110d.dll is missing.
Ok I managed to fix this, here is what you need to do:
Set your SUBSYSTEM to WINDOWS:
Add "sfml-main.lib" to your libraries:
Change your Runtime library to /MD. This is because you're not using the debug versions of the SFML 2.1 libraries (and probably can't in VS2013).
Make sure your "fighter jet.png" image is in the right place. By default Visual Studio uses the Project Directory as the working directory. So put the png in the same folder as your vcxproj file.
Are you sure that the picture is in the execution directory of your program ?
You should avoid spaces in file's name (fighter_jet.png).
If you're not sure about execution directory, try with absolute path (to be sure it's a path problem, and not a picture's problem).
I hope it helps.
I've tried this code on my system (Xcode - OSX), with one of my picture, and it works.
Have you tried with another picture ?
#include <SFML/Graphics.hpp>
#include <iostream>
#include <string>
using namespace std;
int main() {
sf::RenderWindow window;
window.create(sf::VideoMode(800, 600), "My First SFML Game!"); // initializing
sf::Texture jetTexture;
sf::Sprite jetImage;
// Getting Error here!
if (!jetTexture.loadFromFile("fighter jet.png"))
throw std::runtime_error("Could not load fighter jet.png");
jetImage.setTexture(jetTexture);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.draw(jetImage);
window.display();
}
return 0;
}
I'm fairly new to C++ but this thing has me baffled by any logic. My code is as follows:
#include "stdlib.h"
#include "syslog.h"
#include "unistd.h"
#include "sys/stat.h"
#include "X11/Xlib.h"
#include "cstdio"
void process();
void startTracker();
Display *display;
Window rootWindow;
XEvent xevent;
I have the Xlib header included and if I click on member functions in Eclipse it navigates to the definitions.
int main(int argc, char *argv[])
{
// set logging up
openlog("unison", LOG_CONS|LOG_PID|LOG_NDELAY, LOG_LOCAL1);
syslog(LOG_NOTICE, "Starting Unison Handler");
pid_t pid, sid;
pid = fork();
// fork failed
if (pid < 0) {
exit(EXIT_FAILURE);
}
if (pid > 0) {
exit(EXIT_SUCCESS);
}
umask(0);
sid = setsid();
if (sid < 0) {
exit(EXIT_FAILURE);
}
if (chdir("/") < 0) {
exit(EXIT_FAILURE);
}
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
startTracker();
while (true) {
process();
}
closelog();
return(EXIT_SUCCESS);
}
Then I assign the variables for input selection
void startTracker() {
display = XOpenDisplay(0);
rootWindow = XRootWindow(display, 0);
XSelectInput(display, rootWindow, PointerMotionMask);
}
void process()
{
...but when i add the &event here...
XNextEvent(display, &xevent);
switch (xevent.type) {
case MotionNotify:
syslog(
LOG_NOTICE,
"Mouse position is %dx%d",
xevent.xmotion.x_root, xevent.xmotion.y_root
);
}
}
...the whole thing falls apart.
For some reason passing the xevent as reference throws off the entire Xlib header and gives me this:
00:16:15 **** Incremental Build of configuration Debug for project unisond ****
make all
Building file: ../unisond.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"unisond.d" -MT"unisond.d" -o "unisond.o" "../unisond.cpp"
Finished building: ../unisond.cpp
Building target: unisond
Invoking: GCC C++ Linker
g++ -o "unisond" ./unisond.o
./unisond.o: In function `startTracker()':
/home/ancarius/workspace/unisond/Debug/../unisond.cpp:97: undefined reference to `XOpenDisplay'
/home/ancarius/workspace/unisond/Debug/../unisond.cpp:98: undefined reference to `XRootWindow'
/home/ancarius/workspace/unisond/Debug/../unisond.cpp:99: undefined reference to `XSelectInput'
./unisond.o: In function `process()':
/home/ancarius/workspace/unisond/Debug/../unisond.cpp:105: undefined reference to `XNextEvent'
collect2: error: ld returned 1 exit status
make: *** [unisond] Error 1
00:16:15 Build Finished (took 159ms)
At the risk of getting downvoted could someone please explain what I've done wrong? I've tried everything I could think of but no luck.
It looks like you are missing the X11 library for linking.
add -lX11 to the g++ invocation.
This provides the steps required.
Right click on Project Folder> Properties> C/C++ Build > Settings > GCC C++ Linker > Libraries > add "X11"