c++openglglut

OpenGL drawing scale one polygon instead of both


I am trying to change the scale of the second flake (polygon) but keep the first one the same. Currently it looks like it is changing both of them to the same scale, how can I fix this?

The polygons are drawn in the draw() method, and i want to change the scale through the setproperties() method.

#include <GL/glut.h>

#include <math.h>
#include<iostream>
#define M_PI 3.1415926535897932384626433832795


const int FLAKE_COUNT = 5;

const float TRANSLATION_SPEED_X = 0.8;
const float TRANSLATION_SPEED_Y = 0.8;

enum ROTATE_DIRECTION { CLOCKWISE = -1, ANTICLOCKWISE = 1 };
const float ROTATION_SPEED_LIMIT = 49.0;



const float SHRINK_SPEED = 0.001;

bool GLOBAL_MODE = true;

int selectedFlakeIndex = 0;


class Flake {

    // add flake's other properties here

    float colorR, colorG, colorB;

    // vertex coordinates of one-half arm of a flake
    float flakeside[16][2] = { 0.0 , 0.0,
                                2.0 , 0.5,
                                7.0,  0.5,
                                10.0, 5.5,
                                12.0, 5.5,
                                10.0, 0.5,
                                15.0, 0.5,
                                17.0, 5.0,
                                18.5, 5.0,
                                17.0, 0.5,
                                20.0, 0.5,
                                21.0, 3.0,
                                22.0, 3.0,
                                21.5, 0.5,
                                24.0, 0.5,
                                24.5, 0.0 };

    ROTATE_DIRECTION rot_direction;

    float flakeside_tformed[16][2];

    void drawflakeside() 
    {
        for (int i = 0; i < 16; i++) {
            for (int j = 0; j < 2; j++) {
                flakeside_tformed[i][j] = flakeside[i][j];
            }
        }

        glBegin(GL_LINE_LOOP);
        glVertex2f(flakeside_tformed[0][0], flakeside_tformed[0][1]);
        glVertex2f(flakeside_tformed[1][0], flakeside_tformed[1][1]);
        glVertex2f(flakeside_tformed[2][0], flakeside_tformed[2][1]);
        glVertex2f(flakeside_tformed[3][0], flakeside_tformed[3][1]);
        glVertex2f(flakeside_tformed[4][0], flakeside_tformed[4][1]);
        glVertex2f(flakeside_tformed[5][0], flakeside_tformed[5][1]);
        glVertex2f(flakeside_tformed[6][0], flakeside_tformed[6][1]);
        glVertex2f(flakeside_tformed[7][0], flakeside_tformed[7][1]);
        glVertex2f(flakeside_tformed[8][0], flakeside_tformed[8][1]);
        glVertex2f(flakeside_tformed[9][0], flakeside_tformed[9][1]);
        glVertex2f(flakeside_tformed[10][0], flakeside_tformed[10][1]);
        glVertex2f(flakeside_tformed[11][0], flakeside_tformed[11][1]);
        glVertex2f(flakeside_tformed[12][0], flakeside_tformed[12][1]);
        glVertex2f(flakeside_tformed[13][0], flakeside_tformed[13][1]);
        glVertex2f(flakeside_tformed[14][0], flakeside_tformed[14][1]);
        glVertex2f(flakeside_tformed[15][0], flakeside_tformed[15][1]);
        glEnd();

        glBegin(GL_LINE_LOOP);
        glVertex2f(flakeside_tformed[0][0], -flakeside_tformed[0][1]);
        glVertex2f(flakeside_tformed[1][0], -flakeside_tformed[1][1]);
        glVertex2f(flakeside_tformed[2][0], -flakeside_tformed[2][1]);
        glVertex2f(flakeside_tformed[3][0], -flakeside_tformed[3][1]);
        glVertex2f(flakeside_tformed[4][0], -flakeside_tformed[4][1]);
        glVertex2f(flakeside_tformed[5][0], -flakeside_tformed[5][1]);
        glVertex2f(flakeside_tformed[6][0], -flakeside_tformed[6][1]);
        glVertex2f(flakeside_tformed[7][0], -flakeside_tformed[7][1]);
        glVertex2f(flakeside_tformed[8][0], -flakeside_tformed[8][1]);
        glVertex2f(flakeside_tformed[9][0], -flakeside_tformed[9][1]);
        glVertex2f(flakeside_tformed[10][0], -flakeside_tformed[10][1]);
        glVertex2f(flakeside_tformed[11][0], -flakeside_tformed[11][1]);
        glVertex2f(flakeside_tformed[12][0], -flakeside_tformed[12][1]);
        glVertex2f(flakeside_tformed[13][0], -flakeside_tformed[13][1]);
        glVertex2f(flakeside_tformed[14][0], -flakeside_tformed[14][1]);
        glVertex2f(flakeside_tformed[15][0], -flakeside_tformed[15][1]);
        glEnd();
    }

public:

