Problem with items staying projected on screen.

Hello guys. This is my first time here, and as a noob in OpenGl I have a simple ,but hard for me, problem. I’m making a tetris-like program, but each time I want to display the shapes to the position they end up, the window clears itself. I cannot explain it better, so here is the code:


#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
//-------------------------GLOBAL VARIABLES------------------------------
int score=0;
char scoreview[7]=" ";
float myX=80, myY=-40;
float width=40, height=40;
GLsizei winWidth = 240, winHeight = 550;

GLuint regcube;
//-------------------------FUNCTIONS---------------------------
void reshape(GLint newWidth, GLint newHeight)
{
	glViewport (0, 240, 0, 520);
	
	glMatrixMode (GL_PROJECTION);
	glLoadIdentity ( );
	
	glOrtho (0, 240, 520, 0, 1,-1);
	
	glMatrixMode (GL_MODELVIEW); // κατασκευή πίνακα για τους γεωμετρικούς μετασχηματισμούς
	glLoadIdentity ();
	
	glClear (GL_COLOR_BUFFER_BIT);
	
}
void drawBitmapText(char *string,float x,float y) 
{  
	char *c;
	glColor3f(0.0, 0.0, 0.0);
	glRasterPos2f(x, y);
	for (c=string; *c != '\0'; c++) 
	{	
		glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *c);
	}
}

void keyboard (unsigned char key, int x, int y)
{
	switch (key)
	{
		case 27:
		exit(0);
	
		case 115:
		if(myX!=0)
		{
			myX-=40;
		}
		break;
		
		case 102:
		if(myX!=200)
		{
			myX+=40;
		}
		break;
	}
		
}


void display (void)
{

	glutKeyboardFunc(keyboard);
	if(myY!=480){
		myY+=40;
		score++; //checking if score changes without problems
	}
	else{
		myY=-40;
	}
	glClear (GL_COLOR_BUFFER_BIT);  // Clear display window.
//---------------------------------------printing------------------------
	if(myY == 480){
		printf("entered if
");
		glColor3f (0.0, 0.0, 0.0);
		glBegin(GL_QUADS);
		glVertex2f(myX, myY);		
		glVertex2f(myX+width, myY);		
		glColor3f(0.8,0.0,0.8);
		glVertex2f(myX+width, myY+height);		
		glVertex2f(myX, myY+height);		
		glEnd();

		glBegin(GL_LINES);
		glVertex2f(0, 500); 
		glVertex2f(240, 500); 
		glEnd( );
	}
//-----------------------------------------------------------------------
    	glColor3f (0.0, 0.0, 0.0);

//rendering line to separate space for score------------------------
	glBegin(GL_LINES);
		glVertex2f(0, 521); 
		glVertex2f(240, 521); 
	glEnd( );

//rendering score---------------------------------------------------
	sprintf(scoreview, "SCORE:%d", score);
	drawBitmapText(scoreview, 10,545);	
	
//setting matrix mode for object movement---------------------------
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();


//object movement code----------------------------------------------
	
	glPushMatrix();
//	glTranslatef(0.0f, 40.0f, 0.0f);
//	glColor3f (0.0, 0.0, 0.0);
	glBegin(GL_QUADS);
	glVertex2f(myX, myY);		//katw aristerh
	glVertex2f(myX+width, myY);		//katw deksia
	glColor3f(0.8,0.0,0.8);
	glVertex2f(myX+width, myY+height);		//panw deksia
	glVertex2f(myX, myY+height);		//panw aristera
	glEnd();

	glutPostRedisplay ( );	
	glPopMatrix();

//	glLoadIdentity();
	glutSwapBuffers();
	sleep(1);
	glFlush ( );			// Process all OpenGL routines as quickly as possible.
}

void init (void)
{
    	glClearColor (1.0, 1.0, 1.0, 0.0);  // Set display-window color to black.
	glMatrixMode (GL_PROJECTION);       // Set projection parameters.
	glLoadIdentity();
	glOrtho (0, 240, 550, 0, 1,-1);		//gluOrtho2d did not work properly, this one sets the ortho

}


//-------------------------MAIN--------------------------------
int main (int argc, char** argv)
{
	int playwindow;
   	glutInit (&argc, argv);                         	// Initialize GLUT.
	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);   	// Set display mode.
	glutInitWindowPosition (100, 100);   		// Set top-left display-window position.
	glutInitWindowSize (240, 550);      		// Set display-window width and height.
	glutCreateWindow ("VraXaPsa"); 			// Create display window.
	glViewport(0, 0, 240, 550);
	glutKeyboardFunc(keyboard);		//edw

	init ( );                        		// Execute initialization procedure.
	glutDisplayFunc (display);       		// Send graphics to display window.

	glutMainLoop();					// Display everything and wait.
	return 0;
}

