На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
Модераторы: Qraizer
  
> Визуализация трехмерных обектов при помощи OpenGL , Построение октаэдра
    По заданию необходимо разработать OpenGL-приложение, визуализирующее октаэдр. Помогите, пожалуйста, разобраться, где допущена ошибка и почему не идет построение?

    ExpandedWrap disabled
      #include "stdafx.h"
      #include <GL/glut.h>
       
      int R = 1; // радиус
       
      // Нумерация элементов массивов vertices (присвоение вершинам номера от 0 до 7) и colors. Составляем из вершин треугольники - грани (а1, а2, а3, а4, а5, а6, а7, а8)
      GLubyte a1[] = { 0, 1, 2 };
      GLubyte a2[] = { 1, 3, 2 };
      GLubyte a3[] = { 0, 4, 1 };
      GLubyte a4[] = { 1, 4, 3 };
      GLubyte a5[] = { 0, 5, 2 };
      GLubyte a6[] = { 2, 5, 3 };
      GLubyte a7[] = { 0, 5, 4 };
      GLubyte a8[] = { 5, 4, 3 };
       
      void setupPointers(void)
      {   //координаты вершин октаэдра; по 3 координаты для каждой вершины
          static GLint vertices[] = { -R, 0, 0,
              0, 0, R,
              0, R, 0,
              R, 0, 0,
              0, -R, 0,
              0, 0, -R };
       
          static GLfloat colors[] = { 1.0, 0.2, 0.2,
              0.2, 0.2, 1.0,
              0.8, 1.0, 0.2,
              0.75, 0.75, 0.75,
              0.35, 0.35, 0.35,
              0.5, 0.5, 0.5   };
          //включение массивов вершины и цвета
          glEnableClientState(GL_VERTEX_ARRAY);
          glEnableClientState(GL_COLOR_ARRAY);
          //указываем размер этих массивов (сколько элементов будет прочитано за один проход)
          glVertexPointer(3, GL_INT, 0, vertices); //3 - потому что 3 координаты для каждой вершины
          glColorPointer(3, GL_FLOAT, 0, colors);
      }
       
      void display(void)
      {
          glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
          glClear(GL_COLOR_BUFFER_BIT);
          glLoadIdentity();
          glTranslatef(20.0, 20.0, -60.0);
          //8 вызовов по числу граней (пронумерованы выше)
          glDrawElements(GL_QUADS, 3, GL_UNSIGNED_BYTE, a1);
          glDrawElements(GL_QUADS, 3, GL_UNSIGNED_BYTE, a2);
          glDrawElements(GL_QUADS, 3, GL_UNSIGNED_BYTE, a3);
          glDrawElements(GL_QUADS, 3, GL_UNSIGNED_BYTE, a4);
          glDrawElements(GL_QUADS, 3, GL_UNSIGNED_BYTE, a5);
          glDrawElements(GL_QUADS, 3, GL_UNSIGNED_BYTE, a6);
          glDrawElements(GL_QUADS, 3, GL_UNSIGNED_BYTE, a7);
          glDrawElements(GL_QUADS, 3, GL_UNSIGNED_BYTE, a8);
          glFlush();
      }
       
      void reshape(int w, int h)
      {
          glViewport(0, 0, (GLsizei)w, (GLsizei)h);
          glMatrixMode(GL_PROJECTION);
          glLoadIdentity();
          gluPerspective(120, (GLdouble)w / h, 1.0, 100.0);//насколько широко открыто око камеры (120 градусов)
          glMatrixMode(GL_MODELVIEW);
      }
       
      int main(int argc, char** argv)
      {
          glutInit(&argc, argv);
          glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
          glutInitWindowSize(350, 350);
          glutInitWindowPosition(100, 100);
          glutCreateWindow(argv[0]);
          setupPointers();
          glutDisplayFunc(display);
          glutReshapeFunc(reshape);
          glutMainLoop();
          return 0;
      }

    Прикреплённая картинка
    Прикреплённая картинка
      Потому что в квадратике 4 вершины, а вы рисуете 3.
      Замените GL_QUADS на GL_TRIANGLES и всё! ;)
        А если переписать код таким образом:
        ExpandedWrap disabled
          #include "stdafx.h"
          #include <GL/glut.h>
          #include <stdlib.h>
          #include <math.h>
          #include <stdarg.h>
           
          double rotate_y = 0;
          double rotate_x = 0;
           
          // отбраковка граней
          void Init(){
              glEnable(GL_CULL_FACE); // включение режима отбраковки граней
              // отбраковываться будут нелицевые стороны граней
              glCullFace(GL_BACK);
              glFrontFace(GL_CCW);
              glEnable(GL_DEPTH_TEST); // удаление невидимых линий и поверхностей
          }
           
          // Функция обработки сообщений с клавиатуры
          void Keyboard(unsigned char key, int x, int y)
          {
          #define ESCAPE '\033'
              if (key == ESCAPE)
                  exit(0);
          }
           
          void display(void)
          {
              glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // задание цвета очистки кадра
              glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // очистка буфера цвета и буфера глубины
              glLoadIdentity(); // единичная матрица
              //gluLookAt(
              //  1, 2, 0.2, // положение глаза наблюдателя
              //  0, 0, 0,   // точка, в которую направлена камера
              //  0, 0, 1);  // вектор, служащий для определения вектора "вверх"
              
              // Вращение при изменении пользователем значений rotate_x и rotate_y
              glRotatef(rotate_x, 1.0, 0.0, 0.0);
              glRotatef(rotate_y, 0.0, 1.0, 0.0);
              
              // РИСОВАНИЕ ГРАНЕЙ ОКТАЭДРА
           
              //1
              glBegin(GL_POLYGON);
              glColor3f(1.0, 1.0, 1.0);
              glVertex3f(-1, 0, 0);
              glVertex3f(0, 0, 1);
              glVertex3f(0, 1, 0);
              glEnd();
           
              //2
              glBegin(GL_POLYGON);
              glColor3f(1.0, 0.0, 1.0);
              glVertex3f(0, 0, 1);
              glVertex3f(1, 0, 0);
              glVertex3f(0, 1, 0);
              glEnd();
           
              //3
              glBegin(GL_POLYGON);
              glColor3f(0.0, 1.0, 0.0);
              glVertex3f(-1, 0, 0);
              glVertex3f(0, -1, 0);
              glVertex3f(0, 0, 1);
              glEnd();
           
              //4
              glBegin(GL_POLYGON);
              glColor3f(0.0, 0.0, 1.0);
              glVertex3f(0, 0, 1);
              glVertex3f(0, -1, 0);
              glVertex3f(1, 0, 0);
              glEnd();
           
              //5
              glBegin(GL_POLYGON);
              glColor3f(1.0, 0.0, 0.0);
              glVertex3f(-1, 0, 0);
              glVertex3f(0, 0, -1);
              glVertex3f(0, 1, 0);
              glEnd();
           
              //6
              glBegin(GL_POLYGON);
              glColor3f(1.0, 1.0, 0.0);
              glVertex3f(0, 1, 0);
              glVertex3f(0, 0, -1);
              glVertex3f(1, 0, 0);
              glEnd();
           
              //7
              glBegin(GL_POLYGON);
              glColor3f(1.0, 0.0, 1.0);
              glVertex3f(-1, 0, 0);
              glVertex3f(0, -1, 0);
              glVertex3f(0, 0, -1);
              glEnd();
           
              //8
              glBegin(GL_POLYGON);
              glColor3f(0.0, 1.0, 1.0);
              glVertex3f(0, 0, -1);
              glVertex3f(0, -1, 0);
              glVertex3f(1, 0, 0);
              glEnd();
              glFlush();
              glutSwapBuffers();
          }
           
          // управление курсором
          void pressedSpecialKey(int key, int x, int y) {
           
              //  Правая стрелка - увеличение вращения на 5 градусов
              if (key == GLUT_KEY_RIGHT)
                  rotate_y += 5;
           
              //  Левая стрелка - уменьшение вращения на 5 градусов
              else if (key == GLUT_KEY_LEFT)
                  rotate_y -= 5;
           
              else if (key == GLUT_KEY_UP)
                  rotate_x += 5;
           
              else if (key == GLUT_KEY_DOWN)
                  rotate_x -= 5;
           
              //  Запрос обновления экрана
              glutPostRedisplay();
           
          }
           
          int main(int argc, char** argv)
          {
              glutInit(&argc, argv); // начальная инициализация библиотеки GLUT  
              glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // установка режима дисплея
              glutInitWindowSize(350, 350); // установка размера окна
              glutInitWindowPosition(100, 100); // установка положения окна на экране
              glutCreateWindow(" Октаэдр "); // запуск экранного окна
              glEnable(GL_DEPTH_TEST); // тест глубины
              glutDisplayFunc(display);
              glutSpecialFunc(pressedSpecialKey);
              glutKeyboardFunc(Keyboard);
              glutMainLoop(); // вход в бесконечный цикл
              return 0;
          }

        Подскажите, пожалуйста, как сделать задние грани видимыми (как на рисунке задания)?
          Ну, очевидно, надо:
          1.не поставить glEnable(GL_CULL_FACE), а убрать: glDisable(GL_CULL_FACE);
          2.режим показа включить - рёбрами: glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
            Славян, при управлении курсором, цвета граней пропадают, цветные только ребра... Я не в то место вставила?
            ExpandedWrap disabled
              #include "stdafx.h"
              #include <GL/glut.h>
              #include <stdlib.h>
              #include <math.h>
              #include <stdarg.h>
               
              double rotate_y = 0;
              double rotate_x = 0;
               
              // отбраковка граней
              void Init(){
                  glDisable(GL_CULL_FACE);
                  //glEnable(GL_CULL_FACE); // включение режима отбраковки граней
                  // отбраковываться будут нелицевые стороны граней
                  glCullFace(GL_BACK);
                  glFrontFace(GL_CCW);
                  glEnable(GL_DEPTH_TEST); // удаление невидимых линий и поверхностей
              }
               
              // Функция обработки сообщений с клавиатуры
              void Keyboard(unsigned char key, int x, int y)
              {
              #define ESCAPE '\033'
                  if (key == ESCAPE)
                      exit(0);
              }
               
              void display(void)
              {
                  glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // задание цвета очистки кадра
                  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // очистка буфера цвета и буфера глубины
                  glLoadIdentity(); // единичная матрица
                  //gluLookAt(
                  //  1, 2, 0.2, // положение глаза наблюдателя
                  //  0, 0, 0,   // точка, в которую направлена камера
                  //  0, 0, 1);  // вектор, служащий для определения вектора "вверх"
                  
                  // Вращение при изменении пользователем значений rotate_x и rotate_y
                  glRotatef(rotate_x, 1.0, 0.0, 0.0);
                  glRotatef(rotate_y, 0.0, 1.0, 0.0);
                  
                  // РИСОВАНИЕ ГРАНЕЙ ОКТАЭДРА
               
                  //1
                  glBegin(GL_POLYGON);
                  glColor3f(1.0, 1.0, 1.0);
                  glVertex3f(-1, 0, 0);
                  glVertex3f(0, 0, 1);
                  glVertex3f(0, 1, 0);
                  glEnd();
               
                  //2
                  glBegin(GL_POLYGON);
                  glColor3f(1.0, 0.0, 1.0);
                  glVertex3f(0, 0, 1);
                  glVertex3f(1, 0, 0);
                  glVertex3f(0, 1, 0);
                  glEnd();
               
                  //3
                  glBegin(GL_POLYGON);
                  glColor3f(0.0, 1.0, 0.0);
                  glVertex3f(-1, 0, 0);
                  glVertex3f(0, -1, 0);
                  glVertex3f(0, 0, 1);
                  glEnd();
               
                  //4
                  glBegin(GL_POLYGON);
                  glColor3f(0.0, 0.0, 1.0);
                  glVertex3f(0, 0, 1);
                  glVertex3f(0, -1, 0);
                  glVertex3f(1, 0, 0);
                  glEnd();
                  
                  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
               
                  //5
                  glBegin(GL_POLYGON);
                  glColor3f(1.0, 0.0, 0.0);
                  glVertex3f(-1, 0, 0);
                  glVertex3f(0, 0, -1);
                  glVertex3f(0, 1, 0);
                  glEnd();
               
                  //6
                  glBegin(GL_POLYGON);
                  glColor3f(1.0, 1.0, 0.0);
                  glVertex3f(0, 1, 0);
                  glVertex3f(0, 0, -1);
                  glVertex3f(1, 0, 0);
                  glEnd();
               
                  //7
                  glBegin(GL_POLYGON);
                  glColor3f(1.0, 0.0, 1.0);
                  glVertex3f(-1, 0, 0);
                  glVertex3f(0, -1, 0);
                  glVertex3f(0, 0, -1);
                  glEnd();
               
                  //8
                  glBegin(GL_POLYGON);
                  glColor3f(0.0, 1.0, 1.0);
                  glVertex3f(0, 0, -1);
                  glVertex3f(0, -1, 0);
                  glVertex3f(1, 0, 0);
                  glEnd();
                  glFlush();
                  glutSwapBuffers();
              }
               
              // управление курсором
              void pressedSpecialKey(int key, int x, int y) {
               
                  //  Правая стрелка - увеличение вращения на 5 градусов
                  if (key == GLUT_KEY_RIGHT)
                      rotate_y += 5;
               
                  //  Левая стрелка - уменьшение вращения на 5 градусов
                  else if (key == GLUT_KEY_LEFT)
                      rotate_y -= 5;
               
                  else if (key == GLUT_KEY_UP)
                      rotate_x += 5;
               
                  else if (key == GLUT_KEY_DOWN)
                      rotate_x -= 5;
               
                  //  Запрос обновления экрана
                  glutPostRedisplay();
               
              }
               
              int main(int argc, char** argv)
              {
                  glutInit(&argc, argv); // начальная инициализация библиотеки GLUT  
                  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // установка режима дисплея
                  glutInitWindowSize(350, 350); // установка размера окна
                  glutInitWindowPosition(100, 100); // установка положения окна на экране
                  glutCreateWindow(" Октаэдр "); // запуск экранного окна
                  glEnable(GL_DEPTH_TEST); // тест глубины
                  glutDisplayFunc(display);
                  glutSpecialFunc(pressedSpecialKey);
                  glutKeyboardFunc(Keyboard);
                  glutMainLoop(); // вход в бесконечный цикл
                  return 0;
              }
              Так зачем ставить отбраковку граней, коли вам все рёбра надо рисовать? glCullFace(GL_BACK) придётся убрать.
                Славян, а в какое место кода мне нужно вставить glPolygonMode( GL_FRONT_AND_BACK, GL_LINE)?

                Добавлено
                Это вставить перед каждой гранью?
                  Не, один раз где-нибудь можно. Система запомнит.
                  И вернулись бы к своим ClientState... Компактнее было! Ну или здесь поставьте режим GL_TRIANGLES и не насилуйте каждый раз glBegin/glEnd.
                    Славян, можно этот код вставить в функцию display, а функцию Init вообще убрать? У меня пропали цвета граней, я не то написала?! Никак не пойму...
                    ExpandedWrap disabled
                      void display(void)
                      {
                          glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // задание цвета очистки кадра
                          glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // очистка буфера цвета и буфера глубины
                          glLoadIdentity(); // единичная матрица
                          // Вращение при изменении пользователем значений rotate_x и rotate_y
                          glRotatef(rotate_x, 1.0, 0.0, 0.0);
                          glRotatef(rotate_y, 0.0, 1.0, 0.0);
                          
                          glDisable(GL_CULL_FACE);
                          glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
                       
                          // РИСОВАНИЕ ГРАНЕЙ ОКТАЭДРА
                          //1
                          glBegin(GL_TRIANGLES);
                          glColor3f(1.0, 1.0, 1.0);
                          glVertex3f(-1, 0, 0);
                          glVertex3f(0, 0, 1);
                          glVertex3f(0, 1, 0);
                          //2
                          glColor3f(1.0, 0.0, 1.0);
                          glVertex3f(0, 0, 1);
                          glVertex3f(1, 0, 0);
                          glVertex3f(0, 1, 0);
                          //3
                          glColor3f(0.0, 1.0, 0.0);
                          glVertex3f(-1, 0, 0);
                          glVertex3f(0, -1, 0);
                          glVertex3f(0, 0, 1);
                          //4
                          glColor3f(0.0, 0.0, 1.0);
                          glVertex3f(0, 0, 1);
                          glVertex3f(0, -1, 0);
                          glVertex3f(1, 0, 0);
                          //5
                          glColor3f(1.0, 0.0, 0.0);
                          glVertex3f(-1, 0, 0);
                          glVertex3f(0, 0, -1);
                          glVertex3f(0, 1, 0);
                          //6
                          glColor3f(1.0, 1.0, 0.0);
                          glVertex3f(0, 1, 0);
                          glVertex3f(0, 0, -1);
                          glVertex3f(1, 0, 0);
                          //7
                          glColor3f(1.0, 0.0, 1.0);
                          glVertex3f(-1, 0, 0);
                          glVertex3f(0, -1, 0);
                          glVertex3f(0, 0, -1);
                          //8
                          glColor3f(0.0, 1.0, 1.0);
                          glVertex3f(0, 0, -1);
                          glVertex3f(0, -1, 0);
                          glVertex3f(1, 0, 0);
                          glEnd();
                          glFlush();
                          glutSwapBuffers();
                      }
                      Наоборот: лучше как можно больше выносить во всякие Init'ы, т.к. функция отображения вызывается часто, а Init-редко. У вас не цвета пропали, а наверное грани не закрашиваются, т.к. только контур их рисуется.
                        Спасибо!
                        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                        0 пользователей:


                        Рейтинг@Mail.ru
                        [ Script execution time: 0,0665 ]   [ 19 queries used ]   [ Generated: 29.03.24, 12:53 GMT ]