1#include <Engine/Rendering/DebugRender.hpp>
3#include <Engine/Data/DrawPrimitives.hpp>
4#include <Engine/Data/Mesh.hpp>
5#include <Engine/Data/ShaderProgram.hpp>
6#include <Engine/Data/ShaderProgramManager.hpp>
7#include <Engine/OpenGL.hpp>
8#include <Engine/RadiumEngine.hpp>
10#include <Core/Containers/MakeShared.hpp>
11#include <Core/Geometry/MeshPrimitives.hpp>
12#include <Core/Utils/Log.hpp>
14#include <globjects/Program.h>
15#include <globjects/Shader.h>
16#include <globjects/base/StaticStringSource.h>
24using namespace Core::Utils;
26DebugRender::DebugRender() =
default;
28DebugRender::~DebugRender() =
default;
35 const char* vertexShader,
38 config.
addShaderSource( Data::ShaderType::ShaderType_VERTEX, vertexShader );
39 config.addShaderSource( Data::ShaderType::ShaderType_FRAGMENT, fragmentShader );
41 if ( added ) {
return *added; }
42 else {
return nullptr; }
45 auto shaderProgramManager = RadiumEngine::getInstance()->getShaderProgramManager();
47 const char* lineVertStr = R
"(
48 layout (location = 0) in vec3 in_pos;
49 layout (location = 5) in vec3 in_col;
58 gl_Position = proj * view * model * vec4(in_pos, 1.0);
63 const char* lineFragStr = R
"(
69 f_color = vec4(v_color, 1.0);
73 static const char* pointVertStr = R
"(
74 layout (location = 0) in vec3 in_pos;
75 layout (location = 1) in vec3 in_col;
84 gl_Position = proj * view * vec4(in_pos, 1.0);
86 gl_PointSize = 40 / gl_Position.w;
90 static const char* pointFragStr = R
"(
96 f_color = vec4(v_color, 1.0);
99 static const char* meshVertStr = R
"(
100 layout (location = 0) in vec3 in_pos;
101 layout (location = 5) in vec3 in_col;
111 gl_Position = proj * view * model * vec4(in_pos, 1.0);
116 static const char* meshFragStr = R
"(
122 f_color = vec4(v_color, 1.0);
126 m_lineProg = setShader( shaderProgramManager, "dbgLineShader", lineVertStr, lineFragStr );
127 m_pointProg = setShader( shaderProgramManager,
"dbgPointShader", pointVertStr, pointFragStr );
128 m_meshProg = setShader( shaderProgramManager,
"dbgMeshShader", meshVertStr, meshFragStr );
133void DebugRender::render(
const Core::Matrix4& viewMatrix,
const Core::Matrix4& projMatrix ) {
134 renderLines( viewMatrix.cast<
float>(), projMatrix.cast<
float>() );
135 renderPoints( viewMatrix.cast<
float>(), projMatrix.cast<
float>() );
136 renderMeshes( viewMatrix.cast<
float>(), projMatrix.cast<
float>() );
139void DebugRender::renderLines(
const Core::Matrix4f& viewMatrix,
140 const Core::Matrix4f& projMatrix ) {
141 Core::Vector3Array vertices;
142 Core::Vector4Array colors;
144 unsigned int indexI = 0;
145 for (
const auto& l : m_lines ) {
146 vertices.push_back( l.a );
147 vertices.push_back( l.b );
149 colors.push_back( l.col );
150 colors.push_back( l.col );
152 indices.
push_back( { indexI, indexI + 1 } );
156 if ( !vertices.empty() ) {
157 const Core::Matrix4f
id = Core::Matrix4f::Identity();
164 Core::Geometry::LineMesh geom;
165 geom.setVertices( vertices );
167 geom.addAttrib( Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::VERTEX_COLOR ),
170 Data::LineMesh mesh(
"temp",
std::move( geom ) );
174 mesh.render( m_lineProg );
180void DebugRender::renderPoints(
const Core::Matrix4f& viewMatrix,
181 const Core::Matrix4f& projMatrix ) {
182 uint size = m_points.
size();
183 if ( 0 == size ) {
return; }
187 glGenVertexArrays( 1, &vao );
189 glBindVertexArray( vao );
190 glGenBuffers( 1, &vbo );
191 glBindBuffer( GL_ARRAY_BUFFER, vbo );
193 GL_ARRAY_BUFFER, size * 2 *
sizeof( Core::Vector3 ), m_points.
data(), GL_DYNAMIC_DRAW );
195 glVertexAttribPointer( 0, 3, GL_SCALAR, GL_FALSE, 6 *
sizeof( Scalar ), (GLvoid*)ptr );
196 glEnableVertexAttribArray( 0 );
197 ptr += 3 *
sizeof( Scalar );
198 glVertexAttribPointer( 1, 3, GL_SCALAR, GL_FALSE, 6 *
sizeof( Scalar ), (GLvoid*)ptr );
199 glEnableVertexAttribArray( 1 );
201 glEnable( GL_PROGRAM_POINT_SIZE );
204 m_pointProg->
setUniform(
"view", viewMatrix );
205 m_pointProg->
setUniform(
"proj", projMatrix );
207 glDrawArrays( GL_POINTS, 0, size );
208 glDisable( GL_PROGRAM_POINT_SIZE );
210 glBindVertexArray( 0 );
211 glDeleteVertexArrays( 1, &vao );
212 glDeleteBuffers( 1, &vbo );
217void DebugRender::renderMeshes(
const Core::Matrix4f& view,
const Core::Matrix4f& proj ) {
218 if ( m_meshes.
empty() ) {
return; }
222 std::sort( m_meshes.
begin(), m_meshes.
end(), [](
const DbgMesh& a,
const DbgMesh& b ) ->
bool {
223 return a.mesh->getRenderMode() < b.mesh->getRenderMode();
226 for ( ; idx < m_meshes.
size() && m_meshes[idx].mesh->getRenderMode() != GL_TRIANGLES; ++idx )
233 for ( uint i = 0; i < idx; ++i ) {
235 m_meshes[i].mesh->updateGL();
236 m_meshes[i].mesh->render( m_lineProg );
243 for ( uint i = idx; i < m_meshes.
size(); ++i ) {
245 m_meshes[i].mesh->updateGL();
246 m_meshes[i].mesh->render( m_meshProg );
252void DebugRender::addLine(
const Core::Vector3& from,
253 const Core::Vector3& to,
254 const Core::Utils::Color& color ) {
255 Line l( from, to, color );
256 m_lines.push_back( l );
259void DebugRender::addPoint(
const Core::Vector3& p,
const Core::Utils::Color& c ) {
260 m_points.
push_back( { p, c.head<3>() } );
263void DebugRender::addPoints(
const Core::Vector3Array& p,
const Core::Utils::Color& c ) {
264 for ( uint i = 0; i < p.size(); ++i ) {
265 m_points.
push_back( { p[i], c.head<3>() } );
269void DebugRender::addPoints(
const Core::Vector3Array& p,
const Core::Vector4Array& c ) {
270 CORE_ASSERT( p.size() == c.size(),
"Data sizes mismatch." );
271 for ( uint i = 0; i < p.size(); ++i ) {
272 m_points.
push_back( { p[i], c[i].head<3>() } );
277 const Core::Transform& transform ) {
281void DebugRender::addCross(
const Core::Vector3& position,
283 const Core::Utils::Color& color ) {
284 const Scalar hz = size / 2.0;
285 for (
int i = 0; i < 3; ++i ) {
286 Core::Vector3 offset = Core::Vector3::Zero();
289 const Core::Vector3 from = position - offset;
290 const Core::Vector3 to = position + offset;
292 addLine( from, to, color );
296void DebugRender::addSphere(
const Core::Vector3& center,
298 const Core::Utils::Color& color ) {
302void DebugRender::addCircle(
const Core::Vector3& center,
303 const Core::Vector3& normal,
305 const Core::Utils::Color& color ) {
309void DebugRender::addFrame(
const Core::Transform& transform, Scalar size ) {
313void DebugRender::addTriangle(
const Core::Vector3& p0,
314 const Core::Vector3& p1,
315 const Core::Vector3& p2,
316 const Core::Utils::Color& color ) {
320void DebugRender::addAABB(
const Core::Aabb& box,
const Core::Utils::Color& color ) {
324void DebugRender::addOBB(
const Core::Aabb& box,
325 const Core::Transform& transform,
326 const Core::Utils::Color& color ) {
330RA_SINGLETON_IMPLEMENTATION( DebugRender );
void addShaderSource(ShaderType type, const std::string &source)
Core::Utils::optional< const Data::ShaderProgram * > addShaderProgram(const Data::ShaderConfiguration &config)
void setUniform(const char *name, const T &value) const
Uniform setters.
LineMeshPtr Line(const Core::Vector3 &a, const Core::Vector3 &b, const Core::Utils::Color &color)
Displays given line.
AttribArrayDisplayablePtr Triangle(const Core::Vector3 &a, const Core::Vector3 &b, const Core::Vector3 &c, const Core::Utils::Color &color, bool fill)
MeshPtr AABB(const Core::Aabb &aabb, const Core::Utils::Color &color)
Display a wireframe AABB.
MeshPtr Frame(const Core::Transform &frameFromEntity, Scalar scale)
MeshPtr Sphere(const Core::Vector3 ¢er, Scalar radius, const Core::Utils::Color &color)
Displays geodesic sphere computed with given center and radius.
LineMeshPtr Circle(const Core::Vector3 ¢er, const Core::Vector3 &normal, Scalar radius, uint segments, const Core::Utils::Color &color)
hepler function to manage enum as underlying types in VariableSet