Mercurial > hg > orthanc-stone
diff Framework/Scene2D/Internals/OpenGLLinesProgram.cpp @ 947:1091b2adeb5a toa2019081001
Fixed animation frame stopping when returning false + big work on the OpenGL
objects to make them lost context-safe + debug code to forcefully tag a
context as lost + debug macros
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Sat, 10 Aug 2019 13:07:31 +0200 |
parents | 61ba4b504e9a |
children | a7351ad54960 |
line wrap: on
line diff
--- a/Framework/Scene2D/Internals/OpenGLLinesProgram.cpp Tue Aug 06 15:07:23 2019 +0200 +++ b/Framework/Scene2D/Internals/OpenGLLinesProgram.cpp Sat Aug 10 13:07:31 2019 +0200 @@ -263,99 +263,102 @@ verticesCount_(0), thickness_(static_cast<float>(layer.GetThickness())) { - // High-level reference: - // https://mattdesl.svbtle.com/drawing-lines-is-hard - // https://forum.libcinder.org/topic/smooth-thick-lines-using-geometry-shader - - size_t countVertices = 0; - for (size_t i = 0; i < layer.GetChainsCount(); i++) + if (!context_.IsContextLost()) { - size_t countSegments = layer.GetChain(i).size() - 1; + // High-level reference: + // https://mattdesl.svbtle.com/drawing-lines-is-hard + // https://forum.libcinder.org/topic/smooth-thick-lines-using-geometry-shader - if (layer.IsClosedChain(i)) + size_t countVertices = 0; + for (size_t i = 0; i < layer.GetChainsCount(); i++) { - countSegments++; - } - - // Each segment is made of 2 triangles. One triangle is - // defined by 3 points in 2D => 6 vertices per segment. - countVertices += countSegments * 2 * 3; - } - - std::vector<float> coords, colors, miterDirections; - coords.reserve(countVertices * COMPONENTS_POSITION); - colors.reserve(countVertices * COMPONENTS_COLOR); - miterDirections.reserve(countVertices * COMPONENTS_MITER); - - for (size_t i = 0; i < layer.GetChainsCount(); i++) - { - const PolylineSceneLayer::Chain& chain = layer.GetChain(i); - - if (chain.size() > 1) - { - std::vector<Segment> segments; - for (size_t j = 1; j < chain.size(); j++) - { - segments.push_back(Segment(chain, j - 1, j)); - } + size_t countSegments = layer.GetChain(i).size() - 1; if (layer.IsClosedChain(i)) { - segments.push_back(Segment(chain, chain.size() - 1, 0)); - } - - // Try and create nice miters - for (size_t j = 1; j < segments.size(); j++) - { - Segment::CreateMiter(segments[j - 1], segments[j]); + countSegments++; } - if (layer.IsClosedChain(i)) + // Each segment is made of 2 triangles. One triangle is + // defined by 3 points in 2D => 6 vertices per segment. + countVertices += countSegments * 2 * 3; + } + + std::vector<float> coords, colors, miterDirections; + coords.reserve(countVertices * COMPONENTS_POSITION); + colors.reserve(countVertices * COMPONENTS_COLOR); + miterDirections.reserve(countVertices * COMPONENTS_MITER); + + for (size_t i = 0; i < layer.GetChainsCount(); i++) + { + const PolylineSceneLayer::Chain& chain = layer.GetChain(i); + + if (chain.size() > 1) { - Segment::CreateMiter(segments.back(), segments.front()); - } + std::vector<Segment> segments; + for (size_t j = 1; j < chain.size(); j++) + { + segments.push_back(Segment(chain, j - 1, j)); + } - for (size_t j = 0; j < segments.size(); j++) - { - if (!segments[j].IsEmpty()) + if (layer.IsClosedChain(i)) + { + segments.push_back(Segment(chain, chain.size() - 1, 0)); + } + + // Try and create nice miters + for (size_t j = 1; j < segments.size(); j++) { - segments[j].AddTriangles(coords, miterDirections, colors, layer.GetColor(i)); + Segment::CreateMiter(segments[j - 1], segments[j]); + } + + if (layer.IsClosedChain(i)) + { + Segment::CreateMiter(segments.back(), segments.front()); + } + + for (size_t j = 0; j < segments.size(); j++) + { + if (!segments[j].IsEmpty()) + { + segments[j].AddTriangles(coords, miterDirections, colors, layer.GetColor(i)); + } } } } - } - assert(coords.size() == colors.size()); + assert(coords.size() == colors.size()); - if (!coords.empty()) - { - verticesCount_ = coords.size() / COMPONENTS_POSITION; + if (!coords.empty()) + { + verticesCount_ = coords.size() / COMPONENTS_POSITION; + + context_.MakeCurrent(); + glGenBuffers(3, buffers_); - context_.MakeCurrent(); - glGenBuffers(3, buffers_); - - glBindBuffer(GL_ARRAY_BUFFER, buffers_[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * coords.size(), &coords[0], GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, buffers_[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * coords.size(), &coords[0], GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, buffers_[1]); - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * miterDirections.size(), &miterDirections[0], GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, buffers_[1]); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * miterDirections.size(), &miterDirections[0], GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, buffers_[2]); - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * colors.size(), &colors[0], GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, buffers_[2]); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * colors.size(), &colors[0], GL_STATIC_DRAW); + } } } OpenGLLinesProgram::Data::~Data() { - if (!IsEmpty()) + if (!context_.IsContextLost() && !IsEmpty()) { context_.MakeCurrent(); + ORTHANC_OPENGL_TRACE_CURRENT_CONTEXT("About to call glDeleteBuffers"); glDeleteBuffers(3, buffers_); } } - GLuint OpenGLLinesProgram::Data::GetVerticesBuffer() const { if (IsEmpty()) @@ -398,19 +401,20 @@ OpenGLLinesProgram::OpenGLLinesProgram(OpenGL::IOpenGLContext& context) : context_(context) { - context_.MakeCurrent(); - - program_.reset(new OpenGL::OpenGLProgram); - program_->CompileShaders(VERTEX_SHADER, FRAGMENT_SHADER); + if (!context_.IsContextLost()) + { + context_.MakeCurrent(); + program_.reset(new OpenGL::OpenGLProgram(context_)); + program_->CompileShaders(VERTEX_SHADER, FRAGMENT_SHADER); + } } - void OpenGLLinesProgram::Apply(const Data& data, const AffineTransform2D& transform, bool antialiasing, bool scaleIndependantThickness) { - if (!data.IsEmpty()) + if (!context_.IsContextLost() && !data.IsEmpty()) { context_.MakeCurrent(); program_->Use();