GLProgramming.com

home :: about :: development guides :: irc :: forums :: search :: paste :: links :: contribute :: code dump

-> Click here to learn how to get live help <-


New Paste :: Recent Pastes:: No Line Numbers


redraws twice? by Magical1
1
 
#include <windows.h> /* when compiling under windows use this */
#include <gl/glut.h>
#include <gl/glu.h>
#include <stdio.h> /* used for debugging output to console */
#include <gl/gl.h>
#include <math.h>
#include <stdlib.h> /* when compiling under linux use this */

//#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") //use this to eliminate console window in background

#define RED 1
#define GREEN 2
#define BLUE 3
#define PURPLE 4
#define PINK 5
#define YELLOW 6
#define ORANGE 7
#define BURP 8
#define TIE 9
#define TWIST 91

int tester=0;

void createGLUTMenus();

GLUquadric* nQ;
const double DEG2RAD = 3.14159/180.0;
float angle = 0.0;
float red=1.0, blue=1.0, green=1.0;
// radius of uninflated balloon
float radiusU = 0.25;
// radius of inflated balloon
float radiusI = 1.00;
// length of inflated balloon
float lengthU = 70.0;
// set up start drawing point
float bubbleStart = -200;
// set up end drawing point
float bubbleEnd = -200;
// length  of bubble
float bubbleLength;
// create x and y  out of bounds coordinates 
int xCoordinate = -5000 , yCoordinate = -5000;
// a counter of the number of twists made
int twistCount = 0;
// the length of the uniflated and the inflated portion of the balloon
float tail=0, body=0;
// displacement along the x axis for setup
float disp = -150;
float twistHere = 0;
float percUninf, infLength, percInf, perc, inch, endP;
bool clicked= false, inflate= false, knot = false, burp = false, startTwist = false, menu=false;
int menu0, menu1, menu2, menu3, submenu, submenu1, submenu2, submenu3, submenu4, submenu5, submenu6, submenu7;
//an array of segment start points
float startPoint[30];
//an array of segment end points
float endPoint[30];    
// check if menu 2 was destroyed
bool menu2destroyed = false;

//find out what is happening if program dies
void br ()
{
// put breakpoint on this line
    int i = 3;
}


void changeSize(int w, int h)
{
    /* Prevent a divide by zero, when window is too short
     (you cant make a window of zero width).*/
    if(h == 0)
    {
        h = 1;
    }

    float ratio = 2.0* w / h;

    // Reset the coordinate system before modifying
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    
    // Set the viewport to be the entire window
    glViewport(0, 0, w, h);

    // Set the correct perspective.
    gluPerspective(60,ratio,1,1000);
    gluLookAt(0.0,0.0,5.0, 
              0.0,0.0,-1.0,
              0.0f,1.0f,0.0f);
    glMatrixMode(GL_MODELVIEW);
}

void drawUninf(float ul, float displaced)
{
    nQ = gluNewQuadric();
    glLoadIdentity();
    glColor3f(red,green,blue);
    glTranslatef(displaced,0,-100);
    glRotatef(90.0,0.0,1.0,0.0);
        gluCylinder(nQ, radiusU, radiusU, ul, 30, 30);
    gluDeleteQuadric(nQ);

    
    nQ = gluNewQuadric();
    glLoadIdentity();
    glTranslatef(0,0,-100);
    glColor3f(red,green,blue);
    glTranslatef((displaced + ul),0,0);
        gluSphere(nQ, radiusU, 30, 30);
    gluDeleteQuadric(nQ);
}

float drawInf(float il, float displaced)
{
    if (il < (3 * radiusI))
    {
        nQ = gluNewQuadric();
        glLoadIdentity();
        glTranslatef(displaced,0,-100);
        glColor3f(red,green,blue);
            gluSphere(nQ, (il), 30, 30);
        displaced = displaced + (il);
        endP = endP + displaced;
        gluDeleteQuadric(nQ);

    }

    else
    {
        nQ = gluNewQuadric();
        glLoadIdentity();
        glTranslatef(displaced,0,-100);
        glColor3f(red,green,blue);
            gluSphere(nQ, radiusI, 30, 30);
        gluDeleteQuadric(nQ);

        nQ = gluNewQuadric();
        glLoadIdentity();
        glColor3f(red,green,blue);
        glTranslatef(displaced,0,-100);
        glRotatef(90.0,0.0,1.0,0.0);
            gluCylinder(nQ, radiusI, radiusI, (il - radiusI), 30, 30);
        gluDeleteQuadric(nQ);

        displaced = displaced + (il - radiusI);

        endP = endP + displaced;
        
        nQ = gluNewQuadric();
        glLoadIdentity();
        glTranslatef(displaced,0,-100);
        glColor3f(red,green,blue);
        gluSphere(nQ, radiusI, 30, 30);
        gluDeleteQuadric(nQ);

        displaced = displaced + radiusI;
    }
    return displaced;
}

