Qt + CMake + VC++ produce a command prompt - c++

I am using the combination mentioned in the title while trying to run the window layout example from the qt tutorials. The main looks like this:
#include <QtGui>
int main(int argc, char **argv) {
QApplication app(argc, argv);
QWidget window;
QLabel *label = new QLabel(QApplication::translate("windowlayout", "Name:"));
QLineEdit *lineEdit = new QLineEdit();
QHBoxLayout *layout = new QHBoxLayout();
layout->addWidget(label);
layout->addWidget(lineEdit);
window.setLayout(layout);
window.setWindowTitle(
QApplication::translate("windowlayout", "Window layout"));
window.show();
return app.exec();
}
And the CMakeLists.txt like this:
PROJECT(test)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0)
FIND_PACKAGE(Qt4 REQUIRED)
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR} ${QT_QTCORE_INCLUDE_DIR} ${QT_QTGUI_INCLUDE_DIR})
SET(test_SRCS main.cc)
QT4_AUTOMOC(${test_SRCS})
ADD_EXECUTABLE(test ${test_SRCS})
TARGET_LINK_LIBRARIES(test ${QT_QTGUI_LIBRARIES} ${QT_QTCORE_LIBRARIES})
The building and compilation work properly but when I run the application, it always show a command prompt. How do I avoid that?

You need to tell CMake that you want a GUI application:
# GUI Type
if(WIN32)
set(GUI_TYPE WIN32)
endif(WIN32)
if(APPLE)
set(GUI_TYPE MACOSX_BUNDLE)
endif(APPLE)
ADD_EXECUTABLE(test ${GUI_TYPE} ${test_SRCS})
Note that when you are compiling on Windows, this will change the program entry from main() to WinMain(), so you will need to modify your sources as well.
Here's what I usually do:
#ifdef _WIN32
class Win32CommandLineConverter;
int CALLBACK WinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */, int /* nCmdShow */)
{
Win32CommandLineConverter cmd_line;
return main(cmd_line.argc(), cmd_line.argv());
}
class Win32CommandLineConverter {
private:
std::unique_ptr<char*[]> argv_;
std::vector<std::unique_ptr<char[]>> storage_;
public:
Win32CommandLineConverter()
{
LPWSTR cmd_line = GetCommandLineW();
int argc;
LPWSTR* w_argv = CommandLineToArgvW(cmd_line, &argc);
argv_ = std::unique_ptr<char*[]>(new char*[argc]);
storage_.reserve(argc);
for(int i=0; i<argc; ++i) {
storage_.push_back(ConvertWArg(w_argv[i]));
argv_[i] = storage_.back().get();
}
LocalFree(w_argv);
}
int argc() const
{
return static_cast<int>(storage_.size());
}
char** argv() const
{
return argv_.get();
}
static std::unique_ptr<char[]> ConvertWArg(LPWSTR w_arg)
{
int size = WideCharToMultiByte(CP_UTF8, 0, w_arg, -1, nullptr, 0, nullptr, nullptr);
std::unique_ptr<char[]> ret(new char[size]);
WideCharToMultiByte(CP_UTF8, 0, w_arg, -1, ret.get(), size, nullptr, nullptr);
return ret;
}
};
#endif

