C++ SFML Draw to other window - c++

I know how to draw text to window created with sf::RenderWindow(); but I need to draw text to already existing game window. It makes it go black, I don't want to erase whole window, just update text on it. Code:
#include <SFML/Graphics.hpp>
#include <SFML/Graphics/Font.hpp>
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
HWND hWindow = FindWindow(0, "Counter-Strike: Global Offensive");
if(!hWindow) exit(0);
else
{
int i=0;
string tmp, str;
sf::RenderWindow window(hWindow);
sf::Font font;
if(!font.loadFromFile("verdana.ttf"))
{
cout << "error";
}
sf::Text text;
text.setFont(font);
text.setCharacterSize(17);
text.setColor(sf::Color::White);
while (window.isOpen())
{
i++;
itoa(i, (char*)tmp.c_str(), 10);
str = tmp.c_str();
text.setString(str);
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
Sleep(1000);
window.clear(sf::Color::Transparent);
window.draw(text);
window.display();
}
return 0;
}
}
Please help me do it :)

I think it won't be as easy as you might thought.
Every program I know which can manipulate the backbuffer of a game hooks the API calls. That isn't very difficult. There are some good librarys out there for this. But the real problem is that nearly every game use DirectX.
SFML use OpenGL. I don't think they can be mixed.
You should use Direct2D or another drawing libary based on DirectX.
There are even tutorials out there which explains how to code a overlay. Just use Google.

Related

Can't load image with SFML

Am trying to load an image with SFML using Xcode, but everytime I run the program, the window (which has been created using the code) flashes and disappears...
Here's the code I am using:
#include <SFML/Graphics.hpp>
#include <iostream>
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 1024
int main()
{
sf::RenderWindow window(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT), "Orsome Game");
while(window.isOpen())
{
sf::Event e;
while(window.pollEvent(e))
{
switch (e.type)
{
case sf::Event::Closed:
window.close();
break;
}
}
sf::Image image;
if(!image.loadFromFile("sprite.png")){
return -1;
}
window.clear(sf::Color(255,255,255));
window.display();
}
return EXIT_SUCCESS;
}
Have also put the image file where the c++ file is, but it still doesn't work!
I would put an sf::Style::Default in the RenderWindow arguments, straight after "Orsome Game" window name. Because you are using the pollEvent, that would allow you to exit the window by pressing the x button in the top right corner, like a default application layout.
Is the picture in the same directory as your solution file? Or your main.cpp?
It should be, of course.
And, maybe, try loading your image with Texture and Sprite, like this:
sf::Texture texture;
texture.loadFromFile("picturename.png");
sf::Sprite sprite;
sprite.setTexture(texture);
inside the while window is open loop.
To draw it:
// after window.clear() ...
//... your code
window.draw(sprite);
//... other things to draw
// and then, your window.display();
But, probably, your sf::Image should also work. Tell me how it goes
EDIT:
Try this code and see if the window opens.
Otherwise, that might be the problem of setting up the SFML on your computer and you will have to find some good tutorial on how to set it up properly! But let's see:
#include <SFML/Graphics.hpp>
#include <iostream>
using namespace sf;
int main()
{
RenderWindow window(VideoMode(640, 640), "Test", Style::Default);
while (window.isOpen()) {
Event _event;
while (window.pollEvent(_event)) {
switch (_event.type) {
case Event::Closed:
window.close();
break;
}
}
window.clear();
// draw
// ...
window.display();
}
return 0;
}

Launching a new window in SFML (C++)

