Jump to content
  • Advertisement
Sign in to follow this  
Hurp

Sphere creation

This topic is 3212 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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);
}

Share this post


Link to post
Share on other sites
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 ?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Q_clamp() is a macro that just clamps value to [min; max] interval.

This is modified code from DXSDK, it builds triangle indices.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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++;
}
}
}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!