简体   繁体   中英

draw in animated opengl scene

i've a problem with drawing firework effect in animated scene when i clicked on mouse button. Why it don't drawing?

My Code:

#include<GL/glut.h>  
struct Point {
GLint x;
GLint y;
};
Point p1, p2;

int ww=600,wh=400;  

int xi,yi,xf,yf,y1b,x1b,y2b,x2b;
float px, py, t; 
float x=0.,y=0.,x1=5.;


void update()
{
   x+=0.01;
   x1 -= 0.02;

   if (x>6)
   {
       x -= 6;
       x1 = 4;

   }
}

There I create a function that draw firework effect on the basis of bezier curves. It will Okey if I draw on the static window.

// Bezier curve firework
void bezier(int xi, int yi, int xf, int yf)
{

    // Coordinates for additional points of bezier curve
    x1b = xi + rand()%15;
    y1b = yi + rand()%5;
    x2b = xf + rand()%15;
    y2b = xf + rand()%5;

    calculate and draw the curves
    for (t=0.;t<=1.;t+=0.001)
    {
        px=(1-t)*(1-t)*(1-t)*xi+3*t*(1-t)*(1-t)*x1b+3*t*t*(1-t)*x2b+t*t*t*xf; 
        py=(1-t)*(1-t)*(1-t)*yi+3*t*(1-t)*(1-t)*y1b+3*t*t*(1-t)*y2b+t*t*t*yf;
        glPointSize(2);
        glBegin(GL_POINTS);
            //glColor3f(1,0,0);
            glVertex2d(px,py);
        glEnd();
        glFlush();
    }

}  


void initRendering()
{
    glEnable(GL_DEPTH_TEST);
}

void reshaped(int w , int h)
{
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, (double)w/(double)h,1,200);
}

// If pressed ESC -> exit
void keyPressed(unsigned char k, int x, int y)
{
    if(k==27)
    {
        exit(0);
    }
}

Then, if I pressed mouse button it should call the function above and draw what I need. But nothing(

// If pressed mouse button -> draw firework effect
void mousePressed(int button, int state, int x, int y)
{

    if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
    {


             xi=x;  
             yi=wh-y;  


             xf=x + 5.;  

             p1.x = xi; p1.y = yi;
             p2.x = xf; p2.y = yi;

             //drawLine(xi,yi,xf,yi);
             bezier(xi, yi,xf, yi);



    }
glutPostRedisplay();
}

There I create animated window. Two clouds move in gorizontal waves.

// Display a two moving clouds and the earth
void display()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();
    glPushMatrix();
    glTranslatef(x1,y,-5.0);
    glBegin(GL_POLYGON);

        glColor3f(1.,0.,0.5);

        glVertex3f(-1.,1.,-5.);
        glVertex3f(0.,2.,-5.);
        glVertex3f(-2.,2.,-5.);
        glVertex3f(1.,1.,-5.);

    glEnd();
    glPopMatrix();

    glPushMatrix();

    glTranslatef(x,y,-5.);

    glBegin(GL_POLYGON);

        glColor3f(0.,0.5,0.5);

        glVertex3f(1.,0.7,-5.);

        glVertex3f(1.5,1.0,-5.0);

        glVertex3f(0.7,1.5,-5.0);

        glVertex3f(0.0,2.0,-5.0);

        glVertex3f(-0.7,1.5,-5.0);

        glVertex3f(-1.4,1.6,-5.0);

        glVertex3f(-1.7,1.0,-5.0);

        glVertex3f(-1.5,0.7,-5.0);

        glVertex3f(-1.0,0.5,-5.0);

    glEnd();

    glPopMatrix();

    glBegin(GL_POLYGON);

        glColor3f(1.,1.,1.5);

        glVertex3f(-2.,-2.,-5.);
        glVertex3f(-2.0,-2.0,-5.0);
        glVertex3f(-1.0,-1.5,-5.0);
        //glVertex3f(0.0,0.0,-5.0);
        glVertex3f(2.0,-2.0,-5.0);
        glVertex3f(1.2,-1.5,-5.0);

    glEnd();

    update();

    glutSwapBuffers();



    glFlush();  

}

void myinit()  
{  
   glViewport(0,0,ww,wh);  
   glMatrixMode(GL_MODELVIEW);  
   glLoadIdentity();  
   gluOrtho2D(0.0,(GLdouble)ww,0.0,(GLdouble)wh);  
   glMatrixMode(GL_MODELVIEW);  
}  

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

    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);

    glutInitWindowPosition(100,100);

    glutInitWindowSize(400,400);

    glutCreateWindow("Salute | Clouds");

    initRendering();



    // Registration

    glutDisplayFunc(display);

    glutIdleFunc(display);

    glutReshapeFunc(reshaped);

    // Handler of

    myinit();

    glutKeyboardFunc(keyPressed);
    glutMouseFunc(mousePressed);

    // Main Loop
    glutMainLoop();

    return(0);
 }

I think the problem is as follows: I'm trying to draw my firework in an updated animated window. And every time I clicked on the screen, it is updated. And in the end, nothing is visible. Actually the question: How to make so that function glutMoseFunk would draw my salute in updated window?

While your scene is draw in perspective projection, the function bezier works with orthographic projection. This means you have to change the projection matrix befor you call bezier .

Further, do all the rendering in the main loop ( display function). The event mousePressed should only be used to change parameters (set xi , yi , ...).

The display function may look like this:

int ww=400, wh=400;

void display()
{
    // clear the frame buffer
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    // setup perspective projection
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, (double)ww/(double)wh,1,200);

    // set model view matrix (identity matrix)
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();  

    // draw scene
    .....

    // setup ortihgraphic projection
    glMatrixMode(GL_PROJECTION);  
    glLoadIdentity();  
    gluOrtho2D(0.0,(GLdouble)ww,0.0,(GLdouble)wh);

    bezier(xi, yi,xf, yi);
    update();

    glutSwapBuffers();
    glutPostRedisplay(); 
}

The reshaped function should set the viewport and notice the window size only:

void reshaped(int w , int h)
{
    ww = w;
    wh = h;
    glViewport(0, 0, ww, wh);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM