Skip to content

Commit 2e1598a

Browse files
committed
GridPlot speedup and improvements
Added multithreaded plot data generation Using glDrawArrays instead of gl lists (up to 2x speedup)
1 parent 4cc0893 commit 2e1598a

File tree

5 files changed

+390
-116
lines changed

5 files changed

+390
-116
lines changed

include/qwt3d_gridplot.h

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
#pragma once
21
#ifndef qwt3d_gridplot_h__2005_7_10_begin_guarded_code
32
#define qwt3d_gridplot_h__2005_7_10_begin_guarded_code
43

4+
#include <QtCore/QThread>
5+
56
#include "qwt3d_surfaceplot.h"
67

78
namespace Qwt3D
@@ -16,24 +17,41 @@ class QWT3D_EXPORT GridPlot : public SurfacePlot
1617
Q_OBJECT
1718

1819
public:
19-
GridPlot( QWidget * parent = 0, const QGLWidget * shareWidget = 0 );
20+
GridPlot(QWidget* parent = 0, const QGLWidget* shareWidget = 0);
2021
virtual ~GridPlot() {}
22+
2123
int resolution() const {return resolution_p;} //!< Returns data resolution (1 means all data)
2224

2325
int createDataset(Qwt3D::Triple** data, unsigned int columns, unsigned int rows,
2426
bool uperiodic = false, bool vperiodic = false, bool append = false);
2527
int createDataset(double** data, unsigned int columns, unsigned int rows,
2628
double minx, double maxx, double miny, double maxy, bool append = false);
2729

30+
/**
31+
Sets number of rendering threads using glDrawArrays to \a count (1..10, 8 by default).
32+
If \a count = 0, the older (list based, slow) implementation will be used.
33+
\since 0.3.2
34+
\sa renderThreadsCount
35+
*/
36+
void setRenderThreadsCount(int count);
37+
/**
38+
Returns number of rendering threads using glDrawArrays (8 by default).
39+
If this value is 0, the older (list based, slow) implementation is used.
40+
\since 0.3.2
41+
\sa setRenderThreadsCount
42+
*/
43+
int renderThreadsCount() const { return m_threadsCount; }
44+
2845
signals:
2946
void resolutionChanged(int);
3047

3148
public slots:
32-
void setResolution( int );
49+
void setResolution(int);
3350

3451
protected:
35-
void createOpenGlData(const Plotlet& pl);
36-
void processVertex(const Triple& vert1, const Triple& norm1, const Plotlet& pl, bool hl, bool& stripStarted, RGBA& lastColor) const;
52+
virtual void createOpenGlData(const Plotlet& pl);
53+
virtual void drawOpenGlData();
54+
void processVertex(const Triple& vert1, const Triple& norm1, const Color& colorData, bool hl, bool& stripStarted, RGBA& lastColor) const;
3755
void processLineLoopVertex(const Triple& vert1, bool& stripStarted) const;
3856
void processLineStripVertex(const Triple& vert1, bool& stripStarted) const;
3957

@@ -68,10 +86,39 @@ public slots:
6886
void clear();
6987
};
7088

89+
// thread vector processor
90+
class CVertexProcessor: public QThread
91+
{
92+
public:
93+
CVertexProcessor();
94+
95+
void setup(int dataWidth, int dataLength, const GridData& data, int row, int step = 1,
96+
bool m_colorize = true, const Color* colorData = NULL);
97+
98+
virtual void run();
99+
100+
void paintGL();
101+
102+
private:
103+
void processVertex(bool& stripStarted, int i, int j, int& index, int& size);
104+
void endVertex(int& index, int& size);
105+
106+
int m_dataWidth, m_dataLength, m_row, m_step;
107+
TripleVector m_draw_normals, m_draw_vertices;
108+
ColorVector m_draw_colors;
109+
std::vector< QPair<int,int> > m_drawList;
110+
const GridData* m_data;
111+
const Color* m_colorData;
112+
bool m_colorize;
113+
};
114+
115+
int m_threadsCount;
116+
CVertexProcessor m_workers[10];
117+
71118
void createNormals(const Plotlet& pl);
72119
void data2Floor(const Plotlet& pl);
73120
void isolines2Floor(const Plotlet& pl);
74-
void setColorFromVertex(const Plotlet& pl, const Triple& vertex, RGBA& lastColor, bool skip = false) const;
121+
void setColorFromVertex(const Color& colorData, const Triple& vertex, RGBA& lastColor, bool skip = false) const;
75122
void calcNormals(GridData& gdata);
76123
void sewPeriodic(GridData& gdata);
77124
void readIn(GridData& gdata, Triple** data, unsigned int columns, unsigned int rows);