    void draw() {
        // perform appropriate transformations and draw the flake here
        glPushMatrix();
        glRotatef(0.0f, 0.0f, 0.0f, 1.0f);
        drawflakeside();

        glRotatef(60.0f, 0.0f, 0.0f, 1.0f);
        drawflakeside();

        glRotatef(60.0f, 0.0f, 0.0f, 1.0f);
        drawflakeside();

        glRotatef(60.0f, 0.0f, 0.0f, 1.0f);
        drawflakeside();

        glRotatef(60.0f, 0.0f, 0.0f, 1.0f);
        drawflakeside();

        glRotatef(60.0f, 0.0f, 0.0f, 1.0f);
        drawflakeside();
        glPopMatrix();
    }

    void setProperties(float cx, float cy, float sx, float sy, ROTATE_DIRECTION rot_direction) 
    {
        glScalef(sx, sy, 1.0f);
    }


};


Flake flakes[5];


void initScene(void) {
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0);

    // other initializations go here
    flakes[0].setProperties(0.0, 0.0, 1.0, 1.0, CLOCKWISE);
    flakes[1].setProperties(40.0, 40.0, 0.3, 0.3, ANTICLOCKWISE);
}

void display(void) {


    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    //draw your scene here
    glColor3f(1, 1, 0);
    flakes[0].draw();
    glColor3f(1, 0, 0);
    flakes[1].draw();

    glutSwapBuffers();
}

void anim(void) {

    // handle animations here

    // hint: any change that takes place when the user is not interacting with the program goes here

    glutPostRedisplay();


}


void keyboardHandler(unsigned char key, int shrinkFrquency, int y) {

    // handle keybaord events here


    glutPostRedisplay();

}


void print_keymap() {


    std::cout << "\n\nKey Map";
    std::cout << "\n\n\t g   -  GLOBAL_MODE toggle (movement ,rotation, scaling, etc. affect all flakes in Global_Mode)";
    std::cout << "\n";
    std::cout << "\n\n\t 0   -  Select the center flake       ( when GLOBAL MODE is OFF )";
    std::cout << "\n\n\t 1   -  Select the top left flake     ( when GLOBAL MODE is OFF )";
    std::cout << "\n\n\t 2   -  Select the top right flake    ( when GLOBAL MODE is OFF )";
    std::cout << "\n\n\t 3   -  Select the bottom left flake  ( when GLOBAL MODE is OFF )";
    std::cout << "\n\n\t 4   -  Select the bottom right flake ( when GLOBAL MODE is OFF )";
    std::cout << "\n";
    std::cout << "\n\n\t i   -  Move selected flake up ( affect all flakes in Global Mode )";
    std::cout << "\n\n\t k   -  Move selected flake down ( affect all flakes in Global Mode  )";
    std::cout << "\n\n\t j   -  Move selected flake left ( affect all flakes in Global Mode )";
    std::cout << "\n\n\t l   -  Move selected flake right ( affect all flakes in Global Mode  )";
    std::cout << "\n";
    std::cout << "\n\n\t r   -  Toggle Rotation status (torn on/off) of selected flake   ( affect all flakes in Global Mode )";
    std::cout << "\n\n\t t   -  Toggle Rotation direction of selected flake ( affect all flakes in Global Mode )";
    std::cout << "\n\n\t u   -  Increase rotationSpeed of selected flake    ( affect all flakes in Global Mode )";
    std::cout << "\n\n\t y   -  Decrease rotationSpeed of selected flake    ( affect all flakes in Global Mode )";
    std::cout << "\n";
    std::cout << "\n\n\t a   -  Scale along X axis: increase scaling of selected flake ( affect all flakes in Global Mode )";
    std::cout << "\n\n\t d   -  Scale along Y axis: increase scaling of selected flake ( affect all flakes in Global Mode )";
    std::cout << "\n\n\t z   -  Scale along X axis: decrease scaling of selected flake ( affect all flakes in Global Mode )";
    std::cout << "\n\n\t c   -  Scale along Y axis: decrease scaling of selected flake ( affect all flakes in Global Mode )";
    std::cout << "\n";
    std::cout << "\n\n\t s   -  MAKE selected Flake solid ( affect all flakes in Global Mode )";
    std::cout << "\n";
    std::cout << "\n\n\t .   -  Start Shrinking selected Flake ( affect all flakes in Global Mode )";
    std::cout << "\n";
    std::cout << "\n\n\t m   -  Master Reset ( Restores the initial states of all flakes )";

    std::cout << "\n\n\n\n";

}


