C++ project crashes after glewinit() - c++

(Im using Clion and Cmake on Macosx Intel chip)
I wan't to make a Window Application with GLEW. But i get this error:
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
I heard that you should define "GLEW_STATIC" in the preprocessing. But I have no idea how Clion works
My main.cpp:
#include "GL/glew.h"
#include <GLFW/glfw3.h>
int main()
{
GLFWwindow* window;
if (!glfwInit())
return -1;
glewInit();
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
and my cmake:
cmake_minimum_required(VERSION 3.22)
project(renderer)
set(CMAKE_CXX_STANDARD 14)
include_directories(/usr/local/Cellar/glfw/3.3.8/include)
include_directories(/usr/local/Cellar/glew/2.2.0_1/include)
add_definitions(-DGLEW_STATIC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -framework CoreFoundation -framework OpenGL -framework GLUT ")
add_executable(renderer main.cpp)
target_link_libraries(renderer /usr/local/Cellar/glfw/3.3.8/lib/libglfw.3.3.dylib)
target_link_libraries(renderer /usr/local/Cellar/glew/2.2.0_1/lib/libGLEW.2.2.dylib)
How do i fix this problem?

glewInit() requires a current OpenGL context to operate correctly. As written in your code glewInit() will fail and leave its glClear() function-pointer set to nullptr.
Call glewInit() after glfwMakeContextCurrent() 'returns' GLFW_NO_ERROR and verify that it returns GLEW_OK.

Related

Statically linking GLFW to CMake to an executable

In my project, I would like to statically link GLFW to my main executable, but when I try to I do not get any error from my CMakeLists, and the error from my main executable is just saying that GLFW/glfw3.h file is not a valid file.
Here is my CMakeLists.txt code:
cmake_minimum_required(VERSION 3.0.0)
project(openGL VERSION 1.0.0)
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
add_subdirectory(L:\glfw-3.3.2)
add_executable(main main.cpp)
target_link_libraries(main glfw)
find_package(OpenGL REQUIRED)
target_link_libraries(main OpenGL::GL)
And my main executable:
#include <iostream>
#include <GLFW/glfw3.h>
using namespace std;
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
Exact error code:
cannot open source file "GLFW/glfw3.h/"

Calling glewInit() causes main function to not be called

I'm attempting to use GLFW and GLEW. Currently my code works, and I see a window with triangles:
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <time.h>
#include "constants.h"
int main(void) {
GLFWwindow* window;
if (!glfwInit()) {
glfwTerminate();
return -1;
}
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Window", NULL, NULL);
if (!window) {
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
// if (glewInit() != GLEW_OK) {
// fprintf(stderr, "failure");
// return -1;
// }
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
while (glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window) == 0) {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex2f(0, 0);
glVertex2f(0, 1);
glVertex2f(1, 0);
glEnd();
glfwSwapBuffers(window); /* Swap front and back buffers */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
The above code works. However, when I uncomment the lines:
if (glewInit() != GLEW_OK) {
fprintf(stderr, "failure");
return -1;
}
The program exits silently. I confirmed with a breakpoint that the main function is not even being called. If it helps, here is my compilation command:
g++ -g main.cpp -I\glfw-3.3.2\include -I\glew-2.1.0\include -L\glfw-3.3.2\lib-mingw-w64 -L\glew-2.1.0\lib\Release\x64 -lglfw3 -lgdi32 -lopengl32 -luser32 -lshell32 -lglew32 -o main.exe
I can't figure this out for the life of me. I'm calling glewInit after making the OpenGL window, I'm importing glew before glfw. What am I doing wrong?
Crash before main is either because of static initialization or dynamic libraries.
It seems you are on windows, in that case glew release files contain two libraries glew32.lib and glew32s.lib.
You are linking against the non-static one, try -lglew32s. The first one is just a stub that will search for .dll, usually located in glew/bin folder, you would have to copy it to the working directory with main.exe. Remove GLEW_STATIC if you choose to go this way.
To prevent future errors, add glewExperimental=GL_TRUE; somewhere before glewInit. It enables OpenGL 3.3+ functions on some drivers.
As for why is it working now, the whole reason for existence of extension loading libraries in the first place is that the default drivers include only OpenGL 1.x functionality. All newer functions must be loaded directly at run-time from .dll drivers supplied by your GPU using dllopen() and GetProcAddress() which is exactly what these libraries do for you. That is why most newer functions are actually implemented as macros (wrapping the function pointer). That said, you are not using any new functions (you really should), so everything is working fine.

CMake child project can't call OpenGL functions, but parent project can

I have a Parent CMake project and a Child CMake project, inside the parent cmake project I can call any OpenGL function and it works perfectly fine, but inside the child project I can't call any OpenGL functions directly, only through the parent projects functions will it work.
Parent Project:
cmake_minimum_required (VERSION 3.8)
project(LumiumEngine)
set(CMAKE_DEBUG_POSTFIX "-d")
set(LUMI_DIR "LumiumEngine")
# SDL2
find_package(SDL2 CONFIG REQUIRED)
add_library(${PROJECT_NAME} SHARED "${LUMI_DIR}/System/Window.hpp" "${LUMI_DIR}/System/Window.cpp")
# glad
set(GLAD_DIR "${CMAKE_HOME_DIRECTORY}/external/glad")
add_library("glad" "${GLAD_DIR}/src/glad.c")
target_include_directories("glad" PUBLIC "${GLAD_DIR}/include")
target_include_directories(${PROJECT_NAME} PUBLIC "${SDL2_INCLUDE_DIRS}" "${GLAD_DIR}/include")
target_link_libraries(${PROJECT_NAME} PUBLIC SDL2::SDL2 SDL2::SDL2main "glad" "${CMAKE_DL_LIBS}")
set_target_properties(${PROJECT_NAME} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/${PROJECT_NAME}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/${PROJECT_NAME}/bin"
)
install(DIRECTORY bin
DESTINATION "${CMAKE_HOME_DIRECTORY}/Lumin"
FILES_MATCHING
PATTERN "*.dll"
PATTERN "*.ilk" EXCLUDE
PATTERN "*.pdb" EXCLUDE
)
Child Project:
cmake_minimum_required (VERSION 3.8)
project(Lumin)
set(CMAKE_DEBUG_POSTFIX "-d")
# find OpenGL
find_package(OpenGL REQUIRED)
add_executable(${PROJECT_NAME} "main.cpp" "${CMAKE_HOME_DIRECTORY}/external/glad/src/glad.c")
target_link_libraries(${PROJECT_NAME} PUBLIC "${OPENGL_LIBRARIES}" LumiumEngine)
set_target_properties(${PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/${PROJECT_NAME}/bin"
)
The child project is dependent on parent project, (in the parent-parent directory i just add both of these project as sub directories and add_dependency(Child Parent), the proper .dlls and .libs should be loaded in, from my understanding I load SDL2, SDL2main, glad in the parent project and then load in OpenGL + all the libraries from Parent since they were added with the PUBLIC tag
The code is not the issue, since I created a project with two sub projects in Visual Studio with the same code which worked. Is there a library that i'm missing? It also might be an issue with compiling the OpenGL Loader `glad'.
I think the main issue that is confusing me is why do OpenGL functions hidden by an abstraction layer in my Parent project work fine but when i call OpenGL functions in my Child project I get an "Exception Thrown at 0x00010..." at the OpenGL call. Thanks for any help or guidance.
Edit: Adding a code example:
This is my Window.cpp from the Parent project LumiumEngine
#include "Window.hpp"
#include <glad/glad.h>
lumi::Window::Window()
{
m_shouldClose = true;
}
lumi::Window::~Window()
{
SDL_Quit();
}
bool lumi::Window::createWindow(std::string title, int xPos, int yPos, int width, int height, unsigned int flags)
{
// Set SDL as ready and init SDL
SDL_SetMainReady();
if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SDL Init Error", "Could not init SDL2", NULL);
SDL_Quit();
return false;
}
SDL_GL_LoadLibrary(NULL); // Default OpenGL is fine.
// Request an OpenGL 4.5 context (should be core)
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5);
// Also request a depth buffer
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
// create the window
m_pWindow = SDL_CreateWindow(title.c_str(), xPos, yPos, width, height, flags);
if (m_pWindow == nullptr)
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SDL Window Error", "Could not create a window", NULL);
SDL_Quit();
return false;
}
// create the openGL context
m_glContext = SDL_GL_CreateContext(m_pWindow);
if (m_glContext == nullptr)
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SDL Window Error", "Could not create an openGL context with version 4.5", NULL);
SDL_Quit();
return false;
}
printf("OpenGL loaded\n");
gladLoadGLLoader(SDL_GL_GetProcAddress);
printf("Vendor: %s\n", glGetString(GL_VENDOR));
printf("Renderer: %s\n", glGetString(GL_RENDERER));
printf("Version: %s\n", glGetString(GL_VERSION));
m_shouldClose = false;
glViewport(0, 0, width, height);
glClearColor(.2f, .4f, .6f, 1.0f);
return true;
}
bool lumi::Window::isOpen()
{
return !m_shouldClose;
}
Child Project main.cpp
#include <LumiumEngine/System/Window.hpp>
#include <glad/glad.h>
int main(int argc, char **argv)
{
lumi::Window window;
if (window.createWindow("Hello World", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL))
{
glClearColor(0.2f, 0.4f, 0.6f, 1.0f); // exception occurs here, as you can see it's after i create a valid OpenGL context
while (window.isOpen())
{
//window.display();
}
}
return 1;
}
Notice how i call the same exact OpenGL function glClearColor() inside my createWindow function and it runs perfectly fine. I can verify that it works by calling window.display which calls glClear(GL_COLOR_BUFFER_BIT); then SDL_GL_SwapBuffers()
Side note: I tried just getting rid of the child project and making the Parent project into a executable instead of a library and it works fine, but i really would like to be able to make LumiumEngine a library so i can call it from multiple projects in the future. I'm completely stumped at the moment.
Blahhh!
So for some reason you have to manually load OpenGL through glad again in the Child Project, even though it has already been called in the parent project and we have verified that we had a valid OpenGL Context. The simple fix for this was to add a:
gladLoadGLLoader(SDL_GL_GetProcAddress)
call after the SDL window was created:
#include <LumiumEngine/System/Window.hpp>
#include <glad/glad.h>
int main(int argc, char **argv)
{
lumi::Window window;
if (window.createWindow("Hello World", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL))
{
gladLoadGLLoader(SDL_GL_GetProcAddress);
glClearColor(0.2f, 0.4f, 0.6f, 1.0f); // THIS WORKS NOW!!
while (window.isOpen())
{
window.display();
}
}
return 1;
}
Such a simple fix for a simple problem that was giving me a major headache.

glewInit() fails with "Missing GL version", SDL2 OpenGL context, cygwin compiler

The program following, is one that creates a window which does nothing except close when you press esc. When I compile it with cygwin, there are no errors. The GLEW I use is from Cygwin Ports, and the SDL2 is version 2.0.3, from their website's SDL2-devel-2.0.3-mingw.tar.gz download. I have SDL2.dll in the directory of the compiled executable.
Links with: -lSDL2 -lSDL2main -lGLEW -lGLU -lGL -lSDL2 -lSDL2main -lGLEW -lGLU -lGL, twice to ensure everything is linked.
Also compiled with: -std=c++11
On my computer, the following program prints out:
OpenGL Vendor: (null)
OpenGL Renderer: (null)
OpenGL Shading Language Version: (null)
OpenGL Extensions: (null)
Error initializing GLEW! Missing GL version
The program appears to work otherwise. The main problem is that if I try to call, for example glGenVertexArrays, the program will crash with STATUS_ACCESS_VIOLATION. (See the crashing code here. I think this has something to do with GLEW's error Missing GL version.
#include <cstdio>
#include <chrono>
#include <thread>
#include <SDL2/SDL.h>
#include <GL/glew.h>
#include <SDL2/SDL_opengl.h>
#include <GL/glu.h>
const int width = 1000;
const int height = 500;
bool Running = true;
#undef main
int main (int argc, char *argv[]) {
FILE* cdebug = fopen("cdebug.txt", "w");
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
fprintf(cdebug, "SDL could not initialize! SDL Error: %s\n", SDL_GetError()); fflush(cdebug);
}
#define setAttr(attr, value) \
if (SDL_GL_SetAttribute(attr, value) < 0) { \
fprintf(cdebug, "SDL failed to set %s to %s, SDL Error: %s\n", #attr, #value, SDL_GetError()); fflush(cdebug);\
}
setAttr(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
setAttr(SDL_GL_CONTEXT_MINOR_VERSION, 3);
setAttr(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
setAttr(SDL_GL_RED_SIZE, 8);
setAttr(SDL_GL_GREEN_SIZE, 8);
setAttr(SDL_GL_BLUE_SIZE, 8);
setAttr(SDL_GL_DEPTH_SIZE, 24);
setAttr(SDL_GL_DOUBLEBUFFER, 1);
#undef setAttr
/*
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
*/
SDL_Window *window = SDL_CreateWindow(
"test",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
640, 480,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
);
if (window == NULL) {
fprintf(cdebug, "Window could not be created! SDL Error: %s\n", SDL_GetError()); fflush(cdebug);
}
SDL_GLContext GLContext = SDL_GL_CreateContext(window);
if (GLContext == NULL) {
fprintf(cdebug, "OpenGL context could not be created! SDL Error: %s\n", SDL_GetError()); fflush(cdebug);
}
if (SDL_GL_MakeCurrent(window, GLContext) < 0) {
fprintf(cdebug, "OpenGL context could not be made current! SDL Error: %s\n", SDL_GetError()); fflush(cdebug);
}
fprintf(cdebug, "OpenGL Vendor: %s\n", glGetString(GL_VENDOR));
fprintf(cdebug, "OpenGL Renderer: %s\n", glGetString(GL_RENDERER));
fprintf(cdebug, "OpenGL Shading Language Version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
fprintf(cdebug, "OpenGL Extensions: %s\n", glGetString(GL_EXTENSIONS));
fflush(cdebug);
glewExperimental = GL_TRUE;
{
GLenum glewError = glewInit();
if (glewError != GLEW_OK) {
fprintf(cdebug, "Error initializing GLEW! %s\n", glewGetErrorString(glewError)); fflush(cdebug);
}
}
SDL_Event event;
while (Running) {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYUP: {
switch (event.key.keysym.scancode) {
case SDL_SCANCODE_ESCAPE:
Running = false;
break;
}
break;
}
}
}
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapWindow(window);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
SDL_GL_DeleteContext(GLContext);
SDL_DestroyWindow(window);
window = NULL;
SDL_Quit();
return 0;
}
You are mixing cygwin and mingw in ways in which you shouldn't.
If you use cygwin's toolchain and -lGL and so on, you link against cygwin's OpenGL - which is not the native OpenGL lib on windows, but the one provided by cygwin's X server, implementing the GLX protocol.
The mingw version of SDL will use the native GL lib (opengl32.dll) on windows, using the wgl API. So SDL might even create a context for you, but the GL functions your programm are calling belong to a completely different GL implementation - for which your program never created a GL context.
The solution is to stick with one or the other: Completely use cygwin, and a cygwin version of SDL, and a cygwin X server. However, that is not the path I would recommend. I don't know if that would even get you some HW acceleration at all.
The more useful solution would be to not use cygwin, but mingw, for the whole project, with a mingw version of GLEW. That will result in a completely native windows binrary which will use the native OpenGL library with all features provided by the driver and not require cygwin's dlls and especially not cygwin's X server.
I managed to get things working in a weird way.
I am using a self compiled version of SDL2 but the SDL2-devel-2.0.3-mingw.tar.gz provided by the SDL website seems to work as well and using a combination of them (such as mingw version's libs and self-compiled .dll) seem to work as well.
For GLEW, I am using my own compiled version. To compile this, I used their website's source glew-1.11.0.zip and extracted this. Then I edited glew-1.11.0/Makefile and edited line 24 to SYSTEM = cygming. Then in glew-1.11.0/config/Makefile.cygming on line's 7 and 8, I removed the -mno-cygwin flag (so the line's are CC := gcc and LD := gcc) and added -D_WIN32 to line 10 (so the line becomes CFLAGS.SO = -DGLEW_BUILD -D_WIN32). Then in glew-1.11.0, I ran make all and let it compile. After that, I copied glew-1.11.0/include/GL to my includes directory. Next, I copied glew-1.11.0/lib/libglew32.dll.a to my libs folder. I also copied glew-1.11.0/lib/glew32.dll to my .exe's folder. Then to get it to not produce a linker error, I had to place a #define _WIN32 before my #include <GL/glew.h>.
To link everything, I managed to compile it with a minimum of -lSDL2 -lSDL2main -lglew32.dll -lopengl32.

Cannot get GLFW3 Library working

I am trying to get the GLFW3 working on my workstation. I did install GLFW3 on my Ubuntu 12.04 from http://www.glfw.org/download.html
Here is the program I am trying. Got it from GLFW official site
http://www.glfw.org/documentation.html
#include <GLFW/glfw3.h>
#include <iostream>
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
{
std::cout<< "xxx\n";
return -1;
}
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
std::cout<< "yyy\n";
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
Followed this stackoverflow question How to build & install GLFW 3 and use it in a Linux project
compiled it as -
g++ -I/usr/local/include glfw.cpp -L/usr/local/lib -lGL -lGLU -lglfw3 -lX11 -lXxf86vm -lXrandr -lpthread -lXi -lrt
It could successfully compile. However when I launch the executable, I it prints
yyy
Which means the window was not created. What could have been wrong, how can I fix it?