Выполнение нескольких отражений в OpenGL - PullRequest
0 голосов
/ 23 октября 2018

Мое задание - выполнять преобразования (отражения) на 2D-объекте.

Допустим, мой исходный объект - это круг: o

Я хочу отразить его, например, через линию y = 5.о |o

Затем я хочу отразить два объекта, например, в строке x = 5.

oo

__

oo

Затем, наконец, я хочу отразить четыре объекта, например, в строке y = 10.

oo |оо

оо |oo

Итак, в конечном итоге я хочу, чтобы конечный результат включал в себя 8 кружков.

Мой вопрос: как бы я внедрил это в мой код?

Это код для моего проекта:

#include <glut.h>

GLfloat square[4][3] = {{5, 0,0}, {5,20,0},{-5,20,0}, {-5,0,0}};
GLfloat square2[4][3] = { { 10, -5,0 },{ 10,25,0 },{ 0,25,0 },{ 0,-5,0 } };
GLfloat square3[4][3] = { { 0, -5,0 },{ 0,25,0 },{ -10,25,0 },{ -10,-5,0 } };
GLfloat colors[3][3] = {{0,0,1},{1,1,1},{0,0,0}};

void draw_square(void){
     glBegin(GL_POLYGON);
         for(int i = 0; i < 4; i++){
                 glVertex3fv(square[i]);
         }
     glEnd();
}

void draw_square2(void) {
    glBegin(GL_POLYGON);
    for (int i = 0; i < 4; i++) {
        glVertex3fv(square2[i]);
    }
    glEnd();
}

void draw_square3(void) {
    glBegin(GL_POLYGON);
    for (int i = 0; i < 4; i++) {
        glVertex3fv(square3[i]);
    }
    glEnd();
}

void draw_ring(void){
     for(int r =0; r < 360;r+=45){
             glPushMatrix();
             glRotated(r, 0,0,1);
             glTranslated(0,50,0);
             draw_square();
             glPopMatrix();
     }
}

void draw_ring2(void) {
    for (int r = 0; r < 360; r += 45) {
        glPushMatrix();
        glRotated(r, 0, 0, 1);
        glTranslated(0, 50, 0);
        draw_square2();
        glPopMatrix();
    }
}

void draw_ring3(void) {
    for (int r = 0; r < 360; r += 45) {
        glPushMatrix();
        glRotated(r, 0, 0, 1);
        glTranslated(0, 50, 0);
        draw_square3();
        glPopMatrix();
    }
}

Функция отображения ниже создает набор перекрывающихся колец, которые я хочу отразить.Теперь я получаю только один набор перекрывающихся колец в левом нижнем углу.Я хочу, чтобы на выходе было 8 наборов перекрывающихся колец.Я пытался найти способ создания отражений, которые мне нужны, но я не могу понять это.

void display(void){
     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);


         glPushMatrix();
         glColor3fv(colors[0]);
         draw_ring();
         glColor3fv(colors[1]);
         draw_ring2();
         glColor3fv(colors[2]);
         draw_ring3();

         glPopMatrix();


     glFlush();
}

void main(int argc, char** argv){
     glutInit(&argc, argv);
     glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
     glutInitWindowSize(1000,600);
     glutInitWindowPosition(200,100);
     glutCreateWindow("Project 2");
     glClearColor(1.0,1.0,0.0,1.0);
     glEnable(GL_DEPTH_TEST);
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     gluOrtho2D(-100.0, 1000.0, -100.0,600.0);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     glutDisplayFunc(display);
     glutMainLoop();
}

Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 23 октября 2018

Обратите внимание, что рисование с помощью glBegin / glEnd последовательностей и стека конвейерной матрицы с фиксированными функциями устарело с десятилетий.Прочитайте о конвейере с фиксированными функциями и посмотрите Спецификация вершин и Шейдер для современного способа рендеринга.


В любом случае,если вы хотите разбить объекты на блоки, то вы можете сделать это с помощью вложенных циклов:

void draw_object( void )
{
    glPushMatrix();

    glColor3fv(colors[0]);
    draw_ring();
    glColor3fv(colors[1]);
    draw_ring2();
    glColor3fv(colors[2]);
    draw_ring3();

    glPopMatrix();
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    int   tile_x = 4;
    int   tile_y = 2;
    float tile_dist = 200.0f;

    for ( int x = 0; x < tile_x; ++ x )
    {
          for (int y = 0; y < tile_y; ++ y )
          {
              glPushMatrix();
              glTranslatef( (float)x * tile_dist, (float)y * tile_dist, 0.0f );
              draw_object();
              glPopMatrix();
          }
    }

    glFlush();
}

Тот же самый эффект плитки можно получить с помощью рекурсивной функции:

void display_tiles_recursive( int level, float dist )
{
    if ( level == 0 )
    {
        draw_object();
        return;
    }

    int   tile     = level / 2;
    bool  tile_x   = level % 2 != 0;
    float offset_x = tile_x ? pow(2.0f, (float)tile) * dist : 0.0f;
    float offset_y = tile_x ? 0.0f : pow(2.0f, (float)(tile-1)) * dist;

    glPushMatrix();

    display_tiles_recursive( level - 1, dist );
    glTranslatef( offset_x, offset_y, 0.0f );
    display_tiles_recursive( level - 1, dist );

    glPopMatrix();
}

void display_mirror(void)
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    display_tiles_recursive( 3, 200.0f );
    glFlush();
}

Если вы хотите добиться повторного зеркального эффекта, то необходимо зеркально отразить четные плитки по осям x и y.Отражение может быть достигнуто с помощью glScale.glScalef( -1.0f, 1.0f, 1.0f ); для зеркального отражения вдоль оси x и glScalef( 1.0f, -1.0f, 1.0f ); для зеркального отображения вдоль оси y.Вы можете расширить функцию рекурсивного тайлинга, чтобы получить этот эффект:

void display_mirror_recursive( int level, float dist, bool even_x, bool even_y )
{
    if ( level == 0 )
    {
        glPushMatrix();
        if ( even_x )
            glScalef( -1.0f, 1.0f, 1.0f );
        if ( even_y )
            glScalef(  1.0f, -1.0f, 1.0f );
        draw_object();
        glPopMatrix();
        return;
    }

    int   tile     = level / 2;
    bool  tile_x   = level % 2 != 0;
    float offset_x = tile_x ? pow(2.0f, (float)tile) * dist : 0.0f;
    float offset_y = tile_x ? 0.0f : pow(2.0f, (float)(tile-1)) * dist;

    glPushMatrix();
    display_mirror_recursive( level - 1, dist, even_x, even_y );
    glTranslatef( offset_x, offset_y, 0.0f );
    if ( level == 1 )
      even_y = !even_y;
    if ( level == 2)
      even_x = !even_x;
    display_mirror_recursive( level - 1, dist, even_x, even_y );
    glPopMatrix();
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    display_mirror_recursive( 3, 200.0f, false, false );
    glFlush();
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...