Results 1 to 4 of 4

Thread: Taking input while inside while loop

  1. #1
    Newbie Newbie
    Join Date
    Oct 2013
    Posts
    2

    Taking input while inside while loop

    Basically, I am trying to make a brick breaker game using opengl.
    What I am stuck with is the fact, that my functions for all different objects to be drawn gets called inside a while(1) loop, but at the same time I need inputs from my keyboard to be registered. But my glutkeyboardfunc never gets called because of the preceeding infinte while loop. What logic/method can I use to solve this? Thank you.
    Here's the code if required:

    Code :
    using namespace std;
    #include <iostream>
    #include <GL/glut.h>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #define rad 10
    #define noblock 20
    float DEG2RAD = 3.14159/180;
    float xmin=-20, ymin=-200, xmax=70, ymax=-180,cx=35,cy=-170;
    int t=1,r=1;
    float cxmin,cxmax,cymin,cymax;
    void delay(int n)
    {
        clock_t t=n+clock();
        while(t>clock());
    }
    void dcirc(float x, float y)
    {
        glColor3f(1.0,0.0,0.0);
        glBegin(GL_LINE_LOOP);
       for (int i=0; i < 360; i++)
       {
          float degInRad = i*DEG2RAD;
          glVertex2f(x+cos(degInRad)*rad,y+sin(degInRad)*rad);
       }
     
       glEnd();
       glFlush();
    }
    int hit[20]={0};
    vector<float> x1,x2,ay1,y2;
    void box()
    {
        glColor3f(0.0,1.0,0.0);
        float lx1=-160,ly1=150,lx2=-130,ly2=170;
        for(int i=0;i<noblock;i++)
        {
            if(hit[i]==0)
            {
                glBegin(GL_LINE_LOOP);
                glVertex2i(lx1,ly1);
                glVertex2i(lx2,ly1);
                glVertex2i(lx2,ly2);
                glVertex2i(lx1,ly2);
                glEnd();
                x1.push_back(lx1);
                x2.push_back(lx2);
                ay1.push_back(ly1);
                y2.push_back(ly2);
                lx1+=30;
                lx2+=30;
                if(i==9)
                {
                    lx1=-160;lx2=-130;ly1=130;ly2=150;
                }
            }
            else
            {
                lx1+=30;
                lx2+=30;
                if(i==9)
                {
                    lx1=-160;lx2=-130;ly1=130;ly2=150;
                }
            }
        }
        glFlush();
    }
    void dbox()
    {
        glColor3f(0.0,0.0,1.0);
        glBegin(GL_LINE_LOOP);
        glVertex2i(xmin,ymin);
        glVertex2i(xmax,ymin);
        glVertex2i(xmax,ymax);
        glVertex2i(xmin,ymax);
        glEnd();
        glFlush();
    }
    void mc()
    {
        if(cx+rad>200){r=0;}
        if(cx-rad<-200){r=1;}
        if(cy+rad>200){t=0;}
        if(cx<=xmax&&cx>=xmin&&cy==rad-180)   {t=1;}
        if(cy-rad==-200)    t=1;//exit(0);
        for(int i=0;i<noblock;i++)
        {
            if(((cy+rad)==ay1[i])&&(hit[i]==0)&&(cx<=x2[i])&&(cx>=x1[i]))
            {
                hit[i]=1;
                t=0;
            }
            else if(((cy-rad)==y2[i])&&(hit[i]==0)&&(cx<=x2[i])&&(cx>=x1[i]))
            {
                hit[i]=1;
                t=1;
            }
            else if(((cx-rad)==x2[i])&&(hit[i]==0)&&(cy<=y2[i])&&(cy>=ay1[i]))
            {
                hit[i]=1;
                r=1;
            }
            else if(((cx+rad)==x1[i])&&(hit[i]==0)&&(cy<=y2[i])&&(cy>=ay1[i]))
            {
                hit[i]=1;
                r=0;
            }
        }
        if(r==0) {cx--;}
        if(r==1)    {cx++;}
        if(t==0) {cy--;}
        if(t==1)    {cy++;}
        dcirc(cx,cy);
        delay(1);
    }
    void show()
    {
        glClear(GL_COLOR_BUFFER_BIT);
        dbox();
        box();
        mc();
    }
    void display()
    {
        glClearColor(1.0,1.0,1.0,1.0);
        glClear(GL_COLOR_BUFFER_BIT);
        dbox();
        while(1) show();
        glFlush();
    }
    void myKey(unsigned char key, int x, int y)
    {
        glClear(GL_COLOR_BUFFER_BIT);
    	if(key=='l')
    	{
            xmax+=20;
            xmin+=20;
    	}
    	else if(key=='k')
    	{
            xmax-=20;
            xmin-=20;
    	}
    	if(xmax>=200)
    	{
            xmax=200;
            xmin=130;
    	}
    	else if(xmin<=-200)
    	{
            xmin=-200;
            xmax=-130;
    	}
    	show();
    }
    void myInit(void)
    {
        glMatrixMode(GL_PROJECTION);
        gluOrtho2D(-200,200,-200,200);
    }
    int main(int argc,char** argv)
    {
        char p;
        glutInit(&argc,argv);
        glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
        glutInitWindowSize(600,600);
        glutInitWindowPosition(0,0);
        glutCreateWindow("simple");
        myInit();
        glutDisplayFunc(&display);
        glutKeyboardFunc(myKey);
        glutMainLoop();
    }

  2. #2
    Newbie Frequent Contributor
    Join Date
    Mar 2016
    Posts
    896
    You need to structure things a bit differently. Your glutDisplayFunc should only draw a single frame (that allows the other callbacks, like the one for keyboard input to run as well) - think of it as drawing a snapshot of your "scene" at a fixed point in time.
    Since there are things in your game that will move continuously, you should register a glutIdleFunc that just calls glutPostRedisplay(). That call tells glut that something in your game has changed and a new frame needs to be drawn. Your display function then has two tasks: first compute new positions for all objects that move (or other things that happen over time, e.g. animations) then draw things at their new positions/in their new state (sometimes these two steps can be combined - depends on what is most convenient). In order to make your game run independent of the CPU/GPU speed you can use e.g. glutGet(GLUT_ELAPSED_TIME) and calculate the amount objects move based on how much time since the last frame has elapsed (and the objects velocity of course); you can also keep that as a second step, if it otherwise gets too complicated.
    In terms of structuring your code you may want to introduce a couple of structs that hold variables that belong together, e.g.:
    Code :
    struct Box
    {
       GLfloat  position[2];
       // type of box?
       // size of box - if it varies? ...
    };
     
    std::vector<Box>  boxes;

    Similar for other "objects" in your game like the paddle, walls, the ball, etc. Please note that the latter mostly goes into general (game) programming, so questions about these aspects my be better directed at a different forum.

  3. #3
    Newbie Newbie
    Join Date
    Oct 2013
    Posts
    2
    Thanks a lot! I looked up how to use glutIdleFunc() and glutPostRedisplay() and was able to solve the issues I had my with my code.

    Also sorry, I didn't look around enough and thought this would be best place to post it to. If an admin can move it, well and good.

    Thanks a lot again.

  4. #4
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    3,103
    Quote Originally Posted by carsten neumann View Post
    you should register a glutIdleFunc that just calls glutPostRedisplay().
    I'd suggest using glutTimerFunc() instead. Using an idle function can result in 100% CPU usage.

Similar Threads

  1. lot of if and while loops inside a for loop
    By agmegharaj in forum OpenCL
    Replies: 0
    Last Post: 08-24-2011, 01:45 AM
  2. Replies: 0
    Last Post: 12-04-2003, 03:15 AM
  3. Help: Why can't I put glutPostRedisplay inside while loop?
    By songeb in forum OpenGL: Basic Coding
    Replies: 7
    Last Post: 02-06-2002, 03:57 AM
  4. help in taking keyboard input
    By in forum OpenGL: Basic Coding
    Replies: 1
    Last Post: 01-19-2002, 04:40 AM
  5. Help! Need keyboard input during while loop
    By in forum OpenGL: Basic Coding
    Replies: 2
    Last Post: 09-12-2001, 03:11 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean