Wed, 23 Oct 2013 13:14:17 +0300
now compiles again
src/gldata.cpp | file | annotate | diff | comparison | revisions | |
src/gldata.h | file | annotate | diff | comparison | revisions | |
src/gldraw.cpp | file | annotate | diff | comparison | revisions | |
src/gldraw.h | file | annotate | diff | comparison | revisions |
--- a/src/gldata.cpp Wed Oct 23 12:46:10 2013 +0300 +++ b/src/gldata.cpp Wed Oct 23 13:14:17 2013 +0300 @@ -6,8 +6,10 @@ #include "gldraw.h" #include <QDate> +#define DEBUG(...) fprint (stdout, __VA_ARGS__) + cfg (Bool, gl_blackedges, false); -static List<short> g_warnedColors; +static QList<short> g_warnedColors; VertexCompiler g_vertexCompiler; // ============================================================================= @@ -20,15 +22,15 @@ // ============================================================================= // ----------------------------------------------------------------------------- -VertexCompiler::Array::~Array() { - delete[] m_data; +VertexCompiler::Array::~Array() +{ delete[] m_data; } // ============================================================================= // ----------------------------------------------------------------------------- -void VertexCompiler::Array::clear() { - delete[] m_data; - +void VertexCompiler::Array::clear() +{ delete[] m_data; + m_data = new Vertex[64]; m_size = 64; m_ptr = &m_data[0]; @@ -36,27 +38,27 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void VertexCompiler::Array::resizeToFit (Size newSize) { - if (allocatedSize() >= newSize) +void VertexCompiler::Array::resizeToFit (Size newSize) +{ if (allocatedSize() >= newSize) return; - + int32 cachedWriteSize = writtenSize(); - + // Add some lee-way space to reduce the amount of resizing. newSize += 256; - + const Size oldSize = allocatedSize(); - + // We need to back up the data first Vertex* copy = new Vertex[oldSize]; memcpy (copy, m_data, oldSize); - + // Re-create the buffer delete[] m_data; m_data = new Vertex[newSize]; m_size = newSize; m_ptr = &m_data[cachedWriteSize / sizeof (Vertex)]; - + // Copy the data back memcpy (m_data, copy, oldSize); delete[] copy; @@ -64,38 +66,38 @@ // ============================================================================= // ----------------------------------------------------------------------------- -const VertexCompiler::Vertex* VertexCompiler::Array::data() const { - return m_data; +const VertexCompiler::Vertex* VertexCompiler::Array::data() const +{ return m_data; } // ============================================================================= // ----------------------------------------------------------------------------- -const VertexCompiler::Array::Size& VertexCompiler::Array::allocatedSize() const { - return m_size; +const VertexCompiler::Array::Size& VertexCompiler::Array::allocatedSize() const +{ return m_size; } // ============================================================================= // ----------------------------------------------------------------------------- -VertexCompiler::Array::Size VertexCompiler::Array::writtenSize() const { - return (m_ptr - m_data) * sizeof (Vertex); +VertexCompiler::Array::Size VertexCompiler::Array::writtenSize() const +{ return (m_ptr - m_data) * sizeof (Vertex); } // ============================================================================= // ----------------------------------------------------------------------------- -void VertexCompiler::Array::write (const Vertex& f) { - // Ensure there's enoughspace for the new vertex +void VertexCompiler::Array::write (const Vertex& f) +{ // Ensure there's enoughspace for the new vertex resizeToFit (writtenSize() + sizeof f); - + // Write the float in *m_ptr++ = f; } // ============================================================================= // ----------------------------------------------------------------------------- -void VertexCompiler::Array::merge (Array* other) { - // Ensure there's room for both buffers +void VertexCompiler::Array::merge (Array* other) +{ // Ensure there's room for both buffers resizeToFit (writtenSize() + other->writtenSize()); - + memcpy (m_ptr, other->data(), other->writtenSize()); m_ptr += other->writtenSize() / sizeof (Vertex); } @@ -104,8 +106,7 @@ // ----------------------------------------------------------------------------- VertexCompiler::VertexCompiler() : m_file (null) -{ - needMerge(); +{ needMerge(); } VertexCompiler::~VertexCompiler() {} @@ -115,242 +116,250 @@ // This is so that the index color is generated correctly - it has to reference // the top level object's ID. This is crucial for picking to work. // ----------------------------------------------------------------------------- -void VertexCompiler::compilePolygon (LDObject* drawobj, LDObject* trueobj, List<CompiledTriangle>& data) { - const QColor pickColor = getObjectColor (trueobj, PickColor); +void VertexCompiler::compilePolygon (LDObject* drawobj, LDObject* trueobj, QList< VertexCompiler::CompiledTriangle >& data) +{ const QColor pickColor = getObjectColor (trueobj, PickColor); LDObject::Type type = drawobj->getType(); - List<LDObject*> objs; - + QList<LDObject*> objs; + assert (type != LDObject::Subfile); - - if (type == LDObject::Quad) { - for (LDTriangle* t : static_cast<LDQuad*> (drawobj)->splitToTriangles()) + + if (type == LDObject::Quad) + { for (LDTriangle* t : static_cast<LDQuad*> (drawobj)->splitToTriangles()) objs << t; - } else + } + else objs << drawobj; - - for (LDObject* obj : objs) { - const LDObject::Type objtype = obj->getType(); + + for (LDObject* obj : objs) + { const LDObject::Type objtype = obj->getType(); const bool isline = (objtype == LDObject::Line || objtype == LDObject::CndLine); const int verts = isline ? 2 : obj->vertices(); QColor normalColor = getObjectColor (obj, Normal); - + assert (isline || objtype == LDObject::Triangle); - + CompiledTriangle a; a.rgb = normalColor.rgb(); a.pickrgb = pickColor.rgb(); a.numVerts = verts; a.obj = trueobj; a.isCondLine = (objtype == LDObject::CndLine); - - for (int i = 0; i < verts; ++i) { - a.verts[i] = obj->getVertex (i); + + for (int i = 0; i < verts; ++i) + { a.verts[i] = obj->getVertex (i); a.verts[i].y() = -a.verts[i].y(); a.verts[i].z() = -a.verts[i].z(); } - + data << a; } } // ============================================================================= // ----------------------------------------------------------------------------- -void VertexCompiler::compileObject (LDObject* obj) { - initObject (obj); - List<CompiledTriangle> data; +void VertexCompiler::compileObject (LDObject* obj) +{ initObject (obj); + QList<CompiledTriangle> data; QTime t0; - + for (int i = 0; i < GL::NumArrays; ++i) m_objArrays[obj][i].clear(); - + t0 = QTime::currentTime(); compileSubObject (obj, obj, data); - print ("COMPILATION: %1ms\n", t0.msecsTo (QTime::currentTime())); - + DEBUG ("COMPILATION: %1ms\n", t0.msecsTo (QTime::currentTime())); + t0 = QTime::currentTime(); - for (int i = 0; i < GL::NumArrays; ++i) { - GL::VAOType type = (GL::VAOType) i; + + for (int i = 0; i < GL::NumArrays; ++i) + { GL::VAOType type = (GL::VAOType) i; const bool islinearray = (type == GL::EdgeArray || type == GL::EdgePickArray); - - for (const CompiledTriangle& poly : data) { - if (poly.isCondLine) { - // Conditional lines go to the edge pick array and the array + + for (const CompiledTriangle& poly : data) + { if (poly.isCondLine) + { // Conditional lines go to the edge pick array and the array // specifically designated for conditional lines and nowhere else. if (type != GL::EdgePickArray && type != GL::CondEdgeArray) continue; - } else { - // Lines and only lines go to the line array and only to the line array. - if ((poly.numVerts == 2) ^ islinearray) + } + else + { // Lines and only lines go to the line array and only to the line array. + if ( (poly.numVerts == 2) ^ islinearray) continue; - + // Only conditional lines go into the conditional line array if (type == GL::CondEdgeArray) continue; } - + Array* verts = postprocess (poly, type); m_objArrays[obj][type].merge (verts); delete verts; } } - print ("POST-PROCESS: %1ms\n", t0.msecsTo (QTime::currentTime())); - + + DEBUG ("POST-PROCESS: %1ms\n", t0.msecsTo (QTime::currentTime())); + needMerge(); } // ============================================================================= // ----------------------------------------------------------------------------- -void VertexCompiler::compileSubObject (LDObject* obj, LDObject* topobj, List<CompiledTriangle>& data) { - List<LDObject*> objs; - - switch (obj->getType()) { - case LDObject::Triangle: - case LDObject::Line: - case LDObject::CndLine: - compilePolygon (obj, topobj, data); - break; - - case LDObject::Quad: - for (LDTriangle* triangle : static_cast<LDQuad*> (obj)->splitToTriangles()) - compilePolygon (triangle, topobj, data); - break; - - case LDObject::Subfile: - { - QTime t0 = QTime::currentTime(); - objs = static_cast<LDSubfile*> (obj)->inlineContents (LDSubfile::RendererInline | LDSubfile::DeepCacheInline); - print ("\t- INLINE: %1ms\n", t0.msecsTo (QTime::currentTime())); - print ("\t- %1 objects\n", objs.size()); - - t0 = QTime::currentTime(); - for (LDObject* obj : objs) { - compileSubObject (obj, topobj, data); - delete obj; - } - print ("\t- SUB-COMPILATION: %1ms\n", t0.msecsTo (QTime::currentTime())); - } - break; - - default: - break; +void VertexCompiler::compileSubObject (LDObject* obj, LDObject* topobj, QList< VertexCompiler::CompiledTriangle >& data) +{ QList<LDObject*> objs; + + switch (obj->getType()) + { case LDObject::Triangle: + case LDObject::Line: + case LDObject::CndLine: + { compilePolygon (obj, topobj, data); + } break; + + case LDObject::Quad: + { for (LDTriangle * triangle : static_cast<LDQuad*> (obj)->splitToTriangles()) + compilePolygon (triangle, topobj, data); + } break; + + case LDObject::Subfile: + { QTime t0 = QTime::currentTime(); + objs = static_cast<LDSubfile*> (obj)->inlineContents (LDSubfile::RendererInline | LDSubfile::DeepCacheInline); + DEBUG ("\t- INLINE: %1ms\n", t0.msecsTo (QTime::currentTime())); + DEBUG ("\t- %1 objects\n", objs.size()); + + t0 = QTime::currentTime(); + + for (LDObject* obj : objs) + { compileSubObject (obj, topobj, data); + delete obj; + } + + DEBUG ("\t- SUB-COMPILATION: %1ms\n", t0.msecsTo (QTime::currentTime())); + } break; + + default: + {} break; } } // ============================================================================= // ----------------------------------------------------------------------------- -void VertexCompiler::compileFile() { - for (LDObject* obj : m_file->objects()) +void VertexCompiler::compileFile() +{ for (LDObject * obj : m_file->objects()) compileObject (obj); } // ============================================================================= // ----------------------------------------------------------------------------- -void VertexCompiler::forgetObject (LDObject* obj) { - auto it = m_objArrays.find (obj); +void VertexCompiler::forgetObject (LDObject* obj) +{ auto it = m_objArrays.find (obj); + if (it != m_objArrays.end()) delete *it; - + m_objArrays.remove (obj); } // ============================================================================= // ----------------------------------------------------------------------------- -void VertexCompiler::setFile (LDFile* file) { - m_file = file; +void VertexCompiler::setFile (LDFile* file) +{ m_file = file; } // ============================================================================= // ----------------------------------------------------------------------------- -const VertexCompiler::Array* VertexCompiler::getMergedBuffer (GL::VAOType type) { - // If there are objects staged for compilation, compile them now. - if (m_staged.size() > 0) { - for (LDObject* obj : m_staged) +const VertexCompiler::Array* VertexCompiler::getMergedBuffer (GL::VAOType type) +{ // If there are objects staged for compilation, compile them now. + if (m_staged.size() > 0) +{ for (LDObject * obj : m_staged) compileObject (obj); - + m_staged.clear(); } - + assert (type < GL::NumArrays); - - if (m_changed[type]) { - m_changed[type] = false; + + if (m_changed[type]) + { m_changed[type] = false; m_mainArrays[type].clear(); - - for (LDObject* obj : m_file->objects()) { - if (!obj->isScemantic()) + + for (LDObject* obj : m_file->objects()) + { if (!obj->isScemantic()) continue; - + auto it = m_objArrays.find (obj); - + if (it != m_objArrays.end()) - m_mainArrays[type].merge (&(*it)[type]); + m_mainArrays[type].merge (& (*it) [type]); } - - print ("merged array %1: %2 bytes\n", (int) type, m_mainArrays[type].writtenSize()); + + DEBUG ("merged array %1: %2 bytes\n", (int) type, m_mainArrays[type].writtenSize()); } - + return &m_mainArrays[type]; } // ============================================================================= // This turns a compiled triangle into usable VAO vertices // ----------------------------------------------------------------------------- -VertexCompiler::Array* VertexCompiler::postprocess (const CompiledTriangle& triangle, GL::VAOType type) { - Array* va = new Array; - List<Vertex> verts; - - for (int i = 0; i < triangle.numVerts; ++i) { - alias v0 = triangle.verts[i]; +VertexCompiler::Array* VertexCompiler::postprocess (const CompiledTriangle& triangle, GL::VAOType type) +{ Array* va = new Array; + QList<Vertex> verts; + + for (int i = 0; i < triangle.numVerts; ++i) + { alias v0 = triangle.verts[i]; Vertex v; v.x = v0.x(); v.y = v0.y(); v.z = v0.z(); - - switch (type) { - case GL::MainArray: - case GL::EdgeArray: - case GL::CondEdgeArray: - v.color = triangle.rgb; - break; - - case GL::PickArray: - case GL::EdgePickArray: - v.color = triangle.pickrgb; - - case GL::BFCArray: - break; // handled separately - - case GL::NumArrays: - assert (false); + + switch (type) + { case GL::MainArray: + case GL::EdgeArray: + case GL::CondEdgeArray: + { v.color = triangle.rgb; + } break; + + case GL::PickArray: + case GL::EdgePickArray: + { v.color = triangle.pickrgb; + } break; + + case GL::BFCArray: + case GL::NumArrays: + break; // handled separately } - + verts << v; } - - if (type == GL::BFCArray) { - int32 rgb = getObjectColor (triangle.obj, BFCFront).rgb(); - for (Vertex v : verts) { + + if (type == GL::BFCArray) + { int32 rgb = getObjectColor (triangle.obj, BFCFront).rgb(); + + for (Vertex v : verts) + { v.color = rgb; + va->write (v); + } + + rgb = getObjectColor (triangle.obj, BFCBack).rgb(); + + for (int i = verts.size() - 1; i >= 0; --i) + { Vertex v = verts[i]; v.color = rgb; va->write (v); } - - rgb = getObjectColor (triangle.obj, BFCBack).rgb(); - for (Vertex v : c_rev<Vertex> (verts)) { - v.color = rgb; - va->write (v); - } - } else { - for (Vertex v : verts) + } + else + { for (Vertex v : verts) va->write (v); } - + return va; } // ============================================================================= // ----------------------------------------------------------------------------- -uint32 VertexCompiler::getColorRGB (QColor& color) { - return +uint32 VertexCompiler::getColorRGB (QColor& color) +{ return (color.red() & 0xFF) << 0x00 | (color.green() & 0xFF) << 0x08 | (color.blue() & 0xFF) << 0x10 | @@ -359,103 +368,104 @@ // ============================================================================= // ----------------------------------------------------------------------------- -QColor VertexCompiler::getObjectColor (LDObject* obj, ColorType colotype) const { - QColor qcol; - +QColor VertexCompiler::getObjectColor (LDObject* obj, ColorType colotype) const +{ QColor qcol; + if (!obj->isColored()) return QColor(); - - if (colotype == PickColor) { - // Make the color by the object's ID if we're picking, so we can make the + + if (colotype == PickColor) + { // Make the color by the object's ID if we're picking, so we can make the // ID again from the color we get from the picking results. Be sure to use // the top level parent's index since we want a subfile's children point // to the subfile itself. long i = obj->topLevelParent()->id(); - + // Calculate a color based from this index. This method caters for // 16777216 objects. I don't think that'll be exceeded anytime soon. :) // ATM biggest is 53588.dat with 12600 lines. int r = (i / (256 * 256)) % 256, g = (i / 256) % 256, b = i % 256; - + return QColor (r, g, b); } - + if ((colotype == BFCFront || colotype == BFCBack) && obj->getType() != LDObject::Line && - obj->getType() != LDObject::CndLine) { - - if (colotype == BFCFront) + obj->getType() != LDObject::CndLine + ) + { if (colotype == BFCFront) qcol = QColor (40, 192, 0); else qcol = QColor (224, 0, 0); - } else { - if (obj->color() == maincolor) + } + else + { if (obj->color() == maincolor) qcol = GL::getMainColor(); - else { - LDColor* col = getColor (obj->color()); - + else + { LDColor* col = getColor (obj->color()); + if (col) qcol = col->faceColor; } - - if (obj->color() == edgecolor) { - qcol = QColor (32, 32, 32); // luma (m_bgcolor) < 40 ? QColor (64, 64, 64) : Qt::black; + + if (obj->color() == edgecolor) + { qcol = QColor (32, 32, 32); // luma (m_bgcolor) < 40 ? QColor (64, 64, 64) : Qt::black; LDColor* col; - + if (!gl_blackedges && obj->parent() && (col = getColor (obj->parent()->color()))) qcol = col->edgeColor; } - - if (qcol.isValid() == false) { - // The color was unknown. Use main color to make the object at least + + if (qcol.isValid() == false) + { // The color was unknown. Use main color to make the object at least // not appear pitch-black. if (obj->color() != edgecolor) qcol = GL::getMainColor(); else qcol = Qt::black; - + // Warn about the unknown color, but only once. for (short i : g_warnedColors) if (obj->color() == i) return qcol; - + log ("%1: Unknown color %2!\n", __func__, obj->color()); g_warnedColors << obj->color(); return qcol; } } - - if (obj->topLevelParent()->selected()) { - // Brighten it up if selected. + + if (obj->topLevelParent()->selected()) + { // Brighten it up if selected. const int add = 51; - + qcol.setRed (min (qcol.red() + add, 255)); qcol.setGreen (min (qcol.green() + add, 255)); qcol.setBlue (min (qcol.blue() + add, 255)); } - + return qcol; } // ============================================================================= // ----------------------------------------------------------------------------- -void VertexCompiler::needMerge() { - // Set all of m_changed to true +void VertexCompiler::needMerge() +{ // Set all of m_changed to true memset (m_changed, 0xFF, sizeof m_changed); } // ============================================================================= // ----------------------------------------------------------------------------- -void VertexCompiler::initObject (LDObject* obj) { - if (m_objArrays.find (obj) == m_objArrays.end()) +void VertexCompiler::initObject (LDObject* obj) +{ if (m_objArrays.find (obj) == m_objArrays.end()) m_objArrays[obj] = new Array[GL::NumArrays]; } // ============================================================================= // ----------------------------------------------------------------------------- -void VertexCompiler::stageForCompilation (LDObject* obj) { - m_staged << obj; - m_staged.makeUnique(); -} \ No newline at end of file +void VertexCompiler::stageForCompilation (LDObject* obj) +{ m_staged << obj; + removeDuplicates (m_staged); +}
--- a/src/gldata.h Wed Oct 23 12:46:10 2013 +0300 +++ b/src/gldata.h Wed Oct 23 13:14:17 2013 +0300 @@ -37,80 +37,80 @@ * these structs are the VAOs that get passed to the renderer. */ -class VertexCompiler { -public: - enum ColorType { - Normal, - BFCFront, - BFCBack, - PickColor, - }; - - struct CompiledTriangle { - vertex verts[3]; - uint8 numVerts; // 2 if a line - QRgb rgb; // Color of this poly normally - QRgb pickrgb; // Color of this poly while picking - bool isCondLine; // Is this a conditional line? - LDObject* obj; // Pointer to the object this poly represents - }; - - struct Vertex { - float x, y, z; - uint32 color; - float pad[4]; - }; - - class Array { - public: - typedef int32 Size; - - Array(); - Array (const Array& other) = delete; - ~Array(); - - void clear(); - void merge (Array* other); - void resizeToFit (Size newSize); - const Size& allocatedSize() const; - Size writtenSize() const; - const Vertex* data() const; - void write (const VertexCompiler::Vertex& f); - Array& operator= (const Array& other) = delete; - +class VertexCompiler +{ public: + enum ColorType + { Normal, + BFCFront, + BFCBack, + PickColor, + }; + + struct CompiledTriangle + { vertex verts[3]; + uint8 numVerts; // 2 if a line + QRgb rgb; // Color of this poly normally + QRgb pickrgb; // Color of this poly while picking + bool isCondLine; // Is this a conditional line? + LDObject* obj; // Pointer to the object this poly represents + }; + + struct Vertex + { float x, y, z; + uint32 color; + float pad[4]; + }; + + class Array + { public: + typedef int32 Size; + + Array(); + Array (const Array& other) = delete; + ~Array(); + + void clear(); + void merge (Array* other); + void resizeToFit (Size newSize); + const Size& allocatedSize() const; + Size writtenSize() const; + const Vertex* data() const; + void write (const VertexCompiler::Vertex& f); + Array& operator= (const Array& other) = delete; + + private: + Vertex* m_data; + Vertex* m_ptr; + Size m_size; + }; + + VertexCompiler(); + ~VertexCompiler(); + void setFile (LDFile* file); + void compileFile(); + void forgetObject (LDObject* obj); + void initObject (LDObject* obj); + const Array* getMergedBuffer (GL::VAOType type); + QColor getObjectColor (LDObject* obj, ColorType list) const; + void needMerge(); + void stageForCompilation (LDObject* obj); + + static uint32 getColorRGB (QColor& color); + private: - Vertex* m_data; - Vertex* m_ptr; - Size m_size; - }; - - VertexCompiler(); - ~VertexCompiler(); - void setFile (LDFile* file); - void compileFile(); - void forgetObject (LDObject* obj); - void initObject (LDObject* obj); - const Array* getMergedBuffer (GL::VAOType type); - QColor getObjectColor (LDObject* obj, ColorType list) const; - void needMerge(); - void stageForCompilation (LDObject* obj); - - static uint32 getColorRGB (QColor& color); - -private: - void compilePolygon (LDObject* drawobj, LDObject* trueobj, List<CompiledTriangle>& data); - void compileObject (LDObject* obj); - void compileSubObject (LDObject* obj, LDObject* topobj, List<CompiledTriangle>& data); - Array* postprocess (const CompiledTriangle& i, GL::VAOType type); - - QMap<LDObject*, Array*> m_objArrays; - QMap<LDFile*, Array*> m_fileCache; - Array m_mainArrays[GL::NumArrays]; - LDFile* m_file; - bool m_changed[GL::NumArrays]; - List<LDObject*> m_staged; + void compilePolygon (LDObject* drawobj, LDObject* trueobj, QList<CompiledTriangle>& data); + void compileObject (LDObject* obj); + void compileSubObject (LDObject* obj, LDObject* topobj, QList<CompiledTriangle>& data); + Array* postprocess (const CompiledTriangle& i, GL::VAOType type); + + QMap<LDObject*, Array*> m_objArrays; + QMap<LDFile*, Array*> m_fileCache; + Array m_mainArrays[GL::NumArrays]; + LDFile* m_file; + bool m_changed[GL::NumArrays]; + QList<LDObject*> m_staged; }; extern VertexCompiler g_vertexCompiler; -#endif // LDFORGE_GLDATA_H \ No newline at end of file +#endif // LDFORGE_GLDATA_H
--- a/src/gldraw.cpp Wed Oct 23 12:46:10 2013 +0300 +++ b/src/gldraw.cpp Wed Oct 23 13:14:17 2013 +0300 @@ -707,6 +707,12 @@ // ============================================================================= // ----------------------------------------------------------------------------- +QColor GLRenderer::getTextPen () const +{ return m_darkbg ? Qt::white : Qt::black; +} + +// ============================================================================= +// ----------------------------------------------------------------------------- void GLRenderer::compileAllObjects() { g_vertexCompiler.compileFile(); }
--- a/src/gldraw.h Wed Oct 23 12:46:10 2013 +0300 +++ b/src/gldraw.h Wed Oct 23 13:14:17 2013 +0300 @@ -73,6 +73,16 @@ enum Camera { Top, Front, Left, Bottom, Back, Right, Free }; enum ListType { NormalList, PickList, BFCFrontList, BFCBackList }; + enum VAOType { + MainArray, + EdgeArray, + CondEdgeArray, + BFCArray, + PickArray, + EdgePickArray, + NumArrays + }; + GLRenderer (QWidget* parent = null); ~GLRenderer(); @@ -88,7 +98,7 @@ double depthValue() const; void drawGLScene(); void endDraw (bool accept); - QColor getMainColor(); + static QColor getMainColor(); LDGLOverlay& getOverlay (int newcam); void hardRefresh(); void initGLData();