I'm struggling with creating a window with the GLFW 3 function, glfwCreateWindow.
I have set an error callback function, that pretty much just prints out the error number and description, and according to that the GLFW library have not been initialized, even though the glfwInit function just returned success?
Here's an outtake from my code
// Error callback function prints out any errors from GFLW to the console
static void error_callback( int error, const char *description )
{
cout << error << '\t' << description << endl;
}
bool Base::Init()
{
// Set error callback
/*!
* According to the documentation this can be use before glfwInit,
* and removing won't change anything anyway
*/
glfwSetErrorCallback( error_callback );
// Initialize GLFW
/*!
* This return succesfull, but...
*/
if( !glfwInit() )
{
cout << "INITIALIZER: Failed to initialize GLFW!" << endl;
return false;
}
else
{
cout << "INITIALIZER: GLFW Initialized successfully!" << endl;
}
// Create window
/*!
* When this is called, or any other glfw functions, I get a
* "65537 The GLFW library is not initialized" in the console, through
* the error_callback function
*/
window = glfwCreateWindow( 800,
600,
"GLFW Window",
NULL,
NULL );
if( !window )
{
cout << "INITIALIZER: Failed to create window!" << endl;
glfwTerminate();
return false;
}
// Set window to current context
glfwMakeContextCurrent( window );
...
return true;
}
And here's what's printed out in the console
INITIALIZER: GLFW Initialized succesfully!
65537 The GLFW library is not initialized
INITIALIZER: Failed to create window!
I think I'm getting the error because of the setup isn't entirely correct, but I've done the best I can with what I could find around the place
I downloaded the windows 32 from glfw.org and stuck the 2 includes files from it into minGW/include/GLFW, the 2 .a files (from the lib-mingw folder) into minGW/lib and the dll, also from the lib-mingw folder, into Windows/System32
In code::blocks I have, from build options -> linker settings, linked the 2 .a files from the download. I believe I need to link more things, but I can figure out what, or where I should get those things from.
I tried reinstalling codeblocks and mingw, which solved the issue.
Seems like GLFW3 doesn't like having previous versions installed at the same time for some reason, so if anyone else is having a similar problem, you might want to try that.
I experienced similar problems in Cocos 3.8.1 and 3.10.
I have never installed codeblocks or mingw, so it did not make sense to install them for me.
The GLFW.lib file in the cocos directory is out of date.
http://www.glfw.org/download.html, and replace the lib file in your project with the latest one, and it may resolve your error.
Related
After my first successful attempt at a 3D engine using Java and OpenGL (LWJGL3), I have decided to try my hand at Vulkan, using C++.
I have barely any experience with C/C++ and I am aware of the steep learning curve of Vulkan. This is however not a problem.
I decided to follow this tutorial: https://vulkan-tutorial.com/Introduction
It has showed me how to create a new project with Vulkan using XCode (as I am on Mac OS Mojave). I would, however, like to continue the rest of the tutorial using CLion as I would be switching between multiple operating systems.
I tried my hand at creating a CLion project and succeeded in making my first CMakeLists file, however something seems to be wrong. The file currently consists of the following:
cmake_minimum_required(VERSION 3.12)
project(VulkanTesting)
set(CMAKE_CXX_STANDARD 14)
add_executable(VulkanTesting main.cpp)
include_directories(/usr/local/include)
include_directories(/Users/[username]/Documents/Vulkan/SDK/vulkansdk-macos-1.1.92.1/macOS/include)
target_link_libraries(VulkanTesting /usr/local/lib/libglfw.3.3.dylib)
target_link_libraries(VulkanTesting /Users/[username]/Documents/Vulkan/SDK/vulkansdk-macos-1.1.92.1/macOS/lib/libvulkan.1.dylib)
target_link_libraries(VulkanTesting /Users/[username]/Documents/Vulkan/SDK/vulkansdk-macos-1.1.92.1/macOS/lib/libvulkan.1.1.92.dylib)
# Don't know if I need the next two lines
link_directories(/usr/local/lib)
link_directories(/Users/[username]/Documents/Vulkan/SDK/vulkansdk-macos-1.1.92.1/macOS/lib)
The reason I showed the above file will become apparent in the question.
The 'Program' so far is the following:
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#include <iostream>
#include <stdexcept>
#include <functional>
#include <cstdlib>
#include <vector>
const int WIDTH = 800;
const int HEIGHT = 600;
class HelloTriangleApplication {
public:
void run() {
initWindow();
initVulkan();
mainLoop();
cleanup();
}
private:
GLFWwindow* window;
VkInstance instance;
void initWindow(){
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
window = glfwCreateWindow(WIDTH, HEIGHT, "My first Vulkan window", nullptr, nullptr);
}
void initVulkan() {
createInstance();
}
void createInstance(){
// Instantiate Application Info
VkApplicationInfo applicationInfo = {};
applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
applicationInfo.pApplicationName = "Hello Triangle";
applicationInfo.applicationVersion = VK_MAKE_VERSION(1,0,0);
applicationInfo.pEngineName = "No Engine";
applicationInfo.engineVersion = VK_MAKE_VERSION(1,0,0);
applicationInfo.apiVersion = VK_API_VERSION_1_0;
// Instantiate Instance Creation Info
VkInstanceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pApplicationInfo = &applicationInfo;
// Get GLFW platform specific extensions
uint32_t glfwExtensionCount = 0;
const char** glfwExtensions;
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
// Fill in required extensions in Instance Creation Info
createInfo.enabledExtensionCount = glfwExtensionCount;
createInfo.ppEnabledExtensionNames = glfwExtensions;
// For validation layers, this is a later step in the tutorial.
createInfo.enabledLayerCount = 0;
// Create the Vulkan instance, and check if it was successful.
VkResult result = vkCreateInstance(&createInfo, nullptr, &instance);
if(result != VK_SUCCESS){
std::cout << "glfwExtensionCount: " << glfwExtensionCount << "\n";
std::cout << "glfwExtensionNames: " << &glfwExtensions << "\n";
std::cout << "result: " << result << "\n";
throw std::runtime_error("Failed to create Vulkan Instance");
}
}
void mainLoop() {
while(!glfwWindowShouldClose(window)){
glfwPollEvents();
}
}
void cleanup() {
glfwDestroyWindow(window);
glfwTerminate();
}
};
int main() {
HelloTriangleApplication app;
try {
app.run();
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
The problem I am having is that when I try to run the program, it will not create a VkInstance. The function returns VK_ERROR_INCOMPATIBLE_DRIVER. Now, I doubt that the driver is in fact incompatible as I have run the demo applications that came with the Vulkan SDK for one, and for another I have been able to run the exact same 'program' in XCode. When I investigated the problem a bit further, I noticed that the glfwGetRequiredInstanceExtensions function returns no extensions when the program is run in CLion like this, but does return one in the XCode equivalent.
This all leads me to believe that there is something I have done wrong in linking the libraries/frameworks in the Cmake file because I am aware of the fact that Vulkan is not directly supported in Mac OS, but instead (somehow?) passes through a layer to communicate with Metal.
Do I need to specify a way for the program to pass its Vulkan functionality through a Metal layer, and is this done automagically in XCode, or is there another problem with my approach?
Any help would be greatly appreciated!
You might want to look at the MacOS Getting Started Guide on the LunarXchange website and in your SDK. There is a section at the end that shows how to use CMake to build a Vulkan app and run it on MacOS. You also may want to use the FindVulkan CMake module instead of manually setting the include directories and the target link libraries.
But my first guess about your specific problem is that you may not be setting the VK_ICD_FILENAMES environment variable. You are correct in your observation that there is no direct support for Vulkan. Instead, the support is provided by the MoltenVK library which is treated as a Vulkan driver. But this "driver" is not installed in any system directory by the SDK. The SDK is just unzipped in your home directory structure, so you must tell the Vulkan loader where to find it via this environment variable.
Again, the CMake section at the end of the Getting Started Guide demonstrates the use of this environment variable. And the entire guide goes into additional detail about how the various Vulkan and MoltenVK components work.
I'm trying to write a C++ wrapper class around some SDL2 classes.
Now I have this working code, which displays a red screen for 5 seconds (as you can see, my wrapper classes are in namespace sdl2cc):
int main(void)
{
if (SDL_Init(SDL_INIT_VIDEO) < 0) return 1;
sdl2cc::Window window{"SDL_RenderClear"s, sdl2cc::Rect{sdl2cc::Point{SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED}, sdl2cc::Dimension{512, 512}}, {}};
sdl2cc::Renderer renderer{window, {}};
renderer.draw_color(sdl2cc::Color{sdl2cc::RGB{255,0,0}, sdl2cc::Alpha{255}});
SDL_RenderClear(renderer.data());
// renderer.clear();
SDL_RenderPresent(renderer.data());
// renderer.present();
SDL_Delay(5000);
SDL_Quit();
}
In the wrapper class of SDL2's SDL_Renderer I have a std::unique_ptr data member renderer_ pointing to an actual SDL_Renderer.
renderer.data() exposes this pointer (return this->renderer_.get();).
I want to get the member functions renderer.clear() and renderer.present() to work. Sadly neither do. This is how they look:
void sdl2cc::Renderer::clear(void)
{
if (SDL_RenderClear(this->data()) < 0)
{
std::cerr << "Couldn't clear rendering target with drawing color:" << ' ' << SDL_GetError() << '\n';
}
}
void sdl2cc::Renderer::present(void)
{
SDL_RenderPresent(this->data());
}
If I just use renderer.clear(), it will print my error message + Invalid renderer.
If I just use renderer.present(), it will show a black screen.
What is wrong?
Why are my own functions and the SDL functions not equivalent?
The problem seems to lie in the function call:
SDL_RenderClear(renderer.data()); // works
// somewhere else:
void sdl2cc::Renderer::clear(SDL_Renderer* r)
{
if (SDL_RenderClear(r) < 0)
{
std::cerr << "Couldn't clear rendering target with drawing color:" << ' ' << SDL_GetError() << '\n';
}
}
renderer.clear(renderer.data()); // doesn't work: Invalid Renderer
But I still don't understand where the problem lies. To me it seems to accomplish the same thing, but somehow one throws an error, the other doesn't.
EDIT:
Another interesting thing, trying to step in at renderer.clear() with lldb goes directly to the next line, without actually stepping in... I don't even.
The problem had to do with multiply linked libraries.
I compiled my own library with the SDL2 libraries and then compiled my executable with my library and the SDL2 libraries.
My goal is to be able to use a joystick inside of Qt (to add a piloting task to an existing Qt app)
Note : Qt 5.4 // SFML 2.2 (running on CentOS7)
In order to do so, I used the tutorial on the sfml website explaining how to insert an sfml window inside of a Qt widget. That tutorial ( http://www.sfml-dev.org/tutorials/1.6/graphics-qt.php ) being too old, I had to change some things in order to update it for sfml 2.2.
However things do not work as intended and while it does compile, it seems to be unable to create the sfml window from the winid and end up crashing
Here is the part of code corresponding to the window creation :
void QSFMLCanvas::showEvent(QShowEvent*)
{
if (!myInitialized)
{
std::cout << "Bla" << std::endl;
// Under X11, we need to flush the commands sent to the server to ensure that
// SFML will get an updated view of the windows
#ifdef Q_WS_X11
XFlush(QX11Info::display());
#endif
std::cout << "Blabla" << std::endl;
// Create the SFML window with the widget handle
sf::WindowHandle HANDLE;
HANDLE = static_cast<sf::WindowHandle>(winId());
std::cout << HANDLE << std::endl;
std::cout << "Blablabla" << std::endl;
sf::RenderWindow::create(HANDLE);
std::cout << "Blablablabla" << std::endl;
// Let the derived class do its specific stuff
OnInit();
// Setup the timer to trigger a refresh at specified framerate
connect(&myTimer, SIGNAL(timeout()), this, SLOT(repaint()));
myTimer.start();
myInitialized = true;
}
}
And here is the output
Bla
Blabla
35651593
Blablabla
...and crash
As you see it seems to have no trouble obtaining the window handle but can't create the sfml renderwindow from it
Note that there is a static_cast for the handle that isn't there in the tutorial. Different questions suggested putting a reinterpret_cast but then it gives me this error
QSFMLCanvas.cpp: In member function ‘virtual void QSFMLCanvas::showEvent(QShowEvent*)’:
QSFMLCanvas.cpp:48:60: erreur: invalid cast from type ‘WId {aka long long unsigned int}’ to type ‘sf::WindowHandle {aka long unsigned int}’
HANDLE = reinterpret_cast<sf::WindowHandle>(winId());
Is there a way to solve this problem ? Or are just SFML & Qt fated to never work together anymore ?
Thank you for your help
Im using the latest SDL 2.0 version on Xubuntu 64-bits. I installed through the provided install script on the source code.
Compiling works well, however when trying to open a font or image (regardless of its extension), it will always fail to open.
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
int main (int argc, char *argvp[])
{
if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
{
cout << SDL_GetError() << endl;
}
if (TTF_Init() == -1)
{
std::cout << TTF_GetError() << std::endl;
return 2;
}
TTF_Font *font1 = NULL;
font1 = TTF_OpenFont("SourceSansPro-Regular.ttf", 20);
if (font1 == NULL)
{
std::cout << "ERROR OPENING FONT = " << TTF_GetError() << std::endl;
}
TTF_CloseFont(font1);
SDL_Quit();
return 0;
}
I compiled with
g++ -Wall fontTEST.cpp -o TEST -lSDL2 -lSDL_ttf (NOTE that SDL_ttf installs as such, not as SDL2_ttf)
And get the following error: Failed to load font: 0 Couldn't load font file
This happens with images as well. I've already tried with different fonts and images, apparently it works if I compile with SDL 1.2, just not with 2.0.
Also why does the provided install script installs the lib and include folders in /user/local/?
I moved them to /usr/ but the problem persists.
Remember the following:
On Unix, file paths are case-sensitive
As said in Xonar's comment, tilde '~' expansion is a shell feature, it does not work in C/C++ programs, you should use the real path instead.
The strace log says clearly that something is wrong with the path.
You should try the following:
Rename your font file to "font.ttf"
put it in /home/user/font.ttf
use "/home/user/font.ttf" as the path in your code.
I am writing a game in allegro and would like to load some image files. However, whenever I call al_load_bitmap, I am getting a null pointer. I am using XCode 4.1 as my IDE. I would try compiling using g++ (in case it is a path issue) however I don't know what I need to do in order to compile it in the command line with g++ (simply g++ main.cpp does not work). Anyways, here is my code:
ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_RESOURCES_PATH);
for (int i = 0; i < NUM_TILES; i++)
{
switch (static_cast<Tile>(i)) {
case GRASS:
al_set_path_filename(path, "grass.png");
tileFiles[i] = al_load_bitmap(al_path_cstr(path, '/'));
if (!tileFiles[i])
{
std::cerr<<"grass.png not initialized"<<std::endl;
}
break;
case DIRT:
al_set_path_filename(path, "dirt.png");
tileFiles[i] = al_load_bitmap(al_path_cstr(path, '/'));
if (!tileFiles[i])
{
std::cerr<<"dirt.png not initialized"<<std::endl;
}
break;
default:
std::cerr
<< "Missing case statement for datatype Tile numbered at "
<< i
<< " in Board::Board (float mw, float mh, int tst)"
<< " declared in Board.cpp."
<< std::endl;
break;
}
}
I have already run:
if(!al_init_image_addon()) {
al_show_native_message_box(display, "Error", "Error", "Failed to initialize al_init_image_addon!",
NULL, ALLEGRO_MESSAGEBOX_ERROR);
return -1;
}
and I have also put:
#include "allegro5/allegro_image.h"
#include "allegro5/allegro_native_dialog.h"
at the top of my file. Neither grass.png, nor dirt.png load and they are in the exact same directory as my main.cpp file. I get no compilation errors, but I consistently get the null pointer when I try to load my images, so when it comes time to draw them to the display, they do not show. Please help!
Neither grass.png, nor dirt.png load and they are in the exact same directory as my main.cpp file
Just a debugging tip... If you were to output the result of al_path_cstr(path, '/') to the console, it should be extremely obvious why the call is failing.
ALLEGRO_RESOURCES_PATH is the location of "bundled resources," which on OS X means the directory of the executable file. (If you were to use an app bundle, then it would be the resource folder of the bundle.) As a quick check, just copy the images into the same directory that your executable file is being built.
Most IDEs have very odd directory structures, IMO. I would ultimately set it up so that you are building into something like:
/src/main.c
/include/main.h
/obj/release
/obj/debug
/bin/game.exe
/bin/game-debug.exe
/bin/image.png
But that's just my preference. Use whatever you like, but you should read the docs again to get a clear picture of the different locations that al_get_standard_path() reveals.
Okay, I had been having the same problem, and I was absolutely positive that I was looking in the correct directory and that the resources for the program were there. I used al_path_cstr(path, '/') and allegro's working directory was as expected. Then I looked at the resource file sizes....
All my resources in my build directory were zero bytes. Copied them over myself and it solved the issue. I hope this helps some one out!