solution rendering using vertex arrays

This commit is contained in:
Joachim Schöberl 2016-11-01 11:47:49 +01:00
parent 3fcb7d13d5
commit 6d4704770d
3 changed files with 185 additions and 125 deletions

View File

@ -47,9 +47,10 @@ namespace netgen
{ for (int i = 0; i < D; i++) x[i] = v(i); } { for (int i = 0; i < D; i++) x[i] = v(i); }
Point & operator= (const Point<D> & p2) template <typename T2>
Point & operator= (const Point<D,T2> & p2)
{ {
for (int i = 0; i < D; i++) x[i] = p2.x[i]; for (int i = 0; i < D; i++) x[i] = p2(i);
return *this; return *this;
} }
@ -98,10 +99,10 @@ namespace netgen
{ for(int i=0; i<D; i++) x[i] = p2(i)-p1(1); } { for(int i=0; i<D; i++) x[i] = p2(i)-p1(1); }
template <typename T2>
Vec & operator= (const Vec & p2) Vec & operator= (const Vec<D,T2> & p2)
{ {
for (int i = 0; i < D; i++) x[i] = p2.x[i]; for (int i = 0; i < D; i++) x[i] = p2(i);
return *this; return *this;
} }

View File

@ -10,8 +10,6 @@
#include <visual.hpp> #include <visual.hpp>
#include <limits> #include <limits>
namespace netgen namespace netgen
{ {
@ -441,6 +439,10 @@ namespace netgen
// glEnable(GL_BLEND); // glEnable(GL_BLEND);
glDisable(GL_BLEND); glDisable(GL_BLEND);
glCallList (surfellist); glCallList (surfellist);
static int timer = NgProfiler::CreateTimer ("Solution::drawing - DrawSurfaceElements VBO");
NgProfiler::StartTimer(timer);
glDrawElements(GL_TRIANGLES, surfel_vbo_size, GL_UNSIGNED_INT, 0);
NgProfiler::StopTimer(timer);
glDisable(GL_BLEND); glDisable(GL_BLEND);
/* /*
// transparent test ... // transparent test ...
@ -1182,6 +1184,17 @@ namespace netgen
shared_ptr<Mesh> mesh = GetMesh(); shared_ptr<Mesh> mesh = GetMesh();
static int timer = NgProfiler::CreateTimer ("Solution::DrawSurfaceElements"); static int timer = NgProfiler::CreateTimer ("Solution::DrawSurfaceElements");
static int timerstart = NgProfiler::CreateTimer ("Solution::DrawSurfaceElements start");
static int timerloops = NgProfiler::CreateTimer ("Solution::DrawSurfaceElements loops");
static int timerlist = NgProfiler::CreateTimer ("Solution::DrawSurfaceElements list");
static int timerbuffer = NgProfiler::CreateTimer ("Solution::DrawSurfaceElements buffer");
static int timer1 = NgProfiler::CreateTimer ("Solution::DrawSurfaceElements 1");
static int timer1a = NgProfiler::CreateTimer ("Solution::DrawSurfaceElements 1a");
static int timer1b = NgProfiler::CreateTimer ("Solution::DrawSurfaceElements 1b");
static int timer1c = NgProfiler::CreateTimer ("Solution::DrawSurfaceElements 1c");
static int timer2 = NgProfiler::CreateTimer ("Solution::DrawSurfaceElements 2");
static int timer2a = NgProfiler::CreateTimer ("Solution::DrawSurfaceElements 2a");
static int timer2b = NgProfiler::CreateTimer ("Solution::DrawSurfaceElements 2b");
NgProfiler::RegionTimer reg (timer); NgProfiler::RegionTimer reg (timer);
@ -1213,7 +1226,7 @@ namespace netgen
} }
#endif #endif
NgProfiler::StartTimer(timerstart);
if (surfellist) if (surfellist)
glDeleteLists (surfellist, 1); glDeleteLists (surfellist, 1);
@ -1256,18 +1269,55 @@ namespace netgen
Array<double> values(npt); Array<double> values(npt);
Array<double> mvalues(npt); Array<double> mvalues(npt);
int sol_comp = (sol && sol->draw_surface) ? sol->components : 0;
#ifdef __AVX__ #ifdef __AVX__
Array<Point<2,SIMD<double>> > simd_pref ( (npt+SIMD<double>::Size()-1)/SIMD<double>::Size() ); Array<Point<2,SIMD<double>> > simd_pref ( (npt+SIMD<double>::Size()-1)/SIMD<double>::Size() );
Array<Point<3,SIMD<double>> > simd_points ( (npt+SIMD<double>::Size()-1)/SIMD<double>::Size() ); Array<Point<3,SIMD<double>> > simd_points ( (npt+SIMD<double>::Size()-1)/SIMD<double>::Size() );
Array<Mat<3,2,SIMD<double>> > simd_dxdxis ( (npt+SIMD<double>::Size()-1)/SIMD<double>::Size() ); Array<Mat<3,2,SIMD<double>> > simd_dxdxis ( (npt+SIMD<double>::Size()-1)/SIMD<double>::Size() );
Array<Vec<3,SIMD<double>> > simd_nvs( (npt+SIMD<double>::Size()-1)/SIMD<double>::Size() ); Array<Vec<3,SIMD<double>> > simd_nvs( (npt+SIMD<double>::Size()-1)/SIMD<double>::Size() );
Array<SIMD<double>> simd_values( (npt+SIMD<double>::Size()-1)/SIMD<double>::Size() * sol->components); Array<SIMD<double>> simd_values( (npt+SIMD<double>::Size()-1)/SIMD<double>::Size() * sol_comp);
#endif #endif
// Array<Point<3,float>> glob_pnts;
// Array<Vec<3,float>> glob_nvs;
// Array<double> glob_values;
if (sol && sol->draw_surface) mvalues.SetSize (npt * sol->components); if (sol && sol->draw_surface) mvalues.SetSize (npt * sol->components);
Array<complex<double> > valuesc(npt); Array<complex<double> > valuesc(npt);
if (has_surfel_vbo)
glDeleteBuffers (4, &surfel_vbo[0]);
glGenBuffers (4, &surfel_vbo[0]);
has_surfel_vbo = true;
glBindBuffer (GL_ARRAY_BUFFER, surfel_vbo[0]);
glBufferData (GL_ARRAY_BUFFER,
nse*npt*sizeof(Point<3,double>),
NULL, GL_STATIC_DRAW);
glVertexPointer(3, GL_DOUBLE, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer (GL_ARRAY_BUFFER, surfel_vbo[1]);
glBufferData (GL_ARRAY_BUFFER,
nse*npt*sizeof(Vec<3,double>),
NULL, GL_STATIC_DRAW);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_DOUBLE, 0, 0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer (GL_ARRAY_BUFFER, surfel_vbo[2]);
glBufferData (GL_ARRAY_BUFFER, nse*npt*sizeof(double), NULL, GL_STATIC_DRAW);
glTexCoordPointer(1, GL_DOUBLE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surfel_vbo[3]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, nse*npt*6*sizeof(int), NULL, GL_STATIC_DRAW);
surfel_vbo_size = 0;
NgProfiler::StopTimer(timerstart);
for (SurfaceElementIndex sei = 0; sei < nse; sei++) for (SurfaceElementIndex sei = 0; sei < nse; sei++)
{ {
const Element2d & el = (*mesh)[sei]; const Element2d & el = (*mesh)[sei];
@ -1421,6 +1471,37 @@ namespace netgen
n = 1 << subdivisions; n = 1 << subdivisions;
double invn = 1.0 / n; double invn = 1.0 / n;
npt = (n+1)*(n+2)/2; npt = (n+1)*(n+2)/2;
NgProfiler::StartTimer(timerloops);
size_t base_pi = 0;
#ifdef __AVX__
for (int iy = 0, ii = 0; iy <= n; iy++)
for (int ix = 0; ix <= n-iy; ix++, ii++)
pref[ii] = Point<2> (ix*invn, iy*invn);
constexpr size_t simd_size = SIMD<double>::Size();
size_t simd_npt = (npt+simd_size-1)/simd_size;
for (size_t i = 0; i < simd_npt; i++)
{
simd_pref[i](0).SIMD_function ([&] (size_t j) { size_t ii = i*simd_size+j; return (ii < npt) ? pref[ii](0) : 0; }, std::true_type());
simd_pref[i](1).SIMD_function ([&] (size_t j) { size_t ii = i*simd_size+j; return (ii < npt) ? pref[ii](1) : 0; }, std::true_type());
}
#endif
Array<int> ind_reftrig;
for (int iy = 0, ii = 0; iy < n; iy++,ii++)
for (int ix = 0; ix < n-iy; ix++, ii++)
{
int nv = (ix+iy+1 < n) ? 6 : 3;
int ind[] = { ii, ii+1, ii+n-iy+1,
ii+n-iy+1, ii+1, ii+n-iy+2 };
for (int j = 0; j < nv; j++)
ind_reftrig.Append (ind[j]);
}
Array<int> glob_ind;
glob_ind.SetSize(ind_reftrig.Size());
for(SurfaceElementIndex sei = 0; sei < nse; sei++) for(SurfaceElementIndex sei = 0; sei < nse; sei++)
{ {
@ -1444,22 +1525,11 @@ namespace netgen
if ( el.GetType() == TRIG || el.GetType() == TRIG6 ) if ( el.GetType() == TRIG || el.GetType() == TRIG6 )
{ {
NgProfiler::StartTimer(timer1);
#ifdef __AVX_try_it_out__ #ifdef __AVX_try_it_out__
// NgProfiler::StartTimer(timer1a);
bool curved = curv.IsSurfaceElementCurved(sei); bool curved = curv.IsSurfaceElementCurved(sei);
for (int iy = 0, ii = 0; iy <= n; iy++)
for (int ix = 0; ix <= n-iy; ix++, ii++)
pref[ii] = Point<2> (ix*invn, iy*invn);
constexpr size_t simd_size = SIMD<double>::Size();
size_t simd_npt = (npt+simd_size-1)/simd_size;
for (size_t i = 0; i < simd_npt; i++)
{
simd_pref[i](0).SIMD_function ([&] (size_t j) { size_t ii = i*simd_size+j; return (ii < npt) ? pref[ii](0) : 0; }, std::true_type());
simd_pref[i](1).SIMD_function ([&] (size_t j) { size_t ii = i*simd_size+j; return (ii < npt) ? pref[ii](1) : 0; }, std::true_type());
}
if (curved) if (curved)
{ {
mesh->GetCurvedElements(). mesh->GetCurvedElements().
@ -1494,14 +1564,19 @@ namespace netgen
simd_nvs[ii] = nv; simd_nvs[ii] = nv;
} }
bool drawelem = false; bool drawelem = false;
if (sol && sol->draw_surface) if (sol && sol->draw_surface)
{ {
// NgProfiler::StopTimer(timer1a);
// NgProfiler::StartTimer(timer1b);
drawelem = sol->solclass->GetMultiSurfValue (sei, -1, simd_npt, drawelem = sol->solclass->GetMultiSurfValue (sei, -1, simd_npt,
&simd_pref[0](0).Data(), &simd_pref[0](0).Data(),
&simd_points[0](0).Data(), &simd_points[0](0).Data(),
&simd_dxdxis[0](0).Data(), &simd_dxdxis[0](0).Data(),
&simd_values[0].Data()); &simd_values[0].Data());
// NgProfiler::StopTimer(timer1b);
// NgProfiler::StartTimer(timer1c);
for (size_t j = 0; j < sol->components; j++) for (size_t j = 0; j < sol->components; j++)
for (size_t i = 0; i < npt; i++) for (size_t i = 0; i < npt; i++)
@ -1530,6 +1605,9 @@ namespace netgen
if (deform) if (deform)
for (int ii = 0; ii < npt; ii++) for (int ii = 0; ii < npt; ii++)
points[ii] += GetSurfDeformation (sei, -1, pref[ii](0), pref[ii](1)); points[ii] += GetSurfDeformation (sei, -1, pref[ii](0), pref[ii](1));
// NgProfiler::StopTimer(timer1c);
#else #else
bool curved = curv.IsSurfaceElementCurved(sei); bool curved = curv.IsSurfaceElementCurved(sei);
@ -1588,6 +1666,7 @@ namespace netgen
for (int ii = 0; ii < npt; ii++) for (int ii = 0; ii < npt; ii++)
points[ii] += GetSurfDeformation (sei, -1, pref[ii](0), pref[ii](1)); points[ii] += GetSurfDeformation (sei, -1, pref[ii](0), pref[ii](1));
#endif #endif
NgProfiler::StopTimer(timer1);
int save_usetexture = usetexture; int save_usetexture = usetexture;
if (!drawelem) if (!drawelem)
@ -1596,6 +1675,32 @@ namespace netgen
SetTextureMode (usetexture); SetTextureMode (usetexture);
} }
NgProfiler::StartTimer(timer2);
if (drawelem && usetexture == 1 && !logscale)
{
glBindBuffer (GL_ARRAY_BUFFER, surfel_vbo[0]);
glBufferSubData (GL_ARRAY_BUFFER, base_pi*sizeof(Point<3,double>),
npt*sizeof(Point<3,double>), &points[0][0]);
glBindBuffer (GL_ARRAY_BUFFER, surfel_vbo[1]);
glBufferSubData (GL_ARRAY_BUFFER, base_pi*sizeof(Vec<3,double>),
npt*sizeof(Vec<3,double>), &nvs[0][0]);
glBindBuffer (GL_ARRAY_BUFFER, surfel_vbo[2]);
glBufferSubData (GL_ARRAY_BUFFER, base_pi*sizeof(double),
npt*sizeof(double), &values[0]);
for (size_t i = 0; i < ind_reftrig.Size(); i++)
glob_ind[i] = base_pi+ind_reftrig[i];
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, surfel_vbo[3]);
glBufferSubData (GL_ELEMENT_ARRAY_BUFFER, surfel_vbo_size*sizeof(int),
ind_reftrig.Size()*sizeof(int), &glob_ind[0]);
surfel_vbo_size += ind_reftrig.Size();
base_pi += npt;
}
else
for (int iy = 0, ii = 0; iy < n; iy++) for (int iy = 0, ii = 0; iy < n; iy++)
{ {
glBegin (GL_TRIANGLE_STRIP); glBegin (GL_TRIANGLE_STRIP);
@ -1604,7 +1709,6 @@ namespace netgen
{ {
if (ix+iy+k > n) continue; if (ix+iy+k > n) continue;
int hi = (k == 0) ? ii : ii+n-iy+1; int hi = (k == 0) ? ii : ii+n-iy+1;
if (drawelem) if (drawelem)
{ {
if (usetexture != 2) if (usetexture != 2)
@ -1621,81 +1725,9 @@ namespace netgen
glEnd(); glEnd();
} }
NgProfiler::StopTimer(timer2);
/*
GLuint vboId[3];
glGenBuffersARB (3, &vboId[0]);
// cout << "vboId = " << vboId << endl;
glBindBufferARB (GL_ARRAY_BUFFER_ARB, vboId[0]);
glBufferDataARB (GL_ARRAY_BUFFER_ARB, points.Size()*sizeof(Point<3>),
&points[0][0], GL_STATIC_DRAW_ARB);
// not so fast as old-fashened style
glEnableClientState(GL_VERTEX_ARRAY);
// glVertexPointer(3, GL_DOUBLE, 0, &points[0][0]);
glVertexPointer(3, GL_DOUBLE, 0, 0); //ARB
glBindBufferARB (GL_ARRAY_BUFFER_ARB, vboId[1]);
glBufferDataARB (GL_ARRAY_BUFFER_ARB, nvs.Size()*sizeof(Point<3>),
&nvs[0][0], GL_STATIC_DRAW_ARB);
glEnableClientState(GL_NORMAL_ARRAY);
// glNormalPointer(GL_DOUBLE, 0, &nvs[0][0]);
glNormalPointer(GL_DOUBLE, 0, 0); // ARB
// if (drawelem && usetexture == 1)
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// glTexCoordPointer(1, GL_DOUBLE, 0, &values[0]);
glBindBufferARB (GL_ARRAY_BUFFER_ARB, vboId[2]);
glBufferDataARB (GL_ARRAY_BUFFER_ARB, values.Size()*sizeof(double),
&values[0], GL_STATIC_DRAW_ARB);
glTexCoordPointer(1, GL_DOUBLE, 0, 0);
}
Array<int> gind;
for (int iy = 0, ii = 0; iy < n; iy++,ii++)
{
for (int ix = 0; ix < n-iy; ix++, ii++)
{
int nv = (ix+iy+1 < n) ? 6 : 3;
int ind[] = { ii, ii+1, ii+n-iy+1,
ii+n-iy+1, ii+1, ii+n-iy+2 };
// if (ix == 0 && iy == 0)
// for (int l = 0; l < 3; l++)
// {
// if (drawelem)
// {
// if (usetexture != 2)
// // SetOpenGlColor (values[ind[l]]);
// glTexCoord1f ( values[ind[l]] );
// else
// glTexCoord2f ( valuesc[ind[l]].real(), valuesc[ind[l]].imag() );
// }
// else
// glColor3fv (col_grey);
// }
for (int j = 0; j < nv; j++)
gind.Append(ind[j]);
// glDrawElements(GL_TRIANGLES, nv, GL_UNSIGNED_INT, &ind[0]);
}
}
glDrawElements(GL_TRIANGLES, gind.Size(), GL_UNSIGNED_INT, &gind[0]);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDeleteBuffersARB (3, &vboId[0]);
*/
if (!drawelem && (usetexture != save_usetexture)) if (!drawelem && (usetexture != save_usetexture))
@ -1705,8 +1737,31 @@ namespace netgen
} }
} }
} }
glEndList (); NgProfiler::StopTimer(timerloops);
NgProfiler::StartTimer(timerbuffer);
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surfel_vbo[3]);
// glBufferData(GL_ELEMENT_ARRAY_BUFFER, glob_ind.Size()*sizeof(int), &glob_ind[0], GL_STATIC_DRAW);
// surfel_vbo_size = glob_ind.Size();
NgProfiler::StopTimer(timerbuffer);
// glDrawElements(GL_TRIANGLES, surfel_vbo_size, GL_UNSIGNED_INT, 0);
// glDrawElements(GL_TRIANGLES, glob_ind.Size(), GL_UNSIGNED_INT, &glob_ind[0]);
// glDisableClientState(GL_VERTEX_ARRAY);
// glDisableClientState(GL_NORMAL_ARRAY);
// glDisableClientState(GL_TEXTURE_COORD_ARRAY);
// glDeleteBuffers (1, &IndexVBOID);
// glDeleteBuffers (4, &vboId[0]);
NgProfiler::StartTimer(timerlist);
glEndList ();
NgProfiler::StopTimer(timerlist);
#ifdef PARALLELGL #ifdef PARALLELGL
glFinish(); glFinish();
@ -2588,11 +2643,13 @@ namespace netgen
if(minv_local < minv) if(minv_local < minv)
{ {
lock_guard<mutex> guard(min_mutex); lock_guard<mutex> guard(min_mutex);
if(minv_local < minv)
minv = minv_local; minv = minv_local;
} }
if(maxv_local > maxv) if(maxv_local > maxv)
{ {
lock_guard<mutex> guard(max_mutex); lock_guard<mutex> guard(max_mutex);
if(maxv_local > maxv)
maxv = maxv_local; maxv = maxv_local;
} }
}); });

View File

@ -43,7 +43,9 @@ class DLL_HEADER VisualSceneSolution : public VisualScene
Point<3> p; Point<3> p;
}; };
bool has_surfel_vbo = false;
GLuint surfel_vbo[4]; //
size_t surfel_vbo_size;
int surfellist; int surfellist;
int linelist; int linelist;
int element1dlist; int element1dlist;