waving flag not waving

hello , i adapted the code from nehe`s lesson 11 , the waving flag. i started a new clean project and i figured the first step is to make the actual flag without texture . so i did that but the problem is it s not waving …

the variables

float points[45][45][3];    // The Array For The Points On The Grid Of Our "Wave"
int wiggle_count = 0;		// Counter Used To Control How Fast Flag Waves

GLfloat	xrot;				// X Rotation ( NEW )
GLfloat	yrot;				// Y Rotation ( NEW )
GLfloat	zrot;				// Z Rotation ( NEW )
GLfloat hold;				// Temporarily Holds A Floating Point Value


the init function

void init(void) 
{
   glClearColor (0.0, 0.0, 0.0, 0.0);   
   glEnable(GL_DEPTH_TEST);
   glShadeModel (GL_SMOOTH);
   glDepthFunc(GL_LEQUAL);								// The Type Of Depth Testing To Do


   for(int x=0; x<45; x++)
	{
		for(int y=0; y<45; y++)
		{
			points[x][y][0]=float((x/5.0f)-4.5f);
			points[x][y][1]=float((y/5.0f)-4.5f);
			points[x][y][2]=float(sin((((x/5.0f)*40.0f)/360.0f)*3.141592654*2.0f));
		}
	}

}

the flag is an animated, sine-wave picture. composed of a grid that has 45 points by 45 points, which in turn makes 44 quads x 44 quads. the var wiggle_count is used to keep track of how fast the texture waves.

the display function


void display(void)
{
	int x, y;
	float float_x, float_y, float_xb, float_yb;
	
	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity ();
	
	glTranslatef(0.0f,0.0f,-12.0f);
	  
	glRotatef(xrot,1.0f,0.0f,0.0f);
	glRotatef(yrot,0.0f,1.0f,0.0f);  
	glRotatef(zrot,0.0f,0.0f,1.0f);
	
	glBegin(GL_QUADS);
	for( x = 0; x < 44; x++ )
	{
		for( y = 0; y < 44; y++ )
		{
			float_x = float(x)/44.0f;
			float_y = float(y)/44.0f;
			float_xb = float(x+1)/44.0f;
			float_yb = float(y+1)/44.0f;

			glVertex3f( points[x][y][0], points[x][y][1], points[x][y][2] );

			glVertex3f( points[x][y+1][0], points[x][y+1][1], points[x][y+1][2] );

		        glVertex3f( points[x+1][y+1][0], points[x+1][y+1][1], points[x+1][y+1][2] );

			glVertex3f( points[x+1][y][0], points[x+1][y][1], points[x+1][y][2] );
		}
	}
	glEnd();

	if( wiggle_count == 2 )
	{
		for( y = 0; y < 45; y++ )
		{
			hold=points[0][y][2];
			for( x = 0; x < 44; x++)
			{
				points[x][y][2] = points[x+1][y][2];
			}
			points[44][y][2]=hold;
		}
		wiggle_count = 0;
	}

	wiggle_count++;

	xrot+=0.3f;
	yrot+=0.2f;
	zrot+=0.4f;

	Sleep(5);
	glutSwapBuffers();
	
}

my reshape function

void reshape (int w, int h)
{
   glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();

   gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
  
   glMatrixMode (GL_MODELVIEW);
   glLoadIdentity();

   glutPostRedisplay();
}

and main function

int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
   glutInitWindowSize (500, 500); 
   glutInitWindowPosition (100, 100);
   glutCreateWindow (argv[0]);
   init ();
   glutDisplayFunc(display); 
   glutReshapeFunc(reshape);
   glutKeyboardFunc(keyboard);

   glutMainLoop();
   return 0;
}

i added a file with what it display , it s just a static flag.

here s nehes code , if you would please have a look , or just tell me if something is missing from mine

http://nehe.gamedev.net/data/lessons/vc/lesson11.zip

or is the whole effect of waving coming from the texture ?
(maybe this is a stupid question… :slight_smile: )

really…no one ???

Don’t you need a glutTimerFunc or similar that triggers a periodic call to display ?

can you please exemplify how should i do this ?

You have to define a timer function that triggers the redisplay:


void timer(int unused) {
  glutPostRedisplay();
  glutTimerFunc(30,timer,0);
}

and also add a call to glutTimerFunc to your main() before the glutMainLoop() to start the animation:


  glutTimerFunc(30,timer,0);

thank you very much , mbentrup !!!

it s waving now :smiley:

next i ll try to apply the texture , but the problem is that in nehes tutorials code it has a bmp loader that depends to glaux library , which i want my project to independent off. i ll try to use another loader.

i succeded applying a skull texture to the flag , useing a .tga loader .

this is the texture function i use :

GLuint	texture;
Texture	treeTexture;


bool LoadTreeTextures()
{
	// call the tga file loader. 
	if (LoadTGA(&treeTexture, "flag_texture.tga"))	
	{		
		
		glGenTextures(1, &treeTexture.texID);
		glBindTexture(GL_TEXTURE_2D, treeTexture.texID);
		glTexImage2D(GL_TEXTURE_2D, 0, treeTexture.bpp / 8, treeTexture.width, treeTexture.height, 0, treeTexture.type, GL_UNSIGNED_BYTE, treeTexture.imageData);

		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glEnable(GL_TEXTURE_2D);
		if (treeTexture.imageData)		
		{
		free(treeTexture.imageData);					// Free The Texture Image Memory ( CHANGE )
		}
		return true;	
	}													// Return The Status
	else return false;
}

and the display function :

void display(void)
{

	int x, y;
	float float_x, float_y, float_xb, float_yb;
	
	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity ();
	
//	glScalef ( -1,-1 ,-1 );
	glTranslatef(0.0f,0.0f,-12.0f);
	  	

	glBegin(GL_QUADS);
	for( x = 0; x < 44; x++ )
	{
		for( y = 0; y < 44; y++ )
		{
			float_x = float(x)/44.0f;
			float_y = float(y)/44.0f;
			float_xb = float(x+1)/44.0f;
			float_yb = float(y+1)/44.0f;

			glTexCoord2f( float_x, float_y);
			glVertex3f( points[x][y][0], points[x][y][1], points[x][y][2] );

			glTexCoord2f( float_x, float_yb );
			glVertex3f( points[x][y+1][0], points[x][y+1][1], points[x][y+1][2] );

		    glTexCoord2f( float_xb, float_yb );
			glVertex3f( points[x+1][y+1][0], points[x+1][y+1][1], points[x+1][y+1][2] );

			glTexCoord2f( float_xb, float_y );
			glVertex3f( points[x+1][y][0], points[x+1][y][1], points[x+1][y][2] );
		}
	}
	glEnd();

	if( wiggle_count == 2 )
	{
		for( y = 0; y < 45; y++ )
		{
			hold=points[0][y][2];
			for( x = 0; x < 44; x++)
			{
				points[x][y][2] = points[x+1][y][2];
			}
			points[44][y][2]=hold;
		}
		wiggle_count = 0;
	}

	wiggle_count++;

	Sleep(5);
	glutSwapBuffers();
	
   
}

and here s how it looks :X

the next step is my new problem now… :frowning:

i have a project where i imported some models that i made in 3ds max , in wich you can move with mouse + WASD , added lightning , a GLUI interface

i wanted to add the flag on top of another model , a castle.

the flag appears , waves , but with no texture on … i looked a lot , but no luck solving it .
i just copied the code from the previous clean project , in which the flag was textured (as you can see in my prevoius post) .

i ll try to add as little code as i can … some functions i ll only write the definition.

//my first function is the texture function that i wrote in the prevoius post
bool LoadTreeTextures(){
.....}

//the timer function that mbentrup suggested , thanks again
void timer(int unused){
......}

void myGlutIdle( void ){
......}

//the reshape function
void reshape (int w, int h)

{
   int unused;

   glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
   glutSetCursor(GLUT_CURSOR_NONE); //Hide cursor
   glutWarpPointer(WINDOW_WIDTH/2, WINDOW_HEIGHT/2); //Bring cursor to center
   glMatrixMode (GL_PROJECTION);  //next lines of code will affect the projection matrix
   glLoadIdentity();

   gluPerspective (45.0, (GLfloat)w / (GLfloat)h, 1.0, 1000.0); 
 
  timer(unused);

  glutPostRedisplay();
}

//function that draws 3ds max object .obj
void drawmodel(void){
...}

//camera function for mouse rotation
void camera (void) {
....}

//my display function :
void display(void)
{
    int x, y;
    float float_x, float_y, float_xb, float_yb;
	
    glClearColor (1.0,1.0,1.0,1.0);                     //clear the screen to black
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
	
   
    glMatrixMode (GL_MODELVIEW);  
   glLoadIdentity(); 
        camera();										   
glPushMatrix();					
  glScalef(300,300,300);
  drawmodel2();
glPopMatrix();
	
	//FLAG//
  glTranslatef(0.0f,-90.0f,60.0f);		
	
  glBindTexture(GL_TEXTURE_2D, texture);

	glBegin(GL_QUADS);
	for( x = 0; x < 44; x++ )
	{
		for( y = 0; y < 44; y++ )
		{
			float_x = float(x)/44.0f;
			float_y = float(y)/44.0f;
			float_xb = float(x+1)/44.0f;
			float_yb = float(y+1)/44.0f;

			glTexCoord2f( float_x, float_y);
			glVertex3f( points[x][y][0], points[x][y][1], points[x][y][2] );

			glTexCoord2f( float_x, float_yb );
			glVertex3f( points[x][y+1][0], points[x][y+1][1], points[x][y+1][2] );

			glTexCoord2f( float_xb, float_yb );
			glVertex3f( points[x+1][y+1][0], points[x+1][y+1][1], points[x+1][y+1][2] );

			glTexCoord2f( float_xb, float_y );
			glVertex3f( points[x+1][y][0], points[x+1][y][1], points[x+1][y][2] );
		}
	}
	
	glEnd();

	if( wiggle_count == 2 )
	{
		for( y = 0; y < 45; y++ )
		{
			hold=points[0][y][2];
			for( x = 0; x < 44; x++)
			{
				points[x][y][2] = points[x+1][y][2];
			}
			points[44][y][2]=hold;
		}
		wiggle_count = 0;
	}

	wiggle_count++;

glutSwapBuffers();
}


my init function:
int initGL(GLvoid)										
{

	if (!LoadTreeTextures())								// Jump To Texture Loading Routine ( NEW )
	{
		return FALSE;									// If Texture Didn't Load Return FALSE
	}

   glEnable(GL_TEXTURE_2D);
	
   glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);
   glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
   glLightfv(GL_LIGHT0,GL_SPECULAR,specularLight);
   glLightfv(GL_LIGHT0,GL_POSITION,lightDir);
   
     
   glMaterialfv(GL_FRONT, GL_SPECULAR, specularReflection);
   glMateriali(GL_FRONT,GL_SHININESS,128);

   glEnable(GL_LIGHT0);                         	              // activate light0
   glEnable(GL_LIGHTING);                       	              // enable lighting
   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight); 	      // set light model
   glEnable(GL_COLOR_MATERIAL);                 	              // activate material
   glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
   glEnable(GL_NORMALIZE);										  // normalize normal vectors

   glShadeModel(GL_SMOOTH);						        // Enables Smooth Shading

   glEnable(GL_DEPTH_TEST);						        // Enables Depth Testing
   glDepthFunc(GL_LEQUAL);						        // The Type Of Depth Test To Do
   glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);   // Really Nice Perspective Calculations
   

  // glEnable (GL_FOG); //enable the fog
   glFogf(GL_FOG_START, 1.0f);				// Fog Start Depth
   glFogf(GL_FOG_END, 100.0f);				// Fog End Depth
   glFogi (GL_FOG_MODE, GL_EXP2); //set the fog mode to GL_EXP2
   glFogfv (GL_FOG_COLOR, fogColor); //set the fog color to our color chosen above
   glFogf (GL_FOG_DENSITY, density); //set the density to the value above
   glHint (GL_FOG_HINT, GL_NICEST); // set the fog to look the nicest, may slow down on older cards
          
   glPolygonMode( GL_BACK|GL_FRONT , GL_FILL );
   for(int x=0; x<45; x++)
	{
		for(int y=0; y<45; y++)
		{
			points[x][y][0]=float((x/5.0f)-4.5f);
			points[x][y][1]=float((y/5.0f)-4.5f);
			points[x][y][2]=float(sin((((x/5.0f)*40.0f)/360.0f)*3.141592654*2.0f));
		}
	}

   return TRUE;								            // Initialization Went OK
}

//hot keys keyboard funnction :
void (keyboard){
...}

void mouseMovement(int x, int y){
...}

int main(int argc, char** argv)
{
 //  glutInit(&argc, argv);

   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
  
   glutInitWindowPosition (200, 200);				   //window position 
   glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);    //window size

   main_window = glutCreateWindow( "Castle Project" );
   //glutCreateWindow (argv[0]);
   
   glutDisplayFunc(display); 

    glutReshapeFunc(reshape);

   initGL ();

   glutPassiveMotionFunc(mouseMovement); //check for mouse movement
   glutKeyboardFunc(keyboard);

  ....some GLUI code for interface...

      glutTimerFunc(40,timer,0);

   glutMainLoop();
   return 0;
}


can someone see why isn`t my flag textured ?? plsss

