This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/draw/intern/draw_debug.hh
2023-01-06 20:09:51 +01:00

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();