diff --git a/shaders/src/fs_debug.sc b/shaders/src/fs_debug.sc index 574c418..8f9d731 100644 --- a/shaders/src/fs_debug.sc +++ b/shaders/src/fs_debug.sc @@ -1,3 +1,4 @@ +$input v_color0 /* * Copyright 2011-2015 Branimir Karadzic. All rights reserved. * License: http://www.opensource.org/licenses/BSD-2-Clause @@ -9,5 +10,5 @@ uniform vec4 u_color; void main() { - gl_FragColor = u_color; + gl_FragColor = u_color * v_color0; } diff --git a/shaders/src/vs_debug.sc b/shaders/src/vs_debug.sc index 0f20938..1c69373 100644 --- a/shaders/src/vs_debug.sc +++ b/shaders/src/vs_debug.sc @@ -1,4 +1,5 @@ -$input a_position +$input a_position, a_color0 +$output v_color0 /* * Copyright 2011-2015 Branimir Karadzic. All rights reserved. @@ -10,4 +11,5 @@ $input a_position void main() { gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) ); + v_color0 = a_color0; } diff --git a/src/Serializer.h b/src/Serializer.h index a850368..8e68d3c 100644 --- a/src/Serializer.h +++ b/src/Serializer.h @@ -113,6 +113,11 @@ struct ReadSerializer { std::unordered_map blocks; }; +template +bool SerializeBool (Serializer &serializer, const std::string &key, bool& value) { + return serializer.SerializeData(key, reinterpret_cast(&value), sizeof(bool)); +} + template bool SerializeInt (Serializer &serializer, const std::string &key, int& value) { return serializer.SerializeData(key, reinterpret_cast(&value), sizeof(int)); diff --git a/src/modules/RenderModule.cc b/src/modules/RenderModule.cc index c231e68..2ac3aed 100644 --- a/src/modules/RenderModule.cc +++ b/src/modules/RenderModule.cc @@ -83,8 +83,9 @@ static void module_reload(struct module_state *state) { Camera* camera = &gRenderer->cameras[gRenderer->activeCameraIndex]; assert (camera != nullptr); - SerializeVec3 (*gReadSerializer, "protot.RenderModule,camera.eye", camera->eye); - SerializeVec3 (*gReadSerializer, "protot.RenderModule,camera.poi", camera->poi); + SerializeBool (*gReadSerializer, "protot.RenderModule.debug_enabled", gRenderer->drawDebug); + SerializeVec3 (*gReadSerializer, "protot.RenderModule.camera.eye", camera->eye); + SerializeVec3 (*gReadSerializer, "protot.RenderModule.camera.poi", camera->poi); camera->updateMatrices(); } @@ -94,8 +95,9 @@ static void module_unload(struct module_state *state) { //(*gSerializer)["protot"]["RenderModule"]["active_camera"] = (double)gRenderer->activeCameraIndex; - SerializeVec3 (*gWriteSerializer, "protot.RenderModule,camera.eye", camera->eye); - SerializeVec3 (*gWriteSerializer, "protot.RenderModule,camera.poi", camera->poi); + SerializeBool (*gWriteSerializer, "protot.RenderModule.debug_enabled", gRenderer->drawDebug); + SerializeVec3 (*gWriteSerializer, "protot.RenderModule.camera.eye", camera->eye); + SerializeVec3 (*gWriteSerializer, "protot.RenderModule.camera.poi", camera->poi); gRenderer = nullptr; @@ -131,12 +133,14 @@ const struct module_api MODULE_API = { } // BGFX globals - bgfx::VertexBufferHandle cube_vbh; bgfx::IndexBufferHandle cube_ibh; bgfx::IndexBufferHandle cube_edges_ibh; bgfx::VertexBufferHandle plane_vbh; bgfx::IndexBufferHandle plane_ibh; +bgfx::DynamicVertexBufferHandle debug_lines_vbh; +bgfx::DynamicIndexBufferHandle debug_lines_ibh; + bgfx::UniformHandle u_time; bgfx::UniformHandle u_color; @@ -678,6 +682,18 @@ void Renderer::createGeometries() { bgfx::makeRef(s_cubeEdgeIndices, sizeof(s_cubeEdgeIndices) ) ); + // Create dynamic debug line buffer + debug_lines_vbh = bgfx::createDynamicVertexBuffer( + (uint32_t) 10, + PosColorVertex::ms_decl, + BGFX_BUFFER_ALLOW_RESIZE + ); + + debug_lines_ibh = bgfx::createDynamicIndexBuffer( + (uint32_t) 10, + BGFX_BUFFER_ALLOW_RESIZE + ); + plane_vbh = bgfx::createVertexBuffer( bgfx::makeRef(s_hplaneVertices, sizeof(s_hplaneVertices) ) , PosNormalColorTexcoordVertex::ms_decl @@ -1277,6 +1293,75 @@ void Renderer::paintGL() { bgfx::setState(st.m_state); bgfx::submit(st.m_viewId, st.m_program); } + + // debug commands + bgfx::setUniform(u_color, Vector4f(1.0f, 1.0f, 1.0f, 1.f).data(), 4); + + // assemble lines for alls debug lines + uint32_t line_count = 0; + for (uint32_t i = 0; i < debugCommands.size(); i++) { + if (debugCommands[i].type == DebugCommand::Line) { + line_count++; + } + } + + // create buffer data for the lines + uint16_t* line_idx_buf = new uint16_t[line_count * 2]; + PosColorVertex *line_vert_buf = new PosColorVertex[line_count * 2]; + for (uint32_t i = 0; i < debugCommands.size(); i++) { + if (debugCommands[i].type == DebugCommand::Line) { + // from coordinates + line_vert_buf[2 * i].m_x = debugCommands[i].from[0]; + line_vert_buf[2 * i].m_y = debugCommands[i].from[1]; + line_vert_buf[2 * i].m_z = debugCommands[i].from[2]; + + uint32_t color = + (0xff << 24) + + (static_cast(debugCommands[i].color[0]) * 255 << 0) + + (static_cast(debugCommands[i].color[1]) * 255 << 8) + + (static_cast(debugCommands[i].color[2]) * 255 << 16); + + // from color + line_vert_buf[2 * i].m_abgr = color; + + // from index + line_idx_buf[2 * i] = 2 * i; + + // to coordinates + line_vert_buf[2 * i + 1].m_x = debugCommands[i].to[0]; + line_vert_buf[2 * i + 1].m_y = debugCommands[i].to[1]; + line_vert_buf[2 * i + 1].m_z = debugCommands[i].to[2]; + + // to color + line_vert_buf[2 * i + 1].m_abgr = color; + + // to index + line_idx_buf[2 * i + 1] = 2 * i + 1; + } + } + + // update buffer from buffer data + bgfx::updateDynamicVertexBuffer (debug_lines_vbh, + 0, + bgfx::copy(line_vert_buf, sizeof(PosColorVertex) * line_count * 2) + ); + + bgfx::updateDynamicIndexBuffer (debug_lines_ibh, + 0, + bgfx::copy(line_idx_buf, sizeof(uint16_t) * line_count * 2) + ); + + // submit data + const RenderState& st = s_renderStates[RenderState::Debug]; + + bgfx::setIndexBuffer(debug_lines_ibh); + bgfx::setVertexBuffer(debug_lines_vbh); + bgfx::setState(st.m_state); + bgfx::submit(st.m_viewId, st.m_program); + + // free buffer data + delete[] line_vert_buf; + delete[] line_idx_buf; } @@ -1308,6 +1393,9 @@ void Renderer::paintGL() { } ImGui::End(); + + // clear debug commands as they have to be issued every frame + debugCommands.clear(); } Entity* Renderer::createEntity() { @@ -1371,3 +1459,18 @@ bgfxutils::Mesh* Renderer::loadMesh(const char* filename) { return result; } +// debug commands +void Renderer::drawDebugLine ( + const SimpleMath::Vector3f &from, + const SimpleMath::Vector3f &to, + const SimpleMath::Vector3f &color) { + DebugCommand cmd; + cmd.type = DebugCommand::Line; + cmd.from = from; + cmd.to = to; + cmd.color = color; + + debugCommands.push_back(cmd); +} + + diff --git a/src/modules/RenderModule.h b/src/modules/RenderModule.h index ade9aa3..841430b 100644 --- a/src/modules/RenderModule.h +++ b/src/modules/RenderModule.h @@ -176,7 +176,18 @@ struct LightProbe bgfx::TextureHandle m_texIrr; }; +struct DebugCommand { + enum CommandType { + Line, + Arrow + }; + CommandType type; + + SimpleMath::Vector3f from; + SimpleMath::Vector3f to; + SimpleMath::Vector3f color; +}; struct Renderer { bool initialized; @@ -198,6 +209,7 @@ struct Renderer { std::vector cameras; std::vector lights; + std::vector debugCommands; uint16_t activeCameraIndex; @@ -228,6 +240,12 @@ struct Renderer { bool destroyEntity (Entity* entity); bgfxutils::Mesh* loadMesh(const char* filename); + + // debug commands + void drawDebugLine ( + const SimpleMath::Vector3f &from, + const SimpleMath::Vector3f &to, + const SimpleMath::Vector3f &color); }; struct RenderState { diff --git a/src/modules/TestModule.cc b/src/modules/TestModule.cc index faf7cc3..245ea44 100644 --- a/src/modules/TestModule.cc +++ b/src/modules/TestModule.cc @@ -389,6 +389,12 @@ static bool module_step(struct module_state *state, float dt) { handle_keyboard(state, dt); update_character(state, dt); + gRenderer->drawDebugLine ( + Vector3f (0.f, 0.f, 0.f), + Vector3f (5.f, 3.f, 2.f), + Vector3f (0.f, 1.f, 0.f) + ); + return true; }