void drawNozel(void)
{
    nQ = gluNewQuadric();
    glLoadIdentity();
    glTranslatef(0,0,-100);
    glColor3f(red,green,blue);
    glTranslatef((disp - 2.2),0,0);
        glutSolidTorus(0.2,0.25,30,30);
    gluDeleteQuadric(nQ);
        
    nQ = gluNewQuadric();
    glLoadIdentity();
    glTranslatef(0,0,-100);
    glColor3f(red,green,blue);
    glTranslatef((disp),0,0);
        gluCylinder(nQ, radiusU, radiusU, 1.5, 30, 30);
    gluDeleteQuadric(nQ);
}

void drawKnot(void)
{
    nQ = gluNewQuadric();
    glLoadIdentity();
    glTranslatef(0,0,-100);
    glColor3f(red,green,blue);
    glTranslatef((disp - 2.2),0,0);
        glutSolidTorus(0.2,0.25,30,30);
    gluDeleteQuadric(nQ);

    nQ = gluNewQuadric();
    glLoadIdentity();
    glTranslatef(-151.25,0,-100);
    glColor3f(red,green,blue);
        gluSphere(nQ, 0.4, 30, 30);
    gluDeleteQuadric(nQ);
}

void pop(void)
{
    
}

void emptyBalloon(void)
{
    drawNozel();
    drawUninf(lengthU, disp);    
}

void inflateBalloon(double percInf)
{
    /*    draw the inflated Balloon
        Start with the nozzle (a torus),
        next draw the start of the inflated section (1 sphere, 1 cylinder, 1 sphere) 
        Finally draw the uninflated remainder of the balloon (1 cylinder, 1 sphere)
    */
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    infLength = ((percInf)/100 * lengthU * 4);
    percUninf = lengthU*((100 - percInf)/100);
    float dp = disp;
    if (body == 0)
    {
        body = infLength;
    }
    
    if (knot == true)
    {
        drawKnot();
    }
    else 
    {
        drawNozel();
    }
    dp = dp + radiusI;
    //draw inflated segment
    dp = drawInf(infLength, dp);
    //draw uninflated segment
    drawUninf(percUninf, dp); 

    //glutPostRedisplay();
    if(!inflate)
    {
        inflate = true;
        glutDetachMenu(GLUT_RIGHT_BUTTON);
        glutDestroyMenu(menu1);
        glutSetMenu(menu2);
        glutAttachMenu(GLUT_RIGHT_BUTTON);
    }
}

void inchToPercent(double inched)
{
    perc = (inched/60)*100;
    inflateBalloon(perc);
}

void drawTwisted()
{
    /*bubbleStart = disp;
    printf ("Twist Count Greater than Zero :%i \n", twistCount); //use for debugging purposes
    for (int i=0; i<=twistCount; i++)
    {
        float length = abs(startPoint[i] - endPoint[i]) - (2*radiusI);
        bubbleStart = drawInf(length,bubbleStart);
        printf ("Twist @ %i %lf \n", twistCount, length); //use for debugging purposes
        printf ("Start draw at %lf \n", bubbleStart);
    }*/
}

//finish this function later
void twistBalloon()
{
    startTwist = true;
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // Start off and draw the bubble section of balloon
    drawKnot();

    if(twistCount == 0){
        bubbleStart = disp;
        printf ("First Twist \n"); //use for debugging purposes    
    }

    if(twistCount < 0)
    {
        drawTwisted();
    }
    
    if(twistHere == 0){
        return;
    }
    //convert from window coordinate system to GLUT world coordinate system
    printf ("Twisted New Bubble \n\n"); //use for debugging purposes
    bubbleLength = (((twistHere - 60.0)/12.0)/100.0* lengthU * 4.0);
    printf ("Twisted @ %lf  \n", twistHere); //use for debugging purposes
    printf ("Bubble Size = %lf  \n", bubbleLength); //use for debugging purposes
    //record start point of balloon segment 
    startPoint[twistCount] = bubbleStart;
    double displaced = drawInf(bubbleLength,bubbleStart);
    bubbleStart = displaced;
    printf ("Finished drawing\n"); //use for debugging purposes
    //record end point of balloon segment
    endPoint[twistCount] = bubbleStart;
    printf ("\n\n"); //use for debugging purposes
    twistCount++;
    //Now draw the remainder of the inflated balloon    
    /*
    body = infLength + bubbleLength;
    float displace = drawInf(body, bubbleStart);

    //Next draw the remainder of the uninflated balloon 
    percUninf = percUninf - (lengthU)/36;
    drawUninf(percUninf, displace); */
}

