GL Tutorial : Create Simple Game Menu Using PNG Texture

Donwload this menu

based on how hard to find good example to create game menu with GLUT, Alhamdulillah, finally come out with this result. hope will be usefull for other.

menu

the main idea is using image as background, and textured button. First of all, u need to install glut / helloglut and DevIL library to ur project. no need to show how to install both of these libraries, u can check how to use it in my previous post. and then we can start to add function to display

void display() //registered glutDisplayFunc
{
	if(CurrentState==menu) // see enumerable below
	{
		Menu();
	}
	else if(CurrentState==start)
	{
		Unyu();
	}
	glutPostRedisplay(); //dont forget put this function to redraw after looping
}

this is my enumerable and button structure to define the menu button


enum state{
start,option,menu,highscore
}; // to define state of our game

typedef struct polygon
{
     bool over; /* TRUE if polygon exists */
	 float x1,y1,x2,y2; /* world coordinate */
     int xmin, xmax, ymin, ymax; /* bounding box */
} polygon;


state CurrentState = menu; // initiation global variable

/*all global variables*/

polygon polygons[4];
long selectedMenu=-1; // no button selected by mouse cursor
GLuint MenuFruitTexture;	//texture for main background
GLuint MainTitleTexture;        //texture for main Title
GLuint MenuItemsTexture;       //texture for buttons


and then initialize the position of these buttons / polygons


void InitMenu() // my window size is 800x600 
{
	polygons[0].xmin=200;
	polygons[0].xmax=570;
	polygons[0].ymin=150;
	polygons[0].ymax=205;

	polygons[1].xmin=200;
	polygons[1].xmax=570;
	polygons[1].ymin=245;
	polygons[1].ymax=300;

	polygons[2].xmin=200;
	polygons[2].xmax=570;
	polygons[2].ymin=338;
	polygons[2].ymax=393;

	polygons[3].xmin=200;
	polygons[3].xmax=570;
	polygons[3].ymin=430;
	polygons[3].ymax=485;

	polygons[0].x1=-2;
	polygons[0].x2=3;
	polygons[0].y1=1.25;
	polygons[0].y2=2.0;

	polygons[1].x1=-2;
	polygons[1].x2=3;
	polygons[1].y1=0;
	polygons[1].y2=0.75;

	polygons[2].x1=-2;
	polygons[2].x2=3;
	polygons[2].y1=-1.25;
	polygons[2].y2=-0.5;

	polygons[3].x1=-2;
	polygons[3].x2=3;
	polygons[3].y1=-2.5;
	polygons[3].y2=-1.75;
}

create function to handle, or give event to our button, first off all, we need to handle mouse position wether it is over the button or not

void pick_polygon(long x, long y)
{
   /* find first polygon in which we are in bounding box */
   int i;
   for(i=0; i<4; i++)
   {
       
           if((y>=polygons[i].ymin)&&(y<polygons[i].ymax)&&(x>=polygons[i].xmin)&&(x<=polygons[i].xmax)) 
           //simple algorithm of bouncing box, 
           {   
			 selectedMenu=i; //save which button position mouse cursor is
			 polygons[i].over=1; //give flag to this polygon, that the mouse cursor is over it
			 break;
			   
           }
		   else
		   {
			selectedMenu=-1; //forget the position
			polygons[i].over=0; // remove the flag		
		   }
        }
   
}

void myMouse(int button, int state,int x, int y)
{

	  if (state == GLUT_DOWN) {
			std::cout << "\tbutton is down" << std::endl;

		 if (button == GLUT_LEFT_BUTTON) {
			 myMouseAct(); // what we are going to do when left button clicked over this button
		 }
	  }
}

void MouseMove (int x, int y) // track mouse position with passive method
{
	pick_polygon(x,y);
}

and then here is main function, we will initilize everythings here

int main(int argc, char **argv)
{
glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
    
	
	glutInitWindowSize(800,600);
        glutCreateWindow("Kartun Ngampus");	
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);	//to open png with transparancy, we need to register to gl		
    	
	glutPassiveMotionFunc(MouseMove);
	glutMouseFunc(myMouse);

	// Initialise all DevIL functionality
	ilutRenderer(ILUT_OPENGL);
	ilInit();
	iluInit();
	ilutInit();
	ilutRenderer(ILUT_OPENGL);	// Tell DevIL that we're using OpenGL for our rendering

	InitMenu();
	MenuFruitTexture= loadImage("Menu/Menu.png");
	MainTitleTexture= loadImage("Menu/MenuTitleFruit.png");
	MenuItemsTexture= loadImage("Menu/MenuItems.png");
	
	
	
	glutDisplayFunc(display);
    glutMainLoop();       
    return 0;
}

