Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ OpenGL
I draw a circle using a code of cylinder. Now I want to change the code further as it gives a sphere. The code is mentioned below. If any one can help me, please help me to change this code as it gives a sphere
 

#include <cmath>
#include <iostream>

#ifdef __APPLE__
#  include 
#else
#  include 
#endif
 
#define PI 3.14159265358979324
 
using namespace std;
 
// Globals.
static int p = 6; // Number of grid columns.
static int q = 4; // Number of grid rows
static float *vertices = NULL; // Vertex array of the mapped sample on the cylinder.
static float Xangle = 150.0, Yangle = 60.0, Zangle = 0.0; // Angles to rotate the cylinder.
//static float R = 2.0, R2 = 1.5, R3 = 1.0; // Radius of circle.
static float R=2.0;
static int numVertices=100;
static float X = 0.0; // X-coordinate of center of circle.
static float Y = 0.0; // Y-coordinate of center of circle.
//static int numVertices = 100,numCircles = 10; // Number of vertices on circle.

// Fuctions to map the grid vertex (u_i,v_j) to the mesh vertex (f(u_i,v_j), g(u_i,v_j), h(u_i,v_j)) on the cylinder.
float f(int i, int j)
{
   return ( cos( (-1 + 2*(float)i/p) * PI ) );
}
 
float g(int i, int j)
{
   return ( sin( (-1 + 2*(float)i/p) * PI ) );
}
 
float h(int i, int j)
{
   return ( -1 + 2*(float)j/q );
}
 
// Routine to fill the vertex array with co-ordinates of the mapped sample points.
void fillVertexArray(void)
{
   int i, j, k;
 
   k = 0;
   for (j = 0; j <= q; j++)
      for (i = 0; i <= p; i++)
      {
         vertices[k++] = f(i,j);
         vertices[k++] = g(i,j);
         vertices[k++] = h(i,j);
      }
}
 
// Initialization routine.
void setup(void)
{
   glEnableClientState(GL_VERTEX_ARRAY);
 
   glClearColor(1.0, 1.0, 1.0, 0.0); 
}
 
