diff --git a/modules/debugging/rendering/debugrenderer.cpp b/modules/debugging/rendering/debugrenderer.cpp index c4a6bb5cba..13d4c34b7e 100644 --- a/modules/debugging/rendering/debugrenderer.cpp +++ b/modules/debugging/rendering/debugrenderer.cpp @@ -41,7 +41,7 @@ namespace { namespace openspace { - std::shared_ptr DebugRenderer::_singleton = nullptr; + std::shared_ptr DebugRenderer::_reference = nullptr; DebugRenderer::DebugRenderer() { @@ -50,42 +50,47 @@ namespace openspace { "${MODULE_DEBUGGING}/rendering/debugshader_vs.glsl", "${MODULE_DEBUGGING}/rendering/debugshader_fs.glsl" )); + } + DebugRenderer::DebugRenderer(std::shared_ptr programObject) + : _programObject(programObject) + { + // nothing to do } std::shared_ptr DebugRenderer::ref() { - if (_singleton == nullptr) { + if (_reference == nullptr) { try { - _singleton = std::make_shared(); + _reference = std::make_shared(); } catch (const ShaderObject::ShaderCompileError& e) { LERROR(e.what()); } } - return _singleton; + return _reference; } void DebugRenderer::renderVertices(const Vertices& clippingSpacePoints, GLenum mode, RGBA rgba) const { if (clippingSpacePoints.size() == 0) { + // nothing to render return; } + // Generate a vao, vertex array object (keeping track of pointers to vbo) GLuint _vaoID; glGenVertexArrays(1, &_vaoID); ghoul_assert(_vaoID != 0, "Could not generate vertex arrays"); + // Generate a vbo, vertex buffer object (storeing actual data) GLuint _vertexBufferID; glGenBuffers(1, &_vertexBufferID); ghoul_assert(_vertexBufferID != 0, "Could not create vertex buffer"); + // Activate the shader program and set the uniform color within the shader _programObject->activate(); _programObject->setUniform("color", rgba); - glBindVertexArray(_vaoID); - - - // Vertex buffer glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferID); glBufferData( GL_ARRAY_BUFFER, @@ -96,30 +101,29 @@ namespace openspace { glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(clippingSpacePoints[0]), 0); - // uniforms - - - + // Draw the vertices glDrawArrays(mode, 0, clippingSpacePoints.size()); + + // Check for errors GLenum error = glGetError(); if (error != GL_NO_ERROR) { LERROR(error); } + // Clean up after the draw call was made glBindVertexArray(0); - glDeleteVertexArrays(1, &_vaoID); glDeleteBuffers(1, &_vertexBufferID); _programObject->deactivate(); - } void DebugRenderer::renderBoxFaces(const Vertices& clippingSpaceBoxCorners, RGBA rgba) const { - const std::vector& V = clippingSpaceBoxCorners; + ghoul_assert(clippingSpaceBoxCorners.size() == 8, "Box must have 8 vertices"); + const Vertices& V = clippingSpaceBoxCorners; + std::vector T; - // add "sides"; - + // add "sides" T.push_back(V[1]); T.push_back(V[0]); T.push_back(V[4]); T.push_back(V[4]); T.push_back(V[5]); T.push_back(V[1]); @@ -143,9 +147,12 @@ namespace openspace { renderVertices(T, GL_TRIANGLES, rgba); } - void DebugRenderer::renderBoxEdges(const Vertices& clippingSpacePoints, RGBA rgba) const { - const std::vector& V = clippingSpacePoints; + void DebugRenderer::renderBoxEdges(const Vertices& clippingSpaceBoxCorners, RGBA rgba) const { + ghoul_assert(clippingSpaceBoxCorners.size() == 8, "Box must have 8 vertices"); + const Vertices& V = clippingSpaceBoxCorners; + std::vector lineVertices; + for (size_t i = 0; i < 4; i++) { lineVertices.push_back(V[2 * i]); lineVertices.push_back(V[2 * i + 1]); @@ -159,17 +166,17 @@ namespace openspace { DebugRenderer::ref()->renderVertices(lineVertices, GL_LINES, rgba); } - void DebugRenderer::renderNiceBox(const Vertices& clippingSpacePoints, RGBA rgba) const { - renderBoxFaces(clippingSpacePoints, rgba); + void DebugRenderer::renderNiceBox(const Vertices& clippingSpaceBoxCorners, RGBA rgba) const { + renderBoxFaces(clippingSpaceBoxCorners, rgba); glLineWidth(4.0f); - DebugRenderer::ref()->renderBoxEdges(clippingSpacePoints, rgba); + DebugRenderer::ref()->renderBoxEdges(clippingSpaceBoxCorners, rgba); glPointSize(10.0f); - DebugRenderer::ref()->renderVertices(clippingSpacePoints, GL_POINTS, rgba); + DebugRenderer::ref()->renderVertices(clippingSpaceBoxCorners, GL_POINTS, rgba); } - void DebugRenderer::renderCameraFrustum(const RenderData& data, const Camera& otherCamera) const { + void DebugRenderer::renderCameraFrustum(const RenderData& data, const Camera& otherCamera, RGBA rgba) const { using namespace glm; dmat4 modelTransform = translate(dmat4(1), data.position.dvec3()); dmat4 viewTransform = dmat4(data.camera.combinedViewMatrix()); @@ -177,7 +184,7 @@ namespace openspace { dmat4 inverseSavedV = glm::inverse(otherCamera.combinedViewMatrix()); dmat4 inverseSavedP = glm::inverse(otherCamera.projectionMatrix()); - std::vector clippingSpaceFrustumCorners(8); + Vertices clippingSpaceFrustumCorners(8); // loop through the corners of the saved camera frustum for (size_t i = 0; i < 8; i++) { bool cornerIsRight = i % 2 == 0; @@ -203,13 +210,12 @@ namespace openspace { glDisable(GL_CULL_FACE); - vec4 color(1, 1, 1, 0.3); - renderNiceBox(clippingSpaceFrustumCorners, color); + renderNiceBox(clippingSpaceFrustumCorners, rgba); glEnable(GL_CULL_FACE); } void DebugRenderer::renderAABB2(const AABB2& screenSpaceAABB, RGBA rgba) const { - std::vector vertices(4); + Vertices vertices(4); vertices[0] = vec4(screenSpaceAABB.min.x, screenSpaceAABB.min.y, 1, 1); vertices[1] = vec4(screenSpaceAABB.min.x, screenSpaceAABB.max.y, 1, 1); vertices[2] = vec4(screenSpaceAABB.max.x, screenSpaceAABB.min.y, 1, 1); @@ -219,7 +225,7 @@ namespace openspace { } const DebugRenderer::Vertices DebugRenderer::verticesFor(const AABB3& screenSpaceAABB) const { - std::vector vertices(8); + Vertices vertices(8); for (size_t i = 0; i < 8; i++) { bool cornerIsRight = i % 2 == 0; bool cornerIsUp = i > 3; diff --git a/modules/debugging/rendering/debugrenderer.h b/modules/debugging/rendering/debugrenderer.h index c4096d9553..8699e828fa 100644 --- a/modules/debugging/rendering/debugrenderer.h +++ b/modules/debugging/rendering/debugrenderer.h @@ -43,42 +43,122 @@ namespace openspace { using namespace ghoul::opengl; + /** - A helper class for quick rendering of vertices clipping space + A helper class for quick rendering of vertices IN clipping space. + + The class is practically stateless. It only stores a ghoul::opengl::ProgramObject + which can be reused despite the fact that rendering calls are invoked from different callers. + Therefor a static reference is provided for convenience which is accessed through ref(). Note: + That constructors are still public and the class is not a strict singleton. */ class DebugRenderer { public: - DebugRenderer(); - - static std::shared_ptr ref(); typedef std::vector Vertices; typedef glm::vec4 RGBA; - - void renderVertices(const Vertices& clippingSpacePoints, GLenum mode, RGBA = {1, 0, 0, 1}) const; - void renderBoxFaces(const Vertices& clippingSpacePoints, RGBA rgba = { 1, 0, 0, 1 }) const; - void renderBoxEdges(const Vertices& clippingSpacePoints, RGBA rgba = { 1, 0, 0, 1 }) const; - void renderNiceBox(const Vertices& clippingSpacePoints, RGBA rgba = { 1, 0, 0, 0.3 }) const; - void renderCameraFrustum(const RenderData& data, const Camera& otherCamera) const; + /** + * Consider using ref() before creating a new default instance! + */ + DebugRenderer(); + + /** + * Instantiate a new DebugRenderer with a custom shader program + */ + DebugRenderer(std::shared_ptr programObject); + + /** + * Access the static reference + */ + static std::shared_ptr ref(); + + + + + /** + * Render the vector of clipping space points in the specified mode and color. + */ + void renderVertices(const Vertices& clippingSpacePoints, GLenum mode, RGBA = {1, 0, 0, 1}) const; + + /** + * Takes a vector of exactly 8 vertices, i.e. corner points in a box. + * The box corners should be ordered from smaller to larger, + * first by x, the, y and finally z. + * + * 6-------7 + * |\ |\ + * | 2-------3 + * 4 | - - 5 | + * \| \| + * 0-------1 + * + */ + void renderBoxFaces(const Vertices& clippingSpaceBoxCorners, RGBA rgba = { 1, 0, 0, 1 }) const; + + /** + * Takes a vector of exactly 8 vertices, i.e. corner points in a box. + * The box corners should be ordered from smaller to larger, + * first by x, the, y and finally z. + * + * 6-------7 + * |\ |\ + * | 2-------3 + * 4 | - - 5 | + * \| \| + * 0-------1 + * + */ + void renderBoxEdges(const Vertices& clippingSpaceBoxCorners, RGBA rgba = { 1, 0, 0, 1 }) const; + + /** + * Takes a vector of exactly 8 vertices, i.e. corner points in a box. + * The box corners should be ordered from smaller to larger, + * first by x, the, y and finally z. + * + * 6-------7 + * |\ |\ + * | 2-------3 + * 4 | - - 5 | + * \| \| + * 0-------1 + * + */ + void renderNiceBox(const Vertices& clippingSpaceBoxCorners, RGBA rgba = { 1, 0, 0, 0.3 }) const; + + + + /** + * Input arguments: + * 1. const RenderData& data: defines position and camera that we will see the + * other cameras view frustum from + * 2. const Camera& otherCamera: The camera who's view frustum is to be rendered + * 3. RGBA rgba Color to draw the view frustum with + */ + void renderCameraFrustum(const RenderData& data, const Camera& otherCamera, RGBA rgba = { 1, 1, 1, 0.3 }) const; + + /** + * Renders a screen space AABB2 to the screen with the provided color + */ void renderAABB2(const AABB2& screenSpaceAABB, RGBA rgba = { 1, 1, 1, 0.3 }) const; + /** + * Takes a AABB3 in screen space and returns vertices representing the corner points + * of the AABB. The ordering of the corner points is compatible with the box rendering + * methods in this class. + */ const Vertices verticesFor(const AABB3& screenSpaceAABB) const; - private: + protected: - - std::shared_ptr _programObject; - - - static std::shared_ptr _singleton; - + static std::shared_ptr _reference; }; + } // namespace openspace