Thread: How to draw 3D rotating Cylinder

1. How to draw 3D rotating Cylinder

Hi,

i am new to openGL, i am not getting how to draw 3d Cylinder and that should be rotate in x-direction.

2. Re: How to draw 3D rotating Cylinder

Please be more specific -- what books or online articles have you looked at? What tools are you using C/C++? Posting your code always is a good start. It is quite difficult to answer such a broad question -- maybe looking at how to do an animation itself may help so see Post# 267635

That post shows a rotating cube, to get a rotating cylinder the code is modifed to use GLUquadricObj as follows;
Code :
```#include <GL/gl.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>

GLfloat gAngle = 0.0;

void timer(int value)
{
const int desiredFPS=120;
glutTimerFunc(1000/desiredFPS, timer, ++value);
GLfloat dt = 1./desiredFPS;

//put your specific idle code here
//... this code will run at desiredFPS
gAngle += dt*360./8.; //rotate 360 degrees every 8 seconds
//end your specific idle code here

glutPostRedisplay(); // initiate display() call at desiredFPS rate
}

void display() {
// Will be called at FPS rate, ok to use global values now to rener scene
glClear(GL_COLOR_BUFFER_BIT);

glPushMatrix();
glTranslatef(0,0,-100);
glRotatef(gAngle,1.,1.,1.);
//glutWireCube(20.); //cube of size 20x20x20
glPopMatrix();

glutSwapBuffers();
}

void cleanupQuadric(void)          // Properly Kill The Window
{
}

void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);

GLdouble Vol = 10*1.8;
GLdouble Left=-Vol;
GLdouble Right=Vol;
GLdouble Bottom=-Vol;
GLdouble Top=Vol;
GLdouble Near=0;
GLdouble Far=2*Vol;

glMatrixMode(GL_PROJECTION);
glOrtho(Left, Right, Bottom, Top,  Near, Far);

GLdouble eyeX=0;
GLdouble eyeY=0;
GLdouble eyeZ=-100+Vol;
GLdouble centerX=0;
GLdouble centerY=0;
GLdouble centerZ=-100;
GLdouble upX=0;
GLdouble upY=1;
GLdouble upZ=0;

glMatrixMode(GL_MODELVIEW);
gluLookAt(eyeX,eyeY,eyeZ,
centerX,centerY,centerZ,
upX,upY,upZ);
}

void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:  // escape key
exit(0);
break;
default:
break;
}
}

int main(int argc, char** argv) {
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutCreateWindow("FPS test /w glutTimerFunc");

glutTimerFunc(0,timer,0);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);

init();

glutMainLoop();
return 0;
}```

3. Re: How to draw 3D rotating Cylinder

Hi,

Thank you so much.

i checked your code, it's displaying perfect cylinder. i made other code to Display cylinder and rotation of that is mouse control. if you want to check the code means i will send it.

my assignment is to place bmp format images on the side surfaces of the Cylinder. i am using C in Ubuntu.
if i rotate the cylinder around the x-axis, it should highlight the current image from my point of view.

i am thankful for any kind of help.

4. Re: How to draw 3D rotating Cylinder

There is a nice image loading library called DevIL that is cross platform. Since you are on ubuntu it is a simple "sudo apt-get install libdevil-dev" command installation.

To use it see a previous post from earlier today at Post267979.

After you load the image like the post, you simply need to add two lines of code in the Display function before you start drawing the gluCylinder ...
Code :
```struct TextureHandle {
... identical from post267979, cut-n-paste
};

TextureHandle logo;

ILuint LoadImageDevIL (const char *szFileName, struct TextureHandle *T)
{
... identical to post267979, cut-n-paste
}

void init() {
ilInit(); //initialize DevIL library required
}

void display() {
...
//add two line to bind texture
glEnable (GL_TEXTURE_2D);
glBindTexture ( GL_TEXTURE_2D, logo.genID);

glPushMatrix();
glTranslatef(0,0,-100);
glRotatef(gAngle,1.,1.,1.);
glPopMatrix();
...
}```

5. Re: How to draw 3D rotating Cylinder

Texture coordinate generation can be turned on and o with

GLU spec 6.3 page 21

6. Re: How to draw 3D rotating Cylinder