I wanted a release build to hide the console but all other builds to show it. To do that use:
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
SET_TARGET_PROPERTIES(MyApp PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE")
SET_TARGET_PROPERTIES(MyApp PROPERTIES RELWITHDEBINFO "/SUBSYSTEM:CONSOLE")
SET_TARGET_PROPERTIES(MyApp PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
SET_TARGET_PROPERTIES(MyApp PROPERTIES MINSIZEREL "/SUBSYSTEM:WINDOWS")
endif(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
This will introduce the following linker error:
error LNK2019: unresolved external symbol _WinMain#16 referenced in function ___tmainCRTStartup
to fix it link with QT_QTMAIN_LIBRARY in your CMakeLists.txt file
TARGET_LINK_LIBRARIES(MyApp ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${OTHER_STUFF_TO_LINK})
Now you don't even have to change your sources as was done in the previous solution.

In your CMakeFile with Qt4, you don't need to change your CPP code or to add flags at compile time. Simply use
set(QT_USE_QTMAIN TRUE)
It will automatically link qtmain.lib with your executable. This library defines other common main() signatures, including WinMain().
With this trick, your app can compile with MSVC under Windows, without mofiying your original main() function and without displaying a console when you run your app outside of your IDE (QtCreator for example).
Final resulting CMakeLists.txt can be :
PROJECT(test)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0)
FIND_PACKAGE(Qt4 REQUIRED)
if(WIN32)
SET(QT_USE_QTMAIN TRUE)
endif(WIN32)
INCLUDE(${QT_USE_FILE})
SET(test_SRCS main.cc)
QT4_AUTOMOC(${test_SRCS})
ADD_EXECUTABLE(test ${test_SRCS})
TARGET_LINK_LIBRARIES(test ${QT_LIBRARIES})
Additionnaly, you don't need to include QtCore and QtGui, they are included by default with QT_USE_FILE (for include folders) and QT_LIBRARIES (for libraries).
You only have to set what modules you use, or you don't use (for Gui) :
# Use Network and Sql modules
set(QT_USE_QTNETWORK TRUE)
set(QT_USE_QTSQL TRUE)
# Do not use Gui module
set(QT_DONT_USE_QTGUI TRUE)

in the pro file, remove the following console definition and it will go
CONFIG += console

Related

Cant find SDL.h - Windows, MingW, Cmake and SLD2 (in VSCode with CPP)

I want to add SDL2 to a Cmake Project, using C++ in VSCode on Windows, but using Mingw64 from Msys2 (g++).
This is my current CMakeLists.txt:
cmake_minimum_required(VERSION 3.5)
project(TileGameStudio_Runtime LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(PROJ_SRC
${PROJECT_SOURCE_DIR}/src
)
add_subdirectory(${PROJECT_SOURCE_DIR}/SDL2)
include_directories(${PROJECT_SOURCE_DIR}/SDL2/include)
file(GLOB PROJECT_SOURCES CONFIGURE_DEPENDS
${PROJ_SRC}/*.cpp
)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}\\Game")
set(EXECUTABLE_OUTPUT_PATH "${PROJECT_SOURCE_DIR}\\Game")
# add the executable
add_executable(TileGameStudio_Runtime
${PROJECT_SOURCES}
)
target_link_libraries(TileGameStudio_Runtime PRIVATE
SDL2-static
SDL2main
)
set_target_properties(
TileGameStudio_Runtime
PROPERTIES
OUTPUT_NAME "Game"
SUFFIX ".exe"
)
This is my current Project Structure (img)
As you can see. i cloned the Repo from https://github.com/libsdl-org/SDL as a subdirectory to my Project. And this, i added via cmake add_subdirectory.
My Main.cpp is simply this:
#include <iostream>
#include <vector>
#include <string>
#include <SDL.h>
#ifdef main
# undef main
#endif /* main */
using namespace std;
int main(int argc, char *argv[]) {
SDL_Window *win = NULL;
SDL_Renderer *renderer = NULL;
int posX = 100, posY = 100, width = 320, height = 240;
SDL_Init(SDL_INIT_VIDEO);
win = SDL_CreateWindow("Hello World", posX, posY, width, height, 0);
renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
//================================================ Draw a Text
//this opens a font style and sets a size
TTF_Font* Sans = TTF_OpenFont("Sans.ttf", 24);
// this is the color in rgb format,
// maxing out all would give you the color white,
// and it will be your text's color
SDL_Color White = {255, 255, 255};
// as TTF_RenderText_Solid could only be used on
// SDL_Surface then you have to create the surface first
SDL_Surface* surfaceMessage = TTF_RenderText_Solid(Sans, "put your text here", White);
SDL_Texture* Message = SDL_CreateTextureFromSurface(renderer, surfaceMessage);
SDL_Rect Message_rect; //create a rect
Message_rect.x = 0; //controls the rect's x coordinate
Message_rect.y = 0; // controls the rect's y coordinte
Message_rect.w = 100; // controls the width of the rect
Message_rect.h = 100; // controls the height of the rect
SDL_RenderCopy(renderer, Message, NULL, &Message_rect);
//================================================ Draw a Text End
while (1) {
SDL_Event e;
if (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT) {
break;
}
}
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}
Which should create a Window.. and perhaps draw a text to it.
But, SDL.h can´t be found... so i can´t build the Stuff here..
I updated my CMakeLists.txt, cause i reinstalled the whole msys2 (since of a installation problem).
This is the new One:
cmake_minimum_required(VERSION 3.5)
project(TileGameStudio_Runtime LANGUAGES CXX)
set(CMAKE_CXX_FLAGS -v)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(PROJ_SRC
${PROJECT_SOURCE_DIR}/src
)
file(GLOB PROJECT_SOURCES CONFIGURE_DEPENDS
${PROJ_SRC}/*.cpp
)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}\\Game")
set(EXECUTABLE_OUTPUT_PATH "${PROJECT_SOURCE_DIR}\\Game")
INCLUDE(FindPkgConfig)
pkg_check_modules(SDL2 REQUIRED sdl2)
pkg_check_modules(SDL2_IMAGE REQUIRED SDL2_image)
pkg_check_modules(SDL2_TTF REQUIRED SDL2_ttf)
pkg_check_modules(SDL2_MIXER REQUIRED SDL2_mixer)
include_directories(
${SDL2_INCLUDE_DIRS}
${SDL2_IMAGE_INCLUDE_DIRS}
${SDL2_TTF_INCLUDE_DIRS}
${SDL2_MIXER_INCLUDE_DIRS}
)
link_directories (
${SDL2_LIBRARY_DIRS}
${SDL2_IMAGE_LIBRARY_DIRS}
${SDL2_TTF_LIBRARY_DIRS}
${SDL2_MIXER_LIBRARY_DIRS}
)
# add the executable
add_executable(TileGameStudio_Runtime
${PROJECT_SOURCES}
)
target_link_libraries (TileGameStudio_Runtime
${SDL2_LIBRARIES}
${SDL2_IMAGE_LIBRARIES}
${SDL2_TTF_LIBRARIES}
${SDL2_MIXER_LIBRARIES}
)
set_target_properties(
TileGameStudio_Runtime
PROPERTIES
OUTPUT_NAME "Game"
SUFFIX ".exe"
)
I installed the whole mingw64 toolchain and SDL2 via msys (under MingW64 Mode of msys2) now.
it still couldn´t find the SDL.h or SDL2/SDL.h
I checked the SDL2_Dir in the Cmake GUI.. and it has the correct Path to: "C:/msys64/mingw64/lib/cmake/SDL2"
EDIT:
I now changed the Main Folder of all my Projects (unreal, unity..etc) from "Game Design" to "Game_Design".. Working like a Charm now... Cause.. Spaces are evil.. very evil...
Thanks for your Help Trys :D <3

c++ Qt inheriting from QWidget gives linking error re missing vtable

I am on MacOS and I want to inherit QWidget for a class with QObject :: connect but i have a error:
Undefined symbols for architecture x86_64:
"vtable for Core", referenced from:
Core::Core(QWidget*) in Core.cpp.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [bin/babel] Error 1
make[1]: *** [CMakeFiles/babel.dir/all] Error 2
Core.cpp
** EPITECH PROJECT, 2020
** Babel
** File description:
** Core
*/
#include "../include/Core.hpp"
Core::Core(QWidget *parent) : QWidget(parent)
{
this->text = new QLabel("Pseudo", this);
this->textArea = new QTextEdit(this);
this->button = new QPushButton("Connexion", this);
QObject::connect(this->button, SIGNAL(clicked()), this, SLOT(this->buttonPushed()));
this->button->setGeometry(300, 250, 160, 30);
this->textArea->setGeometry(300, 200, 160, 30);
this->text->setGeometry(335, 175, 160, 30);
}
Core::~Core()
{
}
void Core::buttonPushed()
{
printf("EKIP EKIP EKIP\n");
}
Core.hpp:
/*
** EPITECH PROJECT, 2020
** Babel
** File description:
** Core
*/
#ifndef CORE_HPP_
#define CORE_HPP_
#include <stdio.h>
#include <stdlib.h>
#include <opus/opus.h>
#include <portaudio.h>
#include <QtWidgets>
class Core : public QWidget {
Q_OBJECT
public:
explicit Core(QWidget *parent = nullptr);
~Core();
protected:
private slots:
void buttonPushed();
private:
// QApplication *app;
QPushButton *button;
QLabel *text;
QTextEdit *textArea;
};
#endif /* !CORE_HPP_ */
and Main.cpp
/*
** EPITECH PROJECT, 2020
** Babel
** File description:
** main
*/
#include "../include/Core.hpp"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
Core *core = new Core();
core->setGeometry(10, 10, 720, 480);
core->setWindowTitle("Babel");
core->show();
return app.exec();
}
Cmake file:
project(Babel)
cmake_minimum_required(VERSION 2.8.12)
add_definitions("-fPIC")
SET(CMAKE_AUTOMOC ON)
SET(CMAKE_AUTOUIC ON)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Core)
find_package(Qt5Network)
file(GLOB_RECURSE BABEL_SRC PATH ./sources/*.cpp)
include_directories(${CMAKE_INCLUDE_PATH})
add_executable(babel ${BABEL_SRC})
target_link_libraries(babel ${CONAN_LIBS} Qt5::Widgets Qt5::Core Qt5::Network)
add the files with Q_OBJECT in the cmake like this for example :
set(SOURCES core.cpp )
qt5_wrap_cpp(SOURCES core.hpp)
add_executable(babel ${SOURCES} ${BABEL_SRC})

Executable can't find SDL2.dll

I have been trying to figure out why CMake is not adding the static libraries of SDL2. If I add the SDL2.dll file next to the executable, then it does work.
It al builds fine and the headers can be found nice and easily.
The error
My CMakeList.txt looks like this. Trust me, I have tried everything but clearly I am doing something wrong.
cmake_minimum_required(VERSION 3.7)
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
SET(SDL2_DIR ./lib)
project(SDL2Test)
find_package(SDL2 REQUIRED)
include_directories(SDL2Test ${SDL2_INCLUDE_DIRS})
add_executable(SDL2Test Main.cpp)
target_link_libraries(SDL2Test ${SDL2_LIBRARIES})
This is the sdl2-config.cmake:
set(SDL2_INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}/../include")
# Support both 32 and 64 bit builds
if (${CMAKE_SIZEOF_VOID_P} MATCHES 8)
set(SDL2_LIBRARIES "${CMAKE_CURRENT_LIST_DIR}/x64/SDL2.lib;${CMAKE_CURRENT_LIST_DIR}/x64/SDL2main.lib")
else ()
set(SDL2_LIBRARIES "${CMAKE_CURRENT_LIST_DIR}/x86/SDL2.lib;${CMAKE_CURRENT_LIST_DIR}/x86/SDL2main.lib")
endif ()
string(STRIP "${SDL2_LIBRARIES}" SDL2_LIBRARIES)
This is the Main.cpp
#include "SDL.h"
using namespace std;
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *window = SDL_CreateWindow(
"SDL2Test",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
640,
480,
0
);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
SDL_Delay(3000);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Your SDL2.lib is import library, that requires accompanying DLL in the runtime.
To use static library (one that is completely linked with your EXE and does not require DLL), you will need to build static version of SDL2.lib yourself.
Keep in mind that this is discouraged by the author of SDL

SDL_image Can't load .png file with IMG_LoadTexture()

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).

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.