Pass callback function with custom arguments to glfwSetKeyCallback()? - c++

I have a GLWindow class which is a wrapper for OpenGL. This class declares data types enum class that are the arguments of the callback function:
enum class Modifier
{
NoModifier = 0,
Shift = 1,
Control = 2,
Alt = 4,
Super = 8,
};
enum class Action
{
Release = 0,
Press = 1,
Repeat = 2,
};
enum class ButtonCode
{
Button_0 = 0,
//... repeats all buttons codes from the glfw header
};
enum class KeyCode
{
UNKNOWN = -1,
Space = 32,
//.... repeats all key codes from the glfw header
};
Pointers to be passed to glfwSetKeyCallback as second parameter to std::function:
using KeyCallback = std::function<void(GLFWwindow* window, int key, int scancode, int action, int mode)>;
using CursorPosCallback = std::function<void(double, double)>;
using MouseCallback = std::function<void(ButtonCode, Action, Modifier, double, double)>;
using ScrollCallback = std::function<void(double, double)>;
On assignment, I have to declare a callback function in Main.cpp and through the GLWindow class pass a pointer to this function to glfwSetKeyCallback as the second parameter
Main.cpp:
void onKeyCallback(KeyCode key, Action action, Modifier mods)
{
std::cout << "Key: " << glfwGetKeyName(key, 0) << " is pressed." << std::endl;
}
int main()
{
...
GLWindow window("myWindow", 640, 480);
window.setKeyCallback(onKeyCallback);
...
}
And GLWindow.cpp:
void GLWindow::setKeyCallback(const KeyCallback& callback)
{
glfwSetKeyCallback(handle, ?????????);
}
Just in case, I provide the complete program code:
Window.h:
#include <glad/glad.h>
#include <glfw\glfw3.h>
#include <functional>
#include <string>
#include <iostream>
enum class Modifier
{
NoModifier = 0,
Shift = 1,
Control = 2,
Alt = 4,
Super = 8,
};
enum class Action
{
Release = 0,
Press = 1,
Repeat = 2,
};
enum class ButtonCode
{
Button_0 = 0,
//... repeats all buttons codes from the glfw header
};
enum class KeyCode
{
UNKNOWN = -1,
Space = 32,
//.... repeats all key codes from the glfw header
};
class GLWindow
{
public:
using KeyCallback = std::function<void(GLFWwindow* window, int key, int scancode, int action, int mode)>;
using CursorPosCallback = std::function<void(double, double)>;
using MouseCallback = std::function<void(ButtonCode, Action, Modifier, double, double)>;
using ScrollCallback = std::function<void(double, double)>;
GLWindow(const std::string& title, uint32_t width, uint32_t height);
~GLWindow();
uint32_t getWidth() const;
uint32_t getHeight() const;
void setKeyCallback(const KeyCallback& callback);
void setCursorPosCallback(const CursorPosCallback& callback);
void setMouseCallback(const MouseCallback& callback);
void setScrollCallback(const ScrollCallback& callback);
GLFWwindow* getGLFWHandle() const;
private:
GLFWwindow* handle;
// TODO
};
Window.cpp:
#include <glfw\glfw3.h>
#include "GLWindow.h"
GLWindow::GLWindow(const std::string& title, uint32_t width, uint32_t height)
{
handle = glfwCreateWindow(width, height, title.data(), nullptr, nullptr);
glfwMakeContextCurrent(handle);
static bool initGLAD = false;
if (!initGLAD)
{
initGLAD = true;
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
}
glfwSetWindowUserPointer(handle, this);
glfwSetKeyCallback(handle,/* implementation details */);
glfwSetMouseButtonCallback(handle, /* implementation details */);
glfwSetCursorPosCallback(handle, /* implementation details */);
glfwSetScrollCallback(handle, /* implementation details */);
}
GLWindow::~GLWindow()
{
}
uint32_t GLWindow::getWidth() const
{
return uint32_t();
}
uint32_t GLWindow::getHeight() const
{
return uint32_t();
}
void GLWindow::setKeyCallback(const KeyCallback& callback)
{
glfwSetKeyCallback(handle, ?????????);
}
void GLWindow::setCursorPosCallback(const CursorPosCallback& callback)
{
}
void GLWindow::setMouseCallback(const MouseCallback& callback)
{
}
void GLWindow::setScrollCallback(const ScrollCallback& callback)
{
}
GLFWwindow* GLWindow::getGLFWHandle() const
{
return nullptr;
}
Main.cpp:
#include <glfw\glfw3.h>
#include "GLWindow.h"
void onKeyCallback(KeyCode key, Action action, Modifier mods)
{
std::cout << "Key: " << glfwGetKeyName(key, 0) << " is pressed." << std::endl;
}
int main()
{
glfwInit();
GLWindow window("myWindow", 640, 480);
window.setKeyCallback(onKeyCallback);
while (glfwWindowShouldClose(window.getGLFWHandle())
{
glfwSwapBuffers(window.getGLFWHandle());
glfwWaitEvents();
}
glfwTerminate();
return 0;
}

Related

glfwCreateWindow() doesnt work out of DLL`s EntryPoint

I have .dll file with my Game Engine and .exe with game.
.exe uses .dll
Both of them use glfw_mt.lib.
In dll There is Window class (Window.cpp,Window.h) where i try to glfwCreateWindow(), but it returns NULL. HOWEVER when i try it in dlls main function (EntryPoint.h) glfwCreateWindow() works fine.
My Window abstractionm fails to create glfw window. I see no reason
EntryPoint.h in dll
#include "Core.h"
#include "Game.h"
#include "Window.h"
#include "glad/glad.h"
#include "GLFW/glfw3.h"
#ifdef NK_PLATFORM_WINDOWS
#define NIKSON_START Nikson::Game* CreateGame(){return
#define NIKSON_END }
extern NIKSON_API Nikson::Game* CreateGame();
static void callback(int error_code, const char* description) {
std::cout << "GLFW ERROR:" << error_code << " " << description << std::endl;
}
int main()
{
LOG("LOADED!");glfwSetErrorCallback(callback);
if (!glfwInit())
{
LOG("GLFW ERROR");
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//GLFWwindow* win = glfwCreateWindow(1000, 1000, "Nikson", NULL, NULL);
// LOG(win)
//
///*if (win==nullptr) {
// LOG("FAILED TO CREATE WINDOW")
// return 0;
//}*/
//glfwMakeContextCurrent(win);
Nikson::Window* win = Nikson::CreateWindow("Nikson",1000,1000);
std::cin.get();
//Nikson::Game * game= CreateGame();
////Nikson::Window* win = new Nikson::Window();
//game->Run();
delete win;
}
#endif
Window.h
#pragma once
#include "Core.h"
#include "glad/glad.h"
#include "GLFW/glfw3.h"
namespace Nikson {
struct WindowProp {
std::string Title;
uint32_t Width;
uint32_t Height;
GLFWwindow* WindowPtr;
};
class NIKSON_API Window
{
public:
Window(GLFWwindow* window, const std::string& title = "Nikson",
uint32_t width = 1600,
uint32_t height = 900);
void Tick();
private:
WindowProp m_Properities;
};
NIKSON_API Nikson::Window* CreateWindow(const std::string& title = "Nikson",
uint32_t width = 1600,
uint32_t height = 900);
}
Window.cpp
#include "Window.h"
namespace Nikson
{
Window::Window(GLFWwindow* window, const std::string& title,
uint32_t width,
uint32_t height)
{
m_Properities.Title = title;
m_Properities.Width=width;
m_Properities.Height=height;
m_Properities.WindowPtr = window;
}
void Window::Tick() {
glfwPollEvents();
}
Nikson::Window* CreateWindow(const std::string& title,
uint32_t width,
uint32_t height)
{
GLFWwindow* win = glfwCreateWindow(1000,1000,"Nikson", NULL, NULL);
if (win == NULL) {
LOG(win)
}
/*if (win==nullptr) {
LOG("FAILED TO CREATE WINDOW")
return 0;
}*/
glfwMakeContextCurrent(win);
return new Nikson::Window(win, title, width, height);
}
}

Access violation while using std::function assigned to a member function using std::bind()

I am making a game engine. I implemented an event system such that my window takes a WindowData struct which has information about creating a window. It has a field named eventCallback which is a placeholder for a callback function which my window will call when an event occurs.
But, when I am trying to assign my placeholder to my callback function in my client code, I am getting an access violation.
The placeholder is std::function, and I am using std::bind().
This is my client code:
#include "JetByte.h"
#include <iostream>
#include <memory>
#include <functional>
class App : public JetByte::Application
{
public:
App();
void OnInit() override;
void OnUpdate() override;
void OnDestroy() override;
bool EventCallback(JetByte::Event& e);
~App();
private:
bool runningFlag;
std::shared_ptr<JetByte::Window> window;
std::shared_ptr<JetByte::GraphicsContext> context;
};
App::App()
{
}
void App::OnInit()
{
try
{
runningFlag = true;
JetByte::WindowData data;
data.title = "My window";
data.eventCallback = std::bind(&App::EventCallback, this, std::placeholders::_1);
window = JetByte::Window::create({ "My Window" });
context = JetByte::GraphicsContext::Create(window);
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}
}
void App::OnUpdate()
{
while (runningFlag)
{
context->Swap();
window->Update();
}
}
void App::OnDestroy()
{
JetByte::EventDispatcher::Stop();
context.reset();
window.reset();
}
bool App::EventCallback(JetByte::Event& e)
{
if (e.GetEventType() == JetByte::EventType::WindowClose)
{
std::cout << "window closed" << std::endl;
runningFlag = false;
}
return true;
}
App::~App()
{
}
JetByte::Application* JetByte::ClientApplicationPortal() {
return new App();
}
And this is my WindowData struct:
struct WindowData {
const char* title = "JetByte Application";
int width = 500;
int height = 500;
bool vsync = true;
std::function<bool(Event&)> eventCallback;
};

unique_ptr incomplete type for forward declaration with default destructor

My question is quite related to this thread:
std::unique_ptr with an incomplete type won't compile
I understood the concept of incomplete type with unique_ptr and need to provide the default destructor for the holding class. However, I'm still getting following error:
invalid use of incomplete type ‘class Game::Sprite’
Following is my simplified code. Please let me know if I'm still missing something here? :
/*
* Game.h
*/
#pragma once
#include <string>
#include <unordered_map>
#include "SDL.h"
class Game {
public:
Game();
~Game();
void run();
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
private:
void setup();
void loadResources();
void createWorld();
void loop();
window mWindow;
renderer mRenderer;
class Sprite;
using sprite = std::unique_ptr<Sprite>;
sprite mPlayer;
struct Resource {
std::string name;
std::string path;
};
enum class ResourceType {
TEXTURE, IMAGE, AUDIO
};
std::unordered_map<ResourceType, Resource> mResourceList;
std::unordered_map<std::string, texture> mTextureHolder;
};
/*
* Game.cpp
*/
#include <Game.h>
...
#include "Sprite.h"
Game::Game() {
...
}
void Game::run() {
setup();
loadResources();
loop();
}
void Game::setup() {
...
}
void Game::loadResources() {
...
}
void Game::createWorld() {
...
}
void Game::loop() {
bool stop = false;
SDL_Event e;
while (!stop) {
while (SDL_PollEvent(&e) != 0) {
if (e.type == SDL_QUIT) {
stop = true;
}
}
//clear screen
SDL_RenderClear(mRenderer.get());
//render texture
// this gives error:
mPlayer->renderFrame(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 0, 0);
//update screen
SDL_RenderPresent(mRenderer.get());
}
}
//default destructor (tried explicit implmentation too)
Game::~Game() = default;
/*
* Sprite.h
*/
#pragm once
#include "SDL.h"
#include <cstdint>
class Sprite {
public:
Sprite(renderer renderer, texture texture, uint32_t width, uint32_t height);
void renderFrame(uint32_t dstX, uint32_t dstY, uint32_t offsetX,
uint32_t offsetY);
void setTexture(texture texture);
private:
renderer mRenderer;
texture mTexture;
uint32_t mWidth;
uint32_t mHeight;
};
/*
* Sprite.cpp
*/
#include "Sprite.h"
Sprite::Sprite(renderer renderer, texture texture, uint32_t width,
uint32_t height) :
mRenderer(renderer), mTexture(std::move(texture)), mWidth(width), mHeight(
height) {
}
void Sprite::renderFrame(uint32_t dstX, uint32_t dstY, uint32_t offsetX,
uint32_t offsetY) {
...
}
void Sprite::setTexture(texture texture) {
...
}

I don't understand how to make buttons in FLTK

#include "std_lib_facilities_4.h"
#include "Window.h"
#include "Graph.h"
#include "GUI.h"
#include <FL/Fl_Image.H>
using namespace Graph_lib;
using namespace std;
struct Lines_window:Graph_lib::Window{
Lines_window(Point xy, int w, int h, const string& title);
Button button_1;
Button button_2;
static void cb_change_color(Address, Address);
static void cb_change_picture(Address, Address);
};
Lines_window::Lines_window(Point xy, int w, int h, const string& title) :
Window(xy, w, h, title),
button_1(Point(x_max()/2, y_max()/2), 200, 100, "Button 1", cb_change_color),
button_2(Point(x_max()/3, y_max()/3), 200, 100, "Button 2", cb_change_picture)
{
attach(button_1);
attach(button_2);
}
void Lines_window::cb_change_color(Address, Address pw)
{
}
void Lines_window::cb_change_picture(Address, Address pw)
{
}
int main()
try {
if(H112 != 201401L)error("Error: incorrect std_lib_facilities_4.h version ", H112);
using namespace Graph_lib;
Lines_window win(Point(100,100),600,400,"Buttons");
return gui_main();
return 0;
}
catch(exception& e) {
cerr << "exception: " << e.what() << '\n';
return 1;
}
catch (...) {
cerr << "Some exception\n";
return 2;
}
This is my button code. I am trying to make two buttons, one that changes color when you press it and another that puts an image on the button when you press it. I haven't made a callback yet because this won't compile. Errors are:
GUI.cpp:16:6: error: prototype for ‘void Graph_lib::Button::attach(Graph_lib::Window&, Fl_Color)’ does not match any in class ‘Graph_lib::Button’
void Button::attach(Window& win, Fl_Color color)
^
In file included from GUI.cpp:10:0:
GUI.h:66:14: error: candidate is: virtual void Graph_lib::Button::attach(Graph_lib::Window&)
void attach(Window&);
^
Do I need callbacks to compile? I am basing this code off of my professor's code here. I took everything out except for the buttons so I could make them. The GUI.cpp and GUI.h were given to us. What am I doing wrong?
GUI.cpp
//
// This is a GUI support code to the chapters 12-16 of the book
// "Programming -- Principles and Practice Using C++" by Bjarne Stroustrup
//
#include <FL/Fl.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Output.H>
#include "GUI.h"
namespace Graph_lib {
//------------------------------------------------------------------------------
void Button::attach(Window& win, Fl_Color color)
{
pw = new Fl_Button(loc.x, loc.y, width, height, label.c_str());
pw->color(BLUE);
pw->callback(reinterpret_cast<Fl_Callback*>(do_it), &win); // pass the window
own = &win;
}
//------------------------------------------------------------------------------
int In_box::get_int()
{
Fl_Input& pi = reference_to<Fl_Input>(pw);
// return atoi(pi.value());
const char* p = pi.value();
if (!isdigit(p[0])) return -999999;
return atoi(p);
}
//------------------------------------------------------------------------------
string In_box::get_string()
{
Fl_Input& pi = reference_to<Fl_Input>(pw);
return string(pi.value());
}
//------------------------------------------------------------------------------
void In_box::attach(Window& win)
{
pw = new Fl_Input(loc.x, loc.y, width, height, label.c_str());
own = &win;
}
//------------------------------------------------------------------------------
void Out_box::put(const string& s)
{
reference_to<Fl_Output>(pw).value(s.c_str());
}
//------------------------------------------------------------------------------
void Out_box::attach(Window& win)
{
pw = new Fl_Output(loc.x, loc.y, width, height, label.c_str());
own = &win;
}
//------------------------------------------------------------------------------
int Menu::attach(Button& b)
{
b.width = width;
b.height = height;
switch(k) {
case horizontal:
b.loc = Point(loc.x+offset,loc.y);
offset+=b.width;
break;
case vertical:
b.loc = Point(loc.x,loc.y+offset);
offset+=b.height;
break;
}
selection.push_back(b); // b is NOT OWNED: pass by reference
return int(selection.size()-1);
}
//------------------------------------------------------------------------------
int Menu::attach(Button* p)
{
Button& b = *p;
b.width = width;
b.height = height;
switch(k) {
case horizontal:
b.loc = Point(loc.x+offset,loc.y);
offset+=b.width;
break;
case vertical:
b.loc = Point(loc.x,loc.y+offset);
offset+=b.height;
break;
}
selection.push_back(&b); // b is OWNED: pass by pointer
return int(selection.size()-1);
}
//------------------------------------------------------------------------------
} // of namespace Graph_lib
GUI.h
//
// This is a GUI support code to the chapters 12-16 of the book
// "Programming -- Principles and Practice Using C++" by Bjarne Stroustrup
//
#ifndef GUI_GUARD
#define GUI_GUARD
#include "Window.h"
#include "Graph.h"
namespace Graph_lib {
//------------------------------------------------------------------------------
typedef void* Address; // Address is a synonym for void*
typedef void(*Callback)(Address, Address); // FLTK's required function type for all callbacks
//------------------------------------------------------------------------------
template<class W> W& reference_to(Address pw)
// treat an address as a reference to a W
{
return *static_cast<W*>(pw);
}
//------------------------------------------------------------------------------
class Widget {
// Widget is a handle to an Fl_widget - it is *not* an Fl_widget
// We try to keep our interface classes at arm's length from FLTK
public:
Widget(Point xy, int w, int h, const string& s, Callback cb)
: loc(xy), width(w), height(h), label(s), do_it(cb)
{}
virtual void move(int dx,int dy) { hide(); pw->position(loc.x+=dx, loc.y+=dy); show(); }
virtual void hide() { pw->hide(); }
virtual void show() { pw->show(); }
virtual void attach(Window&) = 0;
Point loc;
int width;
int height;
string label;
Callback do_it;
virtual ~Widget() { }
protected:
Window* own; // every Widget belongs to a Window
Fl_Widget* pw; // connection to the FLTK Widget
private:
Widget& operator=(const Widget&); // don't copy Widgets
Widget(const Widget&);
};
//------------------------------------------------------------------------------
struct Button : Widget {
Button(Point xy, int w, int h, const string& label, Callback cb)
: Widget(xy,w,h,label,cb)
{}
void attach(Window&);
};
//------------------------------------------------------------------------------
struct In_box : Widget {
In_box(Point xy, int w, int h, const string& s)
:Widget(xy,w,h,s,0) { }
int get_int();
string get_string();
void attach(Window& win);
};
//------------------------------------------------------------------------------
struct Out_box : Widget {
Out_box(Point xy, int w, int h, const string& s)
:Widget(xy,w,h,s,0) { }
void put(int);
void put(const string&);
void attach(Window& win);
};
//------------------------------------------------------------------------------
struct Menu : Widget {
enum Kind { horizontal, vertical };
Menu(Point xy, int w, int h, Kind kk, const string& label)
: Widget(xy,w,h,label,0), k(kk), offset(0)
{}
Vector_ref<Button> selection;
Kind k;
int offset;
int attach(Button& b); // Menu does not delete &b
int attach(Button* p); // Menu deletes p
void show() // show all buttons
{
for (unsigned int i = 0; i<selection.size(); ++i)
selection[i].show();
}
void hide() // hide all buttons
{
for (unsigned int i = 0; i<selection.size(); ++i)
selection[i].hide();
}
void move(int dx, int dy) // move all buttons
{
for (unsigned int i = 0; i<selection.size(); ++i)
selection[i].move(dx,dy);
}
void attach(Window& win) // attach all buttons
{
for (int i=0; i<selection.size(); ++i) win.attach(selection[i]);
own = &win;
}
};
//------------------------------------------------------------------------------
} // of namespace Graph_lib
#endif // GUI_GUARD
I found the answer. It wouldn't compile because I added an argument to be passed to button (the Fl_Color). I will have to figure out a way to pass a value to the button to change the color.

SDL OpenGL window instantly closes

so i have just started playing with sdl and i have it working fine in a single class but for some reason when i separate things into seperate classes the display opens a insta closes. an ideas ?
Main Class Header
#pragma once
#include <SDL.h>
#include <glew.h>
#include <iostream>
#include "Input.h"
#include "Display.h"
#include "RenderingEngine.h"
#include "PhysicsEngine.h"
class Main
{
public:
Main();
~Main();
/* Engine settings & Engine Controlls*/
void start();
void stop();
void pause(bool value);
void run();
private:
/* Loop Controllers */
bool running;
bool paused;
/* Engine Initialisation */
void initSDL();
RenderingEngine render_core = RenderingEngine(4, 2);
PhysicsEngine physics_core = PhysicsEngine();
Display display = Display("game engine", 900, 900, 900, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
Input input;
};
Main Class
#include "Main.h"
Main::Main()
{
initSDL();
start();
}
Main::~Main()
{
}
void Main::initSDL()
{
SDL_Init(SDL_INIT_EVERYTHING);
}
void Main::start()
{
if (running) return;
running = true;
run();
}
void Main::stop()
{
if (!running) return;
running = false;
exit(0);
}
void Main::pause(bool value)
{
paused = value;
}
void Main::run()
{
while (running)
{
if (!paused)
{
}
render_core.render();
display.swapBackBuffer();
input.update();
}
}
int main(int argc, char *argv[])
{
Main engine;
return 0;
}
Display Header
#pragma once
#include <iostream>
#include <SDL.h>
class Display
{
public:
Display(const char* name, int x, int y, int w, int h, Uint32 flags);
~Display();
void swapBackBuffer();
private:
int x;
int y;
int w;
int h;
const char* name;
Uint32 flags;
SDL_Window *window;
SDL_GLContext opengl;
};
Display Class
#include "Display.h"
Display::Display(const char* n, int x, int y, int w, int h, Uint32 f)
{
this->x = x;
this->y = y;
this->w = w;
this->h = h;
this->name = name;
this->flags = flags;
this->window = SDL_CreateWindow(n, x, y, w, h, f);
this->opengl = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, opengl);
printf("Display: initialised\n\n");
}
Display::~Display()
{
SDL_GL_DeleteContext(opengl);
SDL_DestroyWindow(window);
printf("Display: destroyed\n\n");
}
void Display::swapBackBuffer()
{
SDL_GL_SwapWindow(window);
}
Render Engine class.... there isn't anything important in the header
#include "RenderingEngine.h"
RenderingEngine::RenderingEngine(int major_version, int minor_version)
{
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major_version);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor_version);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
setClearColour(0, 0, 0, 1);
printf("Rendering Engine:: initialised\n\n");
}
RenderingEngine::~RenderingEngine()
{
printf("Rendering Engine:: destroyed\n");
}
void RenderingEngine::setClearColour(float r, float g, float b, float a)
{
glClearColor(r, g, b, a);
}
void RenderingEngine::clearScreen()
{
glClear(GL_COLOR_BUFFER_BIT || GL_DEPTH_BUFFER_BIT);
}
void RenderingEngine::render()
{
clearScreen();
}
input class
#include "Input.h"
Input::Input()
{
printf("Input:: initialised\n");
}
Input::~Input()
{
printf("Input:: destroyed\n");
}
void Input::setMouseVisabilityTo(bool value)
{
if (value) SDL_ShowCursor(1);
else SDL_ShowCursor(0);
}
int Input::getMouseX()
{
return mouseX;
}
int Input::getMouseY()
{
return mouseY;
}
void Input::update()
{
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
break;
case SDL_KEYDOWN:
keyboard[event.key.keysym.sym] = true;
break;
case SDL_KEYUP:
keyboard[event.key.keysym.sym] = false;
break;
case SDL_MOUSEBUTTONDOWN:
mouse[event.button.button] = true;
break;
case SDL_MOUSEBUTTONUP:
mouse[event.button.button] = false;
break;
case SDL_MOUSEWHEEL:
break;
case SDL_MOUSEMOTION:
mouseX = event.button.x;
mouseY = event.button.y;
break;
}
}
}
i know there are a lot a files so the help will be greatly appreciated, this has been bugging me for a while now
my edited main.h file
#include "Display.h"
#include "RenderingEngine.h"
#include "PhysicsEngine.h"
class Main
{
public:
Main() :
render_core(4, 2),
display("game engine", 900, 900, 900, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL),
physics_core(),
input()
{
running = false;
paused = false;
initSDL();
start();
}
~Main();
/* Engine settings & Engine Controlls*/
void start();
void stop();
void pause(bool value);
void run();
private:
/* Loop Controllers */
bool running;
bool paused;
/* Engine Initialisation */
void initSDL();
RenderingEngine render_core;
PhysicsEngine physics_core;
Display display;
Input input;
Is this some weird version of C++ (e.g. C++11) where you can declare and initialize a non-static member variable all in the same statement?
You should not be doing that kind of thing, the order in which your render context is constructed and initialized in relation to the rest of your software is extremely important. This is what constructors are for.
Assuming you actually are intentionally (ab)using C++11 here, your window closes immediately because this statement:
Display display = Display("game engine", 900, 900, 900, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
Constructs a Display object, and then makes a copy of that object and assigns it to display. After this statement "returns", the original object is destroyed.
And look at what the destructor for Display does:
Display::~Display()
{
SDL_GL_DeleteContext(opengl);
SDL_DestroyWindow(window);
printf("Display: destroyed\n\n");
}
Long story short, do not initialize your members this way. Constructors were perfectly fine before C++11 came along and made life more difficult.
Consider something like the following constructor instead:
Main () : render_core (4, 2),
display ("game engine", 900, 900, 900, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL),
physics_core ()
{
initSDL ();
start ();
}
...
private:
RenderingEngine render_core;
PhysicsEngine physics_core;
Display display;
This solution initializes all of the members of Main when it is constructed, without any copy-assignment and is compatible with a much wider range of C++ compilers. No temporary Display object in this code means that your window is not going to be created and then immediately destroyed.