Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.144.113.197] |
|
Сообщ.
#1
,
|
|
|
По заданию необходимо разработать OpenGL-приложение, визуализирующее октаэдр. Помогите, пожалуйста, разобраться, где допущена ошибка и почему не идет построение?
#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; } Прикреплённая картинка
|
Сообщ.
#2
,
|
|
|
Потому что в квадратике 4 вершины, а вы рисуете 3.
Замените GL_QUADS на GL_TRIANGLES и всё! |
Сообщ.
#3
,
|
|
|
А если переписать код таким образом:
#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; } Подскажите, пожалуйста, как сделать задние грани видимыми (как на рисунке задания)? |
Сообщ.
#4
,
|
|
|
Ну, очевидно, надо:
1.не поставить glEnable(GL_CULL_FACE), а убрать: glDisable(GL_CULL_FACE); 2.режим показа включить - рёбрами: glPolygonMode( GL_FRONT_AND_BACK, GL_LINE); |
Сообщ.
#5
,
|
|
|
Славян, при управлении курсором, цвета граней пропадают, цветные только ребра... Я не в то место вставила?
#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; } |
Сообщ.
#6
,
|
|
|
Так зачем ставить отбраковку граней, коли вам все рёбра надо рисовать? glCullFace(GL_BACK) придётся убрать.
|
Сообщ.
#7
,
|
|
|
Славян, а в какое место кода мне нужно вставить glPolygonMode( GL_FRONT_AND_BACK, GL_LINE)?
Добавлено Это вставить перед каждой гранью? |
Сообщ.
#8
,
|
|
|
Не, один раз где-нибудь можно. Система запомнит.
И вернулись бы к своим ClientState... Компактнее было! Ну или здесь поставьте режим GL_TRIANGLES и не насилуйте каждый раз glBegin/glEnd. |
Сообщ.
#9
,
|
|
|
Славян, можно этот код вставить в функцию display, а функцию Init вообще убрать? У меня пропали цвета граней, я не то написала?! Никак не пойму...
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(); } |
Сообщ.
#10
,
|
|
|
Наоборот: лучше как можно больше выносить во всякие Init'ы, т.к. функция отображения вызывается часто, а Init-редко. У вас не цвета пропали, а наверное грани не закрашиваются, т.к. только контур их рисуется.
|
Сообщ.
#11
,
|
|
|
Спасибо!
|