# Thread: How to draw 3D rotating Cylinder

1. ## Re: Slight difference for .c and .cpp

Here's a modified code example from a book well worth getting "OpenGL Programming Guide Fifth Edition, by Dave Shreiner, Mason Woo, Jackie Neider, Tom Davis" -- Chapter 9 has multitex.c. It shows how to do multitexturing in c (but on a QUAD instead of a cylinder). The images themselves are quite indistinct so the example isn't the best but it does show two images -- look at the fullscreen window when running. That will improve when you use your own images that aren't so dark.

Code :
```/*  multitex.c
from [url]http://www.cosc.brocku.ca/Offerings/3P98/course/OpenGL/RedBookExamples/multitex.c[/url]
slightly modified to use GLEW for extensions

// 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>

static GLubyte texels0[32][32][4];
static GLubyte texels1[16][16][4];

void makeCheckImages(void)
{
int i, j;

for (i = 0; i < 32; i++) {
for (j = 0; j < 32; j++) {
texels0[i][j][0] = (GLubyte) i;
texels0[i][j][1] = (GLubyte) j;
texels0[i][j][2] = (GLubyte) (i*j)/255;
texels0[i][j][3] = (GLubyte) 255;
}
}

for (i = 0; i < 16; i++) {
for (j = 0; j < 16; j++) {
texels1[i][j][0] = (GLubyte) 255;
texels1[i][j][1] = (GLubyte) i;
texels1[i][j][2] = (GLubyte) j;
texels1[i][j][3] = (GLubyte) 255;
}
}
}

void init(void)
{
GLuint texNames[2];

glClearColor (0.0, 0.0, 0.5, 0.0);
glEnable(GL_DEPTH_TEST);

makeCheckImages();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glGenTextures(2, texNames);
glBindTexture(GL_TEXTURE_2D, texNames[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA,
GL_UNSIGNED_BYTE, texels0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glBindTexture(GL_TEXTURE_2D, texNames[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
GL_UNSIGNED_BYTE, texels1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
/*  Use the two texture objects to define two texture units
*  for use in multitexturing  */
glActiveTexture (GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texNames[0]);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glMatrixMode (GL_TEXTURE);
glTranslatef(0.5f, 0.5f, 0.0f);
glRotatef(45.0f, 0.0f, 0.0f, 1.0f);
glTranslatef(-0.5f, -0.5f, 0.0f);
glMatrixMode (GL_MODELVIEW);
glActiveTexture (GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texNames[1]);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glMultiTexCoord2f (GL_TEXTURE0, 0.0, 0.0);
glMultiTexCoord2f (GL_TEXTURE1, 1.0, 0.0);
glVertex2f(0.0, 0.0);
glMultiTexCoord2f (GL_TEXTURE0, 0.5, 1.0);
glMultiTexCoord2f (GL_TEXTURE1, 0.5, 0.0);
glVertex2f(50.0, 100.0);
glMultiTexCoord2f (GL_TEXTURE0, 1.0, 0.0);
glMultiTexCoord2f (GL_TEXTURE1, 1.0, 1.0);
glVertex2f(100.0, 0.0);
glEnd();
glutSwapBuffers();
}

void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
if (w <= h)
gluOrtho2D(0.0, 100.0, 0.0, 100.0 * (GLdouble)h/(GLdouble)w);
else
gluOrtho2D(0.0, 100.0 * (GLdouble)w/(GLdouble)h, 0.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}

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

int main(int argc, char** argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
glewInit();
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutKeyboardFunc (keyboard);
glutMainLoop();
return 0;
}```

2. ## Multiple textures with blending instead

I realized my previous post could use the older blending capabilities instead ... see chapter06 in Redbook.

Heres some alternative code that reads two textures (Logo.bmp and Logo2.bmp) and combines them in two passes. The changes mostly occure in the Display() function.
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;
struct TextureHandle logo2;

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 draw_cylinder()
{
glPushMatrix();
glTranslatef(-5.,0,-100);
glRotatef(gAngle,1.,0.,0.);
glRotatef(90,0.,1.,0.);
glPopMatrix();
}

void display()
{
glClear(GL_COLOR_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_COLOR,GL_DST_COLOR);

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

glBindTexture ( GL_TEXTURE_2D, logo2.genID);
draw_cylinder();

glutSwapBuffers();
}

{
}

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

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();

glEnable (GL_TEXTURE_2D);
}

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("Multipass texturing Demo");
glewInit();

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

init();

