(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.
I've installed WSL2 on Windows 10 along with GLFW. When I try to run the default GLFW example program, I run into the following error X11: The DISPLAY environment variable is missing. I build the program using this command-line:
g++ main.cpp -lglfw -lGL -o main
Program:
#include <stdio.h>
#include <iostream>
#include <GLFW/glfw3.h>
static void glfwError(int /*id*/, const char* description)
{
std::cerr << description << '\n';
exit(0);
}
int main(void)
{
GLFWwindow* window;
glfwSetErrorCallback(&glfwError);
/* 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;
}
How can I fix this issue?
I'm starting to learn the OpenGL stuff, but unfortunately, I can't make the initialization right.
I've added the glfw and glew libraries and these functions give me a strange error,
how can I make it work?
The code:
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
{
std::cout << "GLFW initialization failed.\n";
return -1;
}
if (glewInit()!=GLEW_OK)
{
std::cout << "GLEW initialization failed.\n";
return -1;
}
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
std::cout << "Wiondow failed.\n";
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;
}
The errors:
To link the GLEW library correctly, proper preprocessor definitions have to be set. See GLEW - Installation:
[...] On Windows, you also need to define the GLEW_STATIC preprocessor token when building a static library or executable, and the GLEW_BUILD preprocessor token when building a dll [...]
While trying to load a .png file with IMG_LoadTexture(renderer, "idle.png")
SDL_GetError() says: "Couldn't open idle.png"
There are no compiler errors, just a black window appears.
This is my main.cpp
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <iostream>
int main(int argc, char** argv) {
SDL_Event event;
SDL_Renderer *renderer = NULL;
SDL_Texture *texture = NULL;
SDL_Window *window = NULL;
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
SDL_CreateWindowAndRenderer(
800, 600,
0, &window, &renderer
);
IMG_Init(IMG_INIT_PNG);
texture = IMG_LoadTexture(renderer, "idle.png");
std::cout << SDL_GetError();
while (1) {
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
if (SDL_PollEvent(&event) && event.type == SDL_QUIT)
break;
}
SDL_DestroyTexture(texture);
IMG_Quit();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
But I guess the problem is the way I link the library. I installed sdl2, sdl2_image and libpng.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
project(untitled)
set(CMAKE_CXX_STANDARD 17)
add_executable(untitled main.cpp)
INCLUDE(FindPkgConfig)
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
PKG_SEARCH_MODULE(SDL2IMAGE REQUIRED SDL2_image>=2.0.0)
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(untitled ${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARIES})
You are loading the image from the current working directory (CWD) of your application. That is not necessarily the same directory as your executable is in (it depends on how it is launched), which you seem to assume.
3 easy ways to fix:
change the cwd at runtime to where the file is and load as you do now.
provide an absolute path to the file when loading, so cwd is irrelevant.
obtain the path to the executable at runtime and then construct a path to the file relative to where the executable is. (best option in my opinion since it's robust against moving your project around/installing to a different location).
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.