// Copyright (C) 2014-2015 ChaosForge Ltd // http://chaosforge.org/ // // This file is part of Nova libraries. // For conditions of distribution and use, see copying.txt file in root folder. #include "nv/gfx/debug_draw.hh" #include "nv/interface/device.hh" #include "nv/core/logging.hh" static const char *nv_debug_draw_vertex_shader = R"( #version 330 in vec3 nv_position; in vec3 nv_color; out vec3 v_color; uniform mat4 nv_m_mvp; void main(void) { gl_Position = nv_m_mvp * vec4 (nv_position, 1.0); v_color = nv_color; }; )"; static const char *nv_debug_draw_fragment_shader = R"( #version 330 in vec3 v_color; out vec4 o_frag_color; void main(void) { o_frag_color = vec4( v_color, 1.0 ); } )"; nv::debug_data::debug_data( context* a_context ) : m_context( a_context ), m_program(), m_va() { m_program = m_context->create_program( nv_debug_draw_vertex_shader, nv_debug_draw_fragment_shader ); m_buffer_size = 0; } void nv::debug_data::update() { if ( !m_va.is_valid() || m_data.size() > m_buffer_size ) { if ( m_va.is_valid() ) m_context->release( m_va ); m_buffer_size = nv::max( m_data.size(), 4096U, m_buffer_size ); m_vb = m_context->create_buffer( VERTEX_BUFFER, nv::STREAM_DRAW, m_buffer_size * sizeof( debug_vtx ) ); vertex_array_desc va_desc; va_desc.add_vertex_buffers< debug_vtx >( m_vb, true ); m_va = m_context->create_vertex_array( va_desc ); } m_context->update( m_vb, m_data.data(), 0, m_data.size()* sizeof( debug_vtx ) ); } void nv::debug_data::reset() { m_data.clear(); } void nv::debug_data::push_line( const vec3& a, const vec3& b, const vec3& color ) { m_data.emplace_back( a, color ); m_data.emplace_back( b, color ); } void nv::debug_data::push_aabox( const vec3& a, const vec3& b, const vec3& color ) { vec3 corners[8] = { vec3( a.x, a.y, a.z ), vec3( b.x, a.y, a.z ), vec3( b.x, a.y, b.z ), vec3( a.x, a.y, b.z ), vec3( a.x, b.y, a.z ), vec3( b.x, b.y, a.z ), vec3( b.x, b.y, b.z ), vec3( a.x, b.y, b.z ), }; push_line( corners[0], corners[1], color ); push_line( corners[1], corners[2], color ); push_line( corners[2], corners[3], color ); push_line( corners[3], corners[0], color ); push_line( corners[0], corners[4], color ); push_line( corners[1], corners[5], color ); push_line( corners[2], corners[6], color ); push_line( corners[3], corners[7], color ); push_line( corners[4], corners[5], color ); push_line( corners[5], corners[6], color ); push_line( corners[6], corners[7], color ); push_line( corners[7], corners[4], color ); } void nv::debug_data::push_gizmo( const transform& tr, float length ) { vec3 s( 0.0f, 0.0f, 0.0f ); vec3 r( length, 0.0f, 0.0f ); vec3 g( 0.0f, length, 0.0f ); vec3 b( 0.0f, 0.0f, length ); s = s * tr; r = r * tr; g = g * tr; b = b * tr; push_line( s, r, vec3( 1.0f, 0.0f, 0.0f ) ); push_line( s, g, vec3( 0.0f, 1.0f, 0.0f ) ); push_line( s, b, vec3( 0.0f, 0.0f, 1.0f ) ); } nv::debug_data::~debug_data() { m_context->release( m_va ); m_context->release( m_program ); }