• Advertisement
Sign in to follow this  

Rendering a sphere using Triangle strips

This topic is 4576 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

How do I go about rendering a sphere using triangle strips and sphereical coordinates? I understand the following code will draw a sphere but I want to use a triangle strip and put the coordinates into a vertice array. for (float i=0; i<=360; i+=360/detail_latitude) for (float j=-90; j<=90; j+=180/detail_longitude) { Vertex.x = cos(i)*Radius *cos(j); Vertex.y = sin(i)*Radius *cos(j); Vertex.z = sin(j)*radius; } I want to call the render sphere function: glBegin(GL_TRIANGLE_STRIP); for (int i=0; i < number_of_vertices; i++) glVertex3f(vertices.x, vertices.y, vertices.z); glEnd(); Any Suggestions?

Share this post


Link to post
Share on other sites
Advertisement
You need to wind the vertices into the correct order for a triangle strip. So you have to think of them as


1-----3
|\ |
| \ |
| \ |
| \ |
0-----2


and apply the texture coordinates accordingly

Share this post


Link to post
Share on other sites
I can draw a dome using this:


int n =0;
for (phi=0; phi <= 90 - delta_phi; phi += (int)delta_phi) {
for (theta=0; theta <= 360 - delta_theta; theta += (int)delta_theta) {
vertices[n].x = radius_x * sinf(phi*deg2rad) * cosf(deg2rad*theta);
vertices[n].y = radius_y * sinf(phi*deg2rad) * sinf(deg2rad*theta);
vertices[n].z = radius_z * cosf(phi*deg2rad);
n++;

vertices[n].x = radius_x * sinf((phi+delta_phi)*deg2rad) * cosf(theta*deg2rad);
vertices[n].y = radius_y * sinf((phi+delta_phi)*deg2rad) * sinf(theta*deg2rad);
vertices[n].z = radius_z * cosf((phi+delta_phi)*deg2rad);
n++;

vertices[n].x = radius_x * sinf(deg2rad*phi) * cosf(deg2rad*(theta+delta_theta));
vertices[n].y = radius_y * sinf(deg2rad*phi) * sinf(deg2rad*(theta+delta_theta));
vertices[n].z = radius_z * cosf(deg2rad*phi);
n++;

if (phi > -90 && phi < 90) {
vertices[n].x = radius_x * sinf((phi+delta_phi)*deg2rad) * cosf(deg2rad*(theta+delta_theta));
vertices[n].y = radius_y * sinf((phi+delta_phi)*deg2rad) * sinf(deg2rad*(theta+delta_theta));
vertices[n].z = radius_z * cosf((phi+delta_phi)*deg2rad);
n++;
}
}
}



however I am unsure how to convert this to a completesphere. I have tried:

for (phi=0; phi <= 180 - delta_phi; phi += (int)delta_phi)

but this draws two sphere's over each other. Both going the other direction...!

Thanks in advance, anyone?

Share this post


Link to post
Share on other sites
u wanna draw it with a single strip?
if so then u will need to use degenerate triangles (seacrh for what they are) ie
-start at bottom of sphere
-draw a strip around the sphere until u hit the first 2 vertices then repeat one of them 2 or 3 times (work it out on paper)
-move the tri strip up and repeat

Share this post


Link to post
Share on other sites
You don't have to use degenerate triangles to render a sphere in a single strip. You can also use the orange-peel method. Here's some old code to demonstrate (SpiralSphere - it's indexed, but it shouldn't be too difficult to adapt it to non-indexed):
#include <cmath>
#include <vector>
#include <gl/glut.h>

const float PI = 3.14159265358979323846f;

#pragma pack(1)
template <typename TYPE>
class GeometryVector
{

public:

GeometryVector(const TYPE x_ = TYPE(), const TYPE y_ = TYPE(), const TYPE z_ = TYPE());

const TYPE x;
const TYPE y;
const TYPE z;

};
#pragma pack()

template <typename TYPE>
GeometryVector<TYPE>::GeometryVector(const TYPE x_, const TYPE y_, const TYPE z_)
:
x(x_),
y(y_),
z(z_)
{
}

class StackedSphere
{

public:

StackedSphere(const float radius = 1.0f, const unsigned int stacks = 8, const unsigned int slices = 16);
void render() const;

private:

std::vector<GeometryVector<float> > geometryData_;
std::vector<unsigned short> indexData_;

};

