Есть круг.
Но если изменить размеры окна(ресайз) например вот так:
или так:
То получается овал.
Вопрос: как сделать, чтобы при ресайзе, круг всегда оставался кругом?
Код:
#include "stdafx.h"
#include
#include
/* подключаем библиотеку GLUT */
#include
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 < 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 < 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 < 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:
Добавил -
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();
}
Итого всё в порядке,но...
Так хорошо.
Так не хорошо.
Ответ
Вам нужно сделать изменение ширины/высоты в glOrtho при изменении размеров окна, чтобы сохранялись пропорции отрисовки. Попробуйте так:
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 часто такой приём используется.