void MeshCylinderRenderer::DrawCylinderBuffer(const ExpandableBuffer<GLfloat>& position, const ExpandableBuffer<GLfloat>& color, const ExpandableBuffer<GLfloat>& textureCoord1, const ExpandableBuffer<GLfloat>& textureCoord2) { // NOTE: leaked, but this is a singleton if (m_Quadric == 0) { m_Quadric = gluNewQuadric(); } if( m_Quadric == NULL ) { fprintf( stderr, "quadric allocation is failed\n"); } // we extract the centers and radii from the encoding that is usually passed to the CG program const int numBalls = position.getNumObjects()/16; for (int i=0; i<numBalls; i++) { // endpoints const CCVOpenGLMath::Vector endpoint1(textureCoord1.get(i*16 + 0), textureCoord1.get(i*16 + 1), textureCoord1.get(i*16 + 2), 1); const CCVOpenGLMath::Vector endpoint2(textureCoord2.get(i*16 + 0), textureCoord2.get(i*16 + 1), textureCoord2.get(i*16 + 2), 1); // radius is stored as the Z of position const GLfloat radius = position.get(i*16 + 2); // extract color glColor3f(color.get(i*16 + 0), color.get(i*16 + 1), color.get(i*16 + 2)); glPushMatrix(); // gluCylinder draws on the z axis. // so we need to rotate cylinderUp to align with the z axis const CCVOpenGLMath::Vector cylinderUp = (endpoint2 - endpoint1); const GLfloat height = cylinderUp.norm(); // convert cylinderUp to spherical coordinates. OpenGL needs this in degrees. const GLfloat RAD_TO_DEG = 180.0f/M_PI; const GLfloat phi = acos(cylinderUp[2]/height) * RAD_TO_DEG; const GLfloat theta = atan2(cylinderUp[1],cylinderUp[0]) * RAD_TO_DEG; // prepare to draw // (rotate phi down, remaining aligned with x-axis, then rotate theta) glTranslatef(endpoint1[0], endpoint1[1], endpoint1[2]); glRotatef(theta, 0, 0, 1); glRotatef(phi, 0, 1, 0); gluCylinder(m_Quadric, radius, // GLdouble base, radius, // GLdouble top, height, LEVEL_OF_DETAIL, // GLint slices, 1); // GLint stacks); glPopMatrix(); } }
void MeshHelixRenderer::DrawHelixBuffer(const ExpandableBuffer<GLfloat>& position, const ExpandableBuffer<GLfloat>& color, const ExpandableBuffer<GLfloat>& textureCoord1, const ExpandableBuffer<GLfloat>& textureCoord2) { // NOTE: leaked, but this is a singleton if (m_Quadric == 0) { m_Quadric = gluNewQuadric(); } // we extract the centers and radii from the encoding that is usually passed to the CG program const int numBalls = position.getNumObjects()/16; for (int i=0; i<numBalls; i++) { // endpoints const CCVOpenGLMath::Vector endpoint1(textureCoord1.get(i*16 + 0), textureCoord1.get(i*16 + 1), textureCoord1.get(i*16 + 2), 1); const CCVOpenGLMath::Vector endpoint2(textureCoord2.get(i*16 + 0), textureCoord2.get(i*16 + 1), textureCoord2.get(i*16 + 2), 1); // radius is stored as the Z of position const GLfloat radius = position.get(i*16 + 2); // extract color glColor3f(color.get(i*16 + 0), color.get(i*16 + 1), color.get(i*16 + 2)); glPushMatrix(); // gluHelix draws on the z axis. // so we need to rotate helixUp to align with the z axis const CCVOpenGLMath::Vector helixUp = (endpoint2 - endpoint1); const GLfloat height = helixUp.norm(); // convert helixUp to spherical coordinates. OpenGL needs this in degrees. const GLfloat RAD_TO_DEG = 180.0f/M_PI; const GLfloat phi = acos(helixUp[2]/height); const GLfloat theta = atan2(helixUp[1],helixUp[0]); // prepare to draw // (rotate phi down, remaining aligned with x-axis, then rotate theta) glTranslatef(endpoint1[0], endpoint1[1], endpoint1[2]); glRotatef(theta * RAD_TO_DEG, 0, 0, 1); glRotatef(phi * RAD_TO_DEG, 0, 1, 0); // construct a triangle strip helix const GLfloat HEIGHT_TO_THETA = (1.0f / height) * 360.0f * HEIGHT_TO_COILS; int nAngles = height / HEIGHT_STEP; int nVertices = 2 * nAngles; GLfloat vertices[nVertices][3]; GLfloat normals[nVertices][3]; GLfloat heightIter = 0; for (int i = 0; i < nVertices; i+=2) { GLfloat thetaIter = heightIter * HEIGHT_TO_THETA; normals[i+1][0] = normals[i][0] = cos(thetaIter); normals[i+1][1] = normals[i][1] = sin(thetaIter); normals[i+1][2] = normals[i][2] = 0; vertices[i][0] = radius * cos(thetaIter); vertices[i][1] = radius * sin(thetaIter); vertices[i][2] = heightIter + STRIP_HEIGHT; vertices[i+1][0] = radius * cos(thetaIter); vertices[i+1][1] = radius * sin(thetaIter); vertices[i+1][2] = heightIter; heightIter += HEIGHT_STEP; } // render glVertexPointer(3, GL_FLOAT, 0, vertices); glNormalPointer(GL_FLOAT, 0, normals); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glDrawArrays(GL_TRIANGLE_STRIP, 0, nVertices); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glPopMatrix(); } }