So i'm making a game(something similar to a pong)using openGl in cpp , and when i try running the program , the image rendering is too slow ,i feel something is taking a huge toll on my GPU memory ,
(So far i have competed the drawing and movement of the paddle which works fine and the problem arises when the ball is set to motion on the press of a button , Everything slows down after this )
Here i have attached a portion of my code
Point out any deficiencies in my code
#include<stdlib.h>
#include<GL/glut.h>
#include<windows.h>
#include<iostream>
//#include<sstream>
#include<stdio.h>
#include<ctime>
#include<string.h>
typedef double point[3];
point a,b,c,d;
static float xmove=0.0;
static int release=0;
static float ii=0.00;
static int reac_top;
using namespace std;
//GLvoid player1_box();
GLfloat xangle=0.0;
float changeDir=1;// positive direction
double vv[4][3]={ {0.5,0.2,0.0},{ 0.5,0.25,0.0},{0.7,0.25,0.0},{0.7,0.2,0.0}};
void renderoutline()
{
glBegin(GL_LINE_LOOP);
glColor3f(1,0,0);
glVertex2f(0.0,0.0);
glColor3f(1,0,0);
glVertex2f(0,1.2);
glColor3f(1,0,0);
glVertex2f(1.2,1.2);
glColor3f(1,0,0);
glVertex2f(1.2,0);
glEnd();
}
void ball()
{
glBegin(GL_POLYGON);
glColor3f(0,0,1);
glVertex3f(0.6,0.25,0.0);
glColor3f(0,0,1);
glVertex3f(0.6,0.28,0.0);
glColor3f(0,0,1);
glVertex3f(0.62,0.28,0.0);
glColor3f(0,0,1);
glVertex3f(0.62,0.25,0.0);
glEnd();
}
void renderbox1( point a , point b , point c, point d)
{
glBegin(GL_POLYGON);
glColor3f(0,0,0);
glVertex3dv(a);
glColor3f(0,0,0);
glVertex3dv(b);
glColor3f(0,0,0);
glVertex3dv(c);
glColor3f(0,0,0);
glVertex3dv(d);
glEnd();
}
void keyboard(unsigned char key,int x,int y)
{
switch(key){
case 'a':xangle-=0.1;
++xmove;
while(xmove>5)
{
xmove=-5;
xangle=0.5;
continue;
}
break;
case 'd':xangle+=0.1;
--xmove;
while(xmove<-5)
{
xmove=5;
xangle =-0.5;
continue;
}
break;
case 'r':
release=1;
//printf("Inside switch r");
break;
}
glutPostRedisplay();
}
void display()
{
Sleep(2);
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glLineWidth(3.0);
glLoadIdentity();
glTranslatef(xangle,0,0);
renderbox1(vv[0],vv[1],vv[2],vv[3]); // To draw the paddle
glPopMatrix();
//printf("x move in disp:%1f \n",xmove);
renderoutline();
glPushMatrix();
glTranslatef(0,ii,0);
ball(); //To draw the ball
glPopMatrix();
glFlush();
}
void moveBall(){ //glutidlefunction
if(release==1)
{ //Release becomes one when the key 'r' is pressed (glutkeyboardfunc)
Sleep(500);
if(ii>=0&&ii<=0.9 )
{
reac_top=false;
ii=ii+0.05;printf("1\n");//The ball which was intially on the paddle starts moving till it reaches the top edge of thescreen
}
else if(ii>=0.9)
{
//when the boll reaches top
ii=ii-0.05;
reac_top=3;
printf("2\n");
}
else if( (ii<0.9)&& (reac_top==3)&&(ii>0.05)) //The balls journey back to the paddle
{
printf("3\n");
ii=ii-0.05;
}
release=1;
}
}
void reshape(int w, int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1.2, 0, 1.2,-10.0,10.0);
glMatrixMode(GL_MODELVIEW);
glViewport(0,0,w,h);
//glutPostRedisplay();
//Use the whole window for rendering
}
int main(int argc ,char **argv)
{
//clock_t begin= clock();
char n1,n2;
int ack;
/*printf("The object of Tic Tac Toe is to get three in a row. \n . Players alternate placing Xs and Os(Traingles and Boxes in this version) \n on the game board until either opponent has three \n in a row or all nine squares are filled(Which would be a drawObviously). \n");
printf("\n Press 1 if acknowledged \n");
scanf("%d",&ack);*/
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(1000,500);
glutInitWindowPosition(200,0);
glutCreateWindow("3d Gasket");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutIdleFunc(moveBall);
glClearColor(1,1,1,1);
glutMainLoop();
//clock_t end=clock();
}
You're using c++, use C++-style (stdlib.h -> cstdlib) headers.
Apply your projection/modelview matrices each time through display() instead of a reshape callback, helps prevent annoying matrix stack issues.
Don't Sleep(), use a timer/idle callback to glutPostRedisplay(). Bonus points for framerate-independent movement (you can use glutGet(GLUT_ELAPSED_TIME) to calculate delta-t).
Without Sleep() there's no reason to drag windows.h into things.
All together:
#include <GL/glut.h>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <cstring>
typedef double point[3];
point a,b,c,d;
static float xmove=0.0;
static int release=0;
static float ii=0.00;
static int reac_top;
using namespace std;
GLfloat xangle=0.0;
float changeDir=1;// positive direction
double vv[4][3]={ {0.5,0.2,0.0},{ 0.5,0.25,0.0},{0.7,0.25,0.0},{0.7,0.2,0.0}};
void renderoutline()
{
glBegin(GL_LINE_LOOP);
glColor3f(1,0,0);
glVertex2f(0.0,0.0);
glColor3f(1,0,0);
glVertex2f(0,1.2);
glColor3f(1,0,0);
glVertex2f(1.2,1.2);
glColor3f(1,0,0);
glVertex2f(1.2,0);
glEnd();
}
void ball()
{
glBegin(GL_POLYGON);
glColor3f(0,0,1);
glVertex3f(0.6,0.25,0.0);
glColor3f(0,0,1);
glVertex3f(0.6,0.28,0.0);
glColor3f(0,0,1);
glVertex3f(0.62,0.28,0.0);
glColor3f(0,0,1);
glVertex3f(0.62,0.25,0.0);
glEnd();
}
void renderbox1( point a , point b , point c, point d)
{
glBegin(GL_POLYGON);
glColor3f(0,0,0);
glVertex3dv(a);
glColor3f(0,0,0);
glVertex3dv(b);
glColor3f(0,0,0);
glVertex3dv(c);
glColor3f(0,0,0);
glVertex3dv(d);
glEnd();
}
void keyboard(unsigned char key,int x,int y)
{
switch(key)
{
case 'a':xangle-=0.1;
++xmove;
while(xmove>5)
{
xmove=-5;
xangle=0.5;
continue;
}
break;
case 'd':xangle+=0.1;
--xmove;
while(xmove<-5)
{
xmove=5;
xangle =-0.5;
continue;
}
break;
case 'r':
release=1;
break;
}
}
void display()
{
glClearColor(1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1.2, 0, 1.2,-10.0,10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glLineWidth(3.0);
glLoadIdentity();
glTranslatef(xangle,0,0);
renderbox1(vv[0],vv[1],vv[2],vv[3]); // To draw the paddle
glPopMatrix();
renderoutline();
glPushMatrix();
glTranslatef(0,ii,0);
ball();
glPopMatrix();
glFlush();
}
void moveBall()
{
if(release==1)
{
//Release becomes one when the key 'r' is pressed (glutkeyboardfunc)
if(ii>=0&&ii<=0.9 )
{
reac_top=false;
ii=ii+0.05;printf("1\n");//The ball which was intially on the paddle starts moving till it reaches the top edge of thescreen
}
else if(ii>=0.9)
{
//when the boll reaches top
ii=ii-0.05;
reac_top=3;
printf("2\n");
}
else if( (ii<0.9)&& (reac_top==3)&&(ii>0.05)) //The balls journey back to the paddle
{
printf("3\n");
ii=ii-0.05;
}
release=1;
}
}
void timer( int value )
{
moveBall();
glutTimerFunc( 16, timer, 0 );
glutPostRedisplay();
}
int main(int argc ,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(1000,500);
glutInitWindowPosition(200,0);
glutCreateWindow("3d Gasket");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutTimerFunc( 0, timer, 0 );
glutMainLoop();
}
Related
I'm currently doing an assignment in OpenGL and what I'm supposed to do is make two disks and then as I move the cursor on the screen and click the two disks should move to that position where I click on the window but the trick is that both the disks should not move together. The first disk should move and then after a small delay the second disk should move. Now I have been able to make both the disks move together at the point I click. What I want to know is how am I supposed to add a delay in the movement of both the disks. Please help!
This is my current code. Thanks!
EDIT:
Here's my updated code after implementing exactly what you said and now none of the disks are moving. If you understand the problem, fine otherwise thanks for all the help :)
#include <math.h>
#include <cstdlib>
#include <glut.h>
typedef struct _Vector
{
double x,y,z;
} Vector;
const int W_SCREEN = 1366;
const int H_SCREEN = 768;
const double PI = 3.14159265;
GLUquadric *qobja;
double speed = 10;
double radian;
double rot;
Vector pos2;
Vector pos;
Vector vel;
Vector dis;
Vector dir;
Vector mousecoords;
void mouse(int button, int state, int x , int y)
{
mousecoords.x = x - W_SCREEN/2;
mousecoords.y = -y + H_SCREEN/2;
}
void move()
{
dis.x = mousecoords.x - pos.x;
dis.y = mousecoords.y - pos.y;
if(sqrt(dis.x*dis.x + dis.y*dis.y) < speed)
{
pos.x = mousecoords.x;
pos.y = mousecoords.y;
pos2.x = mousecoords.x;
pos2.y = mousecoords.y;
}
else
{
radian = atan2(dis.y,dis.x);
pos.x += cos(radian)*speed;
pos.y += sin(radian)*speed;
pos2.x += cos(radian)*speed;
pos2.y += sin(radian)*speed;
}
}
void moveSecondDisk(int value)
{
// Code that moves (updates coordinates) of second disk
move();
glutPostRedisplay();
}
void moveFirstDisk(int value)
{
// Code that moves (updates coordinates) of first disk
move();
glutPostRedisplay();
unsigned int secondDiskDelay = 5000;
glutTimerFunc(secondDiskDelay, moveSecondDisk, 0);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glOrtho(-W_SCREEN/2,W_SCREEN/2,-H_SCREEN/2,H_SCREEN/2,-100,100);
qobja = gluNewQuadric();
gluQuadricNormals(qobja, GLU_SMOOTH);
glPushMatrix();
glColor3f(0,0,0);
glTranslated(pos.x,pos.y,0);
gluCylinder(qobja,25,50,0,100,100);
glPopMatrix();
glPushMatrix();
glColor3f(0,0,0);
glTranslated(pos2.x,pos2.y,0);
gluCylinder(qobja,50.5,65,0,100,100);
glPopMatrix();
/*glPushMatrix();
glColor3f(0,0,0);
glTranslated(pos.x,pos.y,0);
gluCylinder(qobja,65.5,80,0,100,100);
glPopMatrix();
glPushMatrix();
glColor3f(0,0,0);
glTranslated(pos.x,pos.y,0);
gluCylinder(qobja,80.5,90,0,100,100);
glPopMatrix();
glPushMatrix();
glColor3f(0,0,0);
glTranslated(pos.x,pos.y,0);
gluCylinder(qobja,90.5,100,0,100,100);
glPopMatrix();
glPushMatrix();
glColor3f(0,0,0);
glTranslated(pos.x,pos.y,0);
gluCylinder(qobja,100.5,110,0,100,100);
glPopMatrix();
glPushMatrix();
glColor3f(0,0,0);
glTranslated(pos.x,pos.y,0);
gluCylinder(qobja,110.5,120,0,100,100);
glPopMatrix();
glPushMatrix();
glColor3f(0,0,0);
glTranslated(pos.x,pos.y,0);
gluCylinder(qobja,120.5,130,0,100,100);
glPopMatrix();
glPushMatrix();
glColor3f(0,0,0);
glTranslated(pos.x,pos.y,0);
gluCylinder(qobja,130.5,140,0,100,100);
glPopMatrix();
glPushMatrix();
glColor3f(0,0,0);
glTranslated(pos.x,pos.y,0);
gluCylinder(qobja,140.5,150,0,100,100);
glPopMatrix();
glPushMatrix();
glColor3f(0,0,0);
glTranslated(pos.x,pos.y,0);
gluCylinder(qobja,150.5,160,0,100,100);
glPopMatrix();
glPushMatrix();
glColor3f(0,0,0);
glTranslated(pos.x,pos.y,0);
gluCylinder(qobja,160.5,170,0,100,100);
glPopMatrix();*/
glFlush();
glutSwapBuffers();
glutPostRedisplay();
}
void init(void)
{
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(W_SCREEN,H_SCREEN);
glutCreateWindow("ORCA WHALE SIMULATION");
glutDisplayFunc(display);
glutMouseFunc(mouse);
unsigned int firstDiskDelay = 2000;
glutTimerFunc(firstDiskDelay, moveFirstDisk, 0);
glClearColor(1,1,1,1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
init();
glutMainLoop();
return(0);
}
Use a timer to accomplish this. Create a function that moves the second disk with the following signature:
void moveSecondDisk(int value);
Then, execute the code that moves the first disk. Finally, call function glutTimerFunc, passing it the function moveSecondDisk as callback (second parameter). The first parameter will be delay between moving of two discs (expressed in miliseconds), and the third one will be value that is passed the callback function. Note that you can pass complex data to callback function by passing a pointer to a complex structure (or an object) as an integer, then casting it back to the desired type in the callback function. For more info, check the following links:
https://www.opengl.org/resources/libraries/glut/spec3/node64.html
https://www.opengl.org/discussion_boards/showthread.php/170990-glutTimerFunc
EDIT:
A more detailed explanation:
void movePos()
{
// Code that only modifies pos
...
}
void movePos2()
{
// Code that only modifies pos2
...
}
void moveSecondDisk(int value)
{
movePos2();
glutPostRedisplay();
}
void moveFirstDisk(int value)
{
movePos();
glutPostRedisplay();
unsigned int secondDiskDelay = 200;
glutTimerFunc(secondDiskDelay, moveSecondDisk, 0);
glutTimerFunc(300, moveFirstDisk, 0);
}
void init()
{
...
unsigned int firstDiskDelay = 50;
glutTimerFunc(firstDiskDelay, moveFirstDisk, 0);
...
}
I am making a basic OpenGl program which is my weekend project.
Description: If I drag the mouse on the window screen then after I release the button(left) a line should appear that shows the path of dragging the mouse and a circle should traverse that line from start to end.
My Code Works Very Well but the problem is that the line drawn is not continuous[rather its dashed] and it may be because of the mapping of OS screen to OpenGL screen.
SO is there any way to make a continous line path or correct me If I am doing something wrongHere is my code:
#include <iostream>
#include <glut.h>
#include <string.h>
#define WIDTH 600
#define HEIGHT 600
using namespace std;
double arr[5000][4];
int z=0;
int flag=0;
float radius=0.03;
int ptr=0;
int faltu_bit=1;
float color[3][3]={{1.0,1.0,1.0},{1.0,1.0,0.0},{0.0,1.0,0.0}};
void drawText(char *str,float x,float y,int id)
{
int i;
int len=strlen(str);
//glLoadIdentity();
glColor3f(color[id][0],color[id][1],color[id][2]);
glRasterPos2f(x,y);
for(i=0;i<len;i++)
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,str[i]);
}
void init()
{
glClearColor( 0.0, 0.0, 0.0, 1.0);
glMatrixMode( GL_PROJECTION);
gluOrtho2D(0.0,WIDTH,0.0,HEIGHT);
memset(arr,0,5000);
glPointSize(20.0);
}
void resetAll()
{
memset(arr,0,5000);
z=0;
}
///OPENGL MAPPING///
float getOpenGLX(int x)
{
double ox = x/ (double)WIDTH*(WIDTH);
return ox;
}
float getOpenGLY(int y)
{
double oy = (1 - y/ (double) HEIGHT)*HEIGHT;
return oy;
}
void drawPoints()
{
glBegin( GL_POINTS );
glColor3f( 0.0,1.0,0.0 );
for ( int i = 0; i < z; i++ )
{
glVertex2f( arr[i][0],arr[i][1]);
}
glEnd();
}
void drawBall(float x,float y)
{
glBegin( GL_POINTS);
glColor3f( 1.0,1.0,0.0 );
glVertex2f(x,y);
glEnd();
}
void drawLines()
{
glBegin(GL_LINES);
glColor3f(1.0,0.0,0.0);
for(int i=0;i<z;i++)
{
glVertex2f(arr[i][0],arr[i][1]);
}
glEnd();
}
void addValue(int x,int y)
{
arr[z][0]=getOpenGLX(x);
arr[z++][1]=getOpenGLY(y);
}
void trackBall()
{
drawPoints();
}
void myDisplay()
{
glClear( GL_COLOR_BUFFER_BIT);
if(!flag)
{
drawLines();
if(!faltu_bit)
drawBall(arr[ptr][0],arr[ptr][1]);
}
if(faltu_bit)
{
drawText("Project by: Adil Ansar [10 CSS-32]",50.0,500.0,0);
drawText("Welcome",250.0,300.0,1);
drawText("Drag the Mouse Any Where in the Window to see the Path",10.0,200.0,2);
}
glutSwapBuffers();
glutPostRedisplay();
glFlush();
}
void myMouseStat(int button,int state,int x, int y)
{
if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
{
if(!flag)
{
if(faltu_bit)
{
faltu_bit=0;
}
resetAll();
flag=1;
}
}
else if(button==GLUT_LEFT_BUTTON && state==GLUT_UP)
{
if(flag)
{
ptr=0;
flag=0;
}
}
}
void myPressedMove(int x,int y)
{
if(flag)
{
addValue(x,y);
}
}
void myTimer(int t)
{
if(ptr!=z)
{
ptr++;
}
else
{
ptr=0;
}
glutTimerFunc(100,myTimer,0);
}
int main( int argc, char ** argv)
{
glutInit( &argc, argv);
glutInitDisplayMode( GLUT_DOUBLE| GLUT_RGB);
glutInitWindowPosition( 100, 100);
glutInitWindowSize(WIDTH,HEIGHT);
glutCreateWindow( "Testing");
init();
glutDisplayFunc(myDisplay);
glutMouseFunc(myMouseStat);
glutMotionFunc(myPressedMove);
glutTimerFunc(100,myTimer,0);
glutMainLoop();
return 0;
}
This Is What I get:
In this code
void drawLines()
{
glBegin(GL_LINES);
glColor3f(1.0,0.0,0.0);
for(int i=0;i<z;i++)
{
glVertex2f(arr[i][0],arr[i][1]);
}
glEnd();
}
GL_LINES is a drawing mode where two consecutive vertices make a line segment. Then the next two and so so. What you're drawing is a line strip; replacing GL_LINES with GL_LINE_STRIP will give you your expected result.
On a side note: You should abandon using immediate mode (glBegin, glVertex, glEnd). It's slow, it's cumbersome to work with and in the long term can become a major PITA. Use at least vertex arrays; they've been the recommended way of supplying geometry data for well over 15 years. Plus it makes your code much simpler. Your code above can be replaced with this:
/* vertex data comes from an array */
glEnableClientState(GL_VERTEX_ARRAY);
/* we want to use a common color for all vertices */
glDisableClientState(GL_COLOR_ARRAY);
glColor3f(1.0, 0.0, 0.0);
/* where to get the data from */
glVertexPointer(2, GL_DOUBLE, sizeof(double)*4, arr);
/* draw the whole thing */
glDrawArrays(GL_LINE_STRIP, 0, z);
/* cleanup */
glDisableClientState(GL_VERTEX_ARRAY);
As you can see it's shorter, more concise, easier to read and it avoids doing z+3 function calls, each of which taking some time to execute.
Important that OpenGL can digest that multidimensional array arr is due to the fact, that statically allocated storage of multidimensional arrays is always contiguous. It would not work if you'd allocate an array of pointers to arrays (the naive way to allocate multidimensional arrays dynamically).
Extra Object(Block,not OOP) is formed while playing Game in Opengl during each move.
I tried to made a Bloxerz game ,in which block is moved with keys on a board , The problem is every time, as i move the block, a new Image of block is formed under the board.
I can't find trace of this thing
I think ,there is nothing wrong with the code and logic except it is written nonprofessional like OpenGl programmers write.
There must be some thing missing,some method to stop this.
In order to make every thing visible,i have shared all my code.
Following is my code:
int s=-1;
int stage=0;
int arr[]={5,5,5,4,4,4,4,5,9,9,10,9,10,8,9,8,10,7,11,7,11,6,10,6};
int fallcount=0;
int fallset=0;
int rot[]={0,0,0};
int axis=0;
int a=0;
double x=0.8,y=1.3,z=1;
double move1=0;
int moved=0;
int pos=1;
int position;
void Init()
{
x=0.8;
y=1.3;
z=1;
move1=0;
moved=0;
pos=1;
position=1;
fallcount=0;
}
void wait ( int seconds )
{
clock_t endwait;
endwait = clock () + seconds * CLOCKS_PER_SEC ;
while (clock() < endwait) {}
}
void FallOn()
{
if(position==1||position==3)
{
if(x<=-0.7||y<=-0.7||x>=11.3||y>=11.3)
{
Init();
}
}
if(stage==1)
{
if(x>=2.8&&y<=5.3&&y>=3.8)
{
Init();
}
if((x>=1.8)&&(x<=5.8)&&(y>=8.8))
{
Init();
}
}
}
void checkpos(int arg)
{
if((position==1)&&(arg==1))
{
position=1;
x=x+1;
return;
}
else if((position==1)&&(arg==2))
{
position=2;
rot[1]=-1;
rot[2]=0;
rot[3]=0;
y=y+2;
x=x+0.5;
return;
}
else if((position==1)&&(arg==3))
{
position=1;
rot[1]=0;
rot[2]=-1;
rot[3]=0;
x=x-1;
return;
}
else if((position==1)&&(arg==4))
{
position=2;
rot[1]=0;
rot[2]=0;
rot[3]=1;
y=y-1;
x=x+0.5;
return;
}
if((position==2)&&(arg==1))
{
position=3;
rot[1]=0;
rot[2]=1;
rot[3]=0;
x=x+1;
y=y-0.5;
return;
}
else if((position==2)&&(arg==2))
{
position=1;
rot[1]=0;
rot[2]=-1;
rot[3]=0;
y=y+1;
x=x-0.5;
return;
}
else if((position==2)&&(arg==3))
{
position=3;
rot[1]=0;
rot[2]=-1;
rot[3]=0;
x=x-2;
y=y-0.5;
return;
}
else if((position==2)&&(arg==4))
{
position=1;
rot[1]=0;
rot[2]=0;
rot[3]=1;
y=y-2;
x=x-0.5;
return;
}
if((position==3)&&(arg==1))
{
position=2;
rot[1]=0;
rot[2]=1;
rot[3]=0;
x=x+2;
y=y+0.5;
return;
}
else if((position==3)&&(arg==2))
{
position=3;
rot[1]=0;
rot[2]=0;
rot[3]=-1;
y=y+1;
return;
}
else if((position==3)&&(arg==3))
{
position=2;
rot[1]=0;
rot[2]=-1;
rot[3]=0;
x=x-1;
y=y+0.5;
return;
}
else if((position==3)&&(arg==4))
{
position=3;
rot[1]=1;
rot[2]=0;
rot[3]=0;
y=y-1;
return;
}
}
void draw_string( int x, int y,int z ,const char * buffer ) {
// function to draw a string in glut
glRasterPos3i( x, y,z );
// i think its safe to assume a null terminator appears somewhere
while( *buffer )
glutBitmapCharacter( (void *)GLUT_BITMAP_TIMES_ROMAN_24, *(buffer++) );
}
void Display()
{
FallOn();
glLoadIdentity();
//glu look at
gluLookAt(-30,-30,30,2.5,4,0,0,0,1);
//***********************************************Board************************************************************************
if(stage==0)
{
glBegin(GL_POLYGON);
for(int i=0;i<=12;i++)
{
for(int j=0;j<=12;j++)
{
glColor3d(1,0,1);
glVertex3d(i,i,0);
glVertex3d(j,i,0);
glVertex3d(j,j,0);
glVertex3d(i,j,0);
}
}
glEnd();
glBegin(GL_POLYGON);
glColor3d(0,0,0);
glVertex3d(arr[s+1],arr[s+2],0);
glVertex3d(arr[s+3],arr[s+4],0);
glVertex3d(arr[s+5],arr[s+6],0);
glVertex3d(arr[s+7],arr[s+8],0);
glEnd();
glBegin(GL_LINES);
glColor3d(0,0,0);
for(int i=0;i<=12;i++)
{
glVertex3d(0,i,0);
glVertex3d(12,i,0);
glVertex3d(i,0,0);
glVertex3d(i,12,0);
}
glEnd();
}
else if(stage==1)
{
glFlush();
glClear(GL_CLIP_PLANE0);
glClear(GL_ACCUM_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT);
glBegin(GL_POLYGON);
for(int i=0;i<=12;i++)
{
for(int j=0;j<=12;j++)
{
glColor3d(1,0,1);
glVertex3d(i,i,0);
glVertex3d(j,i,0);
glVertex3d(j,j,0);
glVertex3d(i,j,0);
}
}
glEnd();
glBegin(GL_POLYGON);
glColor3d(0,0,0);
glVertex3d(3,4,0);
glVertex3d(3,6,0);
glVertex3d(12,6,0);
glVertex3d(12,4,0);
glEnd();
glFlush();
glBegin(GL_POLYGON);
glColor3d(0,0,0);
glVertex3d(2,12,0);
glVertex3d(7,12,0);
glVertex3d(7,9,0);
glVertex3d(2,9,0);
glEnd();
glFlush();
s=7;
glBegin(GL_POLYGON);
glColor3d(0,0,0);
glVertex3d(arr[s+1],arr[s+2],0);
glVertex3d(arr[s+3],arr[s+4],0);
glVertex3d(arr[s+5],arr[s+6],0);
glVertex3d(arr[s+7],arr[s+8],0);
glEnd();
glBegin(GL_LINES);
glColor3d(0,0,0);
for(int i=0;i<=12;i++)
{
glVertex3d(0,i,0);
glVertex3d(12,i,0);
glVertex3d(i,0,0);
glVertex3d(i,12,0);
}
glEnd();
}
else if(stage==2)
{
glFlush();
glClear(GL_CLIP_PLANE0);
glClear(GL_ACCUM_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT);
glBegin(GL_POLYGON);
for(int i=0;i<=12;i++)
{
for(int j=0;j<=12;j++)
{
glColor3d(1,0,1);
glVertex3d(i,i,0);
glVertex3d(j,i,0);
glVertex3d(j,j,0);
glVertex3d(i,j,0);
}
}
glEnd();
glBegin(GL_POLYGON);
glColor3d(0,0,0);
glVertex3d(3,11,0);
glVertex3d(9,11,0);
glVertex3d(9,0,0);
glVertex3d(3,0,0);
glEnd();
glFlush();
s=15;
glBegin(GL_POLYGON);
glColor3d(0,0,0);
glVertex3d(arr[s+1],arr[s+2],0);
glVertex3d(arr[s+3],arr[s+4],0);
glVertex3d(arr[s+5],arr[s+6],0);
glVertex3d(arr[s+7],arr[s+8],0);
glEnd();
glBegin(GL_LINES);
glColor3d(0,0,0);
for(int i=0;i<=12;i++)
{
glVertex3d(0,i,0);
glVertex3d(12,i,0);
glVertex3d(i,0,0);
glVertex3d(i,12,0);
}
glEnd();
}
if(moved==0)
{
glPushMatrix();
glColor3d(1,0,0);
glTranslated(x,y,z);
glScalef(1,2.1,1);
glutSolidCube(.9);
glPopMatrix();
}
if(moved==1)
{
if(position==1)
{
glPushMatrix();
glColor3d(1,0,0);
glTranslated(x,y,z);
glScalef(1,2.1,1);
glutSolidCube(.9);
glPopMatrix();
moved=0;
}
else if(position==2)
{
cout<<"2:- "<<"x="<<x<<"y="<<y<<"z="<<z<<"position="<<position<<endl;
if(((x==4.3&&y==4.3)&&stage==0)||((x==9.3&&y==8.3)&&stage==1))
{
cout<<"Event Happened"<<endl;
z=z-1;
cout<<"Stage Cleared"<<endl;
glPushMatrix();
glColor3d(1,0,0);
glTranslated(x,y,z);
glScalef(1,1,2.1);
glutSolidCube(.9);
glPopMatrix();
moved=0;
wait(1);
Init();
stage+=1;
glutPostRedisplay();
glFlush();
}
else if((x==10.3&&y==6.3)&&(stage==2))
{
cout<<"Event Happened"<<endl;
z=z-1;
cout<<"Stage Cleared"<<endl;
glPushMatrix();
glColor3d(1,0,0);
glTranslated(x,y,z);
glScalef(1,1,2.1);
glutSolidCube(.9);
glPopMatrix();
moved=0;
wait(1);
Init();
cout<<"Congratulations!!!!! You Won"<<endl;
stage=0;
glFlush();
}
else
{
glPushMatrix();
glColor3d(1,0,0);
glTranslated(x,y,z);
glScalef(1,1,2.1);
glutSolidCube(.9);
glPopMatrix();
moved=0;
}
}
else if(position==3)
{
glPushMatrix();
glColor3d(1,0,0);
glTranslated(x,y,z);
glScalef(2.1,1,1);
glutSolidCube(.9);
glPopMatrix();
moved=0;
}
moved=3;
}
glFlush();
glutSwapBuffers();
}
void Resize(int h,int w)
{
if(h==0)
{
h=1;
}
float ratio=w*1/h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,w,h);
gluPerspective(14.0f ,ratio,0.1f,100.f);
glMatrixMode(GL_MODELVIEW);
}
void Board(unsigned char key,int x,int y)
{
switch (key)
{
case 'w':
case 'W':
move1=1;
moved=1;
axis=1;
checkpos(1);
glFlush();
glutSwapBuffers();
glutPostRedisplay();
break;
case 'a':
case 'A':
move1=2;
moved=1;
axis=2;
checkpos(2);
glFlush();
glutSwapBuffers();
glutPostRedisplay();
break;
case 'S':
case 's':
move1=3;
moved=1;
axis=1;
checkpos(3);
glFlush();
glutSwapBuffers();
glutPostRedisplay();
break;
case 'd':
case 'D':
move1=4;
moved=1;
axis=2;
checkpos(4);
glFlush();
glutSwapBuffers();
glutPostRedisplay();
break;
default:
break;
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(400, 400);
glutInitWindowPosition(200, 200);
glutCreateWindow("3D Object in OpenGL");
Init();
glutDisplayFunc(Display);
glutReshapeFunc(Resize);
glutKeyboardFunc(Board);
glutMainLoop();
return 0;
}
Do openGl show anomalies?
Extra Object (Block,not OOP) is formed while playing Game in Opengl during each move.
What are those "objects" you're talking about? There are no objects in OpenGL. There are only points, lines an triangles, drawn to a pixel based framebuffer.
In OpenGL there is no scene, there are no models, there are no objects. Any notion of a scene or objects are your burden to implement. On the OpenGL side, whenever something changes the only correct way to go about this is to perform a full redraw: Clear the whole buffer and draw the scene from scratch.
I think ,there is nothing wrong with the code and logic except it is written nonprofessional like OpenGl programmers write.
I'm sorry to break it to you, but your code is full of misconceptions and logic errors.
There must be some thing missing, some method to stop this.
It's rather simple: Don't treat OpenGL like something it is not. OpenGL is not a scene graph. Treat it like a pencil you use to draw onto a piece of paper provided to you by the operating system. If you want to draw some flip page book animation you draw each frame from scratch, and that's how you do it in OpenGL as well.
BTW, there are tools like Uncrustify that make your code readble. The mess you posted is unberable.
Update
Okay, I just sent your code through a pretty formatter to make it readable, and it's quite full of WTFs.
What do you think glClear(GL_CLIP_PLANE0) does? (hint: It's raises an invalid value error)
Why are you calling SwapBuffers followed by a glutPostRedisplay in a input event handlers. You never put graphics code into a event handler. Never!
Why do you have several glutPostRedisplay calls in the drawing code, with the occasional SwapBuffers mixed in?
Clearly you have absolutely no understanding whatsoever what those functions do and how they interact. That's pure Cargo Cult Programming.
Please, please, please go back to an introductionionary tutorial on OpenGL and work through it step for step. Don't skip things, because you clearly demonstrated you lack even the most basic understanding of how things like a double buffer works (what does swapping mean), how calling glFinish is completely uncalled for because the buffer swap implies it.
I recommend you this one: http://arcsynthesis.org/gltut
Add glClear(GL_COLOR_BUFFER_BIT); to the top of your display function.
I've just drawn a 3 dof robot with 3 joints which are revoloute , i've drawn a shere to use as an obstacle which should be constant without any moving but as the gripper of the robot starts to move my obstacle moves too, which shouldnt,2nd problem is : i want to turn arond my robot i did this by arrow keys theres no error but it dosent work.here is my code:
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#define VIEW_TURN_RATE 10
#define GLUT
#define GLUT_KEY
#define GLUT_SPEC
float t1=30;
float t2=45;
float t3=45;
float t4=0;
float t5=0;
float l=1.5;
float h=0.2*l;
double m=0.2;
double n=0.2;
double p=0.2;
float eyex,eyey=0;
float eyez=6;
float lx,ly,lz=0;
int turn = 0, turn1 = 0;
void TurnRight(void)
{
turn = (turn - VIEW_TURN_RATE) % 360;
}
void TurnLeft(void)
{
turn = (turn + VIEW_TURN_RATE) % 360;
}
void TurnForwards(void)
{
turn1 = (turn1 - VIEW_TURN_RATE) % 360;
}
void TurnBackwards(void)
{
turn1 = (turn1 + VIEW_TURN_RATE) % 360;
}
void myidlefunc()
{
if(t1<100)
t1+=2;
else
{
if(t2<150)
t2+=2;
else
{
if(t3<150)
t3+=2;
else
{
if(t4<150)
t4+=2;
else
{
if(t5<120)
t5+=2;
else
{
glutIdleFunc(0);
}
}
}
}
}
glutPostRedisplay();
}
#ifdef GLUT
#ifdef GLUT_SPEC
void
special(int key, int x, int y)
{
int i = 0;
printf("this is special keyboard: %d \n",key);
switch (key) {
/* start of view position functions */
case 'r':{
TurnRight();
i++;
}
break;
case GLUT_KEY_LEFT:{
TurnLeft();
i++;
}
break;
case GLUT_KEY_DOWN:{
TurnForwards();
i++;
}
break;
case GLUT_KEY_UP:{
TurnBackwards();
i++;
}
break;
/* end of view postions functions */
}
if (i)
glutPostRedisplay();
}
#endif
#ifdef GLUT_KEY
void keyboard(unsigned char c,int x,int y)
{
switch(c)
{
case 27:
exit(0);
break;
case 's':
if (t1 < 50) {
t1++;}
break;
case 'S':
//if (t1 < 80) {
t1--;
//}
break;
case 'q':
glutIdleFunc(myidlefunc);
break;
case 'f':
if (t2 < 160) {
t2++;}
break;
case 'F':
t2--;
break;
case 'g':
t3++;
break;
case 'h':
t4++;
break;
case 'k':
t5++;
break;
}
glutPostRedisplay();
}
#endif
#endif
void drawFloor(void)
{
glPushMatrix ();
glBegin(GL_QUADS);
glColor3f(0.0,0.8,0.8);
glVertex3f(-20.0, 0.0, 100.0);
glVertex3f(20.0, 0.0, 100.0);
glVertex3f(20.0, 0.0, -100.0);
glVertex3f(-20.0, 0.0, -100.0);
glEnd();
glPopMatrix ();
glEnable(GL_LIGHTING);
}
void Base(float l)
{
glPushMatrix();
//glColor3f(0.4,0.6,0.5);
glScaled(1.0*l,0.2*l,1.0*l);
glutSolidCube(1);
glPopMatrix();
}
void obst(float radius, int slices, int stacks)
{
glTranslated (0,-0.5,0.0);
glPushMatrix ();
glutSolidSphere (radius,slices,stacks);
glPopMatrix ();
}
void arm(float l,float r,int slices,int stacks,float rotat)
{
float d;
d=0.2*l;
glTranslated (0,l/2+d/2,0);
glPushMatrix ();
glScaled (d/l,1,d/l);
glutSolidCube (l);
glPopMatrix ();
glTranslated (0,l/2,0);
glRotated (rotat,0,0,1);
glPushMatrix ();
glutSolidSphere (r,slices,stacks);
glPopMatrix ();
}
void Base2(float l,float r,int slices,int stacks,float rotat)
{
float d;
d=0.2*l;
glTranslated (d/2,d/2,d/2);
glPushMatrix ();
glScaled (d,d/2,d);
glutSolidCube (2);
glPopMatrix ();
}
void hand(float d,float x)
{
glColor3f(0.0,0.4,0.3);
glRotated(t5,0,1,0);
glPushMatrix ();
glTranslated(0,-d/2+x/2,0);
glScaled(1,x/d,1);
glutSolidCube (d);
glPopMatrix();
glPushMatrix ();
glTranslated(-d/2+x/2,x/2,0);
glScaled (x/(d-x),1,d/(d-x));
glutSolidCube(d-x);
glPopMatrix ();
glPushMatrix ();
glTranslated (d/2-x/2,x/2,0);
glScaled (x/(d-x),1,d/(d-x));
glutSolidCube(d-x);
glPopMatrix ();
}
void display()
{
float l,T,r,x,d;
double radius,height;
int slices, stacks;
l=1.5;
T=30;
d=0.2*l;
x=0.2*d;
r=d/2;
radius=1.0;
height=3;
slices=1000;
stacks=202;
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glPushMatrix ();
//lightning start here
glEnable(GL_LIGHT0);
GLfloat light0_pos []={lx,ly+1,lz+1,1};
GLfloat light0_diffuse []={1,0,0,0};
glLightfv(GL_LIGHT0,GL_DIFFUSE,light0_diffuse);
GLfloat light0_Ambient []={0,1,1,0};
glLightfv(GL_LIGHT0,GL_DIFFUSE,light0_Ambient);
gluLookAt(0.2,0.8,0.0,5.0,3.0,5.0,0.0,0.1,0.0);
glLightfv(GL_LIGHT0,GL_POSITION,light0_pos);
glScaled(0.2,0.2,0.2);
glRotated(90,0.0,1.0,0.0);
/* Draw "bottom" of floor in blue. */
glColor3f(0.0, 0.8, 0.8);
drawFloor();
//base
glColor3f(0.0,0.0,0.0);
Base(2);
//base2
glColor3f(1.0,0.0,0.0);
Base2(l,r,60,60,t1);
//arm1
glColor3f(1.0,0.0,0.8);
arm(l,r,60,60,t1);
glColor3f(0.0,1.0,0.0);
arm(l,r,60,60,t2);
glColor3f(1.0,0.8,0.5);
arm(l,r,60,60,t3);
//hand
glTranslated (0,d/2+r,0);
hand(d,x);
//obst
glTranslated (-1,3,0);
glColor3f(0.0,0.0,1.0);
obst(radius,slices,stacks);
//glRotated(0.0,0.0,1.0,0.0);
glPopMatrix ();
glFlush();
glutSwapBuffers();
}
void reshape(int width,int height)
{
float aspect=(float)width/(float)height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,width,height);
//glOrtho(-aspect,aspect,-1,+1,-1,+1);
gluPerspective(60.0,0.0,0.0,8);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
//glTranslatef(0.0, 0.0, 0.0); /* viewing transform */
}
int main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
glutInitWindowPosition(0,0);
glutInitWindowSize(500,500);
static int window=glutCreateWindow("OPenGL!");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
#ifdef GLUT_SPEC
glutSpecialFunc(special);
#endif
glShadeModel(GL_FLAT);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glutMainLoop();
exit(0);
}
As you are rendering the obstacle last, your modelview matrix has been the recipient of all the transforms up to that point. You need to manage your modelview matrix more carefully using glPushMatrix() and glPopMatrix(). I haven't tested but try a push just before //arm 1 and pop just before your //obst.
I am trying to draw a simple square wherever I press the left mouse button using opengl/glut. My program runs perfectly except for the part where it does not draw the square where I click the left mouse button :). Can someone point out what I am doing wrong?
#include <stdlib.h>
#include <glut.h>
GLsizei WIDTH = 1300, HEIGHT = 700;
GLsizei MOUSEx, MOUSEy;
GLfloat SIDE=1;
GLfloat RED[3] = {1,0,0};
GLfloat GREEN[3] = {0,1,0};
GLfloat BLUE[3] = {0,0,1};
GLfloat WHITE[3] = {1,1,1};
GLfloat BLACK[3] = {0,0,0};
GLfloat YELLOW[3] = {1,1,0};
GLfloat CYAN[3] = {0,1,1};
GLfloat MAGENTA[3] = {1,0,1};
void drawSquare(int x, int y)
{
glColor3fv(YELLOW);
glBegin(GL_POLYGON);
glVertex3f(x+SIDE, y+SIDE,0);
glVertex3f(x-SIDE, y+SIDE,0);
glVertex3f(x-SIDE, y-SIDE,0);
glVertex3f(x+SIDE, y-SIDE,0);
glEnd();
glFlush();
}
void drawSquare1()
{
int x=0,y=0;
glColor3fv(BLUE);
glBegin(GL_POLYGON);
glVertex3f(x+SIDE, y+SIDE,0);
glVertex3f(x-SIDE, y+SIDE,0);
glVertex3f(x-SIDE, y-SIDE,0);
glVertex3f(x+SIDE, y-SIDE,0);
glEnd();
glFlush();
}
void display (void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0,0,-5);
drawSquare1();
glFlush();
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode (GL_MODELVIEW);
WIDTH=w;
HEIGHT=h;
}
void setX(int x)
{
MOUSEx=x;
}
void setY(int y)
{
MOUSEy=y;
}
void mouse(int btn, int state, int x, int y)
{
if(btn==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
{
setX(x);
setY(y);
drawSquare(MOUSEx,HEIGHT-MOUSEy);
glutPostRedisplay();
}
if(btn==GLUT_RIGHT_BUTTON && state==GLUT_DOWN)
{
exit(1);
}
}
int main (int argc, char **argv) {
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (WIDTH, HEIGHT);
glutInitWindowPosition (10, 10);
glutCreateWindow ("New Window");
glutDisplayFunc (display);
glutReshapeFunc (reshape);
glutMouseFunc(mouse);
//glutMotionFunc(drawSquare);
glutMainLoop ();
return 0;
}
In short words: OpenGL is not a scene graph. That means that those drawing commands issued in the mouse handler don't create some kind of "persistency".
Instead clicking the mouse you should store the position in a list/array and draw the squares from the values in that list in the display function.
I am fresh to this Coding But I done it.
Here is My Code It will Work.
#include <GL/glut.h>
GLsizei MOUSEx=0, MOUSEy=0;
GLfloat SIDE=50;
GLfloat BLUE[3] = {0,0,1};
void drawSquare1()
{
glColor3fv(BLUE);
glBegin(GL_POLYGON);
glVertex3f(MOUSEx, MOUSEy,0);
glVertex3f(MOUSEx+SIDE, MOUSEy,0);
glVertex3f(MOUSEx+SIDE, MOUSEy+SIDE,0);
glVertex3f(MOUSEx, MOUSEy+SIDE,0);
glEnd();
glFlush();
}
void display(void)
{
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
drawSquare1();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glOrtho(0.0,1368,768,0,-1.0,1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void spindisplay(void)
{
glutPostRedisplay();
}
void setX(int x)
{
MOUSEx=x;
}
void setY(int y)
{
MOUSEy=y;
}
void mouse(int btn, int state, int x, int y)
{
if(btn==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
{
setX(x);
setY(y);
//drawSquare(MOUSEx,HEIGHT-MOUSEy);
glutPostRedisplay();
}
if(btn==GLUT_RIGHT_BUTTON && state==GLUT_DOWN)
{
exit(1); // To Exit the Program
}
}
int main(int argc, char **argv)
{ glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(1366,768);
glutInitWindowPosition(0,0);
glutCreateWindow("Moving squares");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutIdleFunc(spindisplay);
glutMainLoop();
}
Below is the sample code taken from OpenGL Projects. Try to execute this and I think the problem with your drawing squares in OpenGL would be solve easily. If any question kindly ask.
#include<stdlib.h>
#include<glut.h>
GLsizei wh=500,ww=500;
GLfloat size=3.0;
void display()
{
glFlush();
}
void myInit()
{
glViewport(0,0,ww,wh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)ww,0.0,(GLdouble)wh);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0,0.0,0.0,1.0);
glColor3f(1.0,0.0,0.0);
}
void myReshape(GLsizei w,GLsizei h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0,0,w,h);
ww=w;
wh=h;
}
void drawSquare(int x,int y)
{
y=wh-y;
glBegin(GL_POLYGON);
glVertex2f(x+size,y+size);
glVertex2f(x-size,y+size);
glVertex2f(x-size,y-size);
glVertex2f(x+size,y-size);
glEnd();
glFlush();
}
void size_menu(int id)
{
switch(id)
{
case 2: size=size*2;
break;
case 3:if(size>1) size=size/2;
break;
}
glutPostRedisplay();
}
void top_menu(int id)
{
switch(id)
{
case 1:exit(0);break;
}
glutPostRedisplay();
}
void myMouse(int button,int state,int x,int y)
{
if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN)
drawSquare(x,y);
if(button==GLUT_RIGHT_BUTTON&&state==GLUT_DOWN)
exit(0);
}
int main(int argc,char **argv)
{
int sub_menu;
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(500,500);
glutCreateWindow("Hierarchical Menus to Draw Squares");
glutDisplayFunc(display);
myInit();
glutMouseFunc(myMouse);
sub_menu=glutCreateMenu(size_menu);
glutAddMenuEntry("Increase Square Size",2);
glutAddMenuEntry("Decrease Square Size",3);
glutCreateMenu(top_menu);
glutAddMenuEntry("Quit",1);
glutAddSubMenu("Resize",sub_menu);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutReshapeFunc(myReshape);
glClear(GL_COLOR_BUFFER_BIT);
glutMainLoop();
return 0;
}