# Thread: OpenGL: Draw cylinder yourself

1. ## OpenGL: Draw cylinder yourself

Hello, I am not struggling with OpenGL and have this particular problem:

I'd like to draw a cylinder myself. Not just use gluCylinder() and everything. It is interesting for me to know, how to do it.

I've started with octagon, drew two of them, put them on top of each other in some distance. Then I drew the cover to make it cylindrical.

!And then the cage came down!

It started to do weird things, it drew covering and one octagon and that was it. No cylinder what so ever! I spend a lot of time figuring out how to fix it, but I didn't succeed Here is the code, I'd like to ask some kind people to find this particular mistake or so.
I've commented it here and there to make it easier.

Code:
```#include "cstdio"
#include "GL/glut.h"
#include "math.h"

void drw_polygon(int n = 3, int arg = 0, float mult = 1, float v = 1.0) {
/*
Function drw_polygon:
Arguments:
n - number of sides
arg - starting angle (not so important at all)
mult - multiplying sides to incrase their length
v - cylinder height
*/

// DumbProof Double Check :)
if (arg < 0)
arg = 0;

// Cylinder Bottom
glBegin(GL_POLYGON);
glColor4f(1.0, 0.0, 0.0, 1.0);
for(int i = arg; i <= (360 + arg); i += (360 / n)) {
float a = i * M_PI / 180; // degrees to radians
glVertex3f(mult * cos(a), mult * sin(a), 0.0);
}
glEnd();

// Cylinder Top
glBegin(GL_POLYGON);
glColor4f(0.0, 0.0, 1.0, 1.0);
for(int i = arg; i <= (360 + arg); i += (360 / n)) {
float a = i * M_PI / 180; // degrees to radians
glVertex3f(mult * cos(a), mult * sin(a), v);
}
glEnd();

// Cylinder "Cover"
glColor4f(1.0, 1.0, 0.0, 1.0);
for(int i = arg; i < 480; i += (360 / n)) {
float a = i * M_PI / 180; // degrees to radians
glVertex3f(mult * cos(a), mult * sin(a), 0.0);
glVertex3f(mult * cos(a), mult * sin(a), v);
}
glEnd();

}

void display() {
glClear(GL_COLOR_BUFFER_BIT);
glRotatef(0.05, 1.0, 1.0, 0.0);
drw_polygon(3, 0, 2, 4);
glutSwapBuffers();
}

void timer(int = 0) {
display();
glutTimerFunc(1, timer, 0);
}

int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(200, 200);
glutCreateWindow("Cylinder");
glClearColor(0.0, 0.0, 0.0, 1.0);
glMatrixMode(GL_PROJECTION);
glOrtho(-5, 5, -5, 5, -5, 5);
glutDisplayFunc(display);
timer();
glutMainLoop();
}```
Thanks for any help! 2. So you appear to be drawing this thing edge-on; i.e. looking straight down the top (or straight up the bottom, or whatever). So you should see a triangle and that's about it since the rest of the prism is behind the triangle. Maybe you could draw it off-center (i.e. add 2 to all the x's or something to move it over) and then you might see the whole prism). 3. here is my code. This function APPENDS a cylinder onto the data passed to the function. Generates normals, correct texture coords as well. The caller has to pass a 2 or 4 for the index stride as well

I use alot of my own function calls, like sin32 or cos32, and similarly for the math functions, but you should be able to swap them.