If anyone can help, it would be much much appreciated. Not just because it is a minor problem, but because I think the problem lies in me not understanding OpenGl clearly, and I think I might have messed up the initialisation of the program.

Looking over your code, it seems you’ve set your projection matrix up correctly, and your drawing code looks to be sound.

If I understand your code correctly, you’re clearing to white (even though your comments say black), drawing a square (gradient black to purple) that should move from top to bottom in a loop, moving once a second. You also draw a black line 30 pixels above the bottom and draw your score in the area below the line. Is that right?

I don’t think it makes a difference because you don’t have backface culling enabled, but I think your square is defined clockwise, meaning that you technically are looking at the back of it.

Besides that, the glutPostRedisplay(), glutSwapBuffers(), sleep(1), and glFlush() seem a little worrisome to me. From what little I understand of GLUT, you should only be calling glutPostRedisplay() at the very end of the display function; you’re flagging glut to run display as soon as possible, but it’s not even done running that iteration of display.

I’m not 100% sure about this, but I think glFlush() needs to go before glutSwapBuffers() if you choose to use it, but it might actually be redundant in this context.

Lastly, sleep(1) is a bad idea here. I know you want to slow it down to be visible, but as far as I know sleep(1) will sleep the whole thread, meaning it won’t accept input or do anything for that whole second. It would be better to keep a count of milliseconds and change only the value of myY. Let the display run as fast as it needs to, so you can update the x position of your block in response to keyboard input as well.

Your code seems to run fine on my Windows 7 PC. I compiled it with VC++ 2010 Express.
It shows a little square translating from the top of the window to the bottom.
When it reaches the bottom it starts over again. Is this not what you want?

Do you want to show a trail of squares left behind the moving square?
If so, this is not hard. Let us know.

On a separate note (not related to your problem) -

You are doing something a bit unorthodox to animate the square.
glutPostRedisplay is usually not called within the Display function.
All glutPostRedisplay does is call Display, which means you are
effectively calling the Display function recursively to do animation.
The recommended way to do animation is to use glutIdleFunc.
Read up on it and look at some examples. I think you’ll get better
control of the animation if you use glutIdleFunc. glutPostRedisplay
is called from within the function designated by glutIdleFunc.

Good luck. Carmine

[QUOTE=Carmine;1245155]
You are doing something a bit unorthodox to animate the square.
glutPostRedisplay is usually not called within the Display function.
All glutPostRedisplay does is call Display, which means you are
effectively calling the Display function recursively to do animation.[/QUOTE]

It’s not so much unorthodox as it is typical of beginner tutorials: fastest results with the least amount of code. Do mind though, that glutPostRedisplay just queues up another call to display the next time GLUT goes through its main loop. It’s not a recursive call, or the program would stack overflow pretty quickly.

That said, I do agree that moving the glutPostRedisplay to the glutIdleFunc is a better approach.

please i need help how can help me ,i realy need it in my hw to put comment in the code and describe the job of each function

Guys thank you a lot for the help (I’m still a noob but gladly I almost finished the project). I was informed buy the teacher that the glutIdleFunc (though not informed as I should have been from the beggining) is crucial for the correct display of everything in the window (or the glutTimerFunc i think). The problem was, that at the begining of the exams, we where informed that glutMainLoop() was all you need for the program to loop itself, so as a noob, I went with pure logic and said “yeah, so it should be working”.

glutPostRedisplay code was moved in the code because it was troubling other things I did in the program afterwards.
Again thank you for your time on this one, was truely appreciated.

Now if I may ask one more question here:
I need to put textures, actualy import .pgm files in the program so first thing to do is read the information and pixels from the files. The problem is, when I use fscanf() to read the pixels (will be stored in unsigned char *pixels) do I need just store the numbers, one next to the other, or do they have to be separated, in the way they appear on the .pgm data? To be more clear, I’ll be passing unsigned char *pixels as an variable in glTexture2D() as the final data.
If anyone can help, I would truely owe him 20% of the grade hehe.
Thanks for any help in advance.

Glad to hear that it’s working better now.

As for your .pgm file loading, load the numbers directly into the char array. The spaces separating each value are pretty much only for human readability, something that won’t be necessary for your texture.

That was exactly the kind of information I was seeking. I hope I can get it running with textures till monday. I’ll post a responce if everything goes as planned. Thank you all again for your time and help.