Tue, 21 Jan 2014 02:09:14 +0200
Merge ../ldforge into gl
Conflicts:
src/GLRenderer.cc
src/GLRenderer.h
src/LDObject.cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/GLCompiler.cc Tue Jan 21 02:09:14 2014 +0200 @@ -0,0 +1,433 @@ +#include "GLCompiler.h" +#include "LDObject.h" +#include "Colors.h" +#include "Document.h" +#include "Misc.h" +#include "GLRenderer.h" +#include <QDate> + +#define DE_BUG_PRINT(...) fprint (stdout, __VA_ARGS__) + +extern_cfg (Bool, gl_blackedges); +static QList<short> g_warnedColors; +GLCompiler g_vertexCompiler; + +// ============================================================================= +// +GLCompiler::GLCompiler() : + m_file (null) +{ + needMerge(); +} + +GLCompiler::~GLCompiler() {} + +// ============================================================================= +// Note: we use the top level object's color but the draw object's vertices. +// 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 GLCompiler::compilePolygon (LDObject* drawobj, LDObject* trueobj, QList< GLCompiler::CompiledTriangle >& data) +{ + const QColor pickColor = getObjectColor (trueobj, E_PickColor); + LDObject::Type type = drawobj->getType(); + LDObjectList objs; + + assert (type != LDObject::ESubfile); + + if (type == LDObject::EQuad) + { + for (LDTriangle* t : static_cast<LDQuad*> (drawobj)->splitToTriangles()) + objs << t; + } + else + objs << drawobj; + + for (LDObject* obj : objs) + { + const LDObject::Type objtype = obj->getType(); + const bool isline = (objtype == LDObject::ELine || objtype == LDObject::ECondLine); + const int verts = isline ? 2 : obj->vertices(); + QColor normalColor = getObjectColor (obj, E_NormalColor); + + assert (isline || objtype == LDObject::ETriangle); + + CompiledTriangle a; + a.rgb = getColorRGB (normalColor); + a.pickrgb = getColorRGB (pickColor); + a.numVerts = verts; + a.obj = trueobj; + a.isCondLine = (objtype == LDObject::ECondLine); + + 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 GLCompiler::compileObject (LDObject* obj) +{ + initObject (obj); + QList<CompiledTriangle> data; + QTime t0; + + t0 = QTime::currentTime(); + for (int i = 0; i < E_NumVertexArrays; ++i) + m_objArrays[obj][i].clear(); + DE_BUG_PRINT ("INIT: %1ms\n", t0.msecsTo (QTime::currentTime())); + + t0 = QTime::currentTime(); + compileSubObject (obj, obj, data); + DE_BUG_PRINT ("COMPILATION: %1ms\n", t0.msecsTo (QTime::currentTime())); + + t0 = QTime::currentTime(); + + for (int i = 0; i < E_NumVertexArrays; ++i) + { + E_VertexArrayType type = (E_VertexArrayType) i; + const bool islinearray = (type == E_EdgeArray || type == E_EdgePickArray); + + 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. + // They are kept separate from the regular edge array so that + // they can be drawn as dashed lines. + // + // However we don't need nor desire that behavior for the pick + // scene, so they can be grouped with normal edgelines for that. + if (type != E_EdgePickArray && type != E_CondEdgeArray) + continue; + } + else + { + // Lines and only lines go to line arrays and only to line arrays. + if ((poly.numVerts == 2) ^ islinearray) + continue; + + // Only conditional lines go into the conditional line array + if (type == E_CondEdgeArray) + continue; + } + + // Postprocess the polygon into a VAO and add it in + VertexArray* verts = postprocess (poly, type); + m_objArrays[obj][type] += *verts; + + // The array is changed, it needs a merge now. + m_changed[type] = true; + delete verts; + } + } + + DE_BUG_PRINT ("POST-PROCE_SS: %1ms\n", t0.msecsTo (QTime::currentTime())); +} + +// ============================================================================= +// +void GLCompiler::compileSubObject (LDObject* obj, LDObject* topobj, GLCompiler::PolygonList& data) +{ + LDObjectList objs; + + switch (obj->getType()) + { + case LDObject::ETriangle: + case LDObject::ELine: + case LDObject::ECondLine: + { + compilePolygon (obj, topobj, data); + } break; + + case LDObject::EQuad: + { + QTime t0 = QTime::currentTime(); + for (LDTriangle* triangle : static_cast<LDQuad*> (obj)->splitToTriangles()) + compilePolygon (triangle, topobj, data); + DE_BUG_PRINT ("\t- QUAD COMPILE: %1ms\n", t0.msecsTo (QTime::currentTime())); + } break; + + case LDObject::ESubfile: + { + QTime t0 = QTime::currentTime(); + objs = static_cast<LDSubfile*> (obj)->inlineContents (LDSubfile::RendererInline | LDSubfile::DeepCacheInline); + DE_BUG_PRINT ("\t- INLINE: %1ms\n", t0.msecsTo (QTime::currentTime())); + DE_BUG_PRINT ("\t- %1 objects\n", objs.size()); + + t0 = QTime::currentTime(); + + for (LDObject* obj : objs) + { + compileSubObject (obj, topobj, data); + obj->deleteSelf(); + } + + DE_BUG_PRINT ("\t- SUB-COMPILATION: %1ms\n", t0.msecsTo (QTime::currentTime())); + } break; + + default: + {} break; + } +} + +// ============================================================================= +// +void GLCompiler::compileDocument() +{ + for (LDObject * obj : m_file->getObjects()) + compileObject (obj); +} + +// ============================================================================= +// +void GLCompiler::forgetObject (LDObject* obj) +{ + auto it = m_objArrays.find (obj); + + if (it != m_objArrays.end()) + delete *it; + + m_objArrays.remove (obj); +} + +// ============================================================================= +// +void GLCompiler::setFile (LDDocument* file) +{ + m_file = file; +} + +// ============================================================================= +// +const GLCompiler::VertexArray* GLCompiler::getMergedBuffer (E_VertexArrayType 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 < E_NumVertexArrays); + + if (m_changed[type]) + { + m_changed[type] = false; + m_mainArrays[type].clear(); + + for (LDObject* obj : m_file->getObjects()) + { + if (!obj->isScemantic()) + continue; + + auto it = m_objArrays.find (obj); + + if (it != m_objArrays.end()) + m_mainArrays[type] += (*it)[type]; + } + + DE_BUG_PRINT ("merged array %1: %2 entries\n", (int) type, m_mainArrays[type].size()); + } + + return &m_mainArrays[type]; +} + +// ============================================================================= +// This turns a compiled triangle into usable VAO vertices +// +GLCompiler::VertexArray* GLCompiler::postprocess (const CompiledTriangle& poly, E_VertexArrayType type) +{ + VertexArray* va = new VertexArray; + VertexArray verts; + + for (int i = 0; i < poly.numVerts; ++i) + { + VAO vao; + const auto& v0 = poly.verts[i]; + vao.x = v0.x(); + vao.y = v0.y(); + vao.z = v0.z(); + + switch (type) + { + case E_SurfaceArray: + case E_EdgeArray: + case E_CondEdgeArray: + { + vao.color = poly.rgb; + } break; + + case E_PickArray: + case E_EdgePickArray: + { + vao.color = poly.pickrgb; + } break; + + case E_BFCArray: + case E_NumVertexArrays: + break; + } + + verts << vao; + } + + if (type == E_BFCArray) + { + int32 rgb = getColorRGB (getObjectColor (poly.obj, E_BFCFrontColor)); + + for (VAO vao : verts) + { + vao.color = rgb; + *va << vao; + } + + rgb = getColorRGB (getObjectColor (poly.obj, E_BFCBackColor)); + + for (int i = verts.size() - 1; i >= 0; --i) + { + VAO vao = verts[i]; + vao.color = rgb; + *va << vao; + } + } + else + *va = verts; + + return va; +} + +// ============================================================================= +// +uint32 GLCompiler::getColorRGB (const QColor& color) +{ + return + (color.red() & 0xFF) << 0x00 | + (color.green() & 0xFF) << 0x08 | + (color.blue() & 0xFF) << 0x10 | + (color.alpha() & 0xFF) << 0x18; +} + +// ============================================================================= +// +QColor GLCompiler::getObjectColor (LDObject* obj, GLCompiler::E_ColorType colortype) const +{ + QColor qcol; + + if (!obj->isColored()) + return QColor(); + + if (colortype == E_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()->getID(); + + // 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 / 0x10000) % 0x100, + g = (i / 0x100) % 0x100, + b = i % 0x100; + + return QColor (r, g, b); + } + + if ((colortype == E_BFCFrontColor || colortype == E_BFCBackColor) && + obj->getType() != LDObject::ELine && + obj->getType() != LDObject::ECondLine) + { + if (colortype == E_BFCFrontColor) + qcol = QColor (40, 192, 0); + else + qcol = QColor (224, 0, 0); + } + else + { + if (obj->getColor() == maincolor) + qcol = GLRenderer::getMainColor(); + else + { + LDColor* col = getColor (obj->getColor()); + + if (col) + qcol = col->faceColor; + } + + if (obj->getColor() == edgecolor) + { + qcol = QColor (32, 32, 32); // luma (m_bgcolor) < 40 ? QColor (64, 64, 64) : Qt::black; + LDColor* col; + + if (!gl_blackedges && obj->getParent() && (col = getColor (obj->getParent()->getColor()))) + qcol = col->edgeColor; + } + + if (qcol.isValid() == false) + { + // The color was unknown. Use main color to make the object at least + // not appear pitch-black. + if (obj->getColor() != edgecolor) + qcol = GLRenderer::getMainColor(); + else + qcol = Qt::black; + + // Warn about the unknown color, but only once. + for (short i : g_warnedColors) + if (obj->getColor() == i) + return qcol; + + log ("%1: Unknown color %2!\n", __func__, obj->getColor()); + g_warnedColors << obj->getColor(); + return qcol; + } + } + + if (obj->topLevelParent()->isSelected()) + { + // 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 GLCompiler::needMerge() +{ + // Set all of m_changed to true + memset (m_changed, 0xFF, sizeof m_changed); +} + +// ============================================================================= +// +void GLCompiler::initObject (LDObject* obj) +{ + if (m_objArrays.find (obj) == m_objArrays.end()) + m_objArrays[obj] = new VertexArray[E_NumVertexArrays]; +} + +// ============================================================================= +// +void GLCompiler::stageForCompilation (LDObject* obj) +{ + m_staged << obj; + removeDuplicates (m_staged); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/GLCompiler.h Tue Jan 21 02:09:14 2014 +0200 @@ -0,0 +1,114 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013, 2014 Santeri Piippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef LDFORGE_GLCOMPILER_H +#define LDFORGE_GLCOMPILER_H + +#include "Main.h" +#include "GLRenderer.h" +#include "GLShared.h" +#include <QMap> + +// ============================================================================= +// GLCompiler +// +// This class manages vertex arrays for the GL renderer, compiling vertices into +// VAO-readable triangles which can be requested with getMergedBuffer. +// +// There are 6 main array types: +// - the normal polygon array, for triangles +// - edge line array, for lines +// - conditional line array, for conditional lines. Kept separate so that they +// can be drawn as dashed liness +// - BFC array, this is the same as the normal polygon array except that the +// polygons are listed twice, once normally and green and once reversed +// and red, this allows BFC red/green view. +// - Picking array, this is the same as the normal polygon array except the +// polygons are compiled with their index color, this way the picking +// method is capable of determining which object was selected by pixel +// color. +// - Edge line picking array, the pick array version of the edge line array. +// Conditional lines are grouped with normal edgelines here. +// +// There are also these same 5 arrays for every LDObject compiled. The main +// arrays are generated on demand from the ones in the current file's +// LDObjects and stored in cache for faster renmm dering. +// +// The nested Array class contains a vector-like buffer of the Vertex structs, +// these structs are the VAOs that get passed to the renderer. +// +class GLCompiler +{ + public: + enum E_ColorType + { + E_NormalColor, + E_BFCFrontColor, + E_BFCBackColor, + E_PickColor, + }; + + struct CompiledTriangle + { + Vertex verts[3]; + uint8 numVerts; // 2 if a line + uint32 rgb; // Color of this poly normally + uint32 pickrgb; // Color of this poly while picking + bool isCondLine; // Is this a conditional line? + LDObject* obj; // Pointer to the object this poly represents + }; + + struct VAO + { + float x, y, z; + uint32 color; + float pad[4]; + }; + + using PolygonList = QList<CompiledTriangle>; + using VertexArray = QVector<VAO>; + + GLCompiler(); + ~GLCompiler(); + void setFile (LDDocument* file); + void compileDocument(); + void forgetObject (LDObject* obj); + void initObject (LDObject* obj); + const VertexArray* getMergedBuffer (E_VertexArrayType type); + QColor getObjectColor (LDObject* obj, E_ColorType colortype) const; + void needMerge(); + void stageForCompilation (LDObject* obj); + + static uint32 getColorRGB (const QColor& color); + + private: + void compilePolygon (LDObject* drawobj, LDObject* trueobj, PolygonList& data); + void compileObject (LDObject* obj); + void compileSubObject (LDObject* obj, LDObject* topobj, PolygonList& data); + VertexArray* postprocess (const CompiledTriangle& poly, E_VertexArrayType type); + + QMap<LDObject*, VertexArray*> m_objArrays; + VertexArray m_mainArrays[E_NumVertexArrays]; + LDDocument* m_file; + bool m_changed[E_NumVertexArrays]; + LDObjectList m_staged; // Objects that need to be compiled +}; + +extern GLCompiler g_vertexCompiler; + +#endif // LDFORGE_GLCOMPILER_H
--- a/src/GLRenderer.cc Tue Jan 21 02:03:27 2014 +0200 +++ b/src/GLRenderer.cc Tue Jan 21 02:09:14 2014 +0200 @@ -36,6 +36,7 @@ #include "Dialogs.h" #include "AddObjectDialog.h" #include "MessageLog.h" +#include "GLCompiler.h" #include "Primitives.h" #include "misc/RingFinder.h" #include "moc_GLRenderer.cpp" @@ -109,9 +110,6 @@ { QColor (0, 160, 192), Vertex (0, 0, 10000) }, // Z }; -static bool g_glInvert = false; -static QList<int> g_warnedColors; - // ============================================================================= // GLRenderer::GLRenderer (QWidget* parent) : QGLWidget (parent) @@ -245,11 +243,13 @@ setBackground(); glLineWidth (gl_linethickness); + glLineStipple (1, 0x6666); setAutoFillBackground (false); setMouseTracking (true); setFocusPolicy (Qt::WheelFocus); - compileAllObjects(); + + g_vertexCompiler.compileDocument(); } // ============================================================================= @@ -282,105 +282,7 @@ } // ============================================================================= -// -void GLRenderer::setObjectColor (LDObject* obj, const ListType list) -{ - QColor qcol; - - if (!obj->isColored()) - return; - - if (list == GL::PickList) - { - // 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()->getID(); - - // 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. - double r = (i / 0x10000) % 0x100, - g = (i / 0x100) % 0x100, - b = i % 0x100; - - qglColor (QColor (r, g, b)); - return; - } - - if ((list == BFCFrontList || list == BFCBackList) && - obj->getType() != LDObject::ELine && - obj->getType() != LDObject::ECondLine) - { - if (list == GL::BFCFrontList) - qcol = QColor (40, 192, 0); - else - qcol = QColor (224, 0, 0); - } - else - { - if (obj->getColor() == maincolor) - qcol = getMainColor(); - else - { - LDColor* col = getColor (obj->getColor()); - - if (col) - qcol = col->faceColor; - } - - if (obj->getColor() == edgecolor) - { - LDColor* col; - - if (!gl_blackedges && obj->getParent() && (col = getColor (obj->getParent()->getColor()))) - qcol = col->edgeColor; - else - qcol = (m_darkbg == false) ? Qt::black : Qt::white; - } - - if (qcol.isValid() == false) - { - // The color was unknown. Use main color to make the object at least - // not appear pitch-black. - if (obj->getColor() != edgecolor) - qcol = getMainColor(); - - // Warn about the unknown colors, but only once. - for (int i : g_warnedColors) - if (obj->getColor() == i) - return; - - log ("%1: Unknown color %2!\n", __func__, obj->getColor()); - g_warnedColors << obj->getColor(); - return; - } - } - - int r = qcol.red(), - g = qcol.green(), - b = qcol.blue(), - a = qcol.alpha(); - - if (obj->topLevelParent()->isSelected()) - { - // Brighten it up for the select list. - QColor selcolor (gl_selectcolor); - r = (r + selcolor.red()) / 2; - g = (g + selcolor.green()) / 2; - b = (b + selcolor.blue()) / 2; - } - - glColor4f ( - ((double) r) / 255.0f, - ((double) g) / 255.0f, - ((double) b) / 255.0f, - ((double) a) / 255.0f); -} - -// ============================================================================= -// +// ----------------------------------------------------------------------------- void GLRenderer::refresh() { update(); @@ -388,10 +290,10 @@ } // ============================================================================= -// +// ----------------------------------------------------------------------------- void GLRenderer::hardRefresh() { - compileAllObjects(); + g_vertexCompiler.compileDocument(); refresh(); glLineWidth (gl_linethickness); @@ -462,47 +364,47 @@ glRotatef (rot (Z), 0.0f, 0.0f, 1.0f); } - const GL::ListType list = (!isDrawOnly() && isPicking()) ? PickList : NormalList; - - if (gl_colorbfc && !isPicking() && !isDrawOnly()) - { - glEnable (GL_CULL_FACE); + // Draw the VAOs now + glEnableClientState (GL_VERTEX_ARRAY); + glEnableClientState (GL_COLOR_ARRAY); + glDisableClientState (GL_NORMAL_ARRAY); - for (LDObject* obj : getFile()->getObjects()) - { - if (obj->isHidden()) - continue; - - glCullFace (GL_BACK); - glCallList (obj->glLists[BFCFrontList]); + if (gl_colorbfc) { + glEnable (GL_CULL_FACE); + glCullFace (GL_CCW); + } else + glDisable (GL_CULL_FACE); - glCullFace (GL_FRONT); - glCallList (obj->glLists[BFCBackList]); - } + drawVAOs ((isPicking() ? E_PickArray : gl_colorbfc ? E_BFCArray : E_SurfaceArray), GL_TRIANGLES); + drawVAOs ((isPicking() ? E_EdgePickArray : E_EdgeArray), GL_LINES); - glDisable (GL_CULL_FACE); - } - else + // Draw conditional lines. Note that conditional lines are drawn into + // EdgePickArray in the picking scene so we only draw this array when + // not using the pick scene. + if (!isPicking()) { - for (LDObject* obj : getFile()->getObjects()) - { - if (obj->isHidden()) - continue; - - glCallList (obj->glLists[list]); - } + glEnable (GL_LINE_STIPPLE); + drawVAOs (E_CondEdgeArray, GL_LINES); + glDisable (GL_LINE_STIPPLE); } - if (gl_axes && !isPicking() && !isDrawOnly()) - glCallList (m_axeslist); - glPopMatrix(); + glDisable (GL_CULL_FACE); glMatrixMode (GL_MODELVIEW); glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); } // ============================================================================= // +void GLRenderer::drawVAOs (E_VertexArrayType arrayType, GLenum type) +{ + const GLCompiler::VertexArray* array = g_vertexCompiler.getMergedBuffer (arrayType); + glVertexPointer (3, GL_FLOAT, sizeof (GLCompiler::VAO), &array->data()[0].x); + glColorPointer (4, GL_UNSIGNED_BYTE, sizeof (GLCompiler::VAO), &array->data()[0].color); + glDrawArrays (type, 0, array->size()); +} + +// ============================================================================= // This converts a 2D point on the screen to a 3D point in the model. If 'snap' // is true, the 3D point will snap to the current grid. // @@ -897,127 +799,7 @@ // void GLRenderer::compileAllObjects() { - if (!getFile()) - return; - - // Compiling all is a big job, use a busy cursor - setCursor (Qt::BusyCursor); - - m_knownVerts.clear(); - - for (LDObject* obj : getFile()->getObjects()) - compileObject (obj); - - // Compile axes - glDeleteLists (m_axeslist, 1); - m_axeslist = glGenLists (1); - glNewList (m_axeslist, GL_COMPILE); - glBegin (GL_LINES); - - for (const LDGLAxis& ax : g_GLAxes) - { - qglColor (ax.col); - compileVertex (ax.vert); - compileVertex (-ax.vert); - } - - glEnd(); - glEndList(); - - setCursor (Qt::ArrowCursor); -} - -// ============================================================================= -// -void GLRenderer::compileSubObject (LDObject* obj, const GLenum gltype) -{ - glBegin (gltype); - - const int numverts = (obj->getType() != LDObject::ECondLine) ? obj->vertices() : 2; - - if (g_glInvert == false) - for (int i = 0; i < numverts; ++i) - compileVertex (obj->getVertex (i)); - else - for (int i = numverts - 1; i >= 0; --i) - compileVertex (obj->getVertex (i)); - - glEnd(); -} - -// ============================================================================= -// -void GLRenderer::compileList (LDObject* obj, const GLRenderer::ListType list) -{ - setObjectColor (obj, list); - - switch (obj->getType()) - { - case LDObject::ELine: - { - compileSubObject (obj, GL_LINES); - } break; - - case LDObject::ECondLine: - { - // Draw conditional lines with a dash pattern - however, use a full - // line when drawing a pick list to make selecting them easier. - if (list != GL::PickList) - { - glLineStipple (1, 0x6666); - glEnable (GL_LINE_STIPPLE); - } - - compileSubObject (obj, GL_LINES); - - glDisable (GL_LINE_STIPPLE); - } break; - - case LDObject::ETriangle: - { - compileSubObject (obj, GL_TRIANGLES); - } break; - - case LDObject::EQuad: - { - compileSubObject (obj, GL_QUADS); - } break; - - case LDObject::ESubfile: - { - LDSubfile* ref = static_cast<LDSubfile*> (obj); - LDObjectList objs; - - objs = ref->inlineContents (LDSubfile::DeepCacheInline | LDSubfile::RendererInline); - bool oldinvert = g_glInvert; - - if (ref->getTransform().getDeterminant() < 0) - g_glInvert = !g_glInvert; - - LDObject* prev = ref->prev(); - - if (prev && prev->getType() == LDObject::EBFC && static_cast<LDBFC*> (prev)->type == LDBFC::InvertNext) - g_glInvert = !g_glInvert; - - for (LDObject* obj : objs) - { - compileList (obj, list); - obj->deleteSelf(); - } - - g_glInvert = oldinvert; - } break; - - default: - break; - } -} - -// ============================================================================= -// -void GLRenderer::compileVertex (const Vertex& vrt) -{ - glVertex3d (vrt[X], -vrt[Y], -vrt[Z]); + g_vertexCompiler.compileDocument(); } // ============================================================================= @@ -1376,8 +1158,8 @@ { qint32 idx = (*(pixelptr + 0) * 0x10000) + - (*(pixelptr + 1) * 0x00100) + - (*(pixelptr + 2) * 0x00001); + (*(pixelptr + 1) * 0x100) + + *(pixelptr + 2); pixelptr += 4; if (idx == 0xFFFFFF) @@ -1473,6 +1255,7 @@ void GLRenderer::setFile (LDDocument* const& a) { m_File = a; + g_vertexCompiler.setFile (a); if (a != null) { @@ -1743,24 +1526,10 @@ } // ============================================================================= -// +// ----------------------------------------------------------------------------- void GLRenderer::compileObject (LDObject* obj) { - deleteLists (obj); - - for (const GL::ListType listType : g_glListTypes) - { - if (isDrawOnly() && listType != GL::NormalList) - continue; - - GLuint list = glGenLists (1); - glNewList (list, GL_COMPILE); - - obj->glLists[listType] = list; - compileList (obj, listType); - - glEndList(); - } + g_vertexCompiler.stageForCompilation (obj); // Mark in known vertices of this object QList<Vertex> verts = getVertices (obj);
--- a/src/GLRenderer.h Tue Jan 21 02:03:27 2014 +0200 +++ b/src/GLRenderer.h Tue Jan 21 02:09:14 2014 +0200 @@ -23,6 +23,7 @@ #include "Main.h" #include "LDObject.h" #include "Document.h" +#include "GLShared.h" class MessageManager; class QDialogButtonBox; @@ -152,7 +153,6 @@ Axis getCameraAxis (bool y, EFixedCamera camid = (EFixedCamera) - 1); const char* getCameraName() const; double getDepthValue() const; - QColor getMainColor(); LDGLOverlay& getOverlay (int newcam); uchar* getScreencap (int& w, int& h); void hardRefresh(); @@ -171,6 +171,7 @@ void zoomAllToFit(); static void deleteLists (LDObject* obj); + static QColor getMainColor(); protected: void contextMenuEvent (QContextMenuEvent* ev); @@ -245,6 +246,12 @@ // Convert a 2D point to a 3D point Vertex coordconv2_3 (const QPoint& pos2d, bool snap) const; + // Draw a VAO array + void drawVAOs (E_VertexArrayType arrayType, GLenum type); + + // Determine which color to draw text with + QColor getTextPen() const; + // Convert a 3D point to a 2D point QPoint coordconv3_2 (const Vertex& pos3d) const;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/GLShared.h Tue Jan 21 02:09:14 2014 +0200 @@ -0,0 +1,33 @@ +/* + * LDForge: LDraw parts authoring CAD + * Copyright (C) 2013, 2014 Santeri Piippo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef LDFORGE_GLSHARED_H +#define LDFORGE_GLSHARED_H + +enum E_VertexArrayType +{ + E_SurfaceArray, + E_EdgeArray, + E_CondEdgeArray, + E_BFCArray, + E_PickArray, + E_EdgePickArray, + E_NumVertexArrays +}; + +#endif // LDFORGE_GLSHARED_H \ No newline at end of file