How do you keep the 2D object in the OpenGL window?



  • There's a circle.

    введите сюда описание изображения

    But if you change the size of the window, like this:

    введите сюда описание изображения

    or so:

    введите сюда описание изображения

    It works.

    Question: How do we keep the circle around?

    Code:

    #include "stdafx.h"
    #include <stdlib.h>
    #include <math.h>
    

    /* подключаем библиотеку GLUT */
    #include <GL/glut.h>

    static GLfloat spin = 0.0;

    void init(void)
    {
    //glClearColor() устанавливает черный цвет фона
    glClearColor(0.0, 0.0, 0.0, 0.0);
    //glShadeModel(GL_FLAT);////Режим без сглаживания
    glShadeModel(GL_SMOOTH); //Сглаживание. По умолчанию установлен режим GL_SMOOTH.

    }

    void display(void)
    {
    // glClear() очищает фон .
    //В дальнейшем, всякий раз, когда glClear() будет вызываться,
    //она будет очищать окно в черный цвет .
    glClear(GL_COLOR_BUFFER_BIT);
    glPushMatrix();
    //glRotatef(Angle,Xtrue,Ytrue,Ztrue) отвечает за вращения объекта вдоль
    glRotatef(spin, 0.0, 0.0, 1.0);

    //glColor3f() устанавливает цвет прорисовки - белый цвет.
    glColor3f(1.0, 1.0, 1.0);
    //glColor3f(1.0, 0.0, 0.0);//-красный.
    
    #define PI 3.1415926535898
    GLint circle_points = 25;
    //glBegin() и glEnd() определяют обьект, который будет прорисован .
    glBegin(GL_LINE_LOOP);
    for (int i = 0; i &lt; circle_points; i++) {
        double angle = 2 * PI*i / circle_points;
        //glVertex2f() определяет вершины полигона, в качестве параметров - 2 координаты x, y.
        glVertex2f(cos(angle), sin(angle));
    }
    glEnd();
    
    
    glBegin(GL_LINE_LOOP);
    for (int i = 0; i &lt; circle_points; i++) {
        double angle = 6 * PI*i / circle_points;
        glVertex2f(cos(angle), sin(angle));
    }
    glEnd();
    
    glBegin(GL_LINE_LOOP);
    for (int i = 0; i &lt; circle_points; i++) {
        double angle = 20 * PI*i / circle_points;
        glVertex2f(cos(angle), sin(angle));
    }
    glEnd();
    
    glPopMatrix();
    /*glutSwapBuffers(), делающий свопинг буффера .
    Имеется 2 буффера, и пока на экран не выводится полностью один из них,
    второй остается полностью за кадром, и не произойдет наложения одного надругой .*/
    glutSwapBuffers();
    

    }

    void spinDisplay(void)
    {
    spin = spin + 0.05;
    if (spin > 360.0)
    spin = spin - 360.0;
    glutPostRedisplay();
    }

    void reshape(int w, int h)
    {
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    //glOrtho() определяет координатную систему .
    glOrtho(-2.0, 2.0, -2.0, 2.0, -1.0, 1.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    }

    void mouse(int button, int state, int x, int y)
    {
    switch (button) {
    case GLUT_LEFT_BUTTON:
    if (state == GLUT_DOWN)
    glutIdleFunc(spinDisplay);
    break;
    case GLUT_MIDDLE_BUTTON:
    if (state == GLUT_DOWN)
    glutIdleFunc(NULL);
    break;
    default:
    break;
    }
    }

    /*

    • double buffer display mode.

    • Register mouse input callback functions
      /
      int main(int argc, char
      * argv)
      {
      // glutInit(int *argc, char **argv) - самая первая команда инициализации
      glutInit(&argc, argv);
      //glutInitDisplayMode(unsigned int mode) - устанавливает цветовую модель - RGBA или color - index .
      //Например, glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH) -
      //устанавливает двойной буфер, цветовую модель RGB .
      glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
      //glutInitWindowSize(int width, int size) - размер окна
      glutInitWindowSize(250, 250);
      //glutInitWindowPosition(int x, int y) - установливает начало координат окна.
      glutInitWindowPosition(100, 100);
      //int glutCreateWindow() - создает окно
      glutCreateWindow(argv[0]);
      init();
      //glutDisplayFunc() - вызывается всякий раз при перерисовке окна .
      glutDisplayFunc(display);
      glutReshapeFunc(reshape);
      glutMouseFunc(mouse);
      //glutMainLoop(void) - эта функция вызывается после всех остальных .
      glutMainLoop();
      return 0;
      }

    UPDATE:

    Adding--

    void reshape(int w, int h)
    {
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    double aspect = (double)w / h;
    //glOrtho() определяет координатную систему .
    glOrtho(-2.0 * aspect, 2.0 * aspect, -2.0, 2.0, -1.0, 1.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    }

    It's all right, but... ♪

    That's good.

    введите сюда описание изображения

    That's not good.

    введите сюда описание изображения



  • You need to change width/high to glOrtho when the size of the window is changed to keep the friction proportion. Try this:

    double ww = w, hh = h;
    if (w > h)
        glOrtho(-2.0 * (ww/hh), 2.0 * (ww/hh), -2.0, 2.0, -1.0, 1.0);
    else
        glOrtho(-2.0, 2.0, -2.0 * (hh/ww), 2.0 * (hh/ww), -1.0, 1.0);
    

    OpenGL books often use this technique.


Log in to reply
 


Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2