This semester we have to make a game in C++. As a junior in game development in C++ I choosed SFML for graphics (Is that a good choice ? ). All started well, I made my menu and my button and so on. But when I click on this button my window is just closed. And I want to lauch a new window. Anyone can help me ?
Thanks.
#include <iostream>
#include <SFML/Graphics.hpp>
#include "Button.h"
#include "game.h"
using namespace std;
int main() {
sf::RenderWindow window;
sf::Color Color;
sf::Vector2i centerWindow((sf::VideoMode::getDesktopMode().width / 2) - 445, (sf::VideoMode::getDesktopMode().height / 2) - 480);
window.create(sf::VideoMode(900, 900), "SFML Textbox", sf::Style::Titlebar | sf::Style::Close);
window.setPosition(centerWindow);
window.setKeyRepeatEnabled(true);
sf::Font font;
if (!font.loadFromFile("font.ttf"))
std::cout << "Font not found!\n";
//Création de l'image
sf::Texture texture[1];
texture[0].loadFromFile("logo.jpg");
sf::RectangleShape rectangle;
sf::Sprite sprite[1];
rectangle.setSize(sf::Vector2f(750,182));
sprite[0].setTexture(texture[0]);
sprite[0].setPosition(100,50);
//Création du texte
sf::Text text;
text.setFont(font);
text.setCharacterSize(20);
text.setColor(sf::Color(200,0,0));
text.setString("~Made by Théo Manea - 2019/2020 Paris-Sud University~");
text.setStyle(sf::Text::Bold);
text.setPosition(300,850);
//Création du bouton
Button btn1("Jouer", { 200, 100 }, 30, sf::Color::Green, sf::Color::White);
btn1.setFont(font);
btn1.setPosition({ 350, 300 });
//Main Loop:
while (window.isOpen()) {
sf::Event Event;
//Event Loop:
while (window.pollEvent(Event)) {
switch (Event.type) {
case sf::Event::Closed:
window.close();
case sf::Event::MouseMoved:
if (btn1.isMouseOver(window)) {
btn1.setBackColor(sf::Color(200,0,0));
}
else {
btn1.setBackColor(sf::Color(6,164,154));
}
break;
case sf::Event::MouseButtonPressed:
if (btn1.isMouseOver(window)) {
Squadro squadro;
window.close();
}
}
}
window.clear(sf::Color::White);
btn1.drawTo(window);
window.draw(rectangle);
window.draw(sprite[0]);
window.draw(text);
window.display();
}
}
And my game.h :
'''
#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED
#include <iostream>
#include <SFML/Graphics.hpp>
using namespace std;
class Squadro{
private:
public:
void Test();
void MainFunctions();
};
void Squadro::Test()
{
cout << "okkkkkkkkkkkkkkkkkkkk" << endl;
}
void Squadro::MainFunctions()
{
sf::Window window(sf::VideoMode(800, 600), "My window");
// run the program as long as the window is open
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
sf::Event event;
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
}
}
}
#endif // GAME_H_INCLUDED
'''
N.B : I know it's maybe a dumbie question but I need help ! Thanks :D
In general, SFML can be an as good choice for graphics library as can be SDL, Allegro, etc. you just have to use it right (yes, that's the hard part, I know. :)) But that's really subjective, so off-topic here. Let's get to your issue…
The problem is this part:
if (btn1.isMouseOver(window)) { // This is true, if the cursor is over the button
Squadro squadro; // Here you create an object of the other class that shows its own window
window.close(); // now you close the "main" window
} // once you reach this line, "squadro" is destroyed as well, since we're leaving the scope ({...}) it's defined in.
Can this be fixed? Of course. All you have to do is ensure that your Squadro object doesn't get destroyed immediately (plus the outer program code has to ensure it keeps running/updating the Squadro code as well. This can get a bit tricky, so in general I'd recommend sticking to one window only.
Here's the structure I'd use:
For your simple game you should first of all look into two basic concepts:
Main Loop: Have your program run within one main loop (i.e. "while the window is open and the game is running, repeat this"), within which you first process events (such as mouse movement or keyboard presses) and then you update your game and finally draw it.
Finite State Machine: Which allows your game to have different screens or states (but it can also be used for more basic elements such as buttons, enemies, objects, levels, etc.).
A website (and book!) I'd absolutely recommend is Game Programming Patterns. It might be a bit tricky to understand everything at once as a starter, but this website will explain you most important concepts that can make developing your game (of any scale) significantly easier. Just keep in mind the best or most complex approach might be overkill based on the scope and size of your game.
If you want to know more about finite state machines, definitely have a look at their section about it.
Without going too much into details, here's a basic template for a main Game class one might use with SFML (code is simplified/condensed; this is basically what you have already:
class Game {
private:
sf::RenderWindow mWindow;
public:
Game() {
mWindow.create({640, 480}, "My Game");
// Other initialization code
}
~Game() {
// Code to shutdown the game
}
// This is your main game loop
int run() {
while (mWindow.isOpen()) {
handleEvents();
updateGame();
drawGame();
}
return 0;
}
private:
handleEvents() {
// Event handling as you do already
}
updateGame() {
// Update the game
}
drawGame() {
// Draw the game
}
}
In your program's main() you now just have to create an object of the Game class and tell it to run:
int main(int argc, char **argv) {
Game myGame;
return myGame.run();
}
Now to the actual finite state machine. There are many different approaches to this, but the most basic one is just using one variable and an enumeration to identify the current state of the game. Add both to the class:
```cpp
enum GameState {
TitleScreen = 0,
MainGame,
GameOver
} mCurrentState;```
When initializing the game, you set a default state:
```cpp
mCurrentState = TitleScreen;
And now, if you want to switch to a different screen, all you have to do is update this variable, e.g. when the player clicks on a "Start" button:
mCurrentState = MainGame;
The three functions from your main loop, handling events, updating the game, and drawing everything, can then use this variable to determine what to do:
drawGame() {
switch (mCurrentState) {
case TitleScreen:
// Draw the title screen here
break;
case MainGame:
// Draw the actual game here
break;
case GameOver:
// Draw the game over screen here
break;
}
}
In a very similar way, you can give your button it's own internal state as well:
enum ButtonState {
Idle = 0,
Hovered,
Pushed
} mCurrentState;```

Trouble condensing code in C++ - SFML

This is probably going to sound like a stupid question...
I have this piece of code in C++, that uses the SFML library:
#include <SFML/Graphics.hpp>
#include <string>
void textDisplay(sf::Text& display_text, std::string display_str, sf::Font display_font, int char_size) {
display_text.setString(display_str);
display_text.setFont(display_font);
display_text.setCharacterSize(char_size);
display_text.setStyle(sf::Text::Regular);
}
int main() {
sf::RenderWindow window(sf::VideoMode(400, 400), "Game");
sf::Font arial;
if (!arial.loadFromFile("fonts/arial/arial.ttf")) {
return 0;
}
sf::Text text;
textDisplay(text, "Hello, World!", arial, 30);
sf::CircleShape shape(100.f, 10);
shape.setFillColor(sf::Color::Yellow);
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
}
}
window.clear();
window.draw(text);
window.display();
}
return 0;
}
Because I'm going to repeat the same four lines of code over and over when I'm trying to display the text onto an SFML screen, rather than repeating the code, I created a function (textDisplay) that takes in four arguments (the Text object itself, a string, a font, and the character size) and initializes the Text object for me.
For some reason, the text doesn't display - is there anything I'm doing wrong?
Some stuff:
The window is called window.
There's no error when compiled, so I have no idea where the error is.
The board itself is just black, there's no text on window.
If the error has to do with the function itself, can you recommend an alternative to typing the same four lines over and over again?
Found it, you were setting your text with a temporary font, since its a normal variable and not a reference/pointer:
void textDisplay(sf::Text& display_text, std::string display_str, sf::Font& display_font, int char_size) { //Just make it a reference and its done! :)
display_text.setString(display_str);
display_text.setFont(display_font);
display_text.setCharacterSize(char_size);
display_text.setStyle(sf::Text::Regular);
}