Hi,

I made the changes,what you sent above, but it's giving the error as "logo" is undefined, but it's already declared. i am not getting that.. placing the entire code below and there is two init() functions so i commented the below init()function :

Code :

#include <GL/gl.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>

#include <IL/ilut.h>

GLfloat gAngle = 0.0;

struct TextureHandle {

ILubyte *p;
ILuint id;
ILint w;
ILint h;
ILenum DestFormat;
ILenum DestType;
GLuint genID;

};
TextureHandle wmap, logo, frac;

ILuint LoadImageDevIL (const char *szFileName, struct TextureHandle *T)
{

ilEnable(IL_ORIGIN_SET);

ilOriginFunc(IL_ORIGIN_LOWER_LEFT);

ILuint ImageNameID;
ilGenImages(1, &amp;ImageNameID);
ilBindImage(ImageNameID);
ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);

T->id = ImageNameID;
T->p = ilGetData();
T->w = ilGetInteger(IL_IMAGE_WIDTH);
T->h = ilGetInteger(IL_IMAGE_HEIGHT);

T->DestFormat = ilGetInteger(IL_IMAGE_FORMAT);
T->DestType = ilGetInteger(IL_IMAGE_TYPE);

glGenTextures(1, &amp;T->genID);
glBindTexture(GL_TEXTURE_2D, T->genID);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D (GL_TEXTURE_2D, 0, T->DestFormat, T->w, T->h, 0, T->DestFormat, T->DestType, T->p);

printf("%s %d %d %d\n",szFileName,T->id,T->w,T->h);
return 1;
}

void init() {

ilInit();
}

void timer(int value)
{
const int desiredFPS=120;
glutTimerFunc(1000/desiredFPS, timer, ++value);
GLfloat dt = 1./desiredFPS;

gAngle += dt*360./8.;

glutPostRedisplay();
}

void display() {

glEnable (GL_TEXTURE_2D);
glBindTexture ( GL_TEXTURE_2D, logo.genID);

glClear(GL_COLOR_BUFFER_BIT);

glPushMatrix();
glTranslatef(0,0,-100);
glRotatef(gAngle,1.,1.,1.);

glPopMatrix();

glutSwapBuffers();
}

{
}
/*
void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);

GLdouble Vol = 10*1.8;
GLdouble Left=-Vol;
GLdouble Right=Vol;
GLdouble Bottom=-Vol;
GLdouble Top=Vol;
GLdouble Near=0;
GLdouble Far=2*Vol;

glMatrixMode(GL_PROJECTION);
glOrtho(Left, Right, Bottom, Top, Near, Far);

GLdouble eyeX=0;
GLdouble eyeY=0;
GLdouble eyeZ=-100+Vol;
GLdouble centerX=0;
GLdouble centerY=0;
GLdouble centerZ=-100;
GLdouble upX=0;
GLdouble upY=1;
GLdouble upZ=0;

glMatrixMode(GL_MODELVIEW);
gluLookAt(eyeX,eyeY,eyeZ,
centerX,centerY,centerZ,
upX,upY,upZ);
}
*/
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
default:
break;
}
}

int main(int argc, char** argv) {
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutCreateWindow("FPS test /w glutTimerFunc");

glutTimerFunc(0,timer,0);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);

init();

glutMainLoop();
return 0;
}

and one more is it necessary to place this line
if means, where i should i place ?
Compile: gcc cc1.c -o cc1 -I/usr/x11R6/include/ -L/usr/lib -lX11 -lXmu -lglut -lGL -lGLU

Is there any changes needed in above command, Guide me please.

i am thankful for any kind of help.

7. Slight difference for .c and .cpp

The compile command I use is for C++ (filename.cpp)
Code :
```g++ main.cpp  -lGL -lglut -lIL
but you can also use
gcc main.cpp  -lGL -lglut -lIL```
Now if you have a .c extension instead of .cpp, then the gcc command will assume Ansi-C. In which case you have to declare with a "struct" explicitly.
Code :
```for .cpp: TextureHandle logo;
gcc main.cpp  -lGL -lglut -lIL
for   .c: struct TextureHandle logo;
gcc main.c  -lGL -lglut -lIL```
so your gcc compile command looks fine as is as long as you change to make the "logo" declaration ANSI-C instead of my ANSI-C++ as done in following code ...

