Sphere creation

Started by
44 comments, last by Zakwayda 14 years, 4 months ago
This is a topic that I have been trying to learn for a long time and have been trying to learn on this forum for a few months. Basically I know the bare basic, how to get X, Y, Z and the texture coordinates U/Z but not how to build the indicies. X, Y, Z Algorithm --------- R = 1.0 For J = 0, PI For I = 0, 2*PI X = R * Cos(I) * Sin(J) Y = R * Sin(I) * Sin(J) Z = R * Cos(J) PLOT(X, Y, Z) U, V Algorithm ----------- U = x / (sqrt((x * x) + (y * y) + (z * z))) V = y / (sqrt((x * x) + (y * y) + (z * z))) Could someone please explain to me how to build the indicies?
Advertisement
/*=============R_CreateSphere=============*/static void R_CreateSphere (lightShape_t *shape, float radius, int slices, int stacks) {	float		sinI[MAX_SHAPE_SEGMENTS], cosI[MAX_SHAPE_SEGMENTS];	float		sinJ[MAX_SHAPE_SEGMENTS], cosJ[MAX_SHAPE_SEGMENTS];	drawVert_t	*vertex;	index_t		*index;	index_t		rowA, rowB;	int			i, j;	// validate parameters	radius = max(radius, 0.f);	slices = Q_clamp(slices, 2, MAX_SHAPE_SEGMENTS);	stacks = Q_clamp(stacks, 2, MAX_SHAPE_SEGMENTS);	// setup the shape	shape->numIndices = 6 * (stacks - 1) * slices;	shape->indexBuffer = R_VB_Alloc(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, shape->numIndices * sizeof(index_t));	shape->numVertices = (stacks - 1) * slices + 2;	shape->vertexBuffer = R_VB_Alloc(GL_ARRAY_BUFFER, GL_STATIC_DRAW, shape->numVertices * sizeof(drawVert_t));	// create sin/cos cache	for (i = 0; i < slices; i++)		Q_sincos(2.f * Q_PI * (float)i / (float)slices, &sinI, &cosI);	for (j = 0; j < stacks; j++)		Q_sincos(Q_PI * (float)j / (float)stacks, &sinJ[j], &cosJ[j]);	// generate vertices	vertex = R_VB_Map(shape->vertexBuffer, GL_WRITE_ONLY);	// positive Z pole	vertex->xyz[0] = 0.f;	vertex->xyz[1] = 0.f;	vertex->xyz[2] = radius;	vertex++;	// Stacks counter represents range (0; 180) degrees of rotation around X axis.	// Start from 1 because we've already set positive Z pole.	for (j = 1; j < stacks; j++) {		// sin() range is (0; 1), this is the fraction of circle (see below) distance to use//		stackDist = sinJ[j];		// cos() range is (1; -1), this is the height above XY plane//		stackHeight = cosJ[j];		// Slices counter represents range (0; 360) degrees of rotation around Z axis, i.e. we draw circle lying on XY plane.	        for (i = 0; i < slices; i++) {			// Circle point position.//			circleX = sinI;//			circleY = cosI;			// Now smack them together.			// Unit position in sphere space and also the normal vector.			vertex->xyz[0] = radius * sinI * sinJ[j];			vertex->xyz[1] = radius * cosI * sinJ[j];			vertex->xyz[2] = radius * cosJ;			vertex++;		}	}	// negative Z pole	vertex->xyz[0] = 0.f;	vertex->xyz[1] = 0.f;	vertex->xyz[2] = -radius;	vertex++;	R_VB_Unmap(shape->vertexBuffer);	// generate indices	index = R_VB_Map(shape->indexBuffer, GL_WRITE_ONLY);	// positive Z cap	rowA = 0;	rowB = 1;	for(i = 0; i < slices - 1; i++) {		index[0] = rowA;		index[1] = rowB + i + 1;		index[2] = rowB + i;		index += 3;	}	index[0] = rowA;	index[1] = rowB;	index[2] = rowB + i;	index += 3;	// interior stacks	for (j = 1; j < stacks - 1; j++) {		rowA = 1 + (j - 1) * slices;		rowB = rowA + slices;		for (i = 0; i < slices - 1; i++) {			index[0] = rowA + i;			index[1] = rowA + i + 1;			index[2] = rowB + i;			index += 3;			index[0] = rowA + i + 1;			index[1] = rowB + i + 1;			index[2] = rowB + i;			index += 3;        	}		index[0] = rowA + i;		index[1] = rowA;		index[2] = rowB + i;		index += 3;		index[0] = rowA;		index[1] = rowB;		index[2] = rowB + i;		index += 3;	}	// negative Z cap	rowA = 1 + (stacks - 2) * slices;	rowB = rowA + slices;	for (i = 0; i < slices - 1; i++) {		index[0] = rowA + i;		index[1] = rowA + i + 1;		index[2] = rowB;		index += 3;	}	index[0] = rowA + i;	index[1] = rowA;	index[2] = rowB;	R_VB_Unmap(shape->indexBuffer);}
Quote:Original post by KRIGSSVIN
/*=============R_CreateSphere=============*/static void R_CreateSphere (lightShape_t *shape, float radius, int slices, int stacks) {	float		sinI[MAX_SHAPE_SEGMENTS], cosI[MAX_SHAPE_SEGMENTS];	float		sinJ[MAX_SHAPE_SEGMENTS], cosJ[MAX_SHAPE_SEGMENTS];	drawVert_t	*vertex;	index_t		*index;	index_t		rowA, rowB;	int			i, j;	// validate parameters	radius = max(radius, 0.f);	slices = Q_clamp(slices, 2, MAX_SHAPE_SEGMENTS);	stacks = Q_clamp(stacks, 2, MAX_SHAPE_SEGMENTS);	// setup the shape	shape->numIndices = 6 * (stacks - 1) * slices;	shape->indexBuffer = R_VB_Alloc(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, shape->numIndices * sizeof(index_t));	shape->numVertices = (stacks - 1) * slices + 2;	shape->vertexBuffer = R_VB_Alloc(GL_ARRAY_BUFFER, GL_STATIC_DRAW, shape->numVertices * sizeof(drawVert_t));	// create sin/cos cache	for (i = 0; i < slices; i++)		Q_sincos(2.f * Q_PI * (float)i / (float)slices, &sinI, &cosI);	for (j = 0; j < stacks; j++)		Q_sincos(Q_PI * (float)j / (float)stacks, &sinJ[j], &cosJ[j]);	// generate vertices	vertex = R_VB_Map(shape->vertexBuffer, GL_WRITE_ONLY);	// positive Z pole	vertex->xyz[0] = 0.f;	vertex->xyz[1] = 0.f;	vertex->xyz[2] = radius;	vertex++;	// Stacks counter represents range (0; 180) degrees of rotation around X axis.	// Start from 1 because we've already set positive Z pole.	for (j = 1; j < stacks; j++) {		// sin() range is (0; 1), this is the fraction of circle (see below) distance to use//		stackDist = sinJ[j];		// cos() range is (1; -1), this is the height above XY plane//		stackHeight = cosJ[j];		// Slices counter represents range (0; 360) degrees of rotation around Z axis, i.e. we draw circle lying on XY plane.	        for (i = 0; i < slices; i++) {			// Circle point position.//			circleX = sinI;//			circleY = cosI;			// Now smack them together.			// Unit position in sphere space and also the normal vector.			vertex->xyz[0] = radius * sinI * sinJ[j];			vertex->xyz[1] = radius * cosI * sinJ[j];			vertex->xyz[2] = radius * cosJ;			vertex++;		}	}	// negative Z pole	vertex->xyz[0] = 0.f;	vertex->xyz[1] = 0.f;	vertex->xyz[2] = -radius;	vertex++;	R_VB_Unmap(shape->vertexBuffer);	// generate indices	index = R_VB_Map(shape->indexBuffer, GL_WRITE_ONLY);	// positive Z cap	rowA = 0;	rowB = 1;	for(i = 0; i < slices - 1; i++) {		index[0] = rowA;		index[1] = rowB + i + 1;		index[2] = rowB + i;		index += 3;	}	index[0] = rowA;	index[1] = rowB;	index[2] = rowB + i;	index += 3;	// interior stacks	for (j = 1; j < stacks - 1; j++) {		rowA = 1 + (j - 1) * slices;		rowB = rowA + slices;		for (i = 0; i < slices - 1; i++) {			index[0] = rowA + i;			index[1] = rowA + i + 1;			index[2] = rowB + i;			index += 3;			index[0] = rowA + i + 1;			index[1] = rowB + i + 1;			index[2] = rowB + i;			index += 3;        	}		index[0] = rowA + i;		index[1] = rowA;		index[2] = rowB + i;		index += 3;		index[0] = rowA;		index[1] = rowB;		index[2] = rowB + i;		index += 3;	}	// negative Z cap	rowA = 1 + (stacks - 2) * slices;	rowB = rowA + slices;	for (i = 0; i < slices - 1; i++) {		index[0] = rowA + i;		index[1] = rowA + i + 1;		index[2] = rowB;		index += 3;	}	index[0] = rowA + i;	index[1] = rowA;	index[2] = rowB;	R_VB_Unmap(shape->indexBuffer);}


What in the world is Q_clamp ?
What do you mean with the indices, are you trying to build a vertex and index buffer for the sphere?
Your algorithm seems to be creating multiple circles on top of each other, to make up the surface of the sphere. For drawing that you would create quads in between the different layers. So the first quad in each layer would be vertex number 0 and 1 in the first layer, coupled with vertex number 0 and 1 in the layer above. Or if you have a single vertex at the end-points, the first triangles would be (0, 1, 2), (0, 2, 3) etc.
Q_clamp() is a macro that just clamps value to [min; max] interval.

This is modified code from DXSDK, it builds triangle indices.
Quote:Original post by Erik Rufelt
What do you mean with the indices, are you trying to build a vertex and index buffer for the sphere?
Your algorithm seems to be creating multiple circles on top of each other, to make up the surface of the sphere. For drawing that you would create quads in between the different layers. So the first quad in each layer would be vertex number 0 and 1 in the first layer, coupled with vertex number 0 and 1 in the layer above. Or if you have a single vertex at the end-points, the first triangles would be (0, 1, 2), (0, 2, 3) etc.


I am trying to build an index buffer for the sphere, I know how to build the vertex buffer.

I am not sure what you mean by your explanation though, do you have an example?
Quote:Original post by KRIGSSVIN
/*=============R_CreateSphere=============*/static void R_CreateSphere (lightShape_t *shape, float radius, int slices, int stacks) {	float		sinI[MAX_SHAPE_SEGMENTS], cosI[MAX_SHAPE_SEGMENTS];	float		sinJ[MAX_SHAPE_SEGMENTS], cosJ[MAX_SHAPE_SEGMENTS];	drawVert_t	*vertex;	index_t		*index;	index_t		rowA, rowB;	int			i, j;	// validate parameters	radius = max(radius, 0.f);	slices = Q_clamp(slices, 2, MAX_SHAPE_SEGMENTS);	stacks = Q_clamp(stacks, 2, MAX_SHAPE_SEGMENTS);	// setup the shape	shape->numIndices = 6 * (stacks - 1) * slices;	shape->indexBuffer = R_VB_Alloc(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, shape->numIndices * sizeof(index_t));	shape->numVertices = (stacks - 1) * slices + 2;	shape->vertexBuffer = R_VB_Alloc(GL_ARRAY_BUFFER, GL_STATIC_DRAW, shape->numVertices * sizeof(drawVert_t));	// create sin/cos cache	for (i = 0; i < slices; i++)		Q_sincos(2.f * Q_PI * (float)i / (float)slices, &sinI, &cosI);	for (j = 0; j < stacks; j++)		Q_sincos(Q_PI * (float)j / (float)stacks, &sinJ[j], &cosJ[j]);	// generate vertices	vertex = R_VB_Map(shape->vertexBuffer, GL_WRITE_ONLY);	// positive Z pole	vertex->xyz[0] = 0.f;	vertex->xyz[1] = 0.f;	vertex->xyz[2] = radius;	vertex++;	// Stacks counter represents range (0; 180) degrees of rotation around X axis.	// Start from 1 because we've already set positive Z pole.	for (j = 1; j < stacks; j++) {		// sin() range is (0; 1), this is the fraction of circle (see below) distance to use//		stackDist = sinJ[j];		// cos() range is (1; -1), this is the height above XY plane//		stackHeight = cosJ[j];		// Slices counter represents range (0; 360) degrees of rotation around Z axis, i.e. we draw circle lying on XY plane.	        for (i = 0; i < slices; i++) {			// Circle point position.//			circleX = sinI;//			circleY = cosI;			// Now smack them together.			// Unit position in sphere space and also the normal vector.			vertex->xyz[0] = radius * sinI * sinJ[j];			vertex->xyz[1] = radius * cosI * sinJ[j];			vertex->xyz[2] = radius * cosJ;			vertex++;		}	}	// negative Z pole	vertex->xyz[0] = 0.f;	vertex->xyz[1] = 0.f;	vertex->xyz[2] = -radius;	vertex++;	R_VB_Unmap(shape->vertexBuffer);	// generate indices	index = R_VB_Map(shape->indexBuffer, GL_WRITE_ONLY);	// positive Z cap	rowA = 0;	rowB = 1;	for(i = 0; i < slices - 1; i++) {		index[0] = rowA;		index[1] = rowB + i + 1;		index[2] = rowB + i;		index += 3;	}	index[0] = rowA;	index[1] = rowB;	index[2] = rowB + i;	index += 3;	// interior stacks	for (j = 1; j < stacks - 1; j++) {		rowA = 1 + (j - 1) * slices;		rowB = rowA + slices;		for (i = 0; i < slices - 1; i++) {			index[0] = rowA + i;			index[1] = rowA + i + 1;			index[2] = rowB + i;			index += 3;			index[0] = rowA + i + 1;			index[1] = rowB + i + 1;			index[2] = rowB + i;			index += 3;        	}		index[0] = rowA + i;		index[1] = rowA;		index[2] = rowB + i;		index += 3;		index[0] = rowA;		index[1] = rowB;		index[2] = rowB + i;		index += 3;	}	// negative Z cap	rowA = 1 + (stacks - 2) * slices;	rowB = rowA + slices;	for (i = 0; i < slices - 1; i++) {		index[0] = rowA + i;		index[1] = rowA + i + 1;		index[2] = rowB;		index += 3;	}	index[0] = rowA + i;	index[1] = rowA;	index[2] = rowB;	R_VB_Unmap(shape->indexBuffer);}


Not only does most of this code make no sense to me, I do not even see why it would be done this way, or how it works.

First of all, the "i" variable is modified in the vertex setting, then later it is used for the index positioning. Shouldn't that be reset to 0 some where in between? Or maybe one? Something other then the large number it is about to be where it can never make a variable. Also, it will just get larger every time in the for loop, there is no way this is working C++ code unless you cut some of it out.

Why bother doing this? I mean really, why not just set cos/sin in the vertex loop instead of having a random unnecessary loops?
	// create sin/cos cache	for (i = 0; i &lt; slices; i++)		Q_sincos(2.f * Q_PI * (float)i / (float)slices, &sinI, &cosI);	for (j = 0; j &lt; stacks; j++)		Q_sincos(Q_PI * (float)j / (float)stacks, &sinJ[j], &cosJ[j]);


Is this a triangle strip, fan, line strip, what is it?

Here is my invalid attempt of trying to fix this code to work for direct x, if you have any idea how it can be fixed please let me know.

	m_unTotalVerticies = (unStacks - 1) * unSlices + 2;	m_unTotalIndicies = 6 * (unStacks - 1) * unSlices;	m_unTotalTriangles = 0;	CreateVertexArray(vtVertexType, m_pShapeVerticies, m_unTotalVerticies);	m_pIndices = new WORD[m_unTotalIndicies];	unsigned int unVertexPlacement = 0;	SetVertexLocation(0.0f, 0.0f, fRadius, m_pShapeVerticies, unVertexPlacement, vtVertexType);	unVertexPlacement++;	for (int j = 1; j < unStacks; j++) 	{		for (int i = 0; i < unSlices; i++) 		{			float ranI = cos(2.0f * PI *(float)i /(float)unSlices);			float ranJ = sin(PI * (float)j / (float)unStacks);			float x = fRadius * ranI * ranJ;			float y = fRadius * ranI * ranJ;			float z = fRadius * ranJ;			SetVertexLocation(x, y, z, m_pShapeVerticies, unVertexPlacement, vtVertexType);			unVertexPlacement++;		}	}	SetVertexLocation(0.0f, 0.0f, -fRadius, m_pShapeVerticies, unVertexPlacement, vtVertexType);	unVertexPlacement++;	int i = 0;	int rowA = 0;	int rowB = 1;	int unIndexPlacement = 0;	m_pIndices[unIndexPlacement] = rowA;	m_pIndices[unIndexPlacement + 1] = rowB;	m_pIndices[unIndexPlacement + 2] = rowB + i;	unIndexPlacement += 3;	m_unTotalTriangles++;	for (int j = 1; j < unStacks - 1; j++)	{		rowA = 1 + (j - 1) * unSlices;		rowB = rowA + unSlices;		for (i = 0; i < unSlices - 1; i++)		{			m_pIndices[unIndexPlacement] = rowA + i;			m_pIndices[unIndexPlacement + 1] = rowA + i + 1;			m_pIndices[unIndexPlacement + 2] = rowB + i;			unIndexPlacement += 3;			m_unTotalTriangles++;			m_pIndices[unIndexPlacement] = rowA + i + 1;			m_pIndices[unIndexPlacement + 1] = rowB + i + 1;			m_pIndices[unIndexPlacement + 2] = rowB + i;			unIndexPlacement += 3;			m_unTotalTriangles++;		}		m_pIndices[unIndexPlacement] = rowA + i;		m_pIndices[unIndexPlacement + 1] = rowA;		m_pIndices[unIndexPlacement + 2] = rowB + i;		unIndexPlacement += 3;		m_unTotalTriangles++;		m_pIndices[unIndexPlacement] = rowA;		m_pIndices[unIndexPlacement + 1] = rowB;		m_pIndices[unIndexPlacement + 2] = rowB + i;		unIndexPlacement += 3;		m_unTotalTriangles++;	}	// negative Z cap	rowA = 1 + (unStacks - 2) * unSlices;	rowB = rowA + unSlices;	for (i = 0; i < unSlices - 1; i++)	{		m_pIndices[unIndexPlacement] = rowA + i;		m_pIndices[unIndexPlacement + 1] = rowA + i + 1;		m_pIndices[unIndexPlacement + 2] = rowB;		unIndexPlacement += 3;		m_unTotalTriangles++;	}	m_pIndices[unIndexPlacement] = rowA + i;	m_pIndices[unIndexPlacement + 1] = rowA;	m_pIndices[unIndexPlacement + 2] = rowB;	m_unTotalTriangles++;


Or if anyone else has an idea on how to dynamically build a sphere, I would appreciate to hear other ways too.
Heres mine, if it helps you at all :)
Its made out of quads tho, youll have to convert it to
triangles (its not that hard)

the model structure is called "VM" and it contains .v for verts
and .p for polys.
Youll just have to chop all that out and change the "add_verts" and "add_polys"
line because thats for dynamically inserting verts into the VM structure.


void spawn_sphere(VM& vm, VEC pos, VEC sca){ float scal=1.0f; VEC hsca; hsca.x=sca.x/2; hsca.y=sca.y/2; hsca.z=sca.z/2; int vertices,triangles; int primitive_detail_y=sca.y;	int primitive_detail_x=sca.x; vertices=(primitive_detail_y-2)*primitive_detail_x+2; triangles=primitive_detail_x+((primitive_detail_y-3)*primitive_detail_x); int vpos=vm.vs; int ppos=vm.ps; add_verts(vm,vertices); add_polys(vm,triangles);  int i; int j; float xangle=0; float yangle=0; float xangle_skip=3.14f/(primitive_detail_y-1); float yangle_skip=6.28f/primitive_detail_x; VEC vert; vm.v[vpos+0].pos=(VEC(0,-hsca.y,0)*scal+pos); vm.v[vpos+0].nor=VEC(0,-1,0); vm.v[vpos+1].pos=(VEC(0,hsca.y,0)*scal+pos); vm.v[vpos+1].nor=VEC(0,1,0); xangle=xangle_skip; for(i=1;i<primitive_detail_y-1;i++) {  yangle=0;  for(j=0;j<primitive_detail_x;j++)  {   vert.x=cosf(yangle)*sinf(xangle)*hsca.x;   vert.z=sinf(yangle)*sinf(xangle)*hsca.z;   vert.y=cosf(xangle)*hsca.y;   vm.v[vpos+j+(i-1)*(primitive_detail_x)+2].pos=(vert*scal+pos);   D3DXVec3Normalize(&vm.v[vpos+j+(i-1)*(primitive_detail_x)+2].nor,&(vm.v[vpos+j+(i-1)*(primitive_detail_x)+2].pos-pos));   yangle+=yangle_skip;  }  xangle+=xangle_skip; } int count=0; //top star for(i=0;i<primitive_detail_x;i+=2) {  if(i==primitive_detail_x-2)  {      vm.p[ppos+count].i[0]=2;   vm.p[ppos+count].i[1]=(i+2)+1;		 vm.p[ppos+count].i[2]=(i+2);   vm.p[ppos+count].i[3]=1;  }  else  {   vm.p[ppos+count].i[0]=(i+2)+2;   vm.p[ppos+count].i[1]=(i+2)+1;   vm.p[ppos+count].i[2]=(i+2);   vm.p[ppos+count].i[3]=1;		}  count++;	} //bottom star for(i=0;i<primitive_detail_x;i+=2) {  if(i==primitive_detail_x-2)  {   vm.p[ppos+count].i[0]=0;   vm.p[ppos+count].i[1]=(i+2)+(primitive_detail_y-3)*(primitive_detail_x);   vm.p[ppos+count].i[2]=(i+2)+1+(primitive_detail_y-3)*(primitive_detail_x);   vm.p[ppos+count].i[3]=2+(primitive_detail_y-3)*(primitive_detail_x);  }  else  {   vm.p[ppos+count].i[0]=0;   vm.p[ppos+count].i[1]=(i+2)+(primitive_detail_y-3)*(primitive_detail_x);   vm.p[ppos+count].i[2]=(i+2)+1+(primitive_detail_y-3)*(primitive_detail_x);   vm.p[ppos+count].i[3]=(i+2)+2+(primitive_detail_y-3)*(primitive_detail_x);  }  count++; }	//inner strips for(j=0;j<primitive_detail_y-3;j++) {  int top_add=j;  int bottom_add=(j+1);    for(i=0;i<primitive_detail_x;i++)  {   if(i==primitive_detail_x-1)   {    vm.p[ppos+count].i[0]=(i+2)+(top_add)*(primitive_detail_x);    vm.p[ppos+count].i[1]=(0+2)+(top_add)*(primitive_detail_x);    vm.p[ppos+count].i[2]=(0+2)+(bottom_add)*(primitive_detail_x);    vm.p[ppos+count].i[3]=(i+2)+(bottom_add)*(primitive_detail_x);   }   else   {				vm.p[ppos+count].i[0]=(i+2)+(top_add)*(primitive_detail_x);    vm.p[ppos+count].i[1]=(i+2)+1+(top_add)*(primitive_detail_x);    vm.p[ppos+count].i[2]=(i+2)+1+(bottom_add)*(primitive_detail_x);    vm.p[ppos+count].i[3]=(i+2)+(bottom_add)*(primitive_detail_x);   }   count++;  } }}
Quote:Original post by Hurp
Why bother doing this? I mean really, why not just set cos/sin in the vertex loop instead of having a random unnecessary loops?

     // create sin/cos cache     for (i = 0; i < slices; i++)          Q_sincos(2.f * Q_PI * (float)i / (float)slices, &sinI, &cosI);     for (j = 0; j < stacks; j++)          Q_sincos(Q_PI * (float)j / (float)stacks, &sinJ[j], &cosJ[j]);


Look through the code again.
     for (j = 1; j < stacks; j++) {             for (i = 0; i < slices; i++) {               // Now smack them together.               // Unit position in sphere space and also the normal vector.               vertex->xyz[0] = radius * sinI * sinJ[j];               vertex->xyz[1] = radius * cosI * sinJ[j];               vertex->xyz[2] = radius * cosJ;               vertex++;          }     }


Why would we want to calculate sin and cos for i and j many times? Let stacks be 32, slices 64, this way we get random unnecessary and redundant calculations: 31*64*2 sines. 31*64*2 cosines, I do not even talk about conversion to radians (too little CPU time actually). With caching all we need is 96 sines, 96 cosines. In my opinion it is important and one should try to optimize even non-critical code sections.

Quote:First of all, the "i" variable is modified in the vertex setting, then later it is used for the index positioning. Shouldn't that be reset to 0 some where in between? Or maybe one? Something other then the large number it is about to be where it can never make a variable. Also, it will just get larger every time in the for loop, ...

Ingenious! Question for a million: where did you see that? Please, show me, really.

Quote:Is this a triangle strip, fan, line strip, what is it?

It builds triangle indices, i.e. its just bunch of triangles, t0=(i0,i1,i2), t1=(i3,i4,i5), t2 =(i6,i7,i8) etc. Number of triangles will be (numIndices/3).

Of course this can be re-done to use strips.

Quote:...there is no way this is working C++ code...

First of all, it is pure C code, so all local variables are declared at the start of the function:
int			i, j;

Second of nothing, it is code that worked for my application and DXSDK for a long long time.

About your code and how it can be fixed:
Quote:...unless you cut some of it out.

So, right, you decided to do this to my code, congratulations:
Quote:
     for (int j = 1; j < unStacks; j++)      {          for (int i = 0; i < unSlices; i++)           {


Your mistake is here. Look at my code then look at yours. If nothing happens, I will explain it to you:
Quote:
               float ranI = cos(2.0f * PI *(float)i /(float)unSlices);               float ranJ = sin(PI * (float)j / (float)unStacks);               float x = fRadius * ranI * ranJ;               float y = fRadius * ranI * ranJ;               float z = fRadius * ranJ;               SetVertexLocation(x, y, z, m_pShapeVerticies, unVertexPlacement, vtVertexType);               unVertexPlacement++;          }     }


Please be more attentive.
Quote:
Why would we want to calculate sin and cos for i and j many times? Let stacks be 32, slices 64, this way we get random unnecessary and redundant calculations: 31*64*2 sines. 31*64*2 cosines, I do not even talk about conversion to radians (too little CPU time actually). With caching all we need is 96 sines, 96 cosines. In my opinion it is important and one should try to optimize even non-critical code sections.


I agree, code should be optimized where ever possible. As far as Q_sincos, is it a vector? Like can I just make an std::vector<float> and just put those values in there?

Quote:
Ingenious! Question for a million: where did you see that? Please, show me, really.


Quote:
// Slices counter represents range (0; 360) degrees of rotation around Z axis, i.e. we draw circle lying on XY plane.
for (i = 0; i < slices; i++) {


Is where i is modified. Then in the index setting, it is modified also with same type of loop so index[2] = rowB + i; is really index[2] = rowB + (slices -1). I just figured it looked off because i was never set back to zero or anything.

Quote:
Your mistake is here. Look at my code then look at yours. If nothing happens, I will explain it to you:


Well I know the mistake is that x == y. That is because I do not know how to make the cos/sin work the way you do. Can it be done with a vector (those cos/sin storing).

Quote:
It builds triangle indices, i.e. its just bunch of triangles, t0=(i0,i1,i2), t1=(i3,i4,i5), t2 =(i6,i7,i8) etc. Number of triangles will be (numIndices/3).


I mean when I go to render it will I need to do lpD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, or lpD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP or something else?

This topic is closed to new replies.

Advertisement