/** Compute position on the curve in time t. */ glm::vec3 evaluateClosedCurve(Curve *curve,const float t) { glm::vec3 result(0.0, 0.0, 0.0); int i = (int)t; result = evaluateCurveSegment(curve->points[(i-1) % curve->size],curve->points[(i) % curve->size],curve->points[(i+1) % curve->size],curve->points[(i+2) % curve->size],(float)(t-i)); return result; }
SplineSegmentNode::SplineSegmentNode(const char * name, SceneNode * parent): SceneNode(name, parent) { if(m_program == 0) { std::vector<GLuint> shaderList; // Push vertex shader and fragment shader shaderList.push_back(pgr::createShader(GL_VERTEX_SHADER, strVertexShader )); shaderList.push_back(pgr::createShader(GL_FRAGMENT_SHADER, strFragmentShader)); // Create the program with two shaders m_program = pgr::createProgram(shaderList); m_PVMmatrixLoc = glGetUniformLocation( m_program, "PVMmatrix"); m_colLoc = glGetUniformLocation( m_program, "color"); m_posLoc = glGetAttribLocation( m_program, "position"); } if(m_vertexArrayObject == 0) { const size_t resoulution = 10; // number of samples per parameter step m_numberOfCurveSamples = resoulution * curveTestSize; // samples of the drawn curve glGenBuffers(1, &m_vertexBufferObject); glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferObject); // reserve space for control points + the curve glBufferData(GL_ARRAY_BUFFER, (curveTestSize + m_numberOfCurveSamples + 4) * sizeof(vec3), NULL, GL_STATIC_DRAW); // 4 for tangents // put given control points first glBufferSubData(GL_ARRAY_BUFFER, 0, curveTestSize * sizeof(vec3), curveTestPoints ); // put computed curve points after GLintptr offset = curveTestSize * sizeof(vec3); for( unsigned i = 0; i < m_numberOfCurveSamples; i++ ) { float t = (float)i/m_numberOfCurveSamples; vec3 position = evaluateCurveSegment( curveTestPoints[0], curveTestPoints[1], curveTestPoints[2], curveTestPoints[3], t); // one point along the curve for parameter t glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(vec3), value_ptr(position) ); offset += sizeof(vec3); } // tangent endpoints vec3 t0 = (curveTestPoints[2] - curveTestPoints[0]) * 0.2f; vec3 t1 = (curveTestPoints[3] - curveTestPoints[1]) * 0.2f; glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(vec3), value_ptr(curveTestPoints[1]-t0) ); offset += sizeof(vec3); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(vec3), value_ptr(curveTestPoints[1]+t0) ); offset += sizeof(vec3); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(vec3), value_ptr(curveTestPoints[2]-t1) ); offset += sizeof(vec3); glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(vec3), value_ptr(curveTestPoints[2]+t1) ); offset += sizeof(vec3); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenVertexArrays(1, &m_vertexArrayObject ); glBindVertexArray( m_vertexArrayObject ); glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferObject); // Control points folowed by the points along the curve glEnableVertexAttribArray(m_posLoc); glVertexAttribPointer(m_posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindVertexArray( 0 ); } }