Here's the code with the "struct" added for filename.c (ie c version)
Code :
```// on linux with gcc: g++ main.c  -lGL -lglut -lIL
#include <GL/gl.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>

#include <IL/ilut.h>

GLfloat gAngle = 0.0;

struct TextureHandle
{

ILubyte *p;
ILuint id;
ILint w;
ILint h;
ILenum DestFormat;
ILenum DestType;
GLuint genID;

};

struct TextureHandle logo;

ILuint LoadImageDevIL (const char *szFileName, struct TextureHandle *T)
{

ilEnable(IL_ORIGIN_SET);

ilOriginFunc(IL_ORIGIN_LOWER_LEFT);

ILuint ImageNameID;
ilGenImages(1, &amp;ImageNameID);
ilBindImage(ImageNameID);
ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);

T->id = ImageNameID;
T->p = ilGetData();
T->w = ilGetInteger(IL_IMAGE_WIDTH);
T->h = ilGetInteger(IL_IMAGE_HEIGHT);

T->DestFormat = ilGetInteger(IL_IMAGE_FORMAT);
T->DestType = ilGetInteger(IL_IMAGE_TYPE);

glGenTextures(1, &amp;T->genID);
glBindTexture(GL_TEXTURE_2D, T->genID);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D (GL_TEXTURE_2D, 0, T->DestFormat, T->w, T->h, 0, T->DestFormat, T->DestType, T->p);

printf("%s %d %d %d\n",szFileName,T->id,T->w,T->h);
return 1;
}

void timer(int value)
{
const int desiredFPS=120;
glutTimerFunc(1000/desiredFPS, timer, ++value);
GLfloat dt = 1./desiredFPS;

gAngle += dt*360./8.;

glutPostRedisplay();
}

void display()
{

glEnable (GL_TEXTURE_2D);
glBindTexture ( GL_TEXTURE_2D, logo.genID);

glClear(GL_COLOR_BUFFER_BIT);

glPushMatrix();
glTranslatef(0,0,-100);
glRotatef(gAngle,1.,1.,1.);

glPopMatrix();

glutSwapBuffers();
}

{
}

void init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);

GLdouble Vol = 10*1.8;
GLdouble Left=-Vol;
GLdouble Right=Vol;
GLdouble Bottom=-Vol;
GLdouble Top=Vol;
GLdouble Near=0;
GLdouble Far=2*Vol;

glMatrixMode(GL_PROJECTION);
glOrtho(Left, Right, Bottom, Top, Near, Far);

GLdouble eyeX=0;
GLdouble eyeY=0;
GLdouble eyeZ=-100+Vol;
GLdouble centerX=0;
GLdouble centerY=0;
GLdouble centerZ=-100;
GLdouble upX=0;
GLdouble upY=1;
GLdouble upZ=0;

glMatrixMode(GL_MODELVIEW);
gluLookAt(eyeX,eyeY,eyeZ,
centerX,centerY,centerZ,
upX,upY,upZ);

ilInit();
}

void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27:
exit(0);
break;
default:
break;
}
}

int main(int argc, char** argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutCreateWindow("FPS test /w glutTimerFunc");

glutTimerFunc(0,timer,0);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);

init();

glutMainLoop();
return 0;
}```

8. Re: Slight difference for .c and .cpp

Hi,

The above code is working fine without any error messages.
i just changed width and height to get good clarity.
i dint get what exactly below line indicates, why cant we use directly value for IDquadric :