StackedSphere::StackedSphere(const float radius, const unsigned int stacks, const unsigned int slices)
{
for (unsigned int stackNumber = 0; stackNumber <= stacks; ++stackNumber)
{
for (unsigned int sliceNumber = 0; sliceNumber < slices; ++sliceNumber)
{
float theta = stackNumber * PI / stacks;
float phi = sliceNumber * 2 * PI / slices;
float sinTheta = std::sin(theta);
float sinPhi = std::sin(phi);
float cosTheta = std::cos(theta);
float cosPhi = std::cos(phi);
geometryData_.push_back(GeometryVector<float>(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta));
}
}
for (unsigned int stackNumber = 0; stackNumber < stacks; ++stackNumber)
{
for (unsigned int sliceNumber = 0; sliceNumber <= slices; ++sliceNumber)
{
indexData_.push_back((stackNumber * slices) + (sliceNumber % slices));
indexData_.push_back(((stackNumber + 1) * slices) + (sliceNumber % slices));
}
}
}

void StackedSphere::render() const
{
glVertexPointer(3, GL_FLOAT, 0, &geometryData_[0]);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawElements(GL_TRIANGLE_STRIP, indexData_.size(), GL_UNSIGNED_SHORT, &indexData_[0]);
}

class SpiralSphere
{

public:

SpiralSphere(const float radius = 1.0f, const unsigned int loops = 8, const unsigned int segmentsPerLoop = 16);
void render() const;

private:

std::vector<GeometryVector<float> > geometryData_;
std::vector<unsigned short> indexData_;

};

SpiralSphere::SpiralSphere(const float radius, const unsigned int loops, const unsigned int segmentsPerLoop)
{
for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber)
{
float theta = 0;
float phi = loopSegmentNumber * 2 * PI / segmentsPerLoop;
float sinTheta = std::sin(theta);
float sinPhi = std::sin(phi);
float cosTheta = std::cos(theta);
float cosPhi = std::cos(phi);
geometryData_.push_back(GeometryVector<float>(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta));

}
for (unsigned int loopNumber = 0; loopNumber <= loops; ++loopNumber)
{
for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber)
{
float theta = (loopNumber * PI / loops) + ((PI * loopSegmentNumber) / (segmentsPerLoop * loops));
if (loopNumber == loops)
{
theta = PI;
}
float phi = loopSegmentNumber * 2 * PI / segmentsPerLoop;
float sinTheta = std::sin(theta);
float sinPhi = std::sin(phi);
float cosTheta = std::cos(theta);
float cosPhi = std::cos(phi);
geometryData_.push_back(GeometryVector<float>(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta));

}
}
for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber)
{
indexData_.push_back(loopSegmentNumber);
indexData_.push_back(segmentsPerLoop + loopSegmentNumber);
}
for (unsigned int loopNumber = 0; loopNumber < loops; ++loopNumber)
{
for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber)
{
indexData_.push_back(((loopNumber + 1) * segmentsPerLoop) + loopSegmentNumber);
indexData_.push_back(((loopNumber + 2) * segmentsPerLoop) + loopSegmentNumber);
}
}
}

void SpiralSphere::render() const
{
glVertexPointer(3, GL_FLOAT, 0, &geometryData_[0]);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawElements(GL_TRIANGLE_STRIP, indexData_.size(), GL_UNSIGNED_SHORT, &indexData_[0]);
}

StackedSphere sphere1(4, 8, 16);
SpiralSphere sphere2(4, 8, 16);
int r = 0;

void reshape(int width, int height){
if (height == 0)
{
height = 1;
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, width, height);
gluPerspective(45.0f, GLfloat(width) / GLfloat(height), 0.1f, 50.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void display(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0, 0, -25);
glPushMatrix();
glTranslatef(-5, 0, 0);
glRotatef(r, 0, 1, 0);
sphere1.render();
glPopMatrix();
glPushMatrix();
glTranslatef(5, 0, 0);
glRotatef(r, 0, 1, 0);
sphere2.render();
glPopMatrix();
glutSwapBuffers();
r++;
}

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(0, 0);
glutInitWindowSize(512,512);
glutCreateWindow("Sphere Test");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutIdleFunc(display);
glPolygonMode(GL_FRONT, GL_LINE);
glPolygonMode(GL_BACK, GL_LINE);
glutMainLoop();
return 0;
}

Enigma

Share this post


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

  • Advertisement