It seems that I am having a seg fault while using GLFW and OpenGL on ArchLinux, DWM (fully updated and patched).
I retraced the code and it is having the segFault in the glfwSwapBuffers(window).
Here is my code :
main.cpp
#include <iostream>
#include "gui/window.h"
int main(int, char**) {
Window window("Test GL", 800, 600);
if(!window.hasCorrectlyLoaded()) {
return 1;
}
while (!window.shouldClose())
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
window.pollEvents();
}
}
window.h
#ifndef __WINDOW_H__
#define __WINDOW_H__
#include <string>
#include <glad/gl.h>
#include <GLFW/glfw3.h>
class Window {
private:
GLFWwindow *window;
bool correctlyLoaded;
public:
Window(const std::string&, int, int);
~Window();
const bool hasCorrectlyLoaded();
const bool shouldClose();
const void pollEvents();
};
#endif // __WINDOW_H__
window.cpp
#include "window.h"
#include <spdlog/spdlog.h>
Window::Window(const std::string& title, int width, int height)
{
correctlyLoaded = false;
if(!glfwInit()) {
spdlog::default_logger()->critical("Could not load GLFW");
return;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
GLFWwindow* window = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr);
if (!window)
{
spdlog::default_logger()->critical("Failed to create GLFW window !");
return;
}
glfwMakeContextCurrent(window);
if (!gladLoadGL(glfwGetProcAddress))
{
spdlog::default_logger()->critical("Failed to load OpenGL !");
return;
}
spdlog::default_logger()->info("Loaded OpenGL {}", glfwGetVersionString());
glViewport(0, 0, width, height);
correctlyLoaded = true;
}
const void Window::pollEvents()
{
glfwSwapBuffers(window);
glfwPollEvents(); //<- Seg fault here
}
Window::~Window()
{
glfwTerminate();
}
const bool Window::hasCorrectlyLoaded()
{
return correctlyLoaded;
}
const bool Window::shouldClose()
{
return glfwWindowShouldClose(window);
}
While further researching, I stumbled upon an answer that told me to set the glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API) window hint but I still got a segfault, but at a different place :
GLFW source code
GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (window->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT,
"Cannot swap buffers of a window that has no OpenGL or OpenGL ES context"); //<- Seg fault without window hint
return;
}
window->context.swapBuffers(window); //<- Seg fault with window hint
}
Here is the output I get from the logging :
[2022-05-24 20:01:04.252] [info] Loaded OpenGL 3.4.0 X11 GLX Null EGL OSMesa monotonic
[1] 432406 segmentation fault (core dumped) /home/lygaen/code/testgl/build/testgl
Your problem occurs in Window.cpp, at this line:
//...
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
GLFWwindow* window = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr); //<---
if (!window)
{
//...
You've redeclared window as a local variable to this constructor, and as a result, the pointer never escapes the constructor, and is dangled.
A good habit when trying to assign class members is to use the this keyword. It is often redundant, but it does help indicate intent. So the code should be changed to this:
//...
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
this->window = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr); //<---
if (!this->window)
{
//...
If your style guidelines don't permit it, you can omit the this->; the only important part is that you're not declaring an entirely new variable that's shadowing the class member.
Related
When I attempt to generate a buffer by executing the glGenBuffer() function - no function like that is found.
Some functions are still working, and from what I see most do work, for instance the following code works perfectly:
#include <iostream>
#include <GLFW/glfw3.h>
using namespace std;
class Window_Manager
{
public:
GLFWwindow* window;
int Create_Window(int width, int height, const char* title) {
if (!glfwInit()) {
return -1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
glfwWindowHint(GLFW_FOCUSED, GL_TRUE);
window = glfwCreateWindow(width, height, title, NULL, NULL);
if (window == NULL) {
cout << "Failed to create a window! Aborting early..." << endl;
Terminate_Window(window);
return -1;
}
glfwMakeContextCurrent(window);
glViewport(0, 0, width, height);
return 1;
}
void Terminate_Window(GLFWwindow* window) {
glfwSetWindowShouldClose(window, GL_TRUE);
glfwTerminate();
}
};
but this code does not:
#include <GLFW/glfw3.h>
#include <Engine_Manager.h>
#include <iostream>
using namespace std;
class Shape2D
{
int VBO;
int Setting_Up(){
VBO = glGenBuffer();
return 1;
}
};
In addition to replacing glGenBuffer with glGenBuffers(1, &VBO) as rpress mentioned in the comments, OpenGL is a weird library in that you have to load most of the functions dynamically.
The exact details differ from platform to platform. On Windows, for example, you can use wglGetProcAddress to get pointers to desired functions.
Rather than do it manually, GLEW is an excellent library for getting OpenGL function pointers easily. Other options are documented on the OpenGL wiki.
I am trying to debug and fix all memory leaks in my program. I have went through the entire source code and there is not one call of new or malloc() which isn't supported by a free() or delete. I tried running the program in valgrind. Valgrind found that a consistent(throughout multiple executions of the program) 844 bytes of data were definitely lost. It also constantly points me back to the glewInit() function of my Window class. Is there anything I am doing wrong?
Couple things to note:
My window class is completely static
My window class calls InputManager::init() which is also a static class
I have another completely static class for storing constants
class Window {
public:
// void create(unsigned int width, unsigned int height, const std::string& name, bool resizable, bool decorated){
//
// }
static void create(unsigned int width, unsigned int height, const std::string& name, bool resizable, bool decorated){
if(!glfwInit()){
Utils::log("Failed to initialize GLFW");
return;
}
//Setting Window settings
glfwWindowHint(GLFW_RED_BITS, 8);
glfwWindowHint(GLFW_GREEN_BITS, 8);
glfwWindowHint(GLFW_BLUE_BITS, 8);
glfwWindowHint(GLFW_ALPHA_BITS, 8);
glfwWindowHint(GLFW_DEPTH_BITS, 24);
glfwWindowHint(GLFW_STENCIL_BITS, 8);
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_RESIZABLE, resizable ? GLFW_TRUE : GLFW_FALSE);
glfwWindowHint(GLFW_DECORATED, decorated ? GLFW_TRUE : GLFW_FALSE);
m_width = width;
m_height = height;
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
//Creating the window
window = glfwCreateWindow(width, height, name.c_str(), NULL, NULL);
if(!window){
Utils::log("Window: Failed to create window");
return;
}
//Settings for window
glfwSwapInterval(1);
glfwSetFramebufferSizeCallback(window, windowResized);
//Creating the context for opengl
glfwMakeContextCurrent(window);
//Initializing glew
if(glewInit() != GLEW_OK){
Utils::log("Window: Failed to initialize glew");
}
//Enabling transparency
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//Enabling depth
glEnable(GL_DEPTH_TEST);
glClearDepthf(1.0f);
//Enabling back face culling
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
//Enabling MSAA
glEnable(GL_MULTISAMPLE);
InputManager::init(window);
}
static void clear();
static void update();
static void close();
//Window functions
static void setVerticalSyncEnabled(bool enabled);
static void setMouseCursorGrabbed(bool grabbed);
static int getWidth();
static int getHeight();
static bool isResized();
static bool isCloseRequested();
static GLFWwindow* window;
private:
static void windowResized(GLFWwindow* window, int width, int height);
static int m_width;
static int m_height;
static bool m_isResized;
static bool m_closeRequested;
};
#endif
I started using GLAD and it stopped causing the memory leak.
I tried doing OpenGL using GLFW. I was beginning to make a window
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(500, 500, "Test", NULL, NULL);
if (window == NULL) {
std::cout << "GLAD failed.";
}
glfwMakeContextCurrent(window);
void frameBufferSizeCallback(GLFWwindow* window,int width,int height);
glfwSetFramebufferSizeCallback(window, frameBufferSizeCallback);
glViewport(0, 0, 500, 500);//Error here
while (!glfwWindowShouldClose(window)) {
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
void frameBufferSizeCallback(GLFWwindow* window,int width,int height) {
glViewport(0,0,width,height);
}
I get some error saying Exception thrown at 0x00000000 in OpenGLTest0.exe: 0xC0000005: Access violation executing location 0x00000000. And the window I created doesn't even respond to anything including Task Manager "end task. I was using Visual Studio 2017 and had to "end task" the whole aplication in order to remove the window. Also I am on Windows 10.
Could somebody tell me where I am wrong? I thank you in advance!
You need to initalize the glad library, without that it can't load in the function pointers.
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
I'm making a GL renderer in a window. The program itself works fine but when I "thread" the render loop( as I have done for a networking class so I was guessing it should work), the program opens and work for couple seconds before crashing, like if the memory was being full ?
look in the main to see my problem
class MyWorld {
public:
GLFWwindow *window;
std::thread thread;
MyWorld() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(300, 300, "OUTPUT", nullptr, nullptr);
glfwMakeContextCurrent(window);
glViewport(0, 0, 300, 300);
glewInit();
}
void run() {
while (1) {
glfwMakeContextCurrent(window);
glfwPollEvents();
glClearColor(sin(glfwGetTime()), 0, 0, 1 ); // BG COLOR
glClear( GL_COLOR_BUFFER_BIT );
glfwSwapBuffers(window);
}
}
void threadrun() {
glfwMakeContextCurrent(NULL);
thread = std::thread(&MyWorld::run, this);
thread.detach();
}
};
int main() {
MyWorld world;
// world.run(); // this works fine
world.threadrun(); // this doesn't
while (1) { continue; }
}
I'm using Visual Studio 2013, and as I am learning OpenGL 3.3 I thought best to use
#define GLFW_INCLUDE_GLCOREARB
#include <GLFW/glfw3.h>
to force 'intellisense' to not even show old depreciated functions such as glVertex2f etc...
However the inclusion of said #define prevents any gl* functions from showing up. Even glViewport is undefined. When attempting to compile a simple application I get among many errors
error C3861: 'glViewport': identifier not found
glcorearb.h is my include files path though, downloaded from http://www.opengl.org/registry/api/GL/glcorearb.h only yesterday.
I might be doing something completely wrong here. But here is my full source code...
// Include standard headers
#include <stdio.h>
#include <stdlib.h>
#define GLFW_INCLUDE_GLCOREARB
// Include GLFW3
#include <GLFW/glfw3.h>
//Error Callback - Outputs to STDERR
static void error_callback(int error, const char* description)
{
fputs(description, stderr);
}
//Key Press Callback
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
int main(){
GLFWwindow* window;
glfwSetErrorCallback(error_callback);
// Initialise GLFW
if (!glfwInit())
{
fputs("Failed to initialize GLFW\n", stderr);
exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_SAMPLES, 2); // 2x antialiasing
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // We want OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //We don't want the old OpenGL
// Open a window and create its OpenGL context
window = glfwCreateWindow(640, 480, "Test", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
while (!glfwWindowShouldClose(window))
{
float ratio;
int width, height;
glfwGetFramebufferSize(window, &width, &height);
ratio = width / (float)height;
glViewport(0, 0, width, height);
glClearColor(0.5f, 0.7f, 1.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}