199 lines
6.2 KiB
C++
199 lines
6.2 KiB
C++
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
* Copyright 2022 Blender Foundation. */
|
|
|
|
/** \file
|
|
* \ingroup draw
|
|
*
|
|
* \brief Simple API to draw debug shapes and log in the viewport.
|
|
*
|
|
* Both CPU and GPU implementation are supported and symmetrical (meaning GPU shader can use it
|
|
* too, see common_debug_print/draw_lib.glsl).
|
|
*
|
|
* NOTE: CPU logging will overlap GPU logging on screen as it is drawn after.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "BLI_math_vector_types.hh"
|
|
#include "BLI_string_ref.hh"
|
|
#include "BLI_vector.hh"
|
|
#include "DNA_object_types.h"
|
|
#include "DRW_gpu_wrapper.hh"
|
|
|
|
namespace blender::draw {
|
|
|
|
/* Shortcuts to avoid boilerplate code and match shader API. */
|
|
#define drw_debug_line(...) DRW_debug_get()->draw_line(__VA_ARGS__)
|
|
#define drw_debug_polygon(...) DRW_debug_get()->draw_polygon(__VA_ARGS__)
|
|
#define drw_debug_bbox(...) DRW_debug_get()->draw_bbox(__VA_ARGS__)
|
|
#define drw_debug_sphere(...) DRW_debug_get()->draw_sphere(__VA_ARGS__)
|
|
#define drw_debug_point(...) DRW_debug_get()->draw_point(__VA_ARGS__)
|
|
#define drw_debug_matrix(...) DRW_debug_get()->draw_matrix(__VA_ARGS__)
|
|
#define drw_debug_matrix_as_bbox(...) DRW_debug_get()->draw_matrix_as_bbox(__VA_ARGS__)
|
|
#define drw_print(...) DRW_debug_get()->print(__VA_ARGS__)
|
|
#define drw_print_hex(...) DRW_debug_get()->print_hex(__VA_ARGS__)
|
|
#define drw_print_binary(...) DRW_debug_get()->print_binary(__VA_ARGS__)
|
|
#define drw_print_no_endl(...) DRW_debug_get()->print_no_endl(__VA_ARGS__)
|
|
|
|
/* Will log variable along with its name, like the shader version of print(). */
|
|
#define drw_print_id(v_) DRW_debug_get()->print(#v_, "= ", v_)
|
|
#define drw_print_id_no_endl(v_) DRW_debug_get()->print_no_endl(#v_, "= ", v_)
|
|
|
|
class DebugDraw {
|
|
private:
|
|
using DebugDrawBuf = StorageBuffer<DRWDebugDrawBuffer>;
|
|
using DebugPrintBuf = StorageBuffer<DRWDebugPrintBuffer>;
|
|
|
|
/** Data buffers containing all verts or chars to draw. */
|
|
DebugDrawBuf cpu_draw_buf_ = {"DebugDrawBuf-CPU"};
|
|
DebugDrawBuf gpu_draw_buf_ = {"DebugDrawBuf-GPU"};
|
|
DebugPrintBuf cpu_print_buf_ = {"DebugPrintBuf-CPU"};
|
|
DebugPrintBuf gpu_print_buf_ = {"DebugPrintBuf-GPU"};
|
|
/** True if the gpu buffer have been requested and may contain data to draw. */
|
|
bool gpu_print_buf_used = false;
|
|
bool gpu_draw_buf_used = false;
|
|
/** Matrix applied to all points before drawing. Could be a stack if needed. */
|
|
float4x4 model_mat_;
|
|
/** Precomputed shapes verts. */
|
|
Vector<float3> sphere_verts_;
|
|
Vector<float3> point_verts_;
|
|
/** Cursor position for print functionality. */
|
|
uint print_col_ = 0;
|
|
uint print_row_ = 0;
|
|
|
|
public:
|
|
DebugDraw();
|
|
~DebugDraw(){};
|
|
|
|
/**
|
|
* Resets all buffers and reset model matrix state.
|
|
* Not to be called by user.
|
|
*/
|
|
void init();
|
|
|
|
/**
|
|
* Resets model matrix state to identity.
|
|
*/
|
|
void modelmat_reset();
|
|
/**
|
|
* Sets model matrix transform to apply to any vertex passed to drawing functions.
|
|
*/
|
|
void modelmat_set(const float modelmat[4][4]);
|
|
|
|
/**
|
|
* Drawing functions that will draw wire-frames with the given color.
|
|
*/
|
|
void draw_line(float3 v1, float3 v2, float4 color = {1, 0, 0, 1});
|
|
void draw_polygon(Span<float3> poly_verts, float4 color = {1, 0, 0, 1});
|
|
void draw_bbox(const BoundBox &bbox, const float4 color = {1, 0, 0, 1});
|
|
void draw_sphere(const float3 center, float radius, const float4 color = {1, 0, 0, 1});
|
|
void draw_point(const float3 center, float radius = 0.01f, const float4 color = {1, 0, 0, 1});
|
|
/**
|
|
* Draw a matrix transformation as 3 colored axes.
|
|
*/
|
|
void draw_matrix(const float4x4 m4);
|
|
/**
|
|
* Draw a matrix as a 2 units length bounding box, centered on origin.
|
|
*/
|
|
void draw_matrix_as_bbox(float4x4 mat, const float4 color = {1, 0, 0, 1});
|
|
|
|
/**
|
|
* Will draw all debug shapes and text cached up until now to the current view / frame-buffer.
|
|
* Draw buffers will be emptied and ready for new debug data.
|
|
*/
|
|
void display_to_view();
|
|
|
|
/**
|
|
* Log variable or strings inside the viewport.
|
|
* Using a unique non string argument will print the variable name with it.
|
|
* Concatenate by using multiple arguments. i.e: `print("Looped ", n, "times.")`.
|
|
*/
|
|
template<typename... Ts> void print(StringRefNull str, Ts... args)
|
|
{
|
|
print_no_endl(str, args...);
|
|
print_newline();
|
|
}
|
|
template<typename T> void print(const T &value)
|
|
{
|
|
print_value(value);
|
|
print_newline();
|
|
}
|
|
template<typename T> void print_hex(const T &value)
|
|
{
|
|
print_value_hex(value);
|
|
print_newline();
|
|
}
|
|
template<typename T> void print_binary(const T &value)
|
|
{
|
|
print_value_binary(value);
|
|
print_newline();
|
|
}
|
|
|
|
/**
|
|
* Same as `print()` but does not finish the line.
|
|
*/
|
|
void print_no_endl(std::string arg)
|
|
{
|
|
print_string(arg);
|
|
}
|
|
void print_no_endl(StringRef arg)
|
|
{
|
|
print_string(arg);
|
|
}
|
|
void print_no_endl(StringRefNull arg)
|
|
{
|
|
print_string(arg);
|
|
}
|
|
void print_no_endl(char const *arg)
|
|
{
|
|
print_string(StringRefNull(arg));
|
|
}
|
|
template<typename T> void print_no_endl(T arg)
|
|
{
|
|
print_value(arg);
|
|
}
|
|
template<typename T, typename... Ts> void print_no_endl(T arg, Ts... args)
|
|
{
|
|
print_no_endl(arg);
|
|
print_no_endl(args...);
|
|
}
|
|
|
|
/**
|
|
* Not to be called by user. Should become private.
|
|
*/
|
|
GPUStorageBuf *gpu_draw_buf_get();
|
|
GPUStorageBuf *gpu_print_buf_get();
|
|
|
|
private:
|
|
uint color_pack(float4 color);
|
|
DRWDebugVert vert_pack(float3 pos, uint color);
|
|
|
|
void draw_line(float3 v1, float3 v2, uint color);
|
|
|
|
void print_newline();
|
|
void print_string_start(uint len);
|
|
void print_string(std::string str);
|
|
void print_char4(uint data);
|
|
void print_append_char(uint char1, uint &char4);
|
|
void print_append_digit(uint digit, uint &char4);
|
|
void print_append_space(uint &char4);
|
|
void print_value_binary(uint value);
|
|
void print_value_uint(uint value, const bool hex, bool is_negative, const bool is_unsigned);
|
|
|
|
template<typename T> void print_value(const T &value);
|
|
template<typename T> void print_value_hex(const T &value);
|
|
template<typename T> void print_value_binary(const T &value);
|
|
|
|
void display_lines();
|
|
void display_prints();
|
|
};
|
|
|
|
} // namespace blender::draw
|
|
|
|
/**
|
|
* Ease of use function to get the debug module.
|
|
* TODO(fclem): Should be removed once DRWManager is no longer global.
|
|
* IMPORTANT: Can return nullptr if storage buffer is not supported.
|
|
*/
|
|
blender::draw::DebugDraw *DRW_debug_get();
|