godot_debug_draw_3d icon indicating copy to clipboard operation
godot_debug_draw_3d copied to clipboard

[Feature Request]: Support for calling Debug Draw functions in GDExtension modules

Open sndrec opened this issue 1 year ago • 26 comments

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

sndrec avatar Sep 06 '24 16:09 sndrec

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 avatar Mar 19 '25 11:03 InevitablyDivinity

@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++.

DmitriySalnikov avatar Mar 19 '25 11:03 DmitriySalnikov

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.

InevitablyDivinity avatar Mar 19 '25 11:03 InevitablyDivinity

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.

DmitriySalnikov avatar Mar 19 '25 12:03 DmitriySalnikov

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

But at the moment it's not really a "C API", but rather a "C++ API".

DmitriySalnikov avatar Mar 19 '25 13:03 DmitriySalnikov

❯ 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

InevitablyDivinity avatar Mar 19 '25 13:03 InevitablyDivinity

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

DmitriySalnikov avatar Mar 19 '25 13:03 DmitriySalnikov

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.

InevitablyDivinity avatar Mar 19 '25 14:03 InevitablyDivinity

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.

DmitriySalnikov avatar Mar 19 '25 14:03 DmitriySalnikov

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?

InevitablyDivinity avatar Mar 19 '25 14:03 InevitablyDivinity

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

DmitriySalnikov avatar Mar 19 '25 14:03 DmitriySalnikov

Using GCC 14 myself, maybe a further GCC update broke this.

InevitablyDivinity avatar Mar 19 '25 14:03 InevitablyDivinity

You can also view the logs in gh-actions. And here is the link to the used ubuntu image.

DmitriySalnikov avatar Mar 19 '25 14:03 DmitriySalnikov

For now I've just #included <utility> so I can move on with my port, as this is a trivial issue anyway.

InevitablyDivinity avatar Mar 19 '25 14:03 InevitablyDivinity

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

DmitriySalnikov avatar Mar 19 '25 15:03 DmitriySalnikov

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.

Robert-K avatar Apr 24 '25 15:04 Robert-K

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?

DmitriySalnikov avatar Apr 24 '25 16:04 DmitriySalnikov

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.

Robert-K avatar Apr 24 '25 17:04 Robert-K

Most likely fixed in 7e853cccb1d30c175d29b43807fd0a0bb5b83097

DmitriySalnikov avatar Apr 24 '25 20:04 DmitriySalnikov

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! 😮

Robert-K avatar Apr 24 '25 20:04 Robert-K

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.

Robert-K avatar Nov 16 '25 18:11 Robert-K

Rebased cpp_api 39b2b1e7a81d246f7d1b8f96b08605c8c8648eda

DmitriySalnikov avatar Nov 17 '25 05:11 DmitriySalnikov

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:

Image

Sorry to bother you again, I'm just very much in love with DD3D and use it to develop my GDExtension ^^

Robert-K avatar Nov 27 '25 17:11 Robert-K

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
Image

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.

DmitriySalnikov avatar Nov 27 '25 17:11 DmitriySalnikov

That did the trick, thanks!

Turns out my performance drops came from a wonky godot/master build, not DD3D ^^

Robert-K avatar Nov 27 '25 21:11 Robert-K

Image

Main changes in the cpp_api branch:

  • Added support for Packed*Array and String via native arrays.
    • Added wrappers for Packed*Array and String.
  • 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.
  • Improved performance of draw_* functions that create multiple objects.
    • For example, the performance of draw_points_c was increased by ~30+%
  • 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).

DmitriySalnikov avatar Dec 15 '25 03:12 DmitriySalnikov