and then last function is Menu function with all rendered texture


void Menu()
{	

	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity(); 
	
	glScalef(0.25,0.25,0.25);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glEnable(GL_TEXTURE_2D); 
	glEnable(GL_BLEND);
	glBindTexture(GL_TEXTURE_2D,MenuFruitTexture);	
	glBegin(GL_QUADS);		
	glTexCoord2f(0.0f, 0.0f); 	glVertex2f(-4,   -4);
	glTexCoord2f(0.0f, 1.0f); 	glVertex2f(-4,   4);
	glTexCoord2f(1.0f, 1.0f); 	glVertex2f(4, 4);
	glTexCoord2f(1.0f, 0.0f); 	glVertex2f(4, -4);	
	glEnd();
	glDisable(GL_BLEND);
	glDisable(GL_TEXTURE_2D);
	
	glEnable(GL_TEXTURE_2D); 
	glEnable(GL_BLEND);
	glBindTexture(GL_TEXTURE_2D,MainTitleTexture);	
	glBegin(GL_QUADS);		
	glTexCoord2f(0.0f, 0.0f); 	glVertex2f(-4.85,   -9.0f);
	glTexCoord2f(0.0f, 1.0f); 	glVertex2f(-4.85,  4.0f);
	glTexCoord2f(1.0f, 1.0f); 	glVertex2f(7, 4.0f);	
	glTexCoord2f(1.0f, 0.0f); 	glVertex2f(7, -9.0f);	
	glEnd();
	glDisable(GL_BLEND);
	glDisable(GL_TEXTURE_2D);
	
	glEnable(GL_TEXTURE_2D); 
	glEnable(GL_BLEND);
	glBindTexture(GL_TEXTURE_2D,MenuItemsTexture);	
	for(int i=0;i<4;i++)
	{		
	glBegin(GL_QUADS);
		if(!polygons[i].over)
		{
		glTexCoord2f(0.0f, 0.56f);	glVertex2f(polygons[i].x1 , polygons[i].y1);
		glTexCoord2f(0.0f, 1.0f); 	glVertex2f(polygons[i].x1 , polygons[i].y2);
		glTexCoord2f(1.0f, 1.0f); 	glVertex2f(polygons[i].x2  , polygons[i].y2);
		glTexCoord2f(1.0f, 0.56f); 	glVertex2f(polygons[i].x2  , polygons[i].y1);			
		}
		else
		{
		glTexCoord2f(0.0f, 0.0f);	glVertex2f(polygons[i].x1 , polygons[i].y1-0.1);
		glTexCoord2f(0.0f, 0.55f); 	glVertex2f(polygons[i].x1 , polygons[i].y2-0.1);
		glTexCoord2f(1.0f, 0.55f); 	glVertex2f(polygons[i].x2  , polygons[i].y2-0.1);
		glTexCoord2f(1.0f, 0.0f); 	glVertex2f(polygons[i].x2  , polygons[i].y1-0.1);			
		}
	glEnd();
	}

	glDisable(GL_BLEND);
	glDisable(GL_TEXTURE_2D);

	glColor3f(1,1,1);
	DrawText(-0.55,1.5,"Start");
	DrawText(-0.65,0.25,"Option");
	DrawText(-1.0,-1,"High Score");
	DrawText(-0.55,-2.25,"Exit");		

	glutSwapBuffers();
}

to DrawText, use this function

void DrawText(float x,float y, char *text)
{
    glPushMatrix();
    glTranslatef(x, y, 0);
    glScalef(0.0025,0.0025,0.0025);
    for( char* p = text; *p; p++)
    {
        glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
    }
    glPopMatrix();
}

yep, thats all, if u want to change the png files, make sure u make ur images in 2^n resolution such as 512×128, 256×256, 1024×1024 etc, otherwise, devil will failed to load the png file. good luck.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s