C++ SFML library code not working for drawing a text

I am feeling really frustrated with draw() not working in my SFML project. My compiler gives off no errors, my eyes doesn't catch a thing that's off (as a reference I am using official tutorial). The problem is that when window load it doesn't draw a thing. It just stays a white window without any text in it.
Where could be the problem?
#include <SFML/Graphics.hpp>
int main() {
sf::RenderWindow window(sf::VideoMode(800,600), "Trying to make a game");
sf::Font font;
if (!font.loadFromFile("arial.ttf"))
{
//error
}
sf::Text text;
text.setFont(font);
text.setString("Hello, World!");
text.setCharacterSize(50);
text.setColor(sf::Color::Red);
text.setPosition(10, 50);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
}
window.clear();
window.draw(text);
window.display();
return 0;
}
You're closing the window before drawing the text...

SFML textEntered not working properly

so today I started looking into SFML and I found it quite interesting so decided to learn how to play with it, but I am already hitting some problems, I am trying to use textEntered event, but it is not working properly, it shows complete nonsense and text writes itself even without me pressing any key. Heres link
Code
#include <SFML/Graphics.hpp>
#include <iostream>
int main()
{
sf::RenderWindow window(sf::VideoMode(400, 400), "SFML works!");
std::string display;
sf::Font font;
font.loadFromFile("arial.ttf");
sf::Text text;
text.setFont(font);
text.setCharacterSize(30);
text.setStyle(sf::Text::Bold);
text.setColor(sf::Color::Red);
text.setPosition(50, 50);
while (window.isOpen())
{
sf::Event Revent;
while (window.pollEvent(Revent))
{
if (sf::Event::TextEntered)
{
std::cout << static_cast<char>(Revent.text.unicode);
//text.setString(display);
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
{
window.close();
}
window.clear();
//window.draw(text);
window.display();
}
return 0;
}
You wrote if (sf::Event::TextEntered), which evaluates to true (since it's not equal to 0).
You probably meant
if (Revent.type == sf::Event::TextEntered).
Using Revent.text is undefined behavior in this case (when you're not sure what type of event Revent contains) because sf::Event is an union, so only one of its members is usable at a time. You can read more about SFML events here.