here s picture :

in your loadTreeTexture function you define the texture as treeTexture.texID

in your display function, you define the texture as texture.

I think you are not binding the texture correctly.

Dale

hy delemac , thanks for having a look !

i also think that i m not bindig the texture correctly , but sadly it s not what you said…

here s how the var it s declaired :

GLuint texture;
Texture treeTexture;

the texture var is used for reading the image data , used for the texture , it s from the .tga loader which is in another file “Texture.cpp”

this is the texture var. structure from “Texture.h” :

typedef	struct									
{
	GLubyte	* imageData;									// Image Data (Up To 32 Bits)
	GLuint	bpp;											// Image Color Depth In Bits Per Pixel
	GLuint	width;											// Image Width
	GLuint	height;											// Image Height
	GLuint	texID;											// Texture ID Used To Select A Texture
	GLuint	type;											// Image Type (GL_RGB, GL_RGBA)
} Texture;	

and the function glBindTexture takes this kind of parameteres (GLenum target , GLuint texture);

, the second being an GLuint … so it woun`t work if i pass the treeTexture var , because its not an int.

any other ideeas , suggestions ??

That is true, but from what i understand, you are binding the structure, not the actual id of the structure.

for example, when im binding my textures, i use this configuration:


#define TEXTURES_NUM 1   // define the number of textures 
#define TEXTURE1 0  // id the texture

GLuint	textureID[TEXTURES_NUM]; 

glGenTextures(TEXTURES_NUM, textureID); //create the id list

// A Structure For RGB textures
typedef struct imageRGB
{
	GLuint   width;
	GLuint   height;
	GLubyte* data;
}
imageRGB;

imageRGB img;
if(loadImage("textures/texture1.raw", width,height, &img))
{
	glBindTexture(GL_TEXTURE_2D, textureID[TEXTURE1]);
}

etc.

i guess what im trying to say, is that it doesnt seem to match. Your init function clearly shows that the texture is being loaded, so it has to be something to do with the binding.

delemac , you re right again , it works , thanks for having the patience !

i modified it like this :

 GLuint	texture[1];
 Texture	treeTexture[1];

bool LoadTreeTextures()
{
	if (LoadTGA(&treeTexture[0], "texures/flag_texture.tga"))	
	{		
		glGenTextures(1, &texture[0]);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, treeTexture[0].width, treeTexture[0].height, 0, GL_RGB, GL_UNSIGNED_BYTE, treeTexture[0].imageData);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		
		if (treeTexture[0].imageData)		
		{
					free(treeTexture[0].imageData);						}
		return true;		}							
	else return false;
}

i got confused from the commented code from the loading textures tutorial , from where i ve inspired myself , because of this:
// This tells opengl to create 1 texture and put it’s ID in the given integer variable
// OpenGL keeps a track of loaded textures by numbering them: the first one you load is 1, second is 2, …and so on.
glGenTextures(1, &treeTexture.texID);

but now , my castle will have a kickass flag :smiley:

Hey Adrian,

Your welcome, im glad you got it sorted out.

Dale