void TubeRendererThread::run() { int numThreads = GLFunctions::idealThreadCount; int chunkSize = m_data.size() / numThreads; int begin = m_id * chunkSize; int end = m_id * chunkSize + chunkSize; if ( m_id == numThreads - 1 ) { end = m_data.size(); } // for all voxels: for ( int i = begin; i < end; ++i ) { QVector<float> fib = m_data[i]; QVector<float> extra = m_extraData[i]; if ( fib.size() < 9 ) { printf( "fib with size < 3 detected" ); continue; } int numFloats = fib.size(); QVector3D lineStart( fib[0], fib[1], fib[2] ); QVector3D lineEnd( fib[numFloats-3], fib[numFloats-2], fib[numFloats-1] ); QVector3D globalColor( fabs( lineStart.x() - lineEnd.x() ), fabs( lineStart.y() - lineEnd.y() ), fabs( lineStart.z() - lineEnd.z() ) ); globalColor.normalize(); // push back the first vertex, done seperately because of nomal calculation QVector3D localColor( fib[0] - fib[3], fib[1] - fib[4], fib[2] - fib[5] ); localColor.normalize(); m_verts->push_back( fib[0] ); m_verts->push_back( fib[1] ); m_verts->push_back( fib[2] ); m_verts->push_back( localColor.x() ); m_verts->push_back( localColor.y() ); m_verts->push_back( localColor.z() ); m_verts->push_back( globalColor.x() ); m_verts->push_back( globalColor.y() ); m_verts->push_back( globalColor.z() ); m_verts->push_back( extra.first() ); m_verts->push_back( 1.0 ); m_verts->push_back( fib[0] ); m_verts->push_back( fib[1] ); m_verts->push_back( fib[2] ); m_verts->push_back( localColor.x() ); m_verts->push_back( localColor.y() ); m_verts->push_back( localColor.z() ); m_verts->push_back( globalColor.x() ); m_verts->push_back( globalColor.y() ); m_verts->push_back( globalColor.z() ); m_verts->push_back( extra.first() ); m_verts->push_back( -1.0 ); for ( int k = 1; k < fib.size() / 3 - 1; ++k ) { QVector3D localColor( fib[k*3-3] - fib[k*3+3], fib[k*3-2] - fib[k*3+4], fib[k*3-1] - fib[k*3+5] ); localColor.normalize(); m_verts->push_back( fib[k*3] ); m_verts->push_back( fib[k*3+1] ); m_verts->push_back( fib[k*3+2] ); m_verts->push_back( localColor.x() ); m_verts->push_back( localColor.y() ); m_verts->push_back( localColor.z() ); m_verts->push_back( globalColor.x() ); m_verts->push_back( globalColor.y() ); m_verts->push_back( globalColor.z() ); m_verts->push_back( extra[k] ); m_verts->push_back( 1.0 ); m_verts->push_back( fib[k*3] ); m_verts->push_back( fib[k*3+1] ); m_verts->push_back( fib[k*3+2] ); m_verts->push_back( localColor.x() ); m_verts->push_back( localColor.y() ); m_verts->push_back( localColor.z() ); m_verts->push_back( globalColor.x() ); m_verts->push_back( globalColor.y() ); m_verts->push_back( globalColor.z() ); m_verts->push_back( extra[k] ); m_verts->push_back( -1.0 ); } QVector3D localColor2( fib[numFloats-6] - fib[numFloats-3], fib[numFloats-5] - fib[numFloats-2], fib[numFloats-4] - fib[numFloats-1] ); localColor.normalize(); // push back the last vertex, done seperately because of nomal calculation m_verts->push_back( fib[numFloats-3] ); m_verts->push_back( fib[numFloats-2] ); m_verts->push_back( fib[numFloats-1] ); m_verts->push_back( localColor2.x() ); m_verts->push_back( localColor2.y() ); m_verts->push_back( localColor2.z() ); m_verts->push_back( globalColor.x() ); m_verts->push_back( globalColor.y() ); m_verts->push_back( globalColor.z() ); m_verts->push_back( extra.last() ); m_verts->push_back( 1.0 ); m_verts->push_back( fib[numFloats-3] ); m_verts->push_back( fib[numFloats-2] ); m_verts->push_back( fib[numFloats-1] ); m_verts->push_back( localColor2.x() ); m_verts->push_back( localColor2.y() ); m_verts->push_back( localColor2.z() ); m_verts->push_back( globalColor.x() ); m_verts->push_back( globalColor.y() ); m_verts->push_back( globalColor.z() ); m_verts->push_back( extra.last() ); m_verts->push_back( -1.0 ); } }
void FiberRenderer::initGeometry() { if ( m_isInitialized ) { return; } qDebug() << "create fiber vbo's..."; std::vector<float>verts; try { verts.reserve( m_numPoints * 6 ); } catch ( std::bad_alloc& ) { qCritical() << "***error*** failed to allocate enough memory for vbo"; exit ( 0 ); } for ( unsigned int i = 0; i < m_fibs->size(); ++i ) { Fib fib = m_fibs->at(i); if ( fib.length() < 2 ) { printf( "fib with size < 2 detected" ); continue; } QVector3D lineStart = fib.firstVert(); QVector3D lineEnd = fib.lastVert(); // push back the first vertex, done seperately because of nomal calculation verts.push_back( lineStart.x() ); verts.push_back( lineStart.y() ); verts.push_back( lineStart.z() ); QVector3D secondVert = fib.getVert( 1 ); QVector3D localColor( lineStart.x() - secondVert.x(), lineStart.y() - secondVert.y(), lineStart.z() - secondVert.z() ); localColor.normalize(); verts.push_back( localColor.x() ); verts.push_back( localColor.y() ); verts.push_back( localColor.z() ); for ( unsigned int k = 1; k < fib.length() - 1; ++k ) { verts.push_back( fib[k].x() ); verts.push_back( fib[k].y() ); verts.push_back( fib[k].z() ); QVector3D localColor( fib[k-1].x() - fib[k+1].x(), fib[k-1].y() - fib[k+1].y(), fib[k-1].z() - fib[k+1].z() ); localColor.normalize(); verts.push_back( localColor.x() ); verts.push_back( localColor.y() ); verts.push_back( localColor.z() ); } // push back the last vertex, done seperately because of nomal calculation verts.push_back( lineEnd.x() ); verts.push_back( lineEnd.y() ); verts.push_back( lineEnd.z() ); QVector3D sec2last = fib[ fib.length() - 2 ]; QVector3D localColor2( sec2last.x() - lineEnd.x(), sec2last.y() - lineEnd.y(), sec2last.z() - lineEnd.z() ); localColor.normalize(); verts.push_back( localColor2.x() ); verts.push_back( localColor2.y() ); verts.push_back( localColor2.z() ); } glBindBuffer( GL_ARRAY_BUFFER, vbo ); glBufferData( GL_ARRAY_BUFFER, verts.size() * sizeof(GLfloat), verts.data(), GL_STATIC_DRAW ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); verts.clear(); m_pointsPerLine.resize( m_fibs->size() ); m_startIndexes.resize( m_fibs->size() ); int currentStart = 0; for ( unsigned int i = 0; i < m_fibs->size(); ++i ) { m_pointsPerLine[i] = m_fibs->at( i ).length(); m_startIndexes[i] = currentStart; currentStart += m_pointsPerLine[i]; } updateExtraData( 0 ); qDebug() << "create fiber vbo's done"; m_numPoints = verts.size() / 6; m_isInitialized = true; }