Страницы

Поиск по вопросам

вторник, 5 марта 2019 г.

Как сохранить пропорции 2D объекта в окне рендера OpenGL?

Есть круг.

Но если изменить размеры окна(ресайз) например вот так:

или так:

То получается овал.
Вопрос: как сделать, чтобы при ресайзе, круг всегда оставался кругом?
Код:
#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 часто такой приём используется.

Комментариев нет:

Отправить комментарий