what is wrong with my menger sponge?

Hi, first post. Have a question about my code, I have been working on this forever and it draws a cube without subdividing it how it should. There is some evidence that it is subdividing something because 1 face of the cube is divided into 9 squares for n=1 in divideCube(). the cube that is drawn doesn’t look too much like a cube either. I used sierpinski gasket code to model it after (tetrahedron instead of cube) and tried to make it similar. My divideCube() function seems correct and follows the model. I am figuring that I am either passing parameters incorrectly to drawCube() or even a recursive divideCube() inside the divideCube() function. Thanks for looking, I just need some insight into solving the problem I have as I am an opengl beginner lol. There isn’t too much code to read, just the drawCube() and divideCube() functions. Just posted whole code if anyone needs it.

I also posted the correct code for a sierpinski gasket. At the bottom of this post for reference.

this is the menger sponge code:


#include "SpongeOSX.h"
#include <stdlib.h>
#include <GLUT/Glut.h>
#include <stdio.h>
GLfloat vertices[][3]={{0.0,0.0,0.0},{1.0,0.0,0.0},
	{1.0,1.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},
	{1.0,0.0,1.0},{1.0,1.0,1.0},{0.0,1.0,1.0}};


static int unit = 1; //cube size


//GLfloat colors[][3]={{0.737255,0.560784,0.560784},{0.737255,0.560784,0.560784},{0.737255,0.560784,0.560784},{0.737255,0.560784,0.560784},{0.737255,0.560784,0.560784},
//{0.737255,0.560784,0.560784},{0.737255,0.560784,0.560784},{0.737255,0.560784,0.560784}};
GLfloat colors[][3]={{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},{0.0,0.0,0.0},{0.0,0.0,1.0},
	{1.0,0.0,1.0},{1.0,1.0,1.0},{0.0,1.0,1.0}};//make last black
float theta=0;

void polygon(GLfloat *a, GLfloat *b,GLfloat *c, GLfloat *d)
{
	
	glColor3fv(colors[0]);
	glVertex3fv(a);
	glColor3fv(colors[1]);
	glVertex3fv(b);
	glColor3fv(colors[2]);
	glVertex3fv(c);
	glColor3fv(colors[3]);
	glVertex3fv(d);
	
	
}