void processMenuEvents(int option)
{

    if (option > 0 && option <= 7)
    {
        switch (option)
        {
            case RED : red = 1.0; green = 0.0; blue = 0.0; break;
            case GREEN : red = 0.0; green = 1.0; blue = 0.0; break;
            case BLUE : red = 0.0; green = 0.0; blue = 1.0; break;
            case PURPLE : red = 0.75; green = 0.0; blue = 1.0; break;
            case PINK : red = 1.0; green = 0.0; blue = 1.0; break;
            case YELLOW : red = 1.0; green = 1.0; blue = 0.0; break;
            case ORANGE : red = 1.0; green = 0.75; blue = 0.0; break;
        }
    }

    else if ( option == 8)
    {
        //tie balloon and allow twisting to commence
        burp = true;
    }
    
    else if ( option == 9)
    {
        //let a little air out of the balloon to make tie-ing easier
        if(!knot)
        {
            knot = true;
            glutDetachMenu(GLUT_RIGHT_BUTTON);
            glutDestroyMenu(menu2);
            glutSetMenu(menu3);
            glutAttachMenu(GLUT_RIGHT_BUTTON);
        }
    }
    
    else if ( option >= 10 && option <=70 )
    {
        inch = option-10; 
        inchToPercent(inch);
    }
    
    else if( option >= 70 && option <=90 )
    {
        perc = (option-70)*5;
        inflateBalloon(perc);
    }
    else if( option >= 91 )
    {
        twistBalloon();
    }
    glutPostRedisplay();
}

