Search code examples
c++openglcoordinate-transformation

glScaled(size/window_size) incorrect image


When I use glScale(size/window_size) to draw a tetrahedron (window_size = 600x600) and input size = 600, it draws incorrect picture

[Output1.

When I input size < 600 it draws nothing, up to 1200 it draws the same images as given lower, after 1200 draws nothing again. How to do it correct?

int size_cat;
std::cin >> size_cat;
screen = SDL_CreateWindow("Jack.exe", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 600, SDL_WINDOW_OPENGL);

int size_h = 2 * size_cat;

SDL_GLContext context = SDL_GL_CreateContext(screen);
glClearColor(0, 0, 0, 1);
glRotatef(25, 1, 1, 0);
while (1)
{
    SDL_Event event;
    while (SDL_PollEvent(&event))
    {
        switch (event.type)
        {
            case SDL_QUIT:
                return 0;
            case SDL_KEYDOWN:
                if (event.key.repeat) break;
                switch (event.key.keysym.scancode)
                {
                    case SDL_SCANCODE_1: glColor3b(127, 0, 0); break;
                    case SDL_SCANCODE_2: glColor3b(0, 127, 0); break;
                    case SDL_SCANCODE_3: glColor3b(0, 0, 127); break;
                }
                break;              
        }
    }

    glClear(GL_COLOR_BUFFER_BIT);

    glScalef(size_cat/600, size_cat/600, size_cat/600);

    glBegin(GL_LINES);

    glVertex3f(0.5, 1, -0.5);
    glVertex3f(0.5, 0, -0.5);

    glVertex3f(0.5, 0 ,-0.5);
    glVertex3f(0.5, 0, 0.5);    

    glVertex3f(0.5, 0, 0.5);
    glVertex3f(-0.5, 0, -0.5);

    glVertex3f(-0.5, 0, -0.5);
    glVertex3f(0.5, 0, -0.5);

    glVertex3f(0.5, 1, -0.5);
    glVertex3f(0.5, 0, 0.5);

    glVertex3f(0.5, 1, -0.5);
    glVertex3f(-0.5, 0, -0.5);

Solution

  • Since you use glScale in a loop, you are changing your matrix progressively. glScale multiply the current matrix by a general scaling matrix.

    See glScale:

    glScale produces a nonuniform scaling along the x, y, and z axes. The three parameters indicate the desired scale factor along each of the three axes.

    The current matrix (see glMatrixMode) is multiplied by this scale matrix, and the product replaces the current matrix.


    Either use glLoadIdentity to replace the current matrix with the identity matrix, before you do the scaling:

    while (1)
    {
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glRotatef(25, 1, 1, 0);
        glScalef(size_cat/600, size_cat/600, size_cat/600);
    
        .....
    }
    


    Or use glPushMatrix and glPopMatrix:

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glRotatef(25, 1, 1, 0);
    while (1)
    {
        glPushMatrix();
        glScalef(size_cat/600, size_cat/600, size_cat/600);
    
        .....
    
        glPopMatrix();
    }