[Feature Request]: Support for calling Debug Draw functions in GDExtension modules
Feature description
I recently began working on a game where the gameplay simulation loop runs in a C++ GDExtension. Previously, when making games using just GDScript, DebugDraw3D has been absolutely indispensible to me for debugging complicated vector math, where being able to visualize results in 3D space helps build an intuition for what's going on (and what's going wrong)
I've only been working in C++ for a few days and I'm already desperately missing this capability.
Implementation Ideas
No response
I was writing an addon that used Debug Draw 3D for debug visualisations, but I've started porting it to C++ for performance reasons, so this would be very nice to have!
@InevitablyDivinity In fact, I already have a partially working version of the Cpp API in a separate branch.
I think I need to rebase it to the master and check what's working at all. Probably all the usual draw_* calls should work.
But initially the idea was to support the C API, that is, to be able to access DebugDraw not only from C++.
Will it ever be on main? Would be nice to not have a separately built C-compatible extension that conflicts with a user's already installed main branch version.
It's an interesting task, but I doubt I'll have the motivation to finish everything as planned. Perhaps I will find simpler solutions and finish the work very quickly, in which case the changes will be merged into the master branch.
I have updated the cpp_api branch. Nothing seems to be broken. 😅
To test you just need to clone the repository and build the library.
git clone --recursive -b cpp_api --depth 1 https://github.com/DmitriySalnikov/godot_debug_draw_3d.git
cd godot_debug_draw_3d
scons apply_patches
scons target=editor
After that, a dd3d_cpp_api.hpp file should be created in the addons/debug_draw_3d/native_api/cpp folder, which you need to include in your code. An example of the C++ code is found in tests_native_api/cpp.
And don't forget to copy the compiled library for the editor from addons/debug_draw_3d/libs.
draw_box and scoped_config seem to work without problems and are much faster than GDScript.
But at the moment it's not really a "C API", but rather a "C++ API".
❯ scons apply_patches
scons: Reading SConscript files ...
If you add new source files (e.g. .cpp, .c), do not forget to specify them in 'src/default_sources.json'.
Or add them to 'setup_defines_and_flags' inside 'SConstruct'.
To apply git patches, use 'scons apply_patches'.
To generate native APIs, use 'scons gen_apis'.
Auto-detected 16 CPU cores available for build parallelism. Using 15 cores by default. You can override it with the -j argument.
Building for architecture x86_64 on platform linux
KeyError: 'lto':
File "/home/username/Code/Godot/godot_debug_draw_3d/SConstruct", line 212:
setup_defines_and_flags(env, additional_src)
File "/home/username/Code/Godot/godot_debug_draw_3d/SConstruct", line 102:
if env["lto"] != "none":
File "/usr/lib/python3.13/site-packages/SCons/Environment.py", line 580:
return self._dict[key]
Attempted building, but couldn't apply_patches
Windows, no problem (SCons: v4.8.1):
https://github.com/user-attachments/assets/d1de0d5c-26b9-4eb2-b180-1220cc0ba562
WSL, a completely different problem (SCons: v4.0.1):
https://github.com/user-attachments/assets/cba8590a-5dd4-45da-a38e-79e733df901c
I'm using SCons 4.8.1 (4.8.1-2 package on Arch Linux), and am not experienced enough with SCons to know why it happens.
I fixed SCons 4.0 support (f981da8ec6cab8111f8bb9e0a44861a2d4a6f122), but I didn't encounter any problems with lto.
https://github.com/user-attachments/assets/c67fc352-5696-464a-a2a8-a75630410d5e
Didn't you clone the repository, as I showed? This problem could most likely occur because you have godot-cpp for godot 4.1. In 4.2, the lto flag was added to godot-cpp itself, so I get it without additional checks.
I already had the repository cloned but forgot to update the submodules. Attempted building but now errors with:
/home/username/Code/Godot/godot_debug_draw_3d/src/3d/debug_draw_3d.cpp:64:33: error: 'exchange' is not a member of 'std'
64 | : world_id(std::exchange(other.world_id, 0)),
| ^~~~~~~~
What toolchain do you build with?
std::exchange should be available since C++14. godot-cpp requires C++17, and I'm using it.
Nothing special seems to be used, only gcc and g++:
Linking Shared Library addons/debug_draw_3d/libs/libdd3d.linux.editor.x86_64.so ...
scons: done building targets.
dima@DIMA-PC:~/godot_debug_draw_3d$ ls addons/debug_draw_3d/libs/
libdd3d.linux.editor.x86_64.so
dima@DIMA-PC:~/godot_debug_draw_3d$ gcc --version
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
dima@DIMA-PC:~/godot_debug_draw_3d$ g++ --version
g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
dima@DIMA-PC:~/godot_debug_draw_3d$ clang --version
Command 'clang' not found, but can be installed with:
sudo apt install clang
Using GCC 14 myself, maybe a further GCC update broke this.
You can also view the logs in gh-actions. And here is the link to the used ubuntu image.
For now I've just #included <utility> so I can move on with my port, as this is a trivial issue anyway.
#included<utility>
Strangely, builds for android, macos, or linux are usually interrupted by such errors.
I can just add this header to utils.h. 8cbaef64df85e40dc1ff2417504e0b044fa8c455
But judging by the cppreference std::move and std::swap is also from this header.
I'm trying to use DebugDraw3D to help debug my GDExtension.
I added godot_debug_draw_3d as a submodule and successfully ran scons apply_patches & scons target=editor.
Then, I appended "godot_debug_draw_3d/addons/debug_draw_3d/native_api/cpp" to my GDExtension's SCons CPPPATH.
Including <dd3d_cpp_api.hpp> in any .cpp file of my extension results in a load of errors, which I don't fully unterstand:
Compiling shared src\my_extension_file.cpp ...
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(286): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(286): error C2143: syntax error: missing ',' before '<'
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(291): error C2143: syntax error: missing ';' before '<'
I'm on Windows 11 using Godot 4.4.1.
Edit: I just noticed, the godot-cpp submodule of godot_debug_draw_3d is on 4.1. That might be the issue.
Updating that to the 4.4 branch and rebuilding everything unfortunately results in the same errors as before.
For me, the line 286 is:
/**
* Custom text Font
*/
> void set_text_custom_font(const Ref<godot::Font> & _custom_font) {
static void(*DebugDraw2DConfig_set_text_custom_font)(void *, const Ref<godot::Font> &) = nullptr;
LOAD_AND_CALL_FUNC_POINTER(DebugDraw2DConfig_set_text_custom_font, inst, _custom_font);
}
There may be a problem with Ref<T> as well as with godot::Font.
Were there any other errors in the logs?
Line 286 is the same for me.
Here's the full output:
scons: Reading SConscript files ...
Auto-detected 16 CPU cores available for build parallelism. Using 15 cores by default. You can override it with the -j argument.
Building for architecture x86_64 on platform windows
scons: done reading SConscript files.
scons: Building targets ...
scons: `godot-cpp\bin\libgodot-cpp.windows.template_debug.x86_64.lib' is up to date.
Compiling shared src\drg_terrain.cpp ...
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(286): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(286): error C2143: syntax error: missing ',' before '<'
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(291): error C2143: syntax error: missing ';' before '<'
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(291): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(291): error C2334: unexpected token(s) preceding '{'; skipping apparent function body
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(287): error C2065: 'DebugDraw2DConfig_set_text_custom_font': undeclared identifier
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(287): error C2144: syntax error: 'void' should be preceded by ')'
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(287): error C2144: syntax error: 'void' should be preceded by ';'
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(287): error C2059: syntax error: ','
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(287): error C2059: syntax error: ')'
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(288): error C2065: 'DebugDraw2DConfig_set_text_custom_font': undeclared identifier
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(288): error C2065: '_custom_font': undeclared identifier
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(288): error C3861: 'DebugDraw2DConfig_set_text_custom_font': identifier not found
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(991): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(991): error C2143: syntax error: missing ',' before '&'
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(992): error C2065: 'DebugDraw3D_draw_box': undeclared identifier
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(992): error C2143: syntax error: missing ')' before 'const'
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(992): error C2143: syntax error: missing ';' before 'const'
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(992): error C2059: syntax error: ','
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(992): error C2059: syntax error: ')'
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(993): error C2065: 'DebugDraw3D_draw_box': undeclared identifier
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(993): error C2065: 'rotation': undeclared identifier
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(993): error C2065: 'size': undeclared identifier
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(993): error C2065: 'color': undeclared identifier
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(993): error C2065: 'is_box_centered': undeclared identifier
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(993): error C2065: 'duration': undeclared identifier
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(993): error C3861: 'DebugDraw3D_draw_box': identifier not found
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(1035): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(1035): error C2143: syntax error: missing ',' before '&'
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(1036): error C2065: 'DebugDraw3D_draw_aabb': undeclared identifier
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(1036): error C2143: syntax error: missing ')' before 'const'
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(1036): error C2143: syntax error: missing ';' before 'const'
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(1036): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(1036): error C2143: syntax error: missing ';' before '&'
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(1036): error C2082: redefinition of formal parameter 'AABB'
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(1036): error C2059: syntax error: ','
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(1036): error C2059: syntax error: ')'
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(1037): error C2065: 'DebugDraw3D_draw_aabb': undeclared identifier
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(1037): error C2065: 'aabb': undeclared identifier
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(1037): error C2065: 'color': undeclared identifier
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(1037): error C2065: 'duration': undeclared identifier
godot_debug_draw_3d\addons\debug_draw_3d\native_api\cpp\dd3d_cpp_api.hpp(1037): error C3861: 'DebugDraw3D_draw_aabb': identifier not found
scons: *** [src\drg_terrain.windows.template_debug.x86_64.obj] Error 2
scons: building terminated because of errors.
Most likely fixed in 7e853cccb1d30c175d29b43807fd0a0bb5b83097
That was it! Thank you so much (& for this amazing addon in general, I think it's essential!) ❤️
Edit: Really impressed by the API's quality! 😮
I updated my dd3d submodule today and apparently the generated API is broken.
Some instances of Transform3D, Color, Ref & Font in dd3d_cpp_api.hpp didn't have the godot:: prefix, causing compilation issues in my GDExtension.
Adding the prefixes resolved the issue.
Rebased cpp_api 39b2b1e7a81d246f7d1b8f96b08605c8c8648eda
draw_points() doesn't seem to be exposed. If you could give a super quick rundown of how to add that to the CPP API, I'll happily add it myself.
Without it, debugging my voxel pathfinding (using draw_square()) slows to a crawl:
Sorry to bother you again, I'm just very much in love with DD3D and use it to develop my GDExtension ^^
draw_points()doesn't seem to be exposed.
This patch should help to solve the problem quickly:
diff --git a/src/3d/debug_draw_3d.h b/src/3d/debug_draw_3d.h
index 2d445c3..60874c7 100644
--- a/src/3d/debug_draw_3d.h
+++ b/src/3d/debug_draw_3d.h
@@ -130,9 +130,9 @@ public:
/**
* Appearance of points on the path
*/
- enum PointType : int {
- POINT_TYPE_SQUARE,
- POINT_TYPE_SPHERE,
+ NAPI_ENUM enum PointType : int {
+ POINT_TYPE_SQUARE = 0,
+ POINT_TYPE_SPHERE = 1,
};
private:
@@ -651,7 +651,7 @@ public:
* @param duration The duration of how long the object will be visible
*/
// TODO:
- void draw_points(const godot::PackedVector3Array &points, const PointType type = PointType::POINT_TYPE_SQUARE, const real_t &size = 0.25f, const godot::Color &color = Colors::empty_color, const real_t &duration = 0) FAKE_FUNC_IMPL;
+ NAPI void draw_points(const godot::PackedVector3Array &points, const DebugDraw3D::PointType type = DebugDraw3D::PointType::POINT_TYPE_SQUARE, const real_t &size = 0.25f, const godot::Color &color = Colors::empty_color, const real_t &duration = 0) FAKE_FUNC_IMPL;
/**
* Draw a square that will always be turned towards the camera
But I'm not sure if this will give a big performance boost 🤷♂️ Actually, this function could still be sped up a bit.
At the moment, I'm still trying to make a really C API. I've already added support for Ref<godot::T>, next I need to handle enums more correctly, and finally I can move on to Strings and Packed*Arrays.
That did the trick, thanks!
Turns out my performance drops came from a wonky godot/master build, not DD3D ^^
Main changes in the cpp_api branch:
- Added support for
Packed*ArrayandStringvia native arrays. -
- Added wrappers for
Packed*ArrayandString.
- Added wrappers for
- Added support for
Ref<godot::T>. - Fixed enum support
- Fixed text flickering if it updates in the same frame when its time expires.
- Removed
addons\debug_draw_3d\native_api\cpp\c_api_shared.hpp. -
- This file is now embedded into
dd3d_cpp_api.hpp.
- This file is now embedded into
- Improved performance of
draw_*functions that create multiple objects. -
- For example, the performance of
draw_points_cwas increased by ~30+%
- For example, the performance of
- Removed signatures by default. Signature checking is disabled by default.
Now I need to fix some problems with precision=double that I found during testing. And finally, I will need to write a replacement for the old C# API (hopefully this won't cause any major compatibility issues).