@@ -28,6 +28,7 @@ DEALINGS IN THE SOFTWARE.
2828
2929#include < Graphics/Glyphs/GlyphGeom.h>
3030#include < Core/Datatypes/DenseMatrix.h>
31+ #include < Core/Datatypes/ColorMap.h>
3132#include < Core/Math/MiscMath.h>
3233#include < Core/GeometryPrimitives/Transform.h>
3334
@@ -42,167 +43,150 @@ GlyphGeom::GlyphGeom() : numVBOElements_(0), lineIndex_(0)
4243
4344}
4445
45- void GlyphGeom::buildObject (GeometryObjectSpire& geom, const std::string& uniqueNodeID, const bool isTransparent, const double transparencyValue,
46- const ColorScheme& colorScheme, RenderState state, const SpireIBO::PRIMITIVE& primIn, const BBox& bbox)
46+ void GlyphGeom::buildObject (GeometryObjectSpire& geom, const std::string& uniqueNodeID,
47+ const bool isTransparent, const double transparencyValue, const ColorScheme& colorScheme,
48+ RenderState state, const SpireIBO::PRIMITIVE& primIn, const BBox& bbox, const bool isClippable,
49+ const Core::Datatypes::ColorMapHandle colorMap)
4750{
48- std::string vboName = uniqueNodeID + " VBO " ;
49- std::string iboName = uniqueNodeID + " IBO " ;
50- std::string passName = uniqueNodeID + " Pass " ;
51+ bool useColor = colorScheme == ColorScheme::COLOR_IN_SITU || colorScheme == ColorScheme::COLOR_MAP ;
52+ bool useNormals = normals_. size () == points_. size () ;
53+ int numAttributes = 3 ;
5154
52- bool useTriangles = primIn == SpireIBO::PRIMITIVE::TRIANGLES;
55+ RenderType renderType = RenderType::RENDER_VBO_IBO;
56+ ColorRGB dft = state.defaultColor ;
5357
54- // Construct VBO.
55- std::string shader = " Shaders/UniformColor" ;
58+ std::string shader = (useNormals ? " Shaders/Phong" : " Shaders/Flat" );
5659 std::vector<SpireVBO::AttributeData> attribs;
57- attribs.push_back (SpireVBO::AttributeData (" aPos" , 3 * sizeof (float )));
58- if (useTriangles)
59- attribs.push_back (SpireVBO::AttributeData (" aNormal" , 3 * sizeof (float )));
60- RenderType renderType = RenderType::RENDER_VBO_IBO;
60+ std::vector<SpireSubPass::Uniform> uniforms;
6161
62- // ColorScheme colorScheme = COLOR_UNIFORM;
62+ attribs.push_back (SpireVBO::AttributeData (" aPos" , 3 * sizeof (float )));
63+ uniforms.push_back (SpireSubPass::Uniform (" uUseClippingPlanes" , isClippable));
64+ uniforms.push_back (SpireSubPass::Uniform (" uUseFog" , true ));
6365
64- std::vector<SpireSubPass::Uniform> uniforms;
65- if (isTransparent)
66- uniforms.push_back (SpireSubPass::Uniform (" uTransparency" , static_cast <float >(transparencyValue)));
67- // TODO: add colormapping options
68- if (colorScheme == ColorScheme::COLOR_MAP)
66+ if (useNormals)
6967 {
70- attribs.push_back (SpireVBO::AttributeData (" aColor" , 4 * sizeof (float )));
71- if (useTriangles)
72- {
73- shader = " Shaders/DirPhongCMap" ;
74- uniforms.push_back (SpireSubPass::Uniform (" uAmbientColor" ,
75- glm::vec4 (0 .1f , 0 .1f , 0 .1f , 1 .0f )));
76- uniforms.push_back (SpireSubPass::Uniform (" uSpecularColor" ,
77- glm::vec4 (0 .1f , 0 .1f , 0 .1f , 0 .1f )));
78- uniforms.push_back (SpireSubPass::Uniform (" uSpecularPower" , 32 .0f ));
79- }
80- else
81- {
82- shader = " Shaders/ColorMap" ;
83- }
68+ numAttributes += 3 ;
69+ attribs.push_back (SpireVBO::AttributeData (" aNormal" , 3 * sizeof (float )));
70+ uniforms.push_back (SpireSubPass::Uniform (" uAmbientColor" , glm::vec4 (0 .1f , 0 .1f , 0 .1f , 1 .0f )));
71+ uniforms.push_back (SpireSubPass::Uniform (" uSpecularColor" , glm::vec4 (0 .1f , 0 .1f , 0 .1f , 0 .1f )));
72+ uniforms.push_back (SpireSubPass::Uniform (" uSpecularPower" , 32 .0f ));
8473 }
85- else if (colorScheme == ColorScheme::COLOR_IN_SITU)
74+
75+ SpireText text;
76+ SpireTexture2D texture;
77+ if (useColor)
8678 {
87- attribs.push_back (SpireVBO::AttributeData (" aColor" , 4 * sizeof (float )));
88- if (useTriangles)
79+ if (colorMap)
8980 {
90- shader = " Shaders/DirPhongInSitu" ;
91- uniforms.push_back (SpireSubPass::Uniform (" uAmbientColor" ,
92- glm::vec4 (0 .1f , 0 .1f , 0 .1f , 1 .0f )));
93- uniforms.push_back (SpireSubPass::Uniform (" uSpecularColor" ,
94- glm::vec4 (0 .1f , 0 .1f , 0 .1f , 0 .1f )));
95- uniforms.push_back (SpireSubPass::Uniform (" uSpecularPower" , 32 .0f ));
81+ numAttributes += 2 ;
82+ shader += " _ColorMap" ;
83+ attribs.push_back (SpireVBO::AttributeData (" aTexCoords" , 2 * sizeof (float )));
84+
85+ const static int colorMapResolution = 256 ;
86+ for (int i = 0 ; i < colorMapResolution; ++i)
87+ {
88+ ColorRGB color = colorMap->valueToColor (static_cast <float >(i)/colorMapResolution * 2 .0f - 1 .0f );
89+ texture.bitmap .push_back (color.r ()*255 .99f );
90+ texture.bitmap .push_back (color.g ()*255 .99f );
91+ texture.bitmap .push_back (color.b ()*255 .99f );
92+ texture.bitmap .push_back (color.a ()*255 .99f );
93+ }
94+
95+ texture.name = " ColorMap" ;
96+ texture.height = 1 ;
97+ texture.width = colorMapResolution;
9698 }
9799 else
98100 {
99- shader = " Shaders/InSituColor" ;
101+ numAttributes += 4 ;
102+ shader += " _Color" ;
103+ attribs.push_back (SpireVBO::AttributeData (" aColor" , 4 * sizeof (float )));
100104 }
101105 }
102- else if (colorScheme == ColorScheme::COLOR_UNIFORM)
106+ else
103107 {
104- ColorRGB dft = state.defaultColor ;
105- if (useTriangles)
106- {
107- if (geom.isClippable ())
108- shader = " Shaders/DirPhong" ;
109- else
110- shader = " Shaders/DirPhongNoClipping" ;
111- uniforms.push_back (SpireSubPass::Uniform (" uAmbientColor" ,
112- glm::vec4 (0 .1f , 0 .1f , 0 .1f , 1 .0f )));
113- uniforms.push_back (SpireSubPass::Uniform (" uDiffuseColor" ,
114- glm::vec4 (dft.r (), dft.g (), dft.b (), static_cast <float >(transparencyValue))));
115- uniforms.push_back (SpireSubPass::Uniform (" uSpecularColor" ,
116- glm::vec4 (0 .1f , 0 .1f , 0 .1f , 0 .1f )));
117- uniforms.push_back (SpireSubPass::Uniform (" uSpecularPower" , 32 .0f ));
118- }
119- else
120- {
121- uniforms.emplace_back (" uColor" , glm::vec4 (dft.r (), dft.g (), dft.b (), static_cast <float >(transparencyValue)));
122- }
108+ uniforms.push_back (SpireSubPass::Uniform (" uDiffuseColor" ,
109+ glm::vec4 (dft.r (), dft.g (), dft.b (), static_cast <float >(transparencyValue))));
123110 }
124111
125- uint32_t iboSize = 0 ;
126- uint32_t vboSize = 0 ;
127-
128- vboSize = static_cast <uint32_t >(points_.size ()) * 3 * sizeof (float );
129- vboSize += static_cast <uint32_t >(normals_.size ()) * 3 * sizeof (float );
130- if (colorScheme == ColorScheme::COLOR_IN_SITU || colorScheme == ColorScheme::COLOR_MAP)
131- vboSize += static_cast <uint32_t >(colors_.size ()) * 4 * sizeof (float ); // RGBA
132- iboSize = static_cast <uint32_t >(indices_.size ()) * sizeof (uint32_t );
133- // / \todo To reduce memory requirements, we can use a 16bit index buffer.
134-
135- // / \todo To further reduce a large amount of memory, get rid of the index
136- // / buffer and use glDrawArrays to render without an IBO. An IBO is
137- // / a waste of space.
138- // / http://www.opengl.org/sdk/docs/man3/xhtml/glDrawArrays.xml
139-
140- // / \todo Switch to unique_ptrs and move semantics.
141- std::shared_ptr<spire::VarBuffer> iboBufferSPtr (new spire::VarBuffer (iboSize));
142- std::shared_ptr<spire::VarBuffer> vboBufferSPtr (new spire::VarBuffer (vboSize));
143-
144- // Accessing the pointers like this is contrived. We only do this for
145- // speed since we will be using the pointers in a tight inner loop.
146- auto iboBuffer = iboBufferSPtr.get ();
147- auto vboBuffer = vboBufferSPtr.get ();
148-
149- // write to the IBO/VBOs
150-
151- for (auto a : indices_)
152- iboBuffer->write (a);
112+ if (isTransparent) uniforms.push_back (SpireSubPass::Uniform (" uTransparency" , static_cast <float >(transparencyValue)));
153113
154- BBox newBBox ;
155-
156- const bool writeNormals = normals_. size () == points_. size () ;
157- for ( size_t i = 0 ; i < points_. size (); i++ )
114+ size_t pointsLeft = points_. size () ;
115+ size_t startOfPass = 0 ;
116+ int passNumber = 0 ;
117+ while (pointsLeft > 0 )
158118 {
159- // Write first point on line
160- vboBuffer->write (static_cast <float >(points_.at (i).x ()));
161- vboBuffer->write (static_cast <float >(points_.at (i).y ()));
162- vboBuffer->write (static_cast <float >(points_.at (i).z ()));
163-
164- newBBox.extend (Point (points_.at (i).x (), points_.at (i).y (), points_.at (i).z ()));
165-
166- if (writeNormals)
119+ std::string passID = uniqueNodeID + " _" + std::to_string (passNumber++);
120+ std::string vboName = passID + " VBO" ;
121+ std::string iboName = passID + " IBO" ;
122+ std::string passName = passID + " Pass" ;
123+
124+ const static size_t maxPointsPerPass = 3 << 24 ; // must be a number divisible by 2, 3 and, 4
125+ uint32_t pointsInThisPass = std::min (pointsLeft, maxPointsPerPass);
126+ size_t endOfPass = startOfPass + pointsInThisPass;
127+ pointsLeft -= pointsInThisPass;
128+
129+ size_t vboSize = static_cast <size_t >(pointsInThisPass) * numAttributes * sizeof (float );
130+ size_t iboSize = static_cast <size_t >(pointsInThisPass) * sizeof (uint32_t );
131+ std::shared_ptr<spire::VarBuffer> iboBufferSPtr (new spire::VarBuffer (iboSize));
132+ std::shared_ptr<spire::VarBuffer> vboBufferSPtr (new spire::VarBuffer (vboSize));
133+ auto iboBuffer = iboBufferSPtr.get ();
134+ auto vboBuffer = vboBufferSPtr.get ();
135+
136+ for (auto a : indices_) if (a >= startOfPass && a < endOfPass)
137+ iboBuffer->write (static_cast <uint32_t >(a - startOfPass));
138+
139+ BBox newBBox;
140+ for (size_t i = startOfPass; i < endOfPass; ++i)
167141 {
168- vboBuffer->write (static_cast <float >(normals_.at (i).x ()));
169- vboBuffer->write (static_cast <float >(normals_.at (i).y ()));
170- vboBuffer->write (static_cast <float >(normals_.at (i).z ()));
171- }
172- if (colorScheme == ColorScheme::COLOR_MAP || colorScheme == ColorScheme::COLOR_IN_SITU)
173- {
174- vboBuffer->write (static_cast <float >(colors_.at (i).r ()));
175- vboBuffer->write (static_cast <float >(colors_.at (i).g ()));
176- vboBuffer->write (static_cast <float >(colors_.at (i).b ()));
177- vboBuffer->write (static_cast <float >(colors_.at (i).a ()));
178- // vboBuffer->write(static_cast<float>(1.f));
179- } // no color writing otherwise
180- }
142+ Vector point = points_.at (i);
143+ newBBox.extend (Point (point.x (), point.y (), point.z ()));
144+ vboBuffer->write (static_cast <float >(point.x ()));
145+ vboBuffer->write (static_cast <float >(point.y ()));
146+ vboBuffer->write (static_cast <float >(point.z ()));
181147
182- if (!bbox.valid ())
183- newBBox.reset ();
184-
185- // If true, then the VBO will be placed on the GPU. We don't want to place
186- // VBOs on the GPU when we are generating rendering lists.
187- SpireVBO geomVBO (vboName, attribs, vboBufferSPtr, numVBOElements_, newBBox, true );
148+ if (useNormals)
149+ {
150+ Vector normal = normals_.at (i);
151+ vboBuffer->write (static_cast <float >(normal.x ()));
152+ vboBuffer->write (static_cast <float >(normal.y ()));
153+ vboBuffer->write (static_cast <float >(normal.z ()));
154+ }
188155
189- // Construct IBO.
190- SpireIBO geomIBO (iboName, primIn, sizeof (uint32_t ), iboBufferSPtr);
156+ if (useColor)
157+ {
158+ ColorRGB color = colors_.at (i);
159+ if (!colorMap)
160+ {
161+ vboBuffer->write (static_cast <float >(color.r ()));
162+ vboBuffer->write (static_cast <float >(color.g ()));
163+ vboBuffer->write (static_cast <float >(color.b ()));
164+ vboBuffer->write (static_cast <float >(color.a ()));
165+ }
166+ else
167+ {
168+ vboBuffer->write (static_cast <float >(color.r ()));
169+ vboBuffer->write (static_cast <float >(color.r ()));
170+ }
171+ }
172+ }
173+ if (!bbox.valid ()) newBBox.reset ();
191174
192- state.set (RenderState::IS_ON, true );
193- state.set (RenderState::HAS_DATA, true );
175+ startOfPass = endOfPass;
194176
195- SpireText text;
177+ SpireVBO geomVBO (vboName, attribs, vboBufferSPtr, numVBOElements_, newBBox, true );
178+ SpireIBO geomIBO (iboName, primIn, sizeof (uint32_t ), iboBufferSPtr);
196179
197- // Construct Pass.
198- SpireSubPass pass (passName, vboName, iboName, shader, colorScheme, state, renderType, geomVBO, geomIBO, text);
180+ state.set (RenderState::IS_ON, true );
181+ state.set (RenderState::HAS_DATA, true );
182+ SpireSubPass pass (passName, vboName, iboName, shader, colorScheme, state, renderType, geomVBO, geomIBO, text, texture);
199183
200- // Add all uniforms generated above to the pass.
201- for (const auto & uniform : uniforms) { pass.addUniform (uniform); }
184+ for (const auto & uniform : uniforms) pass.addUniform (uniform);
202185
203- geom.vbos ().push_back (geomVBO);
204- geom.ibos ().push_back (geomIBO);
205- geom.passes ().push_back (pass);
186+ geom.vbos ().push_back (geomVBO);
187+ geom.ibos ().push_back (geomIBO);
188+ geom.passes ().push_back (pass);
189+ }
206190}
207191
208192void GlyphGeom::addArrow (const Point& p1, const Point& p2, double radius, double ratio, int resolution,
0 commit comments