sf::RenderWindow::getPosition() always returns 0, 0 instead of the correct position when I call it from the same scope in which the window is created.
Here's the example code that reproduces the issue:
#include <iostream>
#include <memory>
#include <SFML/Graphics.hpp>
int main() {
std::unique_ptr<sf::RenderWindow> window_;
window_ = std::unique_ptr<sf::RenderWindow>(
new sf::RenderWindow(sf::VideoMode(800, 600), "asd", sf::Style::Default)
);
window_->setFramerateLimit(30);
window_->setVerticalSyncEnabled(false);
while (window_->isOpen()) {
sf::Event evt;
while (window_->pollEvent(evt)) {
if (evt.type == sf::Event::Closed) { window_->close(); }
}
window_->clear();
window_->display();
}
const sf::Vector2i wpos = window_->getPosition();
std::cout << "window position: " << wpos.x << "/" << wpos.y <<std::endl;
return 0;
}
The thing is: I have for example a class MainMenu to which I pass a sf::RenderWindow * (with window_.get()).
When I call window_->getPosition() from MainMenu it reports the correct position, so getPosition() itself is not faulty. It's only wrong when I call it from within the same scope (in main).
I'm using SFML 2.3.1 by the way
You are printing the window position after a loop on while (window_->isOpen()). This means the window is closed, i.e. it does not exist when you call getPosition(). Therefore it is no surprise that the window position is not reported "correctly," because the window has already been closed (permanently, so it has no position).
Related
So I was checking the files for my C++ game, and I see the .exe file already created. I coded a bit to see if it works, and when I debugged it, it said the .exe file was not found. And indeed it was not there. Did I do something wrong? Here is the code
#include <iostream>
#include <SFMl\Graphics.hpp>
using namespace sf;
int main()
{
RenderWindow window(VideoMode(320, 480), "The Game!");
while (window.isOpen())
{
Event e;
while (window.pollEvent(e))
{
if (e.type == Event::Closed)
window.close();
}
window.clear(Color::White);
window.display();
}
return 0;
}
I tested your snippet and it worked fine.
Try to turn off your antivirus software, or test it on other devices.
This is a Juce project. It should show an .exe gui.
It showed " filenook.exe has triggered a breakpoint." after "start debugging"
in this line
jassert (success);
Download Juce framework here:
https://juce.com/get-juce/download
Whole project link:
https://drive.google.com/drive/folders/1kxjIKCZqfALBe_Fpa9-WJSoXiN6JJe2t?usp=sharing
PluginEditor.h
#pragma once
#include<iostream>
#include "../JuceLibraryCode/JuceHeader.h"
#include "PluginProcessor.h"
using namespace std;
class FilebookAudioProcessorEditor : public AudioProcessorEditor
{
public:
FilebookAudioProcessorEditor (FilebookAudioProcessor&);
~FilebookAudioProcessorEditor();
//==============================================================================
void paint (Graphics&) override;
void resized() override;
private:
// This reference is provided as a quick way for your editor to
// access the processor object that created it.
FilebookAudioProcessor& processor;
TextEditor* text;
File myFile;
void openFileInEditor();
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilebookAudioProcessorEditor)
};
PluginEditor.cpp
#include "PluginProcessor.h"
#include "PluginEditor.h"
#include<iostream>
using namespace std;
void FilebookAudioProcessorEditor::openFileInEditor()
{
if (myFile.existsAsFile()) {
text->setText(myFile.loadFileAsString());
}
}
//==============================================================================
FilebookAudioProcessorEditor::FilebookAudioProcessorEditor (FilebookAudioProcessor& p)
: AudioProcessorEditor (&p), processor (p)
{
setSize (400, 300);
text = new TextEditor ("Editor");
addAndMakeVisible (text);
text->setMultiLine (true);
text->setReturnKeyStartsNewLine (true);
myFile = ("C:\\filetest.txt");
openFileInEditor ();
}
FilebookAudioProcessorEditor::~FilebookAudioProcessorEditor()
{
deleteAllChildren();
}
//==============================================================================
void FilebookAudioProcessorEditor::paint (Graphics& g)
{
// (Our component is opaque, so we must completely fill the background with a solid colour)
g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
g.setColour (Colours::white);
g.setFont (15.0f);
g.drawFittedText ("Hello World!", getLocalBounds(), Justification::centred, 1);
}
void FilebookAudioProcessorEditor::resized()
{
text->setBounds (10,10,getWidth()-20,getHeight()-20);
}
JUCE is a partially open-source cross-platform C++ application framework, used for the development of desktop and mobile applications. JUCE is used in particular for its GUI and plug-ins libraries.
For almost all of any object I've added so far (sf::Color, sf::Image, sf::Texture, etc.) to the sample code I grabbed from the SFML site, exceptions get thrown once I run it, to the accord of:
Unhandled exception at 0x61C71B86 (sfml-system-2.dll) in gameboiss.exe: 0xC0000005: Access violation reading location 0x00000074.
It's brought up in reference to the RenderWindow line for whatever reason. If I remove all lines referencing these objects, it works fines. Even if I leave only one line creating the variable (i.e. sf::Texture texture), the exception is still thrown. I've tried multiple things amongst looking at the locals/autos at debug and it doesn't seem to give much light.
I'm working on Visual Studio 2012, any help would be appreiciated. Below is the code. thanks :)
#include <iostream>
#include "SFML/Window.hpp"
#include "SFML/Graphics.hpp"
#include "SFML/System.hpp"
int main(){
sf::RenderWindow window(sf::VideoMode(200,200), "game boi");
sf::CircleShape shape(100.f);
//source of error
sf::Texture texture;
texture.loadFromFile("char\\spartapix.png");
/*if(!hero.loadFromFile("char\\spartapix.png")){
std::cerr << "Error: sprite not loaded.\n";
return 1;
}*/
//sf::Image background;
//if (!background.loadFromFile("background.jpg"))
//return -1;
shape.setFillColor(sf::Color::Blue);
sf::Vector2i pos;
while (window.isOpen()){
sf::Event event;
while (window.pollEvent(event)){
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::GainedFocus)
std::cout << "playing";
if (event.type == sf::Event::LostFocus)
std::cout << "notplaying\n";
if (event.type == sf::Event::MouseButtonPressed){
sf::Vector2i pos = sf::Mouse::getPosition(window);
std::cout << pos.x << " " << pos.y << std::endl;
}
if (event.type == sf::Event::KeyPressed){
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)){
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)){
window.close();
}
}
}
window.clear();
window.draw(shape);
window.display();
}
return 0;
}
<code>
I agree with RetiredNinja's comment above: If it happens as soon as you create the render window, it's most likely some STL version difference (from the passed string; since sf::String is part of sfml-system), which is typically the case when you mix up versions (Visual Studio releases or Release/Debug builds).
Are you sure you've picked the correct download from SFML's download page? As an alternative, you could try downloading and compiling SFML from the official repository.
I'm trying to write a C++ wrapper class around some SDL2 classes.
Now I have this working code, which displays a red screen for 5 seconds (as you can see, my wrapper classes are in namespace sdl2cc):
int main(void)
{
if (SDL_Init(SDL_INIT_VIDEO) < 0) return 1;
sdl2cc::Window window{"SDL_RenderClear"s, sdl2cc::Rect{sdl2cc::Point{SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED}, sdl2cc::Dimension{512, 512}}, {}};
sdl2cc::Renderer renderer{window, {}};
renderer.draw_color(sdl2cc::Color{sdl2cc::RGB{255,0,0}, sdl2cc::Alpha{255}});
SDL_RenderClear(renderer.data());
// renderer.clear();
SDL_RenderPresent(renderer.data());
// renderer.present();
SDL_Delay(5000);
SDL_Quit();
}
In the wrapper class of SDL2's SDL_Renderer I have a std::unique_ptr data member renderer_ pointing to an actual SDL_Renderer.
renderer.data() exposes this pointer (return this->renderer_.get();).
I want to get the member functions renderer.clear() and renderer.present() to work. Sadly neither do. This is how they look:
void sdl2cc::Renderer::clear(void)
{
if (SDL_RenderClear(this->data()) < 0)
{
std::cerr << "Couldn't clear rendering target with drawing color:" << ' ' << SDL_GetError() << '\n';
}
}
void sdl2cc::Renderer::present(void)
{
SDL_RenderPresent(this->data());
}
If I just use renderer.clear(), it will print my error message + Invalid renderer.
If I just use renderer.present(), it will show a black screen.
What is wrong?
Why are my own functions and the SDL functions not equivalent?
The problem seems to lie in the function call:
SDL_RenderClear(renderer.data()); // works
// somewhere else:
void sdl2cc::Renderer::clear(SDL_Renderer* r)
{
if (SDL_RenderClear(r) < 0)
{
std::cerr << "Couldn't clear rendering target with drawing color:" << ' ' << SDL_GetError() << '\n';
}
}
renderer.clear(renderer.data()); // doesn't work: Invalid Renderer
But I still don't understand where the problem lies. To me it seems to accomplish the same thing, but somehow one throws an error, the other doesn't.
EDIT:
Another interesting thing, trying to step in at renderer.clear() with lldb goes directly to the next line, without actually stepping in... I don't even.
The problem had to do with multiply linked libraries.
I compiled my own library with the SDL2 libraries and then compiled my executable with my library and the SDL2 libraries.
This question already has answers here:
static variable link error [duplicate]
(2 answers)
Closed 8 years ago.
I have no idea why this code isn't working. All the source files compile but when I try to link them the compiler yells at me with an undefined reference error. Here's the code:
main.cpp:
#include "SDL/SDL.h"
#include "Initilize.cpp"
int main(int argc, char* args[])
{
//Keeps the program looping
bool quit = false;
SDL_Event exit;
//Initilizes, checks for errors
if(Initilize::Start() == -1)
{
SDL_Quit();
}
//main program loop
while(quit == false)
{
//checks for events
while(SDL_PollEvent(&exit))
{
//checks for type of event;
switch(exit.type)
{
case SDL_QUIT:
quit = true;
break;
}
}
}
return 0;
}
Initilize.h:
#ifndef INITILIZE_H
#define INITILIZE_H
#include "SDL/SDL.h"
/* Declares surface screen, its attributes, and Start(); */
class Initilize {
protected:
static SDL_Surface* screen;
private:
static int SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP;
public:
static int Start();
};
#endif
Initilize.cpp:
#include "Initilize.h"
#include "SDL/SDL.h"
/* Initilizes SDL subsystems, sets the screen, and checks for errors */
int Initilize::Start()
{
//screen attributes
SCREEN_WIDTH = 640;
SCREEN_HEIGHT = 480;
//Bits per pixel
SCREEN_BPP = 32;
//Inits all subsystems, if there's an error, return 1
if(SDL_Init(SDL_INIT_EVERYTHING) == -1) {
return 1;
}
//sets screen
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
//Returns 1 if there was in error with setting the screen
if(screen == NULL) {
return 1;
}
SDL_WM_SetCaption("Game", NULL);
return 0;
}
Sorry if the code was formatted weirdly, inserting four spaces to put in a code block messed things up a little bit.
Add the following to your cpp file:
SDL_Surface* Initilize::screen = 0; // or nullptr
int Initilize::SCREEN_WIDTH = 640;
int Initilize::SCREEN_HEIGHT = 480;
int Initilize::SCREEN_BPP = 32;
Also, if these value never change, it would be good to make them const. The reason you need to add the above to your cpp file is because static member variables need to be defined outside of the class. static SDL_Surface* screen;, etc. inside your class is only a declaration, and not a definition. static members are considered special and is very similar to a global variable.
The reason for this is because static members are shared between all instances of your class. This means they can only be defined once and allowing the definition inside the class would cause multiple definitions to occur, so the C++ standard forces you to define it outside of your class (and also implies you should put the definition in a cpp file).
in Initialize.cpp do
#include "Initialize.h"
#include "SDL/SDL.h"
// this is the new line to insert
SDL_Surface* Initialize::screen = 0;
int Initialize::SCREEN_WIDTH=...; // whatever you want to set it to
int Initialize::SCREEN_HEIGHT=...; // whatever you want to set it to
int Initialize::SCREEN_BPP=...; // whatever you want to set it to
and remove the #include "Initialize.cpp" line in main.cpp
instead do
#include "Initialize.hpp"
if you're using gcc, compile using
g++ -o <output-file> main.cpp Initialize.cpp <include flags like -I> <lib flags like -L>
It appears that you never initialized your vairables. You are assigning them in the Initialize start method but didn't initialize them. Try adding in a int SCREENWIDTH; before you assign it in the source not just header file