int main(int argc, char ** argv) {

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(550, 550);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("SnowFlake");

    initScene();
    print_keymap();

    glutDisplayFunc(display);
    glutKeyboardFunc(keyboardHandler);
    glutIdleFunc(anim);

    glutMainLoop();


    return 0;
}

Solution

  • Save off the scale factors passed into setProperties() into member variables and use those during draw() by doing a glScalef() right after the initial glPushMatrix():

    #include <GL/glut.h>
    
    const int FLAKE_COUNT = 5;
    
    enum ROTATE_DIRECTION { CLOCKWISE = -1, ANTICLOCKWISE = 1 };
    
    class Flake {
        float colorR, colorG, colorB;
    
        // vertex coordinates of one-half arm of a flake
        float flakeside[16][2] = { 0.0 , 0.0,
                                    2.0 , 0.5,
                                    7.0,  0.5,
                                    10.0, 5.5,
                                    12.0, 5.5,
                                    10.0, 0.5,
                                    15.0, 0.5,
                                    17.0, 5.0,
                                    18.5, 5.0,
                                    17.0, 0.5,
                                    20.0, 0.5,
                                    21.0, 3.0,
                                    22.0, 3.0,
                                    21.5, 0.5,
                                    24.0, 0.5,
                                    24.5, 0.0 };
    
        ROTATE_DIRECTION rot_direction;
    
        float flakeside_tformed[16][2];
    
        float mSx = 1.0f;
        float mSy = 1.0f;
    
        void drawflakeside() 
        {
            for (int i = 0; i < 16; i++) {
                for (int j = 0; j < 2; j++) {
                    flakeside_tformed[i][j] = flakeside[i][j];
                }
            }
    
            glBegin(GL_LINE_LOOP);
            glVertex2f(flakeside_tformed[0][0], flakeside_tformed[0][1]);
            glVertex2f(flakeside_tformed[1][0], flakeside_tformed[1][1]);
            glVertex2f(flakeside_tformed[2][0], flakeside_tformed[2][1]);
            glVertex2f(flakeside_tformed[3][0], flakeside_tformed[3][1]);
            glVertex2f(flakeside_tformed[4][0], flakeside_tformed[4][1]);
            glVertex2f(flakeside_tformed[5][0], flakeside_tformed[5][1]);
            glVertex2f(flakeside_tformed[6][0], flakeside_tformed[6][1]);
            glVertex2f(flakeside_tformed[7][0], flakeside_tformed[7][1]);
            glVertex2f(flakeside_tformed[8][0], flakeside_tformed[8][1]);
            glVertex2f(flakeside_tformed[9][0], flakeside_tformed[9][1]);
            glVertex2f(flakeside_tformed[10][0], flakeside_tformed[10][1]);
            glVertex2f(flakeside_tformed[11][0], flakeside_tformed[11][1]);
            glVertex2f(flakeside_tformed[12][0], flakeside_tformed[12][1]);
            glVertex2f(flakeside_tformed[13][0], flakeside_tformed[13][1]);
            glVertex2f(flakeside_tformed[14][0], flakeside_tformed[14][1]);
            glVertex2f(flakeside_tformed[15][0], flakeside_tformed[15][1]);
            glEnd();
    
            glBegin(GL_LINE_LOOP);
            glVertex2f(flakeside_tformed[0][0], -flakeside_tformed[0][1]);
            glVertex2f(flakeside_tformed[1][0], -flakeside_tformed[1][1]);
            glVertex2f(flakeside_tformed[2][0], -flakeside_tformed[2][1]);
            glVertex2f(flakeside_tformed[3][0], -flakeside_tformed[3][1]);
            glVertex2f(flakeside_tformed[4][0], -flakeside_tformed[4][1]);
            glVertex2f(flakeside_tformed[5][0], -flakeside_tformed[5][1]);
            glVertex2f(flakeside_tformed[6][0], -flakeside_tformed[6][1]);
            glVertex2f(flakeside_tformed[7][0], -flakeside_tformed[7][1]);
            glVertex2f(flakeside_tformed[8][0], -flakeside_tformed[8][1]);
            glVertex2f(flakeside_tformed[9][0], -flakeside_tformed[9][1]);
            glVertex2f(flakeside_tformed[10][0], -flakeside_tformed[10][1]);
            glVertex2f(flakeside_tformed[11][0], -flakeside_tformed[11][1]);
            glVertex2f(flakeside_tformed[12][0], -flakeside_tformed[12][1]);
            glVertex2f(flakeside_tformed[13][0], -flakeside_tformed[13][1]);
            glVertex2f(flakeside_tformed[14][0], -flakeside_tformed[14][1]);
            glVertex2f(flakeside_tformed[15][0], -flakeside_tformed[15][1]);
            glEnd();
        }
    
    public:
        void draw() {
            glPushMatrix();
            glScalef(mSx, mSy, 1.0f);
            drawflakeside();
    
            glRotatef(60.0f, 0.0f, 0.0f, 1.0f);
            drawflakeside();
    
            glRotatef(60.0f, 0.0f, 0.0f, 1.0f);
            drawflakeside();
    
            glRotatef(60.0f, 0.0f, 0.0f, 1.0f);
            drawflakeside();
    
            glRotatef(60.0f, 0.0f, 0.0f, 1.0f);
            drawflakeside();
    
            glRotatef(60.0f, 0.0f, 0.0f, 1.0f);
            drawflakeside();
            glPopMatrix();
        }
    
        void setProperties(float cx, float cy, float sx, float sy, ROTATE_DIRECTION rot_direction) 
        {
            mSx = sx;
            mSy = sy;
        }
    };
    
    
    Flake flakes[5];
    
    void initScene(void) {
        flakes[0].setProperties(0.0, 0.0, 1.0, 1.0, CLOCKWISE);
        flakes[1].setProperties(40.0, 40.0, 0.3, 0.3, ANTICLOCKWISE);
    }
    
    void display(void) {
        glClear(GL_COLOR_BUFFER_BIT);
    
        glClearColor(0.0, 0.0, 0.0, 0.0);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0);
    
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    
        //draw your scene here
        glColor3f(1, 1, 0);
        flakes[0].draw();
        glColor3f(1, 0, 0);
        flakes[1].draw();
    
        glutSwapBuffers();
    }
    
    void anim(void) {
        glutPostRedisplay();
    }
    
    int main(int argc, char ** argv) {
    
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
        glutInitWindowSize(550, 550);
        glutCreateWindow("SnowFlake");
    
        initScene();
    
        glutDisplayFunc(display);
        glutIdleFunc(anim);
    
        glutMainLoop();
    
        return 0;
    }