Radium Engine  1.5.20
Loading...
Searching...
No Matches
DebugRender.cpp
1#include <Engine/Rendering/DebugRender.hpp>
2
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>
9
10#include <Core/Containers/MakeShared.hpp>
11#include <Core/Geometry/MeshPrimitives.hpp>
12#include <Core/Utils/Log.hpp>
13
14#include <globjects/Program.h>
15#include <globjects/Shader.h>
16#include <globjects/base/StaticStringSource.h>
17
18#include <fstream>
19
20namespace Ra {
21namespace Engine {
22namespace Rendering {
23
24using namespace Core::Utils; // log
25
26DebugRender::DebugRender() = default;
27
28DebugRender::~DebugRender() = default;
29
33 auto setShader = []( Data::ShaderProgramManager* manager,
34 const std::string& configName,
35 const char* vertexShader,
36 const char* fragmentShader ) -> const Data::ShaderProgram* {
37 Data::ShaderConfiguration config { configName };
38 config.addShaderSource( Data::ShaderType::ShaderType_VERTEX, vertexShader );
39 config.addShaderSource( Data::ShaderType::ShaderType_FRAGMENT, fragmentShader );
40 auto added = manager->addShaderProgram( config );
41 if ( added ) { return *added; }
42 else { return nullptr; }
43 };
44
45 auto shaderProgramManager = RadiumEngine::getInstance()->getShaderProgramManager();
46
47 const char* lineVertStr = R"(
48 layout (location = 0) in vec3 in_pos;
49 layout (location = 5) in vec3 in_col;
50
51 uniform mat4 model;
52 uniform mat4 view;
53 uniform mat4 proj;
54
55 out vec3 v_color;
56 void main()
57 {
58 gl_Position = proj * view * model * vec4(in_pos, 1.0);
59 v_color = in_col;
60 }
61 )";
62
63 const char* lineFragStr = R"(
64 in vec3 v_color;
65 out vec4 f_color;
66
67 void main()
68 {
69 f_color = vec4(v_color, 1.0);
70 }
71 )";
72
73 static const char* pointVertStr = R"(
74 layout (location = 0) in vec3 in_pos;
75 layout (location = 1) in vec3 in_col;
76
77 uniform mat4 view;
78 uniform mat4 proj;
79
80 out vec3 v_color;
81
82 void main()
83 {
84 gl_Position = proj * view * vec4(in_pos, 1.0);
85 v_color = in_col;
86 gl_PointSize = 40 / gl_Position.w;
87 }
88 )";
89
90 static const char* pointFragStr = R"(
91 in vec3 v_color;
92 out vec4 f_color;
93
94 void main()
95 {
96 f_color = vec4(v_color, 1.0);
97 }
98 )";
99 static const char* meshVertStr = R"(
100 layout (location = 0) in vec3 in_pos;
101 layout (location = 5) in vec3 in_col;
102
103 uniform mat4 model;
104 uniform mat4 view;
105 uniform mat4 proj;
106
107 out vec3 v_color;
108
109 void main()
110 {
111 gl_Position = proj * view * model * vec4(in_pos, 1.0);
112 v_color = in_col;
113 }
114 )";
115
116 static const char* meshFragStr = R"(
117 in vec3 v_color;
118 out vec4 f_color;
119
120 void main()
121 {
122 f_color = vec4(v_color, 1.0);
123 }
124 )";
125
126 m_lineProg = setShader( shaderProgramManager, "dbgLineShader", lineVertStr, lineFragStr );
127 m_pointProg = setShader( shaderProgramManager, "dbgPointShader", pointVertStr, pointFragStr );
128 m_meshProg = setShader( shaderProgramManager, "dbgMeshShader", meshVertStr, meshFragStr );
129
130 GL_CHECK_ERROR;
131}
132
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>() );
137}
138
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 );
148
149 colors.push_back( l.col );
150 colors.push_back( l.col );
151
152 indices.push_back( { indexI, indexI + 1 } );
153 indexI += 2;
154 }
155
156 if ( !vertices.empty() ) {
157 const Core::Matrix4f id = Core::Matrix4f::Identity();
158
159 m_lineProg->bind();
160 m_lineProg->setUniform( "model", id );
161 m_lineProg->setUniform( "view", viewMatrix );
162 m_lineProg->setUniform( "proj", projMatrix );
163
164 Core::Geometry::LineMesh geom;
165 geom.setVertices( vertices );
166 geom.setIndices( std::move( indices ) );
167 geom.addAttrib( Ra::Core::Geometry::getAttribName( Ra::Core::Geometry::VERTEX_COLOR ),
168 colors );
169
170 Data::LineMesh mesh( "temp", std::move( geom ) );
171
172 mesh.updateGL();
174 mesh.render( m_lineProg );
175 }
176
177 m_lines.clear();
178}
179
180void DebugRender::renderPoints( const Core::Matrix4f& viewMatrix,
181 const Core::Matrix4f& projMatrix ) {
182 uint size = m_points.size();
183 if ( 0 == size ) { return; }
184
186 GLuint vao, vbo;
187 glGenVertexArrays( 1, &vao );
188
189 glBindVertexArray( vao );
190 glGenBuffers( 1, &vbo );
191 glBindBuffer( GL_ARRAY_BUFFER, vbo );
192 glBufferData(
193 GL_ARRAY_BUFFER, size * 2 * sizeof( Core::Vector3 ), m_points.data(), GL_DYNAMIC_DRAW );
194 GLint64 ptr = 0;
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 );
200
201 glEnable( GL_PROGRAM_POINT_SIZE );
202 m_pointProg->bind();
203
204 m_pointProg->setUniform( "view", viewMatrix );
205 m_pointProg->setUniform( "proj", projMatrix );
206
207 glDrawArrays( GL_POINTS, 0, size );
208 glDisable( GL_PROGRAM_POINT_SIZE );
209
210 glBindVertexArray( 0 );
211 glDeleteVertexArrays( 1, &vao );
212 glDeleteBuffers( 1, &vbo );
213
214 m_points.clear();
215}
216
217void DebugRender::renderMeshes( const Core::Matrix4f& view, const Core::Matrix4f& proj ) {
218 if ( m_meshes.empty() ) { return; }
219
220 // Avoid too much states change
221 uint idx = 0;
222 std::sort( m_meshes.begin(), m_meshes.end(), []( const DbgMesh& a, const DbgMesh& b ) -> bool {
223 return a.mesh->getRenderMode() < b.mesh->getRenderMode();
224 } );
225
226 for ( ; idx < m_meshes.size() && m_meshes[idx].mesh->getRenderMode() != GL_TRIANGLES; ++idx )
227 ;
228
229 m_lineProg->bind();
230 m_lineProg->setUniform( "view", view );
231 m_lineProg->setUniform( "proj", proj );
232
233 for ( uint i = 0; i < idx; ++i ) {
234 m_lineProg->setUniform( "model", m_meshes[i].transform.matrix() );
235 m_meshes[i].mesh->updateGL();
236 m_meshes[i].mesh->render( m_lineProg );
237 }
238
239 m_meshProg->bind();
240 m_meshProg->setUniform( "view", view );
241 m_meshProg->setUniform( "proj", proj );
242
243 for ( uint i = idx; i < m_meshes.size(); ++i ) {
244 m_meshProg->setUniform( "model", m_meshes[i].transform.matrix() );
245 m_meshes[i].mesh->updateGL();
246 m_meshes[i].mesh->render( m_meshProg );
247 }
248
249 m_meshes.clear();
250}
251
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 );
257}
258
259void DebugRender::addPoint( const Core::Vector3& p, const Core::Utils::Color& c ) {
260 m_points.push_back( { p, c.head<3>() } );
261}
262
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>() } );
266 }
267}
268
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>() } );
273 }
274}
275
276void DebugRender::addMesh( const std::shared_ptr<Data::AttribArrayDisplayable>& mesh,
277 const Core::Transform& transform ) {
278 m_meshes.push_back( { mesh, transform } );
279}
280
281void DebugRender::addCross( const Core::Vector3& position,
282 Scalar size,
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();
287 offset[i] = hz;
288
289 const Core::Vector3 from = position - offset;
290 const Core::Vector3 to = position + offset;
291
292 addLine( from, to, color );
293 }
294}
295
296void DebugRender::addSphere( const Core::Vector3& center,
297 Scalar radius,
298 const Core::Utils::Color& color ) {
299 addMesh( Data::DrawPrimitives::Sphere( center, radius, color ) );
300}
301
302void DebugRender::addCircle( const Core::Vector3& center,
303 const Core::Vector3& normal,
304 Scalar radius,
305 const Core::Utils::Color& color ) {
306 addMesh( Data::DrawPrimitives::Circle( center, normal, radius, 64, color ) );
307}
308
309void DebugRender::addFrame( const Core::Transform& transform, Scalar size ) {
310 addMesh( Data::DrawPrimitives::Frame( transform, size ) );
311}
312
313void DebugRender::addTriangle( const Core::Vector3& p0,
314 const Core::Vector3& p1,
315 const Core::Vector3& p2,
316 const Core::Utils::Color& color ) {
317 addMesh( Data::DrawPrimitives::Triangle( p0, p1, p2, color ) );
318}
319
320void DebugRender::addAABB( const Core::Aabb& box, const Core::Utils::Color& color ) {
321 addMesh( Data::DrawPrimitives::AABB( box, color ) );
322}
323
324void DebugRender::addOBB( const Core::Aabb& box,
325 const Core::Transform& transform,
326 const Core::Utils::Color& color ) {
327 addMesh( Data::DrawPrimitives::AABB( box, color ), transform );
328}
329
330RA_SINGLETON_IMPLEMENTATION( DebugRender );
331
332} // namespace Rendering
333} // namespace Engine
334} // namespace Ra
T begin(T... args)
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.
T clear(T... args)
T data(T... args)
T empty(T... args)
T end(T... args)
T move(T... args)
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 &center, Scalar radius, const Core::Utils::Color &color)
Displays geodesic sphere computed with given center and radius.
LineMeshPtr Circle(const Core::Vector3 &center, const Core::Vector3 &normal, Scalar radius, uint segments, const Core::Utils::Color &color)
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:3
T push_back(T... args)
T size(T... args)
T sort(T... args)
T transform(T... args)