and i changed the line as
gluCylinder (30, 5.0f, 5.0f, 10.0f, 24, ;

This shows segmentation fault. This means memory related are what.

one more thing requesting you is how to place many different images on the same cylinder ?

i am thankful for any kind of help.

9. Re: Slight difference for .c and .cpp

This is a C question, whenever you see an argument of the form "type * X" then it expects an address, not the value, to be passed into the function ... see glCylinder definition. Notice how the first argument it expects is a pointer to a GLUquadric. And reading further this pointer is defined by a very specific function, gluNewQuadric(). So you can't use the value of "30" for the first argument of your gluCylinder (30, 5.0f, 5.0f, 10.0f, 24, -- the function is looking for the address not the value 30, this explains why you saw a segmentation fault.

The question about multiple textures on a single cylinder is more involved question. Do you have to do multiple textures or simply make a single texture in some drawing program that has the effect of multiple decals? The second approach easily maps to the code you already have. But if you have to do the first approach -- A quick google search lead to multitexturing tutorial that may help you get started. Also see Post90211.

I believe with this you will have to start using the openGL extensions -- you can get setup to use them with the GLEW library. On Ubuntu you can get it installed with a simple "sudo apt-get install libglew1.5-dev". To use it read Glew basic usage.
Here's code to simply add glew functionality (NOT multitexturing) -- a single include is added with a call to glewInit(). And note the compile command is
Code :
`gcc main.c  -lGL -lglut -lIL -lGLEW`
Code :
```// on linux with gcc: gcc main.c  -lGL -lglut -lIL -lGLEW
#include <GL/glew.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>

#include <IL/ilut.h>

GLfloat gAngle = 0.0;

struct TextureHandle
{

ILubyte *p;
ILuint id;
ILint w;
ILint h;
ILenum DestFormat;
ILenum DestType;
GLuint genID;

};

struct TextureHandle logo;

ILuint LoadImageDevIL (const char *szFileName, struct TextureHandle *T)
{

ilEnable(IL_ORIGIN_SET);

ilOriginFunc(IL_ORIGIN_LOWER_LEFT);

ILuint ImageNameID;
ilGenImages(1, &amp;ImageNameID);
ilBindImage(ImageNameID);
ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);

T->id = ImageNameID;
T->p = ilGetData();
T->w = ilGetInteger(IL_IMAGE_WIDTH);
T->h = ilGetInteger(IL_IMAGE_HEIGHT);

T->DestFormat = ilGetInteger(IL_IMAGE_FORMAT);
T->DestType = ilGetInteger(IL_IMAGE_TYPE);

glGenTextures(1, &amp;T->genID);
glBindTexture(GL_TEXTURE_2D, T->genID);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D (GL_TEXTURE_2D, 0, T->DestFormat, T->w, T->h, 0, T->DestFormat, T->DestType, T->p);

printf("%s %d %d %d\n",szFileName,T->id,T->w,T->h);
return 1;
}

void timer(int value)
{
const int desiredFPS=120;
glutTimerFunc(1000/desiredFPS, timer, ++value);
GLfloat dt = 1./desiredFPS;

gAngle += dt*360./8.;

glutPostRedisplay();
}

void display()
{

glEnable (GL_TEXTURE_2D);
glBindTexture ( GL_TEXTURE_2D, logo.genID);

glClear(GL_COLOR_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(0,0,-100);
glRotatef(gAngle,1.,1.,1.);

glPopMatrix();

glutSwapBuffers();
}

{
}

void init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);

GLdouble Vol = 10*1.8;
GLdouble Left=-Vol;
GLdouble Right=Vol;
GLdouble Bottom=-Vol;
GLdouble Top=Vol;
GLdouble Near=0;
GLdouble Far=2*Vol;

glMatrixMode(GL_PROJECTION);
glOrtho(Left, Right, Bottom, Top, Near, Far);

GLdouble eyeX=0;
GLdouble eyeY=0;
GLdouble eyeZ=-100+Vol;
GLdouble centerX=0;
GLdouble centerY=0;
GLdouble centerZ=-100;
GLdouble upX=0;
GLdouble upY=1;
GLdouble upZ=0;

glMatrixMode(GL_MODELVIEW);
gluLookAt(eyeX,eyeY,eyeZ,
centerX,centerY,centerZ,
upX,upY,upZ);

ilInit();
}

void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27:
exit(0);
break;
default:
break;
}
}

int main(int argc, char** argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutCreateWindow("FPS test /w glutTimerFunc");
glewInit();

glutTimerFunc(0,timer,0);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);

init();

glutMainLoop();
return 0;
}```

10. Re: Slight difference for .c and .cpp

Hi,

i got the idea about segmentation fault. Thank you very much.

Regarding multitexturing, the code which is in above link is in shading language is it same for C. Sorry for asking simple question.