Code:
```class cPNTVert{
public:
vec3 pos, norm;
vec2 tex;
};

inline float DegToRad(const float& deg){ return deg*(Pi/180.0f); }

//vector<cPNTVert>& v can contain vertices and in is the index buffer. They can already have data in them and you can use this function to append a cylinder onto the data already there

void GenCylinder(size_t lengthsegs, size_t heightsegs, vector<cPNTVert>& v, vector<uint16_t>& in, size_t indexstride){
heightsegs+=1;// we need an extra one here!
size_t startvertex = v.size();// if v is empty, the size is 0, so we are starting on an empty buffer, but if there is data, this will append it correctly
size_t totalverts = lengthsegs*heightsegs;
v.resize(startvertex + totalverts);
vector<vec3> verts(totalverts), norms(totalverts);
vector<vec2> texs(totalverts);
float heightstride = 1.0f/static_cast<float>(lengthsegs);
float height = -heightstride;
float deg = 0;
for(size_t i(0); i< lengthsegs; i++){
height+=heightstride;
for(size_t j(0); j < heightsegs; j++){
texs[i*heightsegs + j] = vec2(static_cast<float>(j)/(static_cast<float>(heightsegs)-1.0f), static_cast<float>(i+1));
deg += 360/(static_cast<float>(heightsegs-1));
}
deg = 0.0f;
}
size_t nind = (6*(lengthsegs-1)*(heightsegs));
if(indexstride ==2 ){// two byte index stride
size_t startindex = in.size();
in.resize(nind + startindex);
size_t off(0);
for(size_t i(0); i< lengthsegs-1; i++){
for(size_t j(0); j< heightsegs; j++){
in[off     + startindex] = i*heightsegs + j;
in[off + 1 + startindex] = (i+1)*heightsegs + j;
in[off + 2 + startindex] = i*heightsegs + j + 1;
in[off + 3 + startindex] = i*heightsegs + j + 1;
in[off + 4 + startindex] = (i+1)*heightsegs + j;
in[off + 5 + startindex] = (i+1)*heightsegs + j + 1;
off+=6;
}
}
ComputeNormals(&verts, totalverts, &in[startindex], nind, &norms);
for(size_t i(0); i< (lengthsegs-1)*heightsegs*6; i++) in[i +startindex] += static_cast<uint16_t>(startvertex);// remap the indices
} else {// 4 byte index stride..
size_t startindex = in.size();// beginning of our indices
in.resize((nind*2) + startindex);// allocate twice as many
uint32_t* indices = reinterpret_cast<uint32_t*>(&in[startindex]);
size_t off(0);
for(size_t i(0); i< lengthsegs-1; i++){
for(size_t j(0); j< heightsegs; j++){
indices[off    ] = i*heightsegs + j;
indices[off + 1] = (i+1)*heightsegs + j;
indices[off + 2] = i*heightsegs + j + 1;
indices[off + 3] = i*heightsegs + j + 1;
indices[off + 4] = (i+1)*heightsegs + j;
indices[off + 5] = (i+1)*heightsegs + j + 1;
off+=6;
}
}
ComputeNormals(&verts, totalverts, indices, nind, &norms);
for(size_t i(0); i< (lengthsegs-1)*heightsegs*6; i++) indices[i +startindex] += startvertex;// remap the indices
}
for(size_t i(0); i<totalverts; i++){
v[i + startvertex].pos = verts[i];
v[i + startvertex].tex = texs[i];
v[i + startvertex].norm = norms[i];
}
}

template<class T>void ComputeNormals(vec3* Vertices, size_t numverts, T* indices, size_t numindices, vec3* normals){
size_t i = 0;
memset(normals, 0, sizeof(vec3)* numverts);
do{
vec3 v0(Vertices[indices[i    ]]);
vec3 v1(Vertices[indices[i + 1]]);
vec3 v2(Vertices[indices[i + 2]]);
vec3 normal(Cross(v1 - v0, v2 - v0));
normal.normalize();
normals[indices[i    ]] += normal;
normals[indices[i + 1]] += normal;
normals[indices[i + 2]] += normal;
i += 3;
} while(i < numindices);
i=0;
do{ normals[i].normalize(); } while(++i < numverts);
}``` 4. Damn, smasherprog!! Are you building a game engine or something? Pretty good code! 5. ## yes, i am

Funny you should say, yes I am building a game engine :P 6. A cylinder is two triangle fans connected by a triangle strip. I see no benefit in making your own since you would never do this in any type of game or renderer. The renderer would just load a cylinder model and render it just as any other mesh. Popular pages Recent additions opengl cylinder draw 