Reputation: 21
So im using GLFW and the following method works when called in my main method
void Display::run() {
while (!glfwWindowShouldClose(window))
{
/* Render here */
/* Swap Buffers And Poll */
glfwSwapBuffers(window);
glfwPollEvents();
}
}
but when i try to run it on a separate thread i get a segfault
std::thread t1(&Display::run, this);
any ideas? ask if you want any more of the code
Edit: main.cpp
#include "src/support/Display.h"
int main() {
Display* d;
d->start();
return 0;
}
Display.h
#include <GLFW/glfw3.h>
#include <exception>
#include <thread>
class Display {
private:
GLFWwindow* window;
std::thread* displayThread;
void run();
public:
Display();
void start();
void close();
};
/* Exceptions */
struct GLFWNotInitilizedException : public std::exception
{
const char * what () const throw ()
{
return "ERR: Could Not Initialize GLFW";
}
};
struct WindowNotCreatedException : public std::exception
{
const char * what () const throw ()
{
return "ERR: Could Not Create Window";
}
};
Display.cpp
#include "Display.h"
Display::Display() {
//init glfw
if (!glfwInit())
throw GLFWNotInitilizedException();
//create window and its context
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
throw WindowNotCreatedException();
}
//make windows context current
glfwMakeContextCurrent(window);
//run(); //this works instead of calling start() which puts run() into a thread
}
/* begins the rendering of the display window contents in seperate thread */
void Display::start() {
std::thread t1(&Display::run, this);
displayThread = &t1;
}
/* renders contents of display window */
void Display::run() {
while (!glfwWindowShouldClose(window)) //seg fault is output here
{
/* Render here */
/* Swap Buffers And Poll */
glfwSwapBuffers(window);
glfwPollEvents();
}
}
/* to be used when closing display window */
void Display::close() {
glfwSetWindowShouldClose(window, true);
displayThread->join();
glfwDestroyWindow(window);
}
Upvotes: 1
Views: 1357
Reputation: 7292
//make windows context current
glfwMakeContextCurrent(window);
This makes it active on the CURRENT thread. Run this on the thread where you want to render and it should work. Currently it's in the constructor.
Upvotes: 2
Reputation: 171263
Display* d;
You haven't created an object here, just an uninitialised pointer.
d->start();
This calls a member on a nonexistent object. When it tries to access any members in the run()
function it just accesses garbage because there is no object.
You probably want to create an object like this:
Display d;
d.start();
Also your start function will terminate the program because you don't join the thread before it is destroyed. You should learn the basics of C++ object lifetime before trying to use threads and pointers like this.
Stop using pointers until you understand the basics. displayThread
should be an actual std::thread
not just a pointer to some std::thread
that goes out of scope.
Then you can just do:
void Display::start() {
displayThread = std::thread(&Display::run, this);
}
Make sure you call displayThread.join()
before it is destroyed, e.g in the Display
destructor.
Upvotes: 1