Урок 2 - Простые примитивы
В прошлом уроке мы рассмотрели инициализацию OpenGL. Этот урок будет посвящён рисованию и раскрашиванию простых примитивов: точка, линия, треугольник и квадрат.
В нашем прошлом примере изменим формат пиксела.
После строки
FillChar (pfd, SizeOf (pfd), 0);Допишем:
pfd.dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;Мы сообщили системе, что будет использоваться двойная буферизация. Это необходимо для того чтоб изображение не мерцало.
В процедуре создания Формы напишите:
glEnable(GL_DEPTH_TEST); // включаем проверку разрешения фигур (впереди стоящая закрывает фигуру за ней) glDepthFunc(GL_LEQUAL); //тип проверкиДалее в обработчике события Form1 OnResize создадим процедуру перерисовки нашего окна.
glViewport(0, 0, ClientWidth, ClientHeight); //выделяем область куда будет выводиться наш буфер glMatrixMode ( GL_PROJECTION ); //переходим в матрицу проекции glLoadIdentity; //Сбрасываем текущую матрицу glFrustum ( -1 , 1 , -1 , 1 , 1.25 , 100.0 ); //Область видимости glMatrixMode ( GL_MODELVIEW ); // переходим в модельную матрицу glLoadIdentity; //Сбрасываем текущую матрицу gluLookAt(5,5,5,0,0,0,0,0,1); //позиция наблюдателя InvalidateRect ( Handle,nil,False ); //перерисовка формыФункция glFrustum имеет 6 параметров, первые 4 из них, это границы отсечения: верхняя, правая, нижняя, левая. Последние 2 параметра – это передняя и задняя граница отсечения.
Функция gluLookAt имеет 9 параметров, первые 3 из них - позиция наблюдателя (x, y, z), следующие 3 параметра – точка наблюдения (x, y, z) и последние 3 параметра – вектор верха.
InvalidateRect ( Handle,nil,False ); перерисовывает форму гораздо быстрее, чем Form1.Repaint.
Для того, чтобы наше окно обновлялось надо вызвать процедуру FormResize до отрисовки примитивов.
FormResize(Sender); //процедура обновленияВсё, с приготовлением мы закончили, Теперь давайте приступим к рисованию примитивов и начнём мы с точки. Все фигуры рисуются в логических скобках glBegin(param); и glEnd; где param – тип рисуемого примитива.
glBegin() может иметь один из следующих параметров:
- GL_PONTS - точка
- GL_LINES - линия
- GL_TRIANGLES - треугольник
- GL_QUADS - квадрат
- GL_POLYGON – многоугольник
Теперь нарисуем точку, в процедуре FormPaint после очистки буфера цвета запишем следующий код:
glPointSize(20); // размер точки glBegin(GL_POINTS); glVertex3f(-2,5,1); glEnd;

Вот мы и получили очень большую точку в 20 пикселов :). Теперь давайте изменим цвет точки функцией glColor3f(R,G,B);
Эту функцию следует вызывать перед заданием позиции каждой вершины.
Раскрасим в красный цвет:
glPointSize(20); // размер точки glBegin(GL_POINTS); glColor3f(1,0,0); glVertex3f(-2,5,1); glEnd;

Точку мы нарисовали. Теперь нарисуем линию. Делается это точно так же как и точку. Т.к. линия состоит из 2 вершин то функцию glVertex3f(x, y ,z) будем вызывать 2 раза:
glBegin(GL_LINES); //рисуем линию glColor3f(1,0,0); {раскрасим первую вершину} glVertex3f(-1,0,1); //позиция первой вершины glColor3f(0,1,0); {раскрасим вторую вершину} glVertex3f(-4,5,1); //позиция второй вершины glEnd;Допишем этот код и получим:

OpenGL сам делает плавное перетекание цвета между вершинами. Поучается довольно красиво.
Не хватает квадрата и треугольника. Давайте нарисуем!
glBegin(GL_TRIANGLES); //рисуем треугольник glColor3f(1,0,0); glVertex3f(0,5,1); //первая вершина glColor3f(0,1,0); glVertex3f(1,4,1); //вторая вершина glColor3f(0,1,0); glVertex3f(-1,4,1); //третья вершина glEnd; glBegin(GL_QUADS); //рисуем квадрат glColor3f(1,0,0); glVertex3i(-1,1,0); //первая вершина glColor3f(0,1,0); glVertex3f(1,1,-0); //вторая вершина glColor3f(0,1,1); glVertex3f(1,-1,-0); //третья вершина glColor3f(0,0,1); glVertex3f(-1,-1,0); //четвёртая вершина glEnd;