include/qwt3d_plot3d.h

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class QWT3D_EXPORT Plot3D : public ExtGLWidget
2424
Q_OBJECT
2525

2626
public:
27-
Plot3D ( QWidget * parent = 0, const QGLWidget * shareWidget = 0 );
27+
Plot3D (QWidget * parent = 0, const QGLWidget * shareWidget = 0);
2828
virtual ~Plot3D();
2929

3030
QPixmap renderPixmap (int w=0, int h=0, bool useContext=false);
@@ -71,28 +71,31 @@ class QWT3D_EXPORT Plot3D : public ExtGLWidget
7171

7272
// Convenience/compatibility member for appearance(0) properties
7373

74-
void setPlotStyle( Qwt3D::PLOTSTYLE val ); //!< Set plotting style
75-
Qwt3D::Enrichment* setPlotStyle( Qwt3D::Enrichment const& val );
74+
void setPlotStyle(Qwt3D::PLOTSTYLE val); //!< Set plotting style
75+
Qwt3D::Enrichment* setPlotStyle(Qwt3D::Enrichment const& val);
7676
Qwt3D::PLOTSTYLE plotStyle() const { return appearance(0).plotStyle(); }//!< Returns plotting style
7777
//! Returns current Enrichment object used for plotting styles (if set, zero else)
7878
Qwt3D::Enrichment* userStyle() const { return appearance(0).userStyle(); }
7979

80-
void setShading( Qwt3D::SHADINGSTYLE val ); //!<Set shading style
80+
void setShading(Qwt3D::SHADINGSTYLE val ); //!<Set shading style
8181
Qwt3D::SHADINGSTYLE shading() const { return appearance(0).shading(); }//!< Returns shading style
8282

83-
void setSmoothMesh(bool val ) {appearance(0).setSmoothMesh(val);} //!< Enables/disables smooth data mesh lines. Default is false
83+
void setSmoothMesh(bool val) {appearance(0).setSmoothMesh(val);} //!< Enables/disables smooth data mesh lines. Default is false
8484
bool smoothDataMesh() const {return appearance(0).smoothDataMesh();} //!< True if mesh antialiasing is on
85-
void setMeshColor(Qwt3D::RGBA rgba ); //!< Sets color for data mesh
85+
void setMeshColor(Qwt3D::RGBA rgba); //!< Sets color for data mesh
8686
Qwt3D::RGBA meshColor() const {return appearance(0).meshColor();} //!< Returns color for data mesh
87-
void setMeshLineWidth(double lw ); //!< Sets line width for data mesh
87+
void setMeshLineWidth(double lw); //!< Sets line width for data mesh
8888
double meshLineWidth() const {return appearance(0).meshLineWidth();} //!< Returns line width for data mesh
89-
void setDataColor(const Qwt3D::Color& col ); //!< Sets new data color object
89+
void setDataColor(const Qwt3D::Color& col); //!< Sets new data color object
9090
const Qwt3D::ValuePtr<Qwt3D::Color>& dataColor() const {return appearance(0).dataColor();} //!< Returns data color object
9191

9292
// tweaks
93-
void setPolygonOffset(double d );
93+
void setPolygonOffset(double d);
9494
double polygonOffset() const {return appearance(0).polygonOffset();} //!< Returns relative value for polygon offset [0..1]
9595

96+
//! \since 0.3.2
97+
void enableFastNormals(bool on) { m_fastNormals = on; }
98+
9699
//!< Add an Enrichment
97100
virtual Qwt3D::Enrichment* addEnrichment(Qwt3D::Enrichment const& val){return appearance(0).addEnrichment(val);}
98101
virtual bool degrade(Qwt3D::Enrichment* val){return appearance(0).degrade(val);} //!< Remove an Enrichment
@@ -111,10 +114,10 @@ public slots:
111114

