Урок 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 – многоугольник
Каждая вершина задаётся функцией glVertex3f(x, y ,z) и может иметь вид: glVertex3fv(@массив) , glVertex3i(x, y ,z) с параметрами типа integer.

  Теперь нарисуем точку, в процедуре 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
Супер, спасибо Но возник новый вопрос: в NeHe прочитал, что для координатов полигонов можно использовать нецелые числа, а компилятор говорит ноборот, только целые. В то же время для объемных фигур можно и числа с плавающей точкой. Правда ли это, и почему так?



Добавил(а): 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 выводить не получится, не знаю почему вывести можно например на Panel или на кнопку. Событие OnPaint есть только у формы, а значит на другие компоненты выводить привычный способом не получится. Нужно создать таймер с интервалом 1 мс и туда прописать процедуру рисования, в нашем случае FormPaint(Sender); и параметр функции получения дескриптора - DC:= GetDC(Handle); заменить на Panel1.Handle, тоже самое сделать и при выводе буферов SwapBuffers(), но параметром будет уже DC, в FormResize закоментировать строчку InvalidateRect ( Handle,nil,False ); и изменить параметры функций: glViewport, gluPerspective на аналогичные Panel. Например glViewport(0, 0, Form1.ClientWidth, Form1.ClientHeight); заменить на glViewport(0, 0, Panel.Width, Panel.Height);. производительность падает в десятки раз, но это незаметно



Добавил(а): почти человек Дата: 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. Тогда получается конфетка.


  1. TwiSQ
    TwiSQ 13 days ago
    Drug information sheet. Drug Class. <a href="https://prednisone4u.top">can i get generic prednisone without dr prescription</a> in the USA. Actual about meds. Read information now.
    [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
  2. EfhAT
    EfhAT 12 days ago
    Pills information. Long-Term Effects. <a href="https://viagra4u.top">can i purchase generic viagra for sale</a> in US. Everything what you want to know about drugs. Read here.
    [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&amp;tid=30231&amp;pid=275003&amp;page=5294&amp;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
  3. japancasinox
    japancasinox 4 days ago
    I consider, that you are not right. I suggest it to discuss. Write to me in PM, we will talk.

    -----
    [url=https://japancasino-x.com/]https://japancasino-x.com/[/url] | https://japancasino-x.com/
  4. Dsaf
    Dsaf 2 days ago
    Интернет-развлечения определенно стали нераздельной элементов нашей деятельности собственно под такое, чтобы исполнить ход любой игры более сочным к тому же https://irongamers.ru/ занимательным мы презентует именно для ценителей отличного времяпрепровождения настоящий интернет-маркет проверенных паролей, страниц к тому же планов на распространенных развлечениям. На нашем ресурсе [url=https://irongamers.ru/cyberpunk-2077-vse-romany-i-postelnye-sceny-v-igre.html]секс в cyberpunk 2077[/url] игрового среды юзер сможет подобрать надобную гайд для игры, те что вмещают краткое обрисовку касательно управлению, к тому же реально определить себе гейм аккаунт или шифр сообща с сервисом Xbox, Стим, Epic Games Store, EA play, Юплей к тому же аналогичных сервисов. Функционал презентованной онлайн площадки посодействует для Вас быстро отыскать все такое, необходимое что Вы отыскивали под предназначенную игру, плюс с легкостью совершить транзакцию и продолжать восторгаться новой игрой с применением подсказок также ключей. Не медлите IronGamers.Ru, прямо сейчас дейсвует акция геймс гайдов и страничкой до новым игровым разработкам этого времени года несомненно по очень невысоким прасе!

    Приветствуем игроков на гейм площадке электронных продуктов – игровых аккаунтов и ключей! Созданная торговая https://gamakey.ru точка онлайн типа предлагает геймерам различные инструкции, ключи плюс персональные странички с отличной стоимости из определенных цифровых сервисов, как Твич, Steam, Origin, Xbox, EGS, Uplay PC. Купить выбранные ключи через игровой магазине Gemakey [url=https://gamakey.ru]магазин компьютерных игр steam gamakey.ru[/url] сумеет любой желающий, наша команда продумали легкий функционал специально под того, чтобы сделка в обществе клиентом и торговой платформой действовала предельно удобно также нетрудно. Выбранную формат пользователь сможет выбрать по списка по начальной окне ибо ввести по ленте поиска, плюс рекомендации согласно паролей и рекомендаций можно разделить согласно ценнику, оценки покупателей или возрастанию. Очень известные игры, свежие модификации, оптимальная GamaKey.Ru стоимость и каталог на едином веб ресурсе – игровой диллерской ссылке, переходите, выделяйте затем приобретайте лишь в едином месте!
  5. Schofe
    Schofe a day ago
    Я извиняюсь, но, по-моему, Вы не правы. Я уверен. Предлагаю это обсудить. Пишите мне в PM, пообщаемся.


    --------
    [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/
Отменить.