// Drawing routine.
void drawScene(void)
{
   int  i, j,k;
   vertices = new float[3*(p+1)*(q+1)]; // Dynamic array allocation with new value of p and q. 

   glVertexPointer(3, GL_FLOAT, 0, vertices);   
   glClear(GL_COLOR_BUFFER_BIT);
 
   glLoadIdentity();
   gluLookAt (0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
 
   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 
   glColor3f(0.0, 0.0, 0.0);
 
   // Rotate scene.
   glRotatef(Zangle, 0.0, 0.0, 1.0);
   glRotatef(Yangle, 0.0, 1.0, 0.0);
   glRotatef(Xangle, 1.0, 0.0, 0.0);
 
   // Fill the vertex array.
   fillVertexArray();
 
   // Make the approximating triangular mesh.
   for(j = 0; j < q; j++)
   {
	    float t = 0,h = 0; // Angle parameter.
       int i;
     /* glBegin(GL_TRIANGLE_STRIP);
      for(i = 0; i <= p; i++)
      {
         glArrayElement( (j+1)*(p+1) + i );
         glArrayElement( j*(p+1) + i );
	  }
      glEnd();*/
	    glBegin(GL_LINE_LOOP);
     
 
	/*  for (k = 0; k < numCircles; ++k)
	  {*/
	    for(i = 0; i < numVertices; ++i)
		{
        // glColor3ub(rand()%256, rand()%256, rand()%256); 
         
	     glVertex3f(X+ R * cos(t), Y + R * sin(t), 0);
		 t += 2 * PI / numVertices;
 
		
		
		}
		/*h += 0.2;
		R -= 0.2;
	  }*/
		glEnd();
 
   }
 
   glutSwapBuffers();
}
 
// OpenGL window reshape routine.
void resize(int w, int h)
{
   glViewport(0, 0, (GLsizei)w, (GLsizei)h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(60.0, (float)w/(float)h, 1.0, 50.0);
   glMatrixMode(GL_MODELVIEW);
 
}
 
// Keyboard input processing routine.
void keyInput(unsigned char key, int x, int y)
{
   switch(key) 
   {
      case 27:
         exit(0);
         break;
      case 'x':
         Xangle += 5.0;
		 if (Xangle > 360.0) Xangle -= 360.0;
         glutPostRedisplay();
         break;
      case 'X':
         Xangle -= 5.0;
		 if (Xangle < 0.0) Xangle += 360.0;
         glutPostRedisplay();
         break;
      case 'y':
         Yangle += 5.0;
		 if (Yangle > 360.0) Yangle -= 360.0;
         glutPostRedisplay();
         break;
      case 'Y':
         Yangle -= 5.0;
		 if (Yangle < 0.0) Yangle += 360.0;
         glutPostRedisplay();
         break;
      case 'z':
         Zangle += 5.0;
		 if (Zangle > 360.0) Zangle -= 360.0;
         glutPostRedisplay();
         break;
      case 'Z':
         Zangle -= 5.0;
		 if (Zangle < 0.0) Zangle += 360.0;
         glutPostRedisplay();
         break;
      default:
         break;
   }
}
 
// Callback routine for non-ASCII key entry.
void specialKeyInput(int key, int x, int y)
{
   if (key == GLUT_KEY_LEFT) if (p > 3) p -= 1;
   if (key == GLUT_KEY_RIGHT) p += 1;
   if (key == GLUT_KEY_DOWN) if (q > 3) q -= 1;
   if (key == GLUT_KEY_UP) q += 1;
 
   glutPostRedisplay();
}
 
// Routine to output interaction instructions to the C++ window.
void printInteraction(void)
{
   cout << "Interaction:" << endl;
   cout << "Press left/right arrow keys to increase/decrease the number of grid columns." << endl
        << "Press up/down arrow keys to increase/decrease the number of grid rows." << endl
        << "Press x, X, y, Y, z, Z to turn the cylinder." << endl;
}
 
// Main routine.
int main(int argc, char **argv) 
{
   printInteraction();
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
   glutInitWindowSize(500, 500);
   glutInitWindowPosition(100, 100);
   glutCreateWindow("cylinder.cpp");
   setup();
   glutDisplayFunc(drawScene);
   glutReshapeFunc(resize);
   glutKeyboardFunc(keyInput);
   glutSpecialFunc(specialKeyInput);
   glutMainLoop();
 
   return 0;
}
Edit: code-tags added.
Posted 18-Apr-12 1:06am
Edited 18-Apr-12 1:08am
enhzflep38.1K
v2

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Sorry, not really in the mood to read code and determine the required changes.
Tell you what, I'll just copy/paste some code out of one of my projects. Okay for you?
 
void myGlutBall(float radius, int numStacks, int numSides)
{
//    vec3 points[sides * (sides-1)];
    GLfloat curRadius, curTheta, curRho, deltaTheta, deltaRho, curX,curY,curZ;
    int curStack, curSlice, numVerts = (numStacks-1)*numSides;
    vec3 points[numVerts];
    int curVert = 0;
    int t;
 
    deltaTheta = (2*M_PI) / numSides;
    deltaRho = M_PI / numStacks;
 
        for (curStack=1; curStack<numStacks; curStack++)
        {
            curRho = (3.141/2.0) - curStack*deltaRho;
            curY = sin(curRho) * radius;
            curRadius = cos(curRho) * radius;
            for (curSlice=0; curSlice<numSides; curSlice++)
            {
                curTheta = curSlice * deltaTheta;
                curX = curRadius * cos(curTheta);
                curZ = -curRadius * sin(curTheta);
                points[curVert++] = vec3{curX,curY,curZ};
            }
        }
 
    // option 1 - points only
    /*
    glBegin(GL_POINTS);
    glNormal3d(0,1,0);
    glVertex3d(0,radius,0);
    for (t=0; t<numVerts; t++)
    {
        curX = points[t].x;
        curY = points[t].y;
        curZ = points[t].z;
        glNormal3d(curX, curY, curZ);
        glVertex3d(curX, curY, curZ);
    }
    glNormal3d(0,-1,0);
    glVertex3d(0,-radius,0);
    glEnd();
    */
 
    ///////////////////////////////
    // option 2 - solid
    ///////////////////////////////
    // part A - draw the top 'lid' (tris)
    glBegin(GL_TRIANGLE_FAN);
        glNormal3d(0,1,0);
        glVertex3d(0,radius,0);
        for (t=0; t<numSides; t++)
        {
            curX = points[t].x;
            curY = points[t].y;
            curZ = points[t].z;
            glNormal3d(curX, curY, curZ);
            glVertex3d(curX, curY, curZ);
        }
            curX = points[0].x;
            curY = points[0].y;
            curZ = points[0].z;
        glNormal3d(curX, curY, curZ);
        glVertex3d(curX, curY, curZ);
    glEnd();
 
    // part B - draw the 'sides' (quads)
    int vertIndex;
    for (curStack=0; curStack<numStacks-2; curStack++)
    {
        vertIndex = curStack * numSides;
        glBegin(GL_QUAD_STRIP);
            for (curSlice=0; curSlice<numSides; curSlice++)
            {
                glNormal3d(points[vertIndex+curSlice].x, points[vertIndex+curSlice].y, points[vertIndex+curSlice].z);
                glVertex3d(points[vertIndex+curSlice].x, points[vertIndex+curSlice].y, points[vertIndex+curSlice].z);
 
                glNormal3d(points[vertIndex+numSides+curSlice].x, points[vertIndex+numSides+curSlice].y, points[vertIndex+numSides+curSlice].z);
                glVertex3d(points[vertIndex+numSides+curSlice].x, points[vertIndex+numSides+curSlice].y, points[vertIndex+numSides+curSlice].z);
            }
            glNormal3d(points[vertIndex].x, points[vertIndex].y, points[vertIndex].z);
            glVertex3d(points[vertIndex].x, points[vertIndex].y, points[vertIndex].z);
            glNormal3d(points[vertIndex+numSides].x, points[vertIndex+numSides].y, points[vertIndex+numSides].z);
            glVertex3d(points[vertIndex+numSides].x, points[vertIndex+numSides].y, points[vertIndex+numSides].z);
        glEnd();
    }
 
    // part C - draw the bottom 'lid' (tris)
    glBegin(GL_TRIANGLE_FAN);
        glNormal3d(0,-1,0);
        glVertex3d(0,-radius,0);
        for (t=0; t<numSides; t++)
        {
            curX = points[numVerts-t].x;
            curY = points[numVerts-t].y;
            curZ = points[numVerts-t].z;
            glNormal3d(curX, curY, curZ);
            glVertex3d(curX, curY, curZ);
        }
            curX = points[numVerts-0].x;
            curY = points[numVerts-0].y;
            curZ = points[numVerts-0].z;
        glNormal3d(curX, curY, curZ);
        glVertex3d(curX, curY, curZ);
    glEnd();
 
}
  Permalink  
v2
Comments
CPallini at 18-Apr-12 6:26am
   
OK for me.
enhzflep at 18-Apr-12 6:39am
   
:grins:
Jeremy Shin Woo at 18-Apr-12 6:42am
   
Thanx enhzflep... but I want to add some part to this code as it give as a sphere
 
void drawScene(void)
{
int i, j,k;
vertices = new float[3*(p+1)*(q+1)]; // Dynamic array allocation with new value of p and q.
 
glVertexPointer(3, GL_FLOAT, 0, vertices);
glClear(GL_COLOR_BUFFER_BIT);

glLoadIdentity();
gluLookAt (0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

glColor3f(0.0, 0.0, 0.0);

// Rotate scene.
glRotatef(Zangle, 0.0, 0.0, 1.0);
glRotatef(Yangle, 0.0, 1.0, 0.0);
glRotatef(Xangle, 1.0, 0.0, 0.0);

// Fill the vertex array.
fillVertexArray();

// Make the approximating triangular mesh.
for(j = 0; j < q; j++)
{
float t = 0,h = 0; // Angle parameter.
int i;
/* glBegin(GL_TRIANGLE_STRIP);
for(i = 0; i <= p; i++)
{
glArrayElement( (j+1)*(p+1) + i );
glArrayElement( j*(p+1) + i );
}
glEnd();*/
glBegin(GL_LINE_LOOP);


/* for (k = 0; k < numCircles; ++k)
{*/
for(i = 0; i < numVertices; ++i)
{
// glColor3ub(rand()%256, rand()%256, rand()%256);

glVertex3f(X+ R * cos(t), Y + R * sin(t), 0);
t += 2 * PI / numVertices;



}
/*h += 0.2;
R -= 0.2;
}*/
glEnd();

}

glutSwapBuffers();
}
enhzflep at 18-Apr-12 7:18am
   
Sorry, I don't seem understand your question. Can't you just place a call to myGlutBall inside your drawScene function? Also, you don't handle the up/down left/right keys. You could use these to increment/decrement the numStacks and numSides input vars.
 
Two things:
1) Haven't used this in wireframe mode before. There is a vertex in the wrong spot.
2) I forgot the definition of vec3 - see below.
 
typedef struct {
GLfloat x, y, z;
}vec3;
 
void drawScene2(void)
{
int i, j,k;
glClear(GL_COLOR_BUFFER_BIT);
 
glLoadIdentity();
gluLookAt (0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
 
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 
glColor3f(0.0, 0.0, 0.0);
 
// Rotate scene.
glRotatef(Zangle, 0.0, 0.0, 1.0);
glRotatef(Yangle, 0.0, 1.0, 0.0);
glRotatef(Xangle, 1.0, 0.0, 0.0);
 
myGlutBall(0.75, 16, 16);
 
glutSwapBuffers();
}

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Advertise | Privacy | Mobile
Web02 | 2.8.1411022.1 | Last Updated 18 Apr 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100