Вроде бы получилось.
В примере данного урока я сделал небольшое дополнение: при нажатии стрелки вправо вся система координат поворачивается вправо функцией glRotatef(угол, x, y, z) где x, y, z – координаты оси поворота, а при нажатии на стрелку влево, то вся система координат поворачивается влево.
Можете поэкспериментировать и нарисовать что-нибудь другое.
В следующем уроке мы будем работать с освещением и нарисуем объёмные геометрические фигуры с падающим на них светом.
Добавил(а): Drimer | Дата: 2012-12-05 | |
в примере одно ))) а тут другоє))))
![]() |
Добавил(а): Doggy | Дата: 2013-01-11 | |
не пойму зачем FormResize(Sender). Рисунок с ней рябит при перетаскивании формы, а без нее все норм (рисунок сохраняется).
И еще - что это за wglMakeCurrent(0,0); - в первом уроке он есть а во втором он тупо мешает (с этой строкой не работает прога)
|
Добавил(а): Doggy | Дата: 2013-01-11 | |
а, и еще - что такое SwapBuffers(Canvas.Handle);
в первом уроке его небыло
|
Добавил(а): Doggy | Дата: 2013-01-12 | |
![]() ![]() ![]() ![]() |
Добавил(а): Klesh | Дата: 2013-01-12 | |
wglMakeCurrent(0,0); - удаляет созданный контекст воспроизведения. В первом уроке мы просто инициализировали OpenGL ничего не рисуя, поэтому контекст нам был не нужен. В этом уроке используется двойная буферизация, чтобы не было мерцания, сначала сцена отрисовывается в задний буфер, а затем разом выводится в передний, то есть на форму. Эту процедуру выполняет функция SwapBuffers(Canvas.Handle);
|
Добавил(а): Doggy | Дата: 2013-01-12 | |
ясно. спасибо. я правда пока еще плохо понимаю что такое контекст воспроизведения, но будем постепенно разбираться.
![]() |
Добавил(а): susczanski | Дата: 2013-04-04 | |
і, все-таки, для чого FormResize? Чому не можна той код прописувати відразу в FormPaint?
![]() |
Добавил(а): susczanski | Дата: 2013-04-05 | |
Переведу, наверно так понятнее.
В Ваших в уроках все основные действия (оброботка клавиатуры, мыши, прорисовка и т.д.) выполняются в процедуре formpaint. Мне же в проэкте надо создать цыкл, в конце которого должна выполняться прорисовка 3-д. Пробовал вызывать с цыкла formpaint, что-то не так. Пробовал всю прорисовку всунуть всам ц
жикл но тогда глючит formresize. Подскажите, пожалуйста, что делат?
|
Добавил(а): Klesh | Дата: 2013-04-07 | |
Конечно можно и засунуть код FormResize в FormPaint, это я так сделал чтоб было удобнее и за одно обрабатывалось сжатие/растяжение формы, оно и так обработается но это будет не синхронно . Здесь замкнутый цыкл сначала при создании формы она перерисовывается, выполняется FromPaint, следовательно выполнится FormResize, а там есть функция InvalidateRect ( Handle,nil,False ); которая опять все сотрёт с формы и её придется снова перерисовывается (FormPaint) и так по кругу. Вам надо стереть InvalidateRect и вставить в конец вашего цикла тогда форма перересуется 1 раз.
|
Добавил(а): Klesh | Дата: 2013-04-07 | |
и еще цыкл который вы хотите сделать не должен быть в FormPaint или FornResize, например в обработчике нажатия на кнопку.
![]() |
Добавил(а): susczanski | Дата: 2013-04-08 | |
Супер, спасибо
![]() |
Добавил(а): susczanski | Дата: 2013-04-08 | |
А как сделать так, чтоб вместо формы графика была на Image? Просто заменить Handle на Image1.Canvas.Handle не получаеться...
![]() |
Добавил(а): Klesh | Дата: 2013-04-10 | |
Да можно передавать вещественные числа, у вас скорее всего ошибка в типе переменной которую вы передаёте или или используете функцию которая принимает только целый тип(glVertex3i(x,y,z: integer)). Последняя буква в названии функции говорит о типе передаваемых данных: i - integer, f - Single и все вещественные типы (Double тоже), fv - ссылка(Pointer). Попробуйте glVertex3f(x,y,z: Single).
![]() |
Добавил(а): Klesh | Дата: 2013-04-10 | |
На Image выводить не получится, не знаю почему
![]() ![]() |
Добавил(а): почти человек | Дата: 2014-04-14 | |
не знаю почему, но у меня выводится только пустая форма, хотя выполнял всё по инструкции.
|
Добавил(а): kuza2011zaika | Дата: 2015-04-19 | |
У меня форма вся пустая. Почему так?
|
Добавил(а): R1D16ST29 | Дата: 2015-08-06 | |
glutSolidCube(1); почему то не знает как оператор, а другие (от opengl) знает
![]() ![]() |
Добавил(а): Nesf | Дата: 2017-03-14 | |
Если у вас выводится пустая форма, то у вас включился режим двойной буферизации, поэтому в конце обработчика события OnPaint следует написать команду SwapBuffers;
|
Добавил(а): dimonsky | Дата: 2017-07-03 | |
GetDC(handle) вместо canvas.handle, и убрать вызов FormResize. Тогда получается конфетка.
|
[url=http://oceansoftvietnam.com/product/opencart-migration/woocommerce-to-opencart-migration/#comment-1691]Some news about pills.[/url] [url=http://e-jurnal.pnl.ac.id/index.php/polimesin/comment/view/563/637/580921]Everything about medicine.[/url] [url=http://bpo.gov.mn/content/562]Actual trends of medicine.[/url] a706a28
[url=http://shop.khunjib.com/product/3516/%E0%B8%88%E0%B8%B1%E0%B9%89%E0%B8%A1%E0%B8%AA%E0%B8%B9%E0%B8%97%E0%B8%82%E0%B8%B2%E0%B8%A2%E0%B8%B2%E0%B8%A7%E0%B8%9C%E0%B9%88%E0%B8%B2%E0%B8%82%E0%B9%89%E0%B8%B2%E0%B8%87%20%E0%B8%AA%E0%B8%B5%E0%B9%80%E0%B8%82%E0%B8%B5%E0%B8%A2%E0%B8%A7.html]Everything what you want to know about drugs.[/url] [url=http://www.yliaow.com/forum.php?mod=viewthread&tid=30231&pid=275003&page=5294&extra=page%3D1#pid275003]All what you want to know about drug.[/url] [url=https://www.divifabriken.se/produkt/logo-collection/#comment-7340]Everything trends of medication.[/url] 05aa706
-----
[url=https://japancasino-x.com/]https://japancasino-x.com/[/url] | https://japancasino-x.com/
Приветствуем игроков на гейм площадке электронных продуктов – игровых аккаунтов и ключей! Созданная торговая https://gamakey.ru точка онлайн типа предлагает геймерам различные инструкции, ключи плюс персональные странички с отличной стоимости из определенных цифровых сервисов, как Твич, Steam, Origin, Xbox, EGS, Uplay PC. Купить выбранные ключи через игровой магазине Gemakey [url=https://gamakey.ru]магазин компьютерных игр steam gamakey.ru[/url] сумеет любой желающий, наша команда продумали легкий функционал специально под того, чтобы сделка в обществе клиентом и торговой платформой действовала предельно удобно также нетрудно. Выбранную формат пользователь сможет выбрать по списка по начальной окне ибо ввести по ленте поиска, плюс рекомендации согласно паролей и рекомендаций можно разделить согласно ценнику, оценки покупателей или возрастанию. Очень известные игры, свежие модификации, оптимальная GamaKey.Ru стоимость и каталог на едином веб ресурсе – игровой диллерской ссылке, переходите, выделяйте затем приобретайте лишь в едином месте!
--------
[url=https://avenue17.ru/zapchasti-dlja-vyduvnogo-oborudovanija?product_id=375]РАСПРЕДЕЛИТЕЛЬ FESTO MEBH-5/2-D-1-ZSR-FR-C[/url] | https://avenue17.ru/
Весьма хорошая идея
--------
[url=https://novopet.ru/pet-preformi/pet-preforma-alk]https://novopet.ru/pet-preformi/pet-preforma-alk[/url] | https://novopet.ru/