glutMainLoop();
return 0;
}```

3. ## Re: Slight difference for .c and .cpp

Hi Thank you very much.

How to do multitexturing ?

i am using the code below :

{
FILE *File=NULL;

if (!Filename)
{
return NULL;
}

File=fopen(Filename,"r");

if (File)
{
fclose(File);
}

return NULL;
}

{
int Status=FALSE;

AUX_RGBImageRec *TextureImage[2];

memset(TextureImage,0,sizeof(void *)*2);

{
Status=TRUE;

glGenTextures(6, &amp;texture[0]);

for (int loop=0; loop<=1; loop++)
{

glBindTexture(GL_TEXTURE_2D, texture[loop]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[loop]->sizeX, TextureImage[loop]->sizeY,
0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop]->data);

glBindTexture(GL_TEXTURE_2D, texture[loop+2]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[loop]->sizeX, TextureImage[loop]->sizeY,
0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop]->data);

glBindTexture(GL_TEXTURE_2D, texture[loop+4]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[loop]->sizeX, TextureImage[loop]->sizeY,
GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop]->data);
}
for (loop=0; loop<=1; loop++)
{
if (TextureImage[loop])
{
if (TextureImage[loop]->data)
{
free(TextureImage[loop]->data);
}
free(TextureImage[loop]);
}
}
}

return Status;
}

bool load_rgb_image(const char* file_name, int w, int h, RGBIMG* refimg)
{
GLuint sz;
FILE* file;
long fsize;
GLubyte* p;

refimg->w = (GLuint) w;
refimg->h = (GLuint) h;
sz = (((3*refimg->w+3)>>2)<<2)*refimg->h;
refimg->data = new GLubyte [sz];
if (refimg->data == NULL) return false;

file = fopen(file_name , "rb");
if (!file) return false;
fseek(file, 0L, SEEK_END);
fsize = ftell(file);
if (fsize != (long)sz) {
fclose(file);
return false;
}
fseek(file, 0L, SEEK_SET);
p = refimg->data;
while (fsize > 0) {
p++;
fsize--;
}
fclose(file);
return true;
}

bool setup_textures()
{
RGBIMG img;

glGenTextures(TEXTURES_NUM, g_texid);

if (!load_rgb_image("wall_64x64.raw", 64, 64, &amp;img)) return false;

glBindTexture(GL_TEXTURE_2D, g_texid[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3, img.w, img.h, 0, GL_RGB, GL_UNSIGNED_BYTE, img.data);

glBindTexture(GL_TEXTURE_2D, g_texid[1]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, img.w, img.h, 0, GL_RGB, GL_UNSIGNED_BYTE, img.data);

glBindTexture(GL_TEXTURE_2D, g_texid[2]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, img.w, img.h, GL_RGB, GL_UNSIGNED_BYTE, img.data);

delete img.data;
return true;
}

bool init(void)
{
{
return FALSE;
}

glEnable(GL_TEXTURE_2D);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

glLightfv(GL_LIGHT1, GL_AMBIENT, g_lightAmbient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, g_lightDiffuse);
glLightfv(GL_LIGHT1, GL_POSITION,g_lightPosition);
glEnable(GL_LIGHT1);

if (g_quadratic == 0) return false;

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
return true;
}

int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
return TRUE; // Keep Going
}

void render(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glTranslatef(0.0f,0.0f,g_z);

glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);

glBindTexture(GL_TEXTURE_2D, texture[g_filter+(g_filter+1)]);
glPushMatrix();
glRotatef(g_xrot,1.0f,0.0f,0.0f);
glRotatef(g_yrot,0.0f,1.0f,0.0f);
switch(g_object)
{
case 0:
glDrawCube();
break;
case 1:
glTranslatef(0.0f,0.0f,-1.5f);
break;
case 2:
break;
case 3:
glTranslatef(0.0f,0.0f,-1.5f);
break;
};

glPopMatrix();
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);

glBindTexture(GL_TEXTURE_2D, texture[g_filter*2]);
glPushMatrix();
glTranslatef(0.0f, 0.0f, -24.0f);
glNormal3f( 0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-13.3f, -10.0f, 10.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 13.3f, -10.0f, 10.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 13.3f, 10.0f, 10.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-13.3f, 10.0f, 10.0f);
glEnd();

glPopMatrix();

g_xrot+=g_xspeed;
g_yrot+=g_yspeed;

glutSwapBuffers ( );
}

The above part of code i used for multitexturing, but it's not working.

please i am new to openGL, help me out from this.

i am thankful for any kind of help.

4. ## Re: Slight difference for .c and .cpp

Hi,

Yes as you told, it's displaying rectangle like object not a perfect Cylinder and two images on that are not so clear, they are compressed and shuffled..

i am thankful for Help.

5. ## GLaux is old and deprecated

What code are you referring exactly? I have lost track. Also did you see the Post268130 and compile and run it -- that I think is a better example of multitexturing.

I have made a point to not use GLaux since it is over 15 years old, buggy, leaks memory, and deprecated -- see the section on "External Links:Image Loader"
Getting Started. I really can't help you debug that code with GLaux. I would suggest going back to using IL/il.h.

The GLaux code you posted is not a multitexturing example ie it does not apply two or more textures to the same geometric object. Instead it has one texture for each object and there are three objects which is not multitexturing. -- Maybe we have a semantics misunderstanding -- Do you want to apply two or more textures to the same object or simply have many objects each with their own texure decal?

As for why the image is compressed and distorted, understanding the Redbook Chapter 9 would be a better help there. But in essence it has to do with the specific numbers defined for S and T texture coordinates. Take a look at "Figure 9-6 : Texture-Map Distortion." This is one of the more difficult things to get straight when first learning texturing -- how the S and T coordinates and the original texture image correspond to one another visually.

6. ## Re: GLaux is old and deprecated

Hi,
Thank you very much.

sorry for late reply. i am out.

I referred code which i placed above is from NeHe's production example, which uses GLaux library. ok leave, if it's old one.

I tried the code in Post268130 it's working without errors,This code generates a rectangle object not a cylinder and images placed on that are shuffled, no clear separation between those images. you are right i need to place more images on the single object.

please what to do Now ?

I am thankful for any kind of help.

7. ## Re: GLaux is old and deprecated

Here is a slightly modified code from post268130 -- to show it is a cylinder by changing axis of rotation and adding a global gState that toggles between 0 and 1 as you press a key.
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;

GLuint gState = 0;

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

};

struct TextureHandle logo;
struct TextureHandle logo2;

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 draw_cylinder()
{
glPushMatrix();
glTranslatef(-5.,0,-100);
glRotatef(gAngle,1.,0.,0.);
glRotatef(90,1.,1.,0.);
glPopMatrix();
}

void display()
{
glClear(GL_COLOR_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);

if (gState) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_COLOR,GL_DST_COLOR);

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

glBindTexture ( GL_TEXTURE_2D, logo2.genID);
draw_cylinder();

glDisable(GL_BLEND);
} else {
glBindTexture ( GL_TEXTURE_2D, logo.genID);
draw_cylinder();
}

glutSwapBuffers();
}

{
}

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

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();

glEnable (GL_TEXTURE_2D);
}

void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27:
exit(0);
break;
default:
gState++;
gState %= 2;
printf("%d\n",gState);
break;
}
}

int main(int argc, char** argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutCreateWindow("Multipass texturing Demo");
glewInit();

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

init();

glutMainLoop();
return 0;
}```
Supply any two textures that will be applied multi-textured onto a single cylinder (lines 155 and 156), compile and run this code.

