-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Using raylib with Cpp
This page will go over some of the common questions new users of raylib have when using C++.
raylib works with C++ in the exact same way it does with the C language. You can use raylib from C++ with no special modifications or build steps. Simply include raylib for your compiler and platform in the exact same way you do for C. raylib is fully compatible with both C and C++.
No, raylib-cpp
is not required to use raylib with C++. raylib-cpp
is an optional wrapper that sits on top of the regular C raylib in order to provide object oriented access to raylib. raylib-cpp
still calls the same C raylib in the end.
How can I fix C compound-literals related errors?
You can get the folllowing error when building raylib examples in C++:
A parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax
This type of structure initialization (Vector3){ 1.0f, 2.0f, 3.0f }
is called a compound literal and is not supported by C++. Some C++ compilers are strict and will not allow it. This code can be converted to brace initialization in C++ by simply removing the parentheses around the type. Changing the code to Vector3{ 1.0f, 2.0f, 3.0f }
will fix the error.
This change needs to be made for code that is pulled from the raylib C examples.
DrawText()
takes a const char *text
, but I have a std::string
in C++; std::string
has a method named c_str()
, this will return the const char *str
stored in the string, use it as the argument for any C function that takes a const char *text
. Example:
DrawText(my_string.c_str(),0,0,20,RED);
It is a common Object Oriented pattern to use Resource Acquisition Is Initialization (RAII). It may seem obvious to use this pattern with textures and models in raylib. This is possible to do, but the developer must be aware of the object lifetime, and when copies are made. For shared resources you need to follow the rule of 5 (https://en.cppreference.com/w/cpp/language/rule_of_three).
It is very common for new developer to make a class like this to automatically load an unload textures when things are created or go out of scope.
class MySprite
{
private:
Texture2D m_texture = { 0 };
public:
MySprite(Texture2D texture)
:m_texture(texture);\
{
}
~MySprite()
{
UnloadTexture(m_texture);
}
};
The problem is when you use that class in code like this.
std::vector<MySprite> sprites;
MySprite aSprite(LoadTexture("Somefile.png"));
sprites.push_back(aSprite);
Push_back on the vector will make a copy of aSprite in the vector and then aSprite will go out of scope. The copy constructor for MySprite does not load a new texture, it just copies the ID values from the source texture. So then you have (for a short time) two objects that point to the same texture. When aSprite goes out of scope, it will call UnloadTexture and remove the texture ID from the GPU. So now you have a copy of the sprite in the container that points to an unloaded texture. This will not work for drawing.
If you want to use this pattern, you need to ensure that you don't make copies of things that contain shared resources. The simplest way to handle this is to remove the assignment and copy constructor operators and use std::move or emplace features to ensure that the container owns the data and manages the lifetime.
class MySprite
{
private:
Texture2D m_texture = { 0 };
public:
MySprite(Texture2D texture)
: m_texture(texture)
{
}
MySprite(const MySprite&) = delete;
MySprite& operator = (const MySprite&) = delete;
~MySprite()
{
UnloadTexture(m_texture);
}
};
std::vector<MySprite> sprites;
sprites.emplace_back(LoadTexture("SomeFile.png"));
Scope and object lifetime are very important when dealing with this pattern.
www.raylib.com | itch.io | GitHub | Discord | YouTube
- Architecture
- Syntax analysis
- Data structures
- Enumerated types
- External dependencies
- GLFW dependency
- libc dependency
- Platforms and graphics
- Input system
- Default shader
- Custom shaders
- Coding conventions
- Integration with other libs
- Working on Windows
- Working on macOS
- Working on GNU Linux
- Working on Chrome OS
- Working on FreeBSD
- Working on Raspberry Pi
- Working for Android
- Working for Web (HTML5)
- Working on exaequOS Web Computer
- Creating Discord Activities
- Working anywhere with CMake
- CMake Build Options
- raylib templates: Get started easily
- How To: Quick C/C++ Setup in Visual Studio 2022, GCC or MinGW
- How To: C# Visual Studio Setup
- How To: VSCode
- How To: Eclipse
- How To: Sublime Text
- How To: Code::Blocks