void drawCube(GLfloat *a,GLfloat *b,GLfloat *c,GLfloat *d, GLfloat *e,GLfloat *f, GLfloat *g, GLfloat *h)
{

	polygon(a,d,c,b);
	polygon(c,d,h,g);
	polygon(a,e,h,d);
	polygon(b,c,g,f);
	polygon(e,f,g,h);
	polygon(a,b,f,e);
}
void divideCube(GLfloat *a,GLfloat *b, GLfloat *c, GLfloat *d, GLfloat *e, GLfloat *f, GLfloat *g, GLfloat *h, int n)
{
	GLfloat cubePoints[64][3];
	int i,j;
	int stride = 16;
	
	/*
	 
	 order i did the first face in 
	 |------->--|
	 |			|
  ^  ^			|
  |  |(0,0)	    V
	 |--------<--
	 */
	if(n > 0)
	{
		//bottom left corner, point 1
		for(i=0; i < 3 ;i++)
			cubePoints[0][i]=a[i];
		//front left
		//row, column -> 0,0 = a, point 2
		for(i = 0; i < 3; i++)// row 2 column 0
			cubePoints[1][i]=(a[i]+d[i])/3;
		
		for(i = 0; i < 3; i++)//row  1 column 0, point 3
			cubePoints[2][i]=2*(a[i]+d[i])/3;
		//front top left, 
		for(i=0; i < 3; i++)//row 0 col 0
			cubePoints[3][i]=d[i];
		//front top
		for(i = 0; i < 3; i++)//row 0, column 1, point 4
		{
			//if i !=1 because you dont want to change the y coordinate
			if( i!=1)
				cubePoints[4][i]=(c[i]+d[i])/3;
			else cubePoints[4][i]=d[i];
		}
		for(i = 0; i < 3; i++)//row 0, column 2, point 5
		{
			if(i!=1)
				cubePoints[5][i]=2*(c[i]+d[i])/3;
			else cubePoints[5][i]=d[i];
		}
		//front right top
		for(i=0; i < 3; i++)//row 0, col 3, point 6
			cubePoints[6][i]=c[i];
		
		
		for(i = 0; i < 3; i++)//row 2, column 3, point 7, was point 8
		{
			if(i!=0)
				cubePoints[7][i]=2*(b[i]+c[i])/3;
			else cubePoints[7][i]=c[i];
		}
		for(i = 0; i < 3; i++)//row 1, column 3, point 8, was point 7
		{
			if(i!=0)
				cubePoints[8][i]=(b[i]+c[i])/3;
			else cubePoints[8][i]=c[i];
		}
		//front bottom right, point 9, row 3 column 3
		for(i=0; i < 3; i++)
			cubePoints[9][i]=b[i];
		
		for(i = 0; i < 3; i++)//row 3, column 2
			cubePoints[10][i]=2*(a[i]+b[i])/3;
		for(i = 0; i < 3; i++)//row 3, column 1
			cubePoints[11][i]=(a[i]+b[i])/3;
		
	
	
		for(i = 0; i < 3; i++)//row 2, column 1, point 12
		{
			//printf("cubepoints 11[i]: %f, cubepoints 4[i]: %f
", cubePoints[11][i], cubePoints[4][i]);  
			if(i!=0)
				cubePoints[12][i]=(cubePoints[11][i]+cubePoints[4][i])/3;
			else cubePoints[12][i]=cubePoints[11][i];
		}
		for(i = 0; i < 3; i++)//row 1, column 1, point 13
		{
			if(i!=0)
				cubePoints[13][i]=2*(cubePoints[11][i]+cubePoints[4][i])/3;
			else cubePoints[13][i]=cubePoints[11][i];
		}
	
		for(i=0; i < 3; i++)//row 2, column 2
		{
			if(i!=0)
				cubePoints[14][i]=(cubePoints[10][i]+cubePoints[5][i])/3;
			else cubePoints[14][i]=cubePoints[10][i];
		}
		for(i=0; i < 3; i++)//row 1 column 2
		{
			if(i!=0)
				cubePoints[15][i]=2*(cubePoints[10][i]+cubePoints[5][i])/3;
			else cubePoints[15][i]=cubePoints[10][i];
		}
		
		for(i =0;i < 16;i++)
		{
			printf("point %d
",i);
			int j;
			for(j=0; j < 3; j++)
			{
				printf("%f
",cubePoints[i][j]);
			}
			printf("
");
		}
		
	
		for(i=16;i<32;i++)
			for(j = 0; j < 3; j++)
			{
				if(j<2)
					cubePoints[i][j]=cubePoints[i-16][j];
				else cubePoints[i][j]=unit/3;
			}
		for(i=32;i<48;i++)
			for(j = 0; j < 3; j++)
			{
				if(j<2)
					cubePoints[i][j]=cubePoints[i-32][j];
				else cubePoints[i][j]=2*(unit/3);
			}
		for(i=48;i<64;i++)
			for(j = 0; j < 3; j++)
			{
				if(j<2)
					cubePoints[i][j]=cubePoints[i-48][j];
				else cubePoints[i][j]=unit;
			}
		unit/=3;
		/*********Front of the cube************/
		//create 27 cubes by subdivision
		//order: bottom left front->bottom right front->top right front -> top left front
		//front 8 cubes
		//bottom, left, front cube ******** left column of front
		divideCube(cubePoints[0],cubePoints[11],cubePoints[12],cubePoints[1],cubePoints[stride],cubePoints[stride+11],
				   cubePoints[stride+12],cubePoints[stride+1],n-1);
		divideCube(cubePoints[1],cubePoints[12],cubePoints[13],cubePoints[2],cubePoints[stride+1],cubePoints[stride+12],
				   cubePoints[stride+13],cubePoints[stride+2],n-1);//make sure 13 is correct
		divideCube(cubePoints[2],cubePoints[13],cubePoints[4],cubePoints[3],cubePoints[stride+2],cubePoints[stride+13],
				   cubePoints[stride+4],cubePoints[stride+3],n-1);
		//middle column of front of cube 
		divideCube(cubePoints[11],cubePoints[10],cubePoints[14],cubePoints[12],cubePoints[stride+11],cubePoints[stride+10],
				   cubePoints[stride+14],cubePoints[stride+12],n-1);
		divideCube(cubePoints[13],cubePoints[15],cubePoints[5],cubePoints[4],cubePoints[13+stride],cubePoints[15+stride],
				   cubePoints[5+stride],cubePoints[4+stride],n-1);
		//right column of front of cube
		divideCube(cubePoints[10],cubePoints[9],cubePoints[7],cubePoints[14],cubePoints[10+stride],cubePoints[9+stride],
				   cubePoints[7+stride],cubePoints[14+stride],n-1);
		divideCube(cubePoints[14],cubePoints[7],cubePoints[8],cubePoints[15],cubePoints[stride+14],cubePoints[stride+7],
				   cubePoints[stride+8],cubePoints[stride+15],n-1);
		divideCube(cubePoints[15],cubePoints[8],cubePoints[6],cubePoints[5],cubePoints[stride+15],cubePoints[stride+8],
				   cubePoints[stride+6],cubePoints[stride+5],n-1);
		
		//bottom and top middle left
		divideCube(cubePoints[stride],cubePoints[stride+11],cubePoints[stride+12],cubePoints[stride+1],cubePoints[2*stride],cubePoints[2*stride+11],
				   cubePoints[2*stride+12],cubePoints[2*stride+1],n-1);
		divideCube(cubePoints[2+stride],cubePoints[13+stride],cubePoints[4+stride],cubePoints[3+stride],cubePoints[2*stride+2],cubePoints[2*stride+13],
				   cubePoints[2*stride+4],cubePoints[2*stride+3],n-1);
		
		//bottom and top middle right 
		divideCube(cubePoints[10+stride],cubePoints[9+stride],cubePoints[7+stride],cubePoints[14+stride],cubePoints[10+stride*2],cubePoints[9+stride*2],
				   cubePoints[7+stride*2],cubePoints[14+stride*2],n-1);
		divideCube(cubePoints[15+stride],cubePoints[8+stride],cubePoints[6+stride],cubePoints[5+stride],cubePoints[stride*2+15],cubePoints[stride*2+8],
				   cubePoints[stride*2+6],cubePoints[stride*2+5],n-1);
		
		//left column of back of cube
		divideCube(cubePoints[0 + stride*2],cubePoints[11+stride*2],cubePoints[12+stride*2],cubePoints[1+stride*2],cubePoints[stride*3],cubePoints[stride*3+11],
				   cubePoints[stride*3+12],cubePoints[stride*3+1],n-1);
		divideCube(cubePoints[1+stride*2],cubePoints[12+stride*2],cubePoints[13+stride*2],cubePoints[2+stride*2],cubePoints[stride*3+1],cubePoints[stride*3+12],
				   cubePoints[stride*3+13],cubePoints[stride*3+2],n-1);//make sure 13 is correct
		divideCube(cubePoints[2+stride*2],cubePoints[13+stride*2],cubePoints[4+stride*2],cubePoints[3+stride*2],cubePoints[stride*3+2],cubePoints[stride*3+13],
				   cubePoints[stride*3+4],cubePoints[stride*3+3],n-1);
		//middle column of back of cube 
		divideCube(cubePoints[11+stride*2],cubePoints[10+stride*2],cubePoints[14+stride*2],cubePoints[12+stride*2],cubePoints[stride*3+11],cubePoints[stride*3+10],
				   cubePoints[stride*3+14],cubePoints[stride*3+12],n-1);
		divideCube(cubePoints[13+stride*2],cubePoints[15+stride*2],cubePoints[5+stride*2],cubePoints[4+stride*2],cubePoints[13+stride*3],cubePoints[15+stride*3],
				   cubePoints[5+stride*3],cubePoints[4+stride*3],n-1);
		//right column of back of cube
		divideCube(cubePoints[10+stride*2],cubePoints[9+stride*2],cubePoints[7+stride*2],cubePoints[14+stride*2],cubePoints[10+stride*3],cubePoints[9+stride*3],
				   cubePoints[7+stride*3],cubePoints[14+stride*3],n-1);
		divideCube(cubePoints[14+stride*2],cubePoints[7+stride*2],cubePoints[8+stride*2],cubePoints[15+stride*2],cubePoints[stride*3+14],cubePoints[stride*3+7],
				   cubePoints[stride*3+8],cubePoints[stride*3+15],n-1);
		divideCube(cubePoints[15+stride*2],cubePoints[8+stride*2],cubePoints[6+stride*2],cubePoints[5+stride*2],cubePoints[stride*3+15],cubePoints[stride*3+8],
				   cubePoints[stride*3+6],cubePoints[stride*3+5],n-1);
	}
	{
		drawCube(a,b,c,d,e,f,g,h);
	}
	
	
}

void colorcube()
{
	
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	
	glPushMatrix();
	glRotatef(theta, 1,1,1);
	glBegin(GL_POLYGON);
	//drawCube();
	divideCube(vertices[0],vertices[1],vertices[2],vertices[3],vertices[4],vertices[5],vertices[6],vertices[7],1);
	glPopMatrix();
	glEnd();

	glFlush();
	glutPostRedisplay();//refresh the screen
	
}

void myReshape(int w, int h)
{
	glViewport(0,0,w,h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	if(w<=h)
		glOrtho(-1.0,2.0,-1.0*(GLfloat) h / (GLfloat) w,
				2.0*(GLfloat) h / (GLfloat) w, -10.0, 10.0);
	else
		glOrtho(-1.0*(GLfloat) w/(GLfloat) h, 2.0*(GLfloat) w / (GLfloat) h,-1.0,2.0,-10.0,10.0);
	glMatrixMode(GL_MODELVIEW);
	glutPostRedisplay();
}
void init()
{
	glClearColor (0.0, 0.0, 0.0, 1.0);
	
	glColor3f(1.0, 0.0, 1.0); 
	
	glMatrixMode (GL_PROJECTION);    
	glEnable(GL_DEPTH_TEST);
	glLoadIdentity ();  
	glOrtho(-2.0, 2.0, -2.0, 2.0, -2.0, 2.0);  
}
void idle()
{
	theta+=.00005;
	if(theta>360)theta=0;
}
int main(int argc, char**argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
    glutInitWindowSize(500,500);    	
	glutInitWindowPosition(0,0); 
	
	glutCreateWindow("Cube");
	
	init();
	glutReshapeFunc(myReshape);
	glutDisplayFunc(colorcube);
	glutIdleFunc(idle);
	glutMainLoop();
	return 0;
}

here is the example that i am following to create the cube, it is a tetrahedron, the sierpinski gasket


/* recursive subdivision of a tetrahedron to form 3D Sierpinski gasket */
/* number of recursive steps given on command line */

#include <stdlib.h>
//#include <glut.h>  /* for windows */
#include <GL/glut.h>

/* initial tetrahedron */

GLfloat v[4][3]={{0.0, 0.0, 1.0}, {0.0, 0.942809, -0.33333},
      {-0.816497, -0.471405, -0.333333}, {0.816497, -0.471405, -0.333333}};

GLfloat colors[4][3] = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0},
                        {0.0, 0.0, 1.0}, {0.0, 0.0, 0.0}};

int n;

void triangle(GLfloat *va, GLfloat *vb, GLfloat *vc) {
  glVertex3fv(va);
  glVertex3fv(vb);
  glVertex3fv(vc);
}


void tetra(GLfloat *a, GLfloat *b, GLfloat *c, GLfloat *d) {
  glColor3fv(colors[0]);
  triangle(a, b, c);
  glColor3fv(colors[1]);
  triangle(a, c, d);
  glColor3fv(colors[2]);
  triangle(a, d, b);
  glColor3fv(colors[3]);
  triangle(b, d, c);
}


void divide_tetra(GLfloat *a, GLfloat *b, GLfloat *c, GLfloat *d, int m) {
    GLfloat mid[6][3];
    int j;
    if( m > 0 ) {
      // compute six midpoints...
      for(j=0; j<3; j++) mid[0][j]=(a[j]+b[j])/2;
      for(j=0; j<3; j++) mid[1][j]=(a[j]+c[j])/2;
      for(j=0; j<3; j++) mid[2][j]=(a[j]+d[j])/2;
      for(j=0; j<3; j++) mid[3][j]=(b[j]+c[j])/2;
      for(j=0; j<3; j++) mid[4][j]=(c[j]+d[j])/2;
      for(j=0; j<3; j++) mid[5][j]=(b[j]+d[j])/2;
      
      // create 4 tetrahedrons by subdivision...
      divide_tetra(a, mid[0], mid[1], mid[2], m-1);
      divide_tetra(mid[0], b, mid[3], mid[5], m-1);
      divide_tetra(mid[1], mid[3], c, mid[4], m-1);
      divide_tetra(mid[2], mid[5], mid[4], d, m-1);

    }
    else {
      // draw tetrahedron at end of recursion...
      tetra(a,b,c,d);
    } 
}


void myDisplay() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBegin(GL_TRIANGLES);
    divide_tetra(v[0], v[1], v[2], v[3], n);
    glEnd();
    glFlush();
}


void myReshape(int w, int h) {
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (w <= h)
        glOrtho(-2.0, 2.0, -2.0 * (GLfloat) h / (GLfloat) w,
            2.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0);
    else
        glOrtho(-2.0 * (GLfloat) w / (GLfloat) h,
            2.0 * (GLfloat) w / (GLfloat) h, -2.0, 2.0, -10.0, 10.0);
    glMatrixMode(GL_MODELVIEW);
    glutPostRedisplay();
}



void myInit() {
  // Clear color...
  glClearColor(0.0, 0.0, 0.0, 1.0);

  // Fill color...
  glColor3f(1.0, 0.0, 0.0);

  // Enable double buffering...
  glEnable(GL_DEPTH_TEST);

  // Standard orthogonal view -- first refer to the projection
  // matrix...
  glMatrixMode(GL_PROJECTION);
  // Load it to be an identity matrix...
  glLoadIdentity();
  // Set desired viewing/clipping rectangle...
  glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
  glMatrixMode(GL_MODELVIEW);
}




int main(int argc, char **argv) {
  /* enter number of subdivision steps here */
  if (argc > 1) {
    n=atoi(argv[1]);
  }
  else n = 3;

  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(500, 500);

  glutCreateWindow("3D Gasket");
  glutReshapeFunc(myReshape);
  glutDisplayFunc(myDisplay);
   
  myInit();
  glutMainLoop();
}