Notice what happens when you press the spacebar key -- this will toggle between single texture and multi-texturing. Then look at the code that is relevant (see if-gState in Display). That's all there is to multi-texturing using blending. To understand this read the chapters in the Redbook that I referred you to in the previous posts.

8. ## Re: GLaux is old and deprecated

Hi,

The above code result's into cylinder,But while rotating, the back part of the cylinder is invisible.

i mean it shows semi-cylinder rotation. i gave two-textures on line 155 & 156. i changed the rotation parameters,but not displaying complete cylinder.

one more is i saw changes from single texture to multiple-texture
by pressing any key.

i am thankful for your help.

9. ## Re: GLaux is old and deprecated

Actually the code is showing a complete cylinder but culling the back faces -- to "fix" this I have added code to explicitly draw the top and bottom of the cylinder (see draw_cylinder() and the newly added gluDisk calls). Have you read Chapters 6 and 9 in the Redbook?
Code :
```// on linux with gcc: gcc main.c  -lGL -lglut -lIL -lGLEW
// on win+mingw: gcc main8.c -lglut32 -lglu32 -lopengl32 -lwinmm -lgdi32  -lglew32 -lIL -L/usr/local/lib -I/usr/local/include
//
#include <GL/glew.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>

#include <IL/il.h>

GLfloat gAngle = 0.0;

GLuint gState = 0;

struct TextureHandle
{
ILubyte *p;
ILuint id;
ILint w;
ILint h;
ILenum DestFormat;
ILenum DestType;
GLuint genID;
};

struct TextureHandle logo;
struct TextureHandle logo2;

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 draw_cylinder()
{
glPushMatrix();
glTranslatef(-5.,0,-100);
glRotatef(gAngle,1.,1.,0.);

glPushMatrix(); // top of cylinder
glTranslatef(0.,0.,10.);
glPopMatrix();

glPushMatrix(); // bottom of cylinder
glFrontFace(GL_CW);
glFrontFace(GL_CCW);
glPopMatrix();

glPopMatrix();
}

void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);

if (gState) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_COLOR,GL_DST_COLOR);

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

glBindTexture ( GL_TEXTURE_2D, logo2.genID);
draw_cylinder();

glDisable(GL_BLEND);
} else {
glBindTexture ( GL_TEXTURE_2D, logo.genID);
draw_cylinder();
}

glutSwapBuffers();
}

{
}

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

glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

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();

glEnable (GL_TEXTURE_2D);
}

void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27:
exit(0);
break;
default:
gState++;
gState %= 2;
printf("%d\n",gState);
break;
}
}

int main(int argc, char** argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
glutCreateWindow("Multipass texturing Demo");
glewInit();

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

init();

glutMainLoop();
return 0;
}```

10. ## Re: GLaux is old and deprecated

Hi,

thank You So much for replying.

The above code is generating complete cylinder with top face.
Is there any function to display complete cylinder without top face. if i comment gluDisk()function it is not showing complete cylinder.

Yes as you specified in the previous post #268169, i studied Chapter-9. one more is as a fresher it is getting quite difficult for understanding. i will pickup shortly..