void createGLUTMenus()
{
    glutDetachMenu(GLUT_RIGHT_BUTTON);
    submenu7 = glutCreateMenu(processMenuEvents);
    glutAddMenuEntry("49 inches",59);
    glutAddMenuEntry("50 inches",60);
    glutAddMenuEntry("51 inches",61);
    glutAddMenuEntry("52 inches",62);
    glutAddMenuEntry("53 inches",63);
    glutAddMenuEntry("54 inches",64);
    glutAddMenuEntry("55 inches",65);
    glutAddMenuEntry("56 inches",66);
    glutAddMenuEntry("57 inches",67);
    glutAddMenuEntry("58 inches",68);
    glutAddMenuEntry("59 inches",69);
    glutAddMenuEntry("60 inches",70);

    submenu6 = glutCreateMenu(processMenuEvents);
    glutAddMenuEntry("37 inches",47);
    glutAddMenuEntry("38 inches",48);
    glutAddMenuEntry("39 inches",49);
    glutAddMenuEntry("40 inches",50);
    glutAddMenuEntry("41 inches",51);
    glutAddMenuEntry("42 inches",52);
    glutAddMenuEntry("43 inches",53);
    glutAddMenuEntry("44 inches",54);
    glutAddMenuEntry("45 inches",55);
    glutAddMenuEntry("46 inches",56);
    glutAddMenuEntry("47 inches",57);
    glutAddMenuEntry("48 inches",58);
    glutAddSubMenu("49 -> 60",submenu7);
    
    submenu5 = glutCreateMenu(processMenuEvents);
    glutAddMenuEntry("25 inches",35);
    glutAddMenuEntry("26 inches",36);
    glutAddMenuEntry("27 inches",37);
    glutAddMenuEntry("28 inches",38);
    glutAddMenuEntry("29 inches",39);
    glutAddMenuEntry("30 inches",40);
    glutAddMenuEntry("31 inches",41);
    glutAddMenuEntry("32 inches",42);
    glutAddMenuEntry("33 inches",43);
    glutAddMenuEntry("34 inches",44);
    glutAddMenuEntry("35 inches",45);
    glutAddMenuEntry("36 inches",46);
    glutAddSubMenu("37 -> 48",submenu6);
    
    submenu4 = glutCreateMenu(processMenuEvents);
    glutAddMenuEntry("13 inches",23);
    glutAddMenuEntry("14 inches",24);
    glutAddMenuEntry("15 inches",25);
    glutAddMenuEntry("16 inches",26);
    glutAddMenuEntry("17 inches",27);
    glutAddMenuEntry("18 inches",28);
    glutAddMenuEntry("19 inches",29);
    glutAddMenuEntry("20 inches",30);
    glutAddMenuEntry("21 inches",31);
    glutAddMenuEntry("22 inches",32);
    glutAddMenuEntry("23 inches",33);
    glutAddMenuEntry("24 inches",34);
    glutAddSubMenu("25 -> 36",submenu5);
    
    submenu3 = glutCreateMenu(processMenuEvents);
    glutAddMenuEntry("  5%",71);
    glutAddMenuEntry(" 10%",72);
    glutAddMenuEntry(" 15%",73);
    glutAddMenuEntry(" 20%",74);
    glutAddMenuEntry(" 25%",75);
    glutAddMenuEntry(" 30%",76);
    glutAddMenuEntry(" 35%",77);
    glutAddMenuEntry(" 40%",78);
    glutAddMenuEntry(" 45%",79);
    glutAddMenuEntry(" 50%",80);
    glutAddMenuEntry(" 55%",81);
    glutAddMenuEntry(" 60%",82);
    glutAddMenuEntry(" 65%",83);
    glutAddMenuEntry(" 70%",84);
    glutAddMenuEntry(" 75%",85);
    glutAddMenuEntry(" 80%",86);
    glutAddMenuEntry(" 85%",87);
    glutAddMenuEntry(" 90%",88);
    glutAddMenuEntry(" 95%",89);
    glutAddMenuEntry("100%",90);
    
    submenu2 = glutCreateMenu(processMenuEvents);
    glutAddMenuEntry(" 1 inch",11);
    glutAddMenuEntry(" 2 inches",12);
    glutAddMenuEntry(" 3 inches",13);
    glutAddMenuEntry(" 4 inches",14);
    glutAddMenuEntry(" 5 inches",15);
    glutAddMenuEntry(" 6 inches",16);
    glutAddMenuEntry(" 7 inches",17);
    glutAddMenuEntry(" 8 inches",18);
    glutAddMenuEntry(" 9 inches",19);
    glutAddMenuEntry("10 inches",20);
    glutAddMenuEntry("11 inches",21);
    glutAddMenuEntry("12 inches",22);
    glutAddSubMenu("13 -> 24",submenu4);

    submenu = glutCreateMenu(processMenuEvents);
    glutAddMenuEntry("Red",RED);
    glutAddMenuEntry("Blue",BLUE);
    glutAddMenuEntry("Green",GREEN);
    glutAddMenuEntry("Purple",PURPLE);
    glutAddMenuEntry("Pink",PINK);
    glutAddMenuEntry("Yellow",YELLOW);
    glutAddMenuEntry("Orange",ORANGE);


    submenu1 = glutCreateMenu(processMenuEvents);
    glutAddSubMenu("Inflate (inches)",submenu2);
    glutAddSubMenu("Inflate (percentage)",submenu3);

    menu3 = glutCreateMenu(processMenuEvents);
    glutAddMenuEntry("Twist",TWIST);
    glutAddSubMenu("Change Color",submenu);
    

    menu2 = glutCreateMenu(processMenuEvents);
    glutAddMenuEntry("Burp",BURP);
    glutAddMenuEntry("Tie Off",TIE);
    glutAddSubMenu("Change Color",submenu);
    
    menu1 = glutCreateMenu(processMenuEvents);
    glutAddSubMenu("Inflate",submenu1);
    glutAddSubMenu("Change Color",submenu);
    
    glutSetMenu(menu1);
    glutAttachMenu(GLUT_RIGHT_BUTTON);
}

void myMouse(int button, int state, int x, int y)
{
    if (button==GLUT_LEFT_BUTTON && state==GLUT_DOWN){
        twistHere = x;
        printf ("Clicked %lf \n" ,twistHere); //use for debugging purposes
        return;
    }
    else{
        return;
    }
}


void renderScene(void)
{
    // Draw uninflated balloon
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    if (inflate == false)
    {
        emptyBalloon();
    }
    else if((inflate == true) && (knot == false))
    {
        inflateBalloon(perc);
    }
    else if((inflate == true) && (knot == true))
    {
        if(!startTwist){
            inflateBalloon(perc);
        }
        else{
            twistBalloon();
        }
    }
    glutSwapBuffers();
}

void exitBalloon(int key, int x, int y)
{
    if ((key == GLUT_KEY_F4) && (GLUT_ACTIVE_ALT))
    {
        exit(0);
    }
}

int main(int argc, char **argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(0,0);
    glutInitWindowSize(1400,1050);
    glutCreateWindow("Interactive Balloon Sculptor");
    glutMouseFunc(myMouse);
    glutDisplayFunc(renderScene);
    glutReshapeFunc(changeSize);
    glutSpecialFunc(exitBalloon);
    //call function to create the menu
    createGLUTMenus();
    //call function to define menu choice
    glutMainLoop();
    return 0;
}