112115
//! Combines data with their visual appearance
113116
/**
114-
A Plotlet describes the plot's part related to a single dataset. In this respect, it has
115-
no own coordinate system (but a hull) and other plot-wide properties. A single
116-
data- and the associated Appearance object form a Plotlet.
117-
*/
117+
A Plotlet describes the plot's part related to a single dataset. In this respect, it has
118+
no own coordinate system (but a hull) and other plot-wide properties. A single
119+
data- and the associated Appearance object form a Plotlet.
120+
*/
118121
struct Plotlet
119122
{
120123
public:
@@ -125,17 +128,18 @@ public slots:
125128

126129
void initializeGL();
127130
void paintGL();
128-
void resizeGL( int w, int h );
131+
void resizeGL(int w, int h);
129132

130133
Qwt3D::CoordinateSystem coordinates_p;
131134

132135
virtual void calculateHull();
133136
virtual void updateAppearances();
134137
virtual void createOpenGlData();
135138
virtual void createOpenGlData(const Plotlet& pl) = 0;
139+
virtual void drawOpenGlData();
136140

137141
void createCoordinateSystem();
138-
void setHull(Qwt3D::ParallelEpiped const& h) {hull_ = h;}
142+
void setHull(Qwt3D::ParallelEpiped const& h) { hull_ = h; }
139143

140144
std::vector<Plotlet> plotlets_p;
141145

@@ -144,6 +148,8 @@ public slots:
144148
std::vector<double> isolinesZ_p;
145149
bool delayisolinecalculation_p;
146150

151+
bool m_fastNormals;
152+
147153
// debug
148154
quint64 m_createTime;
149155

@@ -201,7 +207,7 @@ The function returns the Appearance object for the Plotlet at idx.
201207
For invalid arguments the return value contains the standard appearance
202208
(equivalent to idx==0) is returned
203209
*/
204-
Appearance& Plot3D::appearance( unsigned idx )
210+
Appearance& Plot3D::appearance(unsigned idx)
205211
{
206212
assert(!plotlets_p.empty());
207213
if (idx >= plotlets_p.size())
@@ -214,7 +220,7 @@ The function returns the Appearance object for the Plotlet at idx.
214220
For invalid arguments the return value contains the standard appearance
215221
(equivalent to idx==0) is returned
216222
*/
217-
const Appearance& Plot3D::appearance( unsigned idx ) const
223+
const Appearance& Plot3D::appearance(unsigned idx) const
218224
{
219225
assert(!plotlets_p.empty());
220226
if (idx >= plotlets_p.size())

src/qwt3d_drawable.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ using namespace Qwt3D;
44

55
Drawable::~Drawable()
66
{
7-
detachAll();
7+
detachAll();
88
}
99

1010
void Drawable::saveGLState()
@@ -30,7 +30,7 @@ void Drawable::restoreGLState()
3030
{
3131
Enable(GL_LINE_SMOOTH, ls);
3232
Enable(GL_POLYGON_SMOOTH, pols);
33-
33+
3434
setLineWidth(lw);
3535
glBlendFunc(blsrc, bldst);
3636
glColor4dv(col);
@@ -50,7 +50,7 @@ void Drawable::Enable(GLenum what, GLboolean val)
5050
{
5151
if (val)
5252
glEnable(what);
53-
else
53+
else
5454
glDisable(what);
5555
}
5656

@@ -66,12 +66,13 @@ void Drawable::attach(Drawable* dr)
6666
void Drawable::detach(Drawable* dr)
6767
{
6868
std::list<Drawable*>::iterator it = std::find(dlist.begin(), dlist.end(), dr);
69-
69+
7070
if ( it != dlist.end() )
7171
{
7272
dlist.erase(it);
7373
}
7474
}
75+
7576
void Drawable::detachAll()
7677
{
7778
dlist.clear();
@@ -84,8 +85,8 @@ void Drawable::detachAll()
8485
*/
8586
Triple Drawable::ViewPort2World(Triple win, bool* err)
8687
{
87-
Triple obj;
88-
88+
Triple obj;
89+
8990
getMatrices(modelMatrix, projMatrix, viewport);
9091
int res = gluUnProject(win.x, win.y, win.z, modelMatrix, projMatrix, viewport, &obj.x, &obj.y, &obj.z);
9192

@@ -100,8 +101,8 @@ Triple Drawable::ViewPort2World(Triple win, bool* err)
100101
*/
101102
Triple Drawable::World2ViewPort(Triple obj, bool* err)
102103
{
103-
Triple win;
104-
104+
Triple win;
105+
105106
getMatrices(modelMatrix, projMatrix, viewport);
106107
int res = gluProject(obj.x, obj.y, obj.z, modelMatrix, projMatrix, viewport, &win.x, &win.y, &win.z);
107108

0 commit comments

Comments
 (0)