<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=131816&amp;view=findpost&amp;p=1012012</guid>
        <pubDate>Thu, 09 Feb 2006 19:11:46 +0000</pubDate>
        <title>OpenGL</title>
        <link>https://forum.sources.ru/index.php?showtopic=131816&amp;view=findpost&amp;p=1012012</link>
        <description><![CDATA[Zoobastik: <div class="tag-mod"><div class="tag-mod__prefix">M</div><div class="tag-mod__body">Комментарий автора от 11 апреля 2011&#58;<br>
На данный момент статья не актуальна. С версии OpenGL, на которую все стремительно переходят,<br>
почти все функции, используемые в статье, помечены устаревшими и с версии 3.1 не поддерживаются.<br>
Не зачем смущать устаревшим подходом. Новый совсем другой. </div></div><br>
<br>
И еще немного.<br>
<br>
*************************************<br>
************ Часть II ***************<br>
*************************************<br>
<br>
В этой части будут только указаны исправления кода MyOpenGL.pas, которые <br>
надеюсь без труда сделаете сами, или просто общие сведения.<br>
<br>
09 Списки <br>
=========<br>
<br>
&quot;Список - это некоторый набор команд OpenGL, который можно создать один раз, <br>
например, перед началом работы программы, а потом им пользоваться вызывая его. <br>
По логике он аналогичен процедуре (или функции, как хотите). Отличие его от <br>
процедуры в том, что при формировании списка библиотека сохраняет его в <br>
каком-то своем, оптимизированном формате и вызовы списка приводят к значительно <br>
меньшим вычислительным затратам чем вызов функции, делающей тоже самое. Особенно <br>
хорошо это заметно на картах, где операции со списками реализованы аппаратно.&quot;<br>
(Взято с http://firststeps.ru/mfc/opengl/r.php?41)<br>
<br>
Где-то до использования MyOpenGL.glDraw (напр. в MyOpenGL.glInit)<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// Глобальная переменная для MyOpenGL.pas</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;MyList: GLuint;</div><div class="code_line">...</div><div class="code_line">&nbsp;&nbsp;// указываем, что в списке два набора команд</div><div class="code_line">&nbsp;&nbsp;MyList := glGenLists(2);</div><div class="code_line">&nbsp;&nbsp;// Создаем первый набор команд</div><div class="code_line">&nbsp;&nbsp;// Флаг GL_COMPILE указывает что его надо только создать</div><div class="code_line">&nbsp;&nbsp;// Использование GL_COMPILE_AND_EXECUTE сразу же еще и выполнило бы этот набор</div><div class="code_line">&nbsp;&nbsp;// В первом наборе будем рисовать треугольник</div><div class="code_line">&nbsp;&nbsp;glNewList(MyList, GL_COMPILE);</div><div class="code_line">&nbsp;&nbsp; &nbsp;glBegin(GL_POLYGON);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;glVertex3F(0.0, 0.0, 0.0);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;glVertex3F(100.0, 0.0, 0.0);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;glVertex3F(50.0, sqrt(3)*50, 0.0);</div><div class="code_line">&nbsp;&nbsp; &nbsp;glEnd;</div><div class="code_line">&nbsp;&nbsp;// Указываем что завершили создание набора команд</div><div class="code_line">&nbsp;&nbsp;glEndList();</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Создаем второй набор команд</div><div class="code_line">&nbsp;&nbsp;// Во втором наборе к матрице GL_MODELVIEW будет добавляться параллельный</div><div class="code_line">&nbsp;&nbsp;// перенос на 50 по оси OX и на 1 по оси OZ (это чтобы поверх остального)</div><div class="code_line">&nbsp;&nbsp;// Поставить переменные значения в перенос нельзя, так как это будет уже </div><div class="code_line">&nbsp;&nbsp;// другая матрица. Хотя может я и ошибаюсь.</div><div class="code_line">&nbsp;&nbsp;glNewList(MyList + 1, GL_COMPILE);</div><div class="code_line">&nbsp;&nbsp; &nbsp;glTranslatef(50, sqrt(3) * 12.5, 1);</div><div class="code_line">&nbsp;&nbsp;// Указываем что завершили создание набора команд</div><div class="code_line">&nbsp;&nbsp;glEndList();</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
<br>
MyOpenGL.glDraw можно переписать так. В итоге получим, что рисуется одна <br>
неподвижная фигура (зеленая), а другая вращающаяся, выполненая как и первая, <br>
и перенесенная в центр первой и на уровень выше первой (красная).<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">procedure glDraw();</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// очистка Экрана и буфера глубины</div><div class="code_line">&nbsp;&nbsp;glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Сбрасываем GL_MODELVIEW до единичной</div><div class="code_line">&nbsp;&nbsp;glLoadIdentity();</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Устанавливаем зеленый цвет для фигур </div><div class="code_line">&nbsp;&nbsp;glColor(0.0, 1.0, 0.0, 1);</div><div class="code_line">&nbsp;&nbsp;// Создаем фигуру, используя набор команд MyList</div><div class="code_line">&nbsp;&nbsp;glCallList(MyList);</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Добавляем значение к углу поворота</div><div class="code_line">&nbsp;&nbsp;Angle := (Angle + 5) mod 360;</div><div class="code_line">&nbsp;&nbsp;// Вызываем второй набор команд, который хранится по MyList + 1</div><div class="code_line">&nbsp;&nbsp;// В результате к GL_MODELVIEW добавляется перенос</div><div class="code_line">&nbsp;&nbsp;glCallList(MyList + 1);</div><div class="code_line">&nbsp;&nbsp;// Добавим к GL_MODELVIEW-матрице еще и поворот на угол Angle</div><div class="code_line">&nbsp;&nbsp;glRotate(Angle, 0.0, 0.0, 1.0);</div><div class="code_line">&nbsp;&nbsp;// Устанавливаем красный цвет для фигур </div><div class="code_line">&nbsp;&nbsp;glColor(1.0, 0.0, 0.0, 1);</div><div class="code_line">&nbsp;&nbsp;// Создаем фигуру, используя набор команд MyList</div><div class="code_line">&nbsp;&nbsp;// Поскольку GL_MODELVIEW-матрица у нее другая, то и распалагается</div><div class="code_line">&nbsp;&nbsp;// она уже иначе, чем первая фигура</div><div class="code_line">&nbsp;&nbsp;glCallList(MyList);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Выводим на экран подготовленную сцену</div><div class="code_line">&nbsp;&nbsp;SwapBuffers(DC);</div><div class="code_line">end;</div></ol></div></div></div></div><br>
<br>
Ну и в MyOpenGL.glKill стоит добавить<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;glDeleteLists(MyList, 2); // удаляем все элементы списка :-)</div></ol></div></div></div></div><br>
<br>
Примечание: устоявшееся понятие &quot;список отображениия&quot; - список, в котором все <br>
наборы команд - это рисование фигуры (шаблон). См. Народный учебник, Глава 12.<br>
<br>
10 Собранный пример WinAPI без таймера для отрисовки<br>
====================================================<br>
<br>
Взято у Jan Horn (http://www.sulaco.co.za, http://home.global.co.za/~jhorn)<br>
Как обычно, в папке проекта есть MYOpenGL.pas и 1.bmp :-)<br>
<br>
Идеи таковы: <br>
* пока приложение не обработает всю свою очередь сообщений, перерисовка<br>
  выполняться не будет;<br>
* Если нажали кнопку, то в массиве &quot;Статус кнопок&quot; для соответсвующего <br>
  элемента выстанавливается значение True, которое скинется после<br>
  обработки этого нажатия в ProcessKey. Такая схема позволяет запретить<br>
  накопление нажатий. <br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">program a;</div><div class="code_line">&nbsp;</div><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;windows,</div><div class="code_line">&nbsp;&nbsp;messages,</div><div class="code_line">&nbsp;&nbsp;MyOpenGL in &#39;MyOpenGL.pas&#39;;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;MainWnd: hWND;</div><div class="code_line">&nbsp;&nbsp;FPSCount: Integer; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Число FPS</div><div class="code_line">&nbsp;&nbsp;keys : array [0..255] of Boolean; // Статусы кнопок</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">function IntToStr(Num: Integer) : String;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Str(Num, result);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// Обработка кнопок</div><div class="code_line">procedure ProcessKeys;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if (keys[VK_UP]) then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Что-то делаем</div><div class="code_line">&nbsp;&nbsp; &nbsp;//...</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Сбрасываем нажатие этой кнопки</div><div class="code_line">&nbsp;&nbsp; &nbsp;keys[VK_UP] := False;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;if Keys[Ord(&#39;H&#39;)] then</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Что-то делаем</div><div class="code_line">&nbsp;&nbsp; &nbsp;//...</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Сбрасываем нажатие этой кнопки</div><div class="code_line">&nbsp;&nbsp; &nbsp;Keys[Ord(&#39;H&#39;)] := FALSE;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function WindowProc(Wnd: HWND; Msg: Integer; wParam: wParam; lParam:lParam):lResult;stdcall;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;case Msg of</div><div class="code_line">&nbsp;&nbsp; &nbsp;WM_DESTROY:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;glKill(MainWnd);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;postquitmessage(0);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;exit;</div><div class="code_line">&nbsp;&nbsp; &nbsp; end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WM_KEYDOWN:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;keys[wParam] := True;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WM_KEYUP:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;keys[wParam] := False;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WM_TIMER:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;FPSCount := Round(FPSCount * 1000/{FPS-интервал - у нас 1с}1000);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;SetWindowText(MainWnd, PChar(&#39;FPS: &#39; + IntToStr(FPSCount)));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;FPSCount := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WM_SIZE:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;glOnResize(loWord(lParam), hiWord(lParam));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result := DefWindowProc(Wnd, Msg, wParam, lParam);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;Mesg: TMsg;</div><div class="code_line">&nbsp;&nbsp;wc : TWndClassEx;</div><div class="code_line">&nbsp;&nbsp;finished: Boolean = False; // Флаг завершения работы OpenGL</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;wc.cbSize := sizeof(wc);</div><div class="code_line">&nbsp;&nbsp;wc.style := CS_HREDRAW or CS_VREDRAW;</div><div class="code_line">&nbsp;&nbsp;wc.lpfnWndProc := @WindowProc;</div><div class="code_line">&nbsp;&nbsp;wc.cbClsExtra := 0;</div><div class="code_line">&nbsp;&nbsp;wc.cbWndExtra := 0;</div><div class="code_line">&nbsp;&nbsp;wc.hInstance := hInstance;</div><div class="code_line">&nbsp;&nbsp;wc.hIcon := LoadIcon(0, IDI_WINLOGO);</div><div class="code_line">&nbsp;&nbsp;wc.hCursor := LoadCursor(0, IDC_ARROW);</div><div class="code_line">&nbsp;&nbsp;wc.hbrBackground := COLOR_BTNFACE + 2;</div><div class="code_line">&nbsp;&nbsp;wc.lpszMenuName := nil;</div><div class="code_line">&nbsp;&nbsp;wc.lpszClassName := &#39;aWnd&#39;;</div><div class="code_line">&nbsp;&nbsp;RegisterClassEx(wc);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Создаем окно 400х400</div><div class="code_line">&nbsp;&nbsp;MainWnd := CreateWindowEx (0, &#39;aWnd&#39;, &#39;MyOpenGL&#39;, WS_OVERLAPPEDWINDOW or WS_VISIBLE, 100, 100, 400, 400, 0, 0, hInstance, nil);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Создаем контекст воспроизведения OpenGL и его параметры</div><div class="code_line">&nbsp;&nbsp;glInit(MainWnd);</div><div class="code_line">&nbsp;&nbsp;// Задаем матрицы OpenGL для размера окна 400х400</div><div class="code_line">&nbsp;&nbsp;glOnResize(400, 400);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Устанавливаем таймер на 1с для отображения FPS в заголовке окна</div><div class="code_line">&nbsp;&nbsp;SetTimer(MainWnd, 1, 1000, nil);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;while not finished do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Если очередь сообщений для окна пуста, то проводим</div><div class="code_line">&nbsp;&nbsp; &nbsp;// расчет и отрисовку сцены, иначе обрабатываем</div><div class="code_line">&nbsp;&nbsp; &nbsp;// очередь сообщений</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (PeekMessage(Mesg, 0, 0, 0, PM_REMOVE)) then</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Если было получено WM_QUIT, то выход</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if (Mesg.message = WM_QUIT) then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;finished := True</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TranslateMessage(Mesg);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;DispatchMessage(Mesg);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Увеличиваем счетчик отрисованных кадров</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Inc(FPSCount);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Рисуем-с кадр</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;glDraw();</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Если была до этого нажата ESC, то сразу выходим</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if (keys[VK_ESCAPE]) then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;finished := True</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ProcessKeys;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
<br>
11 Разное<br>
=========<br>
<br>
а. Получение текста последней ошибки OpenGL<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;MessageBox(0, gluErrorString(glGetError), &#39;OpenGL error&#39;, MB_OK);</div></ol></div></div></div></div><br>
<br>
б. Восстановление состояния режима<br>
Лампа GL_LIGHT0 будет включена или выключена в зависимости от ее состоянием<br>
перед началом блока<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">glPushAttrib(GL_LIGHT0); </div><div class="code_line">...</div><div class="code_line">glEnable(GL_LIGH0);</div><div class="code_line">...</div><div class="code_line">glPopAttrib();</div></ol></div></div></div></div><br>
<br>
12 Вывод текста в OpenGL<br>
========================<br>
<br>
Код получен объединением кода Jan Horn, NeHe (уроки 13 и 14) и DRKB <br>
Работа с графикой и мультимедиа &gt; DerectX, OpenGL &gt; OpenGL: Каким обpазом <br>
выбиpать pазмеp шpифта.<br>
<br>
Итак, можем выводить текст как растровое изображение и как векторное (буквы<br>
это 3D объекты). Идея такова, что для алфавита подготавливается список <br>
(см 09), а при вводе текст разбивается на буквы и потом последовательно для<br>
каждой буквы печатаемой строки выполняется соответствующий набор команд из <br>
списка.<br>
<br>
Ниже код, который реализует как растровый, так и как векторный вывод.<br>
(необходимо лишь закоментировать указанные строки).<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;CharList: GLuint; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Вот этот список</div><div class="code_line">&nbsp;&nbsp;gmf: array [0..255] of GLYPHMETRICSFLOAT; &nbsp; &nbsp; &nbsp;// массив требуется для векторного</div><div class="code_line">...</div><div class="code_line">{----------------------------------------------------------------}</div><div class="code_line">{ &nbsp;Создание списка букв &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">{----------------------------------------------------------------}</div><div class="code_line">procedure glBuildFont;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;Font: hFont;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// Список для 256 букв алфавита</div><div class="code_line">&nbsp;&nbsp;CharList := glGenLists(256);</div><div class="code_line">&nbsp;&nbsp;// Создаем шрифт, подробнее см. SDK</div><div class="code_line">&nbsp;&nbsp;Font := CreateFont(-28, 0, 0, 0, FW_BOLD, 0, 0, 0, RUSSIAN_CHARSET,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FF_DONTCARE or DEFAULT_PITCH, &#39;Comic Sans MS&#39;);</div><div class="code_line">&nbsp;&nbsp;// Устанавливаем шрифт для DC</div><div class="code_line">&nbsp;&nbsp;SelectObject(DC, Font);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Создаем команды списка.</div><div class="code_line">&nbsp;&nbsp;// Выбираем один из двух вариантов</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Если используем wglUseFontBitmaps то - это растровое изображение</div><div class="code_line">&nbsp;&nbsp;if not wglUseFontBitmaps(DC, 0, 256, CharList) then</div><div class="code_line">или</div><div class="code_line">&nbsp;&nbsp;// Если используем wglUseFontOutlines то - это векторное изображение &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp;if not wglUseFontOutlines(DC, 0, 255, CharList, 0, 0.2, WGL_FONT_POLYGONS, @gmf) then</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; MessageBox(0, &#39;Font not create&#39;, &#39;glBuildFont&#39;, MB_OK);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Удаляем шрифт, так как соответствующий список уже создан</div><div class="code_line">&nbsp;&nbsp;DeleteObject(Font);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{----------------------------------------------------------------}</div><div class="code_line">{ &nbsp;Вывод строки на экран &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="code_line">{----------------------------------------------------------------}</div><div class="code_line">procedure glPrint(X, Y: Integer; text: String);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// Расчитывается позиция на экране. Требуется только для растрового</div><div class="code_line">&nbsp;&nbsp;// вывода. То есть при векторном выводе X и Y gLPrint игнорируются, </div><div class="code_line">&nbsp;&nbsp;// поэтому перед выводом надо будет воспользоваться glTranslatef </div><div class="code_line">&nbsp;&nbsp;glRasterPos2i(X, Y);</div><div class="code_line">&nbsp;&nbsp;glPushAttrib(GL_LIST_BIT);</div><div class="code_line">&nbsp;&nbsp;// Указыывем, что первая буква алфавита рисуется 1-ым набором команд</div><div class="code_line">&nbsp;&nbsp;glListBase(1);</div><div class="code_line">&nbsp;&nbsp;// Выводим текст</div><div class="code_line">&nbsp;&nbsp;glCallLists(length(text), GL_UNSIGNED_BYTE, PChar(text));</div><div class="code_line">&nbsp;&nbsp;glPopAttrib();</div><div class="code_line">end;</div><div class="code_line">...</div><div class="code_line">// Где-то перед использованием вывода текста, напр. в MyOpenGL.glInit</div><div class="code_line">// после создания контеста воспроизведения RC</div><div class="code_line">&nbsp;&nbsp;glBuildFont;</div><div class="code_line">...</div><div class="code_line">// Когда работа с текстом будет уже не нужна, то очистим список</div><div class="code_line">// Напр. в MyOpenGL.glKill перед освобождением RC </div><div class="code_line">&nbsp;&nbsp;glDeleteLists(CharList, 256);</div></ol></div></div></div></div> <br>
<br>
Добавление теста на сцену немного различается. Далее добавляемый код в<br>
процедуру построения сцены (напр. в MyOpenGL.glDraw).<br>
Для растрового текста<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;// Устанавливаем цвет букв</div><div class="code_line">&nbsp;&nbsp;glColor3f(1.0, 0.0, 1.0);</div><div class="code_line">&nbsp;&nbsp;// Добавляем текст на сцену</div><div class="code_line">&nbsp;&nbsp;glPrint(-150, 0, &#39;Даст ист фантастиш&#39;);</div></ol></div></div></div></div><br>
Вывод векторного шрифта несколько сложнее, поскольку команды списка создают <br>
3D объекты с определенными размерами (все буквы маленького размераа типа 0.01) <br>
(для растровых шрифтов велична букв определяется только первым параметром<br>
функции CreateFont в glBuildFont) и поэтому, если у матрица проекций работает <br>
не с такими размерами (у меня она работает с размерами как напр. 100), то надо <br>
увеличить текст glScale. Так же надо подобрать режимы, чтобы текст смотрелся <br>
по-настоящему 3D.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;// Подбираем нужный режим</div><div class="code_line">&nbsp;&nbsp;glEnable(GL_LIGHT0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Включаем стандартную лампу</div><div class="code_line">&nbsp;&nbsp;glDisable(GL_LIGHT1); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Отключаем пользовательскую лампу </div><div class="code_line">&nbsp;&nbsp;glDisable(GL_NORMALIZE); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Отключаем режим нормалей</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;glLoadIdentity; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Загружаем в GL_MODELVIEW единичную матрицу</div><div class="code_line">&nbsp;&nbsp;glTranslatef(-150, 0.0, 0.0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Добавим перенос от центра</div><div class="code_line">&nbsp;&nbsp;glScale(100, 100, 1.0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Растягиваем текст на 100 по ОХ и OY </div><div class="code_line">&nbsp;&nbsp;glRotate(45, 1.0, 1.0, 0.0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Добавим поворот</div><div class="code_line">&nbsp;&nbsp;glColor(1.0, 0.0, 1.0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Установим цвет букв</div><div class="code_line">&nbsp;&nbsp;glPrint(0, 0, &#39;Даст ист фантастиш&#39;); &nbsp; // Добавим текст на сцену</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Возвращаем все как было</div><div class="code_line">&nbsp;&nbsp;glDisable(GL_LIGHT0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Выключаем стандартную лампу</div><div class="code_line">&nbsp;&nbsp;glEnable(GL_NORMALIZE); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Включаем режим нормалей</div><div class="code_line">&nbsp;&nbsp;glEnable(GL_LIGHT1); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Включаем пользовательскую лампу</div></ol></div></div></div></div> <br>
<br>
13 Компонент для работы с OpenGL<br>
================================<br>
<br>
Напр. на http://glscene.org - GL_Scene - версии для Delphi5-7.<br>
Умеет много чего, в частности импорт 3DS файлов.<br>
<br>
14 Загрузка объектов под отрисовку из файла<br>
===========================================<br>
<br>
Почти всегда хочется, чтобы в функции создании сцены (у меня это MyOpenGL.glDraw)<br>
объекты под отрисовку загружались с файла. Обычно реализуют свой формат хранения<br>
фигур и функции для работы с ним. Я ленивый, потому предлагаю свой способ - <br>
хранить не объекты, а набор gl-комманд ему соответствующий, который будет <br>
загружаться в список. Например рассмотрим такой фаил.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">2</div><div class="code_line">&nbsp;</div><div class="code_line">glNewList</div><div class="code_line">glBegin 4</div><div class="code_line">glVertex3f 0 0 0</div><div class="code_line">glVertex3f 100,4 0 0</div><div class="code_line">glVertex3f 50 100 0</div><div class="code_line">glEnd</div><div class="code_line">glEndList </div><div class="code_line">&nbsp;</div><div class="code_line">glNewList</div><div class="code_line">glRotate 10 0 1 0 </div><div class="code_line">glEndList</div></ol></div></div></div></div> <br>
2 - это то что в списке 2 набора команд. Соответвенно в самой программе это<br>
будет использоваться так (на примере MyOpenGL)<br>
Примечания: <br>
1. дробная часть указывается через запятую&#33;<br>
2. Для glBegin значения констант смотреть в OpenGL.pas <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses MyGLU;</div><div class="code_line">...</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;List: GLuint;</div><div class="code_line">&nbsp;&nbsp;Count: Integer;</div><div class="code_line">...</div><div class="code_line">// Где-то до использования создания сцены, напр. в MyOpenGL.glInit</div><div class="code_line">&nbsp;&nbsp;Count := gluLoadList(&#39;1.gls&#39;, List); &nbsp; &nbsp;// моя функция загрузки скрипта из файла из MyGLU.pas</div><div class="code_line">...</div><div class="code_line">// Где-то в функции создания сцены, напр. в MyOpenGL.glDraw</div><div class="code_line">&nbsp;&nbsp;for i := 0 to Count - 1 do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;glCallList(List + i); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Вызываем i-ый набор команд; нумерация с нулевого </div><div class="code_line">&nbsp;&nbsp;end;</div></ol></div></div></div></div><br>
<br>
По-моему замечательная идея ;-) Возможно у нее уже есть реализация. <br>
А теперь черновой код MyGLU.pas (поддерживаются не все функции gl, да и контроль ошибок<br>
минимальный). Дописывать я его уже наверно не буду; если вам понравилась идея, то<br>
доработать его думаю труда не составит - все прозрачно.<br>
 <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">unit MyGLU;</div><div class="code_line">&nbsp;</div><div class="code_line">interface</div><div class="code_line">&nbsp;</div><div class="code_line">uses windows, OpenGL, SysUtils;</div><div class="code_line">&nbsp;</div><div class="code_line">// Функция создает список, используя команды из текстового файла</div><div class="code_line">// Возвращаемое значение - число элементов созданного списка &nbsp;</div><div class="code_line">function gluLoadList(FileName: String; var List: GLuint): Integer;</div><div class="code_line">&nbsp;</div><div class="code_line">implementation</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;Param: array [1..10] of Extended;</div><div class="code_line">&nbsp;</div><div class="code_line">// Получение из входной строки S подслов, которые конвертируется в Float</div><div class="code_line">// и помещаются в соответствующий Param[i]. S начинает обрабатываться</div><div class="code_line">// с S[Pos].</div><div class="code_line">function GetParam(S: String; Pos: Integer): Integer;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;i, j: Integer;</div><div class="code_line">&nbsp;&nbsp;Value: String;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;for i := 1 to 10 do Param[i] := 0;</div><div class="code_line">&nbsp;&nbsp;j := 1;</div><div class="code_line">&nbsp;&nbsp;Value := &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp;for i := Pos + 1 to Length(S) do</div><div class="code_line">&nbsp;&nbsp; &nbsp;if (S[i] = &#39; &#39;) &nbsp;then</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Param[j] := StrToFloat(Value);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if j = 10 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result := 10;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;MessageBox(0, PChar(&#39;Too many params!&#39;), &#39;GetParam&#39;, MB_OK);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;exit;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;else j := j + 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Value := &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp;else Value := Value + S[i];</div><div class="code_line">&nbsp;&nbsp;if Value &#60;&#62; &#39;&#39; then Param[j] := StrToFloat(Value);</div><div class="code_line">&nbsp;&nbsp;Result := j;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function gluLoadList(FileName: String; var List: GLuint): Integer;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;F: TextFile;</div><div class="code_line">&nbsp;&nbsp;S, Command: String;</div><div class="code_line">&nbsp;&nbsp;Count, CurrList, i: Integer;</div><div class="code_line">&nbsp;&nbsp;Obj: GLUquadricObj;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if not FileExists(FileName) then</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;MessageBox(0, PChar(&#39;File &#39;+FileName + &#39; not found&#39;), &#39;glLoadList&#39;, MB_OK);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;AssignFile(F, FileName);</div><div class="code_line">&nbsp;&nbsp;Reset(F);</div><div class="code_line">&nbsp;&nbsp;readln(F, S);</div><div class="code_line">&nbsp;&nbsp;Count := StrToInt(S);</div><div class="code_line">&nbsp;&nbsp;CurrList := 0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// сдвиг; иначе номер набора команд.</div><div class="code_line">&nbsp;&nbsp;List := glGenLists(Count);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Obj := gluNewQuadric;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; // читаем из файла, если видим знакомую команду, то выполняем</div><div class="code_line">&nbsp;&nbsp; &nbsp; while not EOF(F) do</div><div class="code_line">&nbsp;&nbsp; &nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; Command := &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; readln(F, S);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; for i := 1 to Length(S) do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; if S[i] = &#39; &#39; then break</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else Command := Command + S[i];</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; GetParam(S, i);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; Command := UpperCase(Command);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; if Command = &#39;GLNEWLIST&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; glNewList(List + CurrList, GL_COMPILE);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; if Command = &#39;GLENDLIST&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; glEndList;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; CurrList := CurrList + 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; if Command = &#39;GLBEGIN&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;glBegin(round(Param[1]));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; if Command = &#39;GLEND&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;glEnd;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; if Command = &#39;GLROTATE&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; glRotate(Param[1], Param[2], Param[3], Param[4]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; if Command = &#39;GLSCALE&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; glScale(Param[1], Param[2], Param[3]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; if Command = &#39;GLTRANSLATEF&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; glTranslatef(Param[1], Param[2], Param[3]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; if Command = &#39;GLVERTEX3F&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; glVertex3f(Param[1], Param[2], Param[3]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; if Command = &#39;GLCOLOR&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; glColor(Param[1], Param[2], Param[3], Param[4]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; if Command = &#39;GLLOADIDENTITY&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; glLoadIdentity;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; if Command = &#39;GLPUSHMATRIX&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; glPushMatrix;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; if Command = &#39;GLPOPMATRIX&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; glPopMatrix;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; if Command = &#39;GLUSPHERE&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; gluSphere(Obj, Param[1], round(Param[2]), round(Param[3]));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; if Command = &#39;GLUCYLINDER&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; gluCylinder(Obj, Param[1], Param[2], Param[3], round(Param[4]), round(Param[5]));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; if Command = &#39;GLUDISK&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; gluDisk(Obj, Param[1], Param[2], round(Param[3]), round(Param[4]));</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; end;</div><div class="code_line">&nbsp;&nbsp;glEndList;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;gluDeleteQuadric(Obj);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;CloseFile(F);</div><div class="code_line">&nbsp;&nbsp;Result := Count;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
15 Bmp - формат<br>
===============<br>
<br>
Вообщем то к OpenGL это никакого отношения не имеет, но загрузку текстур все-таки<br>
зачастую приходится производить из него, так что полезно представлять что это такое.<br>
Описание самое простейшее, многое выкинуто, но для общего понимания и загрузки<br>
текстур из bmp-файлов - этого будет достаточно.<br>
<br>
В начале каждого bmp-файла идет служебная информация - общая информация о файле <br>
TBitmapFileHeader и потом общая информация о bmp-изображении - TBitmapInfoHeader.<br>
Определения типов из windows.pas (комментарии мои)<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;tagBITMAPFILEHEADER = packed record</div><div class="code_line">&nbsp;&nbsp; &nbsp;bfType: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // тип файла - для Bmp = BM ~ D</div><div class="code_line">&nbsp;&nbsp; &nbsp;bfSize: DWORD; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// размер файла в байтах</div><div class="code_line">&nbsp;&nbsp; &nbsp;bfReserved1: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// зарезервировано</div><div class="code_line">&nbsp;&nbsp; &nbsp;bfReserved2: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// зарезервировано</div><div class="code_line">&nbsp;&nbsp; &nbsp;bfOffBits: DWORD; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // номер байта; со следующего начнется &quot;изображение&quot;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;TBitmapFileHeader = tagBITMAPFILEHEADER;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;tagBITMAPINFOHEADER = packed record</div><div class="code_line">&nbsp;&nbsp; &nbsp;biSize: DWORD; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// размер структуры BitmapInfoHeader, байт</div><div class="code_line">&nbsp;&nbsp; &nbsp;biWidth: Longint; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ширина изображения</div><div class="code_line">&nbsp;&nbsp; &nbsp;biHeight: Longint; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// высота изображения; отрицательна, если изображение</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// надо перевернуть</div><div class="code_line">&nbsp;&nbsp; &nbsp;biPlanes: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // число плоскостей изображения, всегда 1</div><div class="code_line">&nbsp;&nbsp; &nbsp;biBitCount: Word; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // число бит на точку; ОЧЕНЬ ВАЖНЫЙ ПАРАМЕТР</div><div class="code_line">&nbsp;&nbsp; &nbsp;biCompression: DWORD; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Флаг компрессии - обычно BI_RGB (=0) </div><div class="code_line">&nbsp;&nbsp; &nbsp;biSizeImage: DWORD; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Размер изображения в байтах</div><div class="code_line">&nbsp;&nbsp; &nbsp;biXPelsPerMeter: Longint; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // разрешение точек на метр по OX И по OY</div><div class="code_line">&nbsp;&nbsp; &nbsp;biYPelsPerMeter: Longint;</div><div class="code_line">&nbsp;&nbsp; &nbsp;biClrUsed: DWORD; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // используемое количество цветов</div><div class="code_line">&nbsp;&nbsp; &nbsp;biClrImportant: DWORD; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Обычно = biClrUsed</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;TBitmapInfoHeader = tagBITMAPINFOHEADER;</div><div class="code_line">&nbsp;&nbsp;end;</div></ol></div></div></div></div><br>
Код поясняющий это <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// Для простоты определим тип, состоящий из двух нужных нам</div><div class="code_line">type </div><div class="code_line">&nbsp;&nbsp;TBitmapHeader = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;FH: TBitmapFileHeader;</div><div class="code_line">&nbsp;&nbsp; &nbsp;IH: TBitmapInfoHeader;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">...</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;Bmp: TBitmapHeader;</div><div class="code_line">&nbsp;&nbsp;tmp: Cardinal;</div><div class="code_line">&nbsp;&nbsp;F: hFile;</div><div class="code_line">...</div><div class="code_line">&nbsp;&nbsp;// Для доступа к файлу, определяемого FileName, я использую WinAPI-функцию</div><div class="code_line">&nbsp;&nbsp;// Примерный смысл параметров, думаю, ясен</div><div class="code_line">&nbsp;&nbsp;F := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);</div><div class="code_line">&nbsp;&nbsp;// Читаем данные из файла F, данные помещаются в Bmp, количество байт которых</div><div class="code_line">&nbsp;&nbsp;// хотим прочитать - это третий параметр, количество прочитанных байт будет</div><div class="code_line">&nbsp;&nbsp;// помещено в tmp</div><div class="code_line">&nbsp;&nbsp;ReadFile(F, Bmp, sizeof(TBitmapHeader), tmp, nil);</div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">&nbsp;&nbsp;//</div><div class="code_line">&nbsp;&nbsp;// Ширина изображения для примера</div><div class="code_line">&nbsp;&nbsp;MessageBox(0, PChar(IntToStr(Bmp.IH.biWidth)), &#39;Width&#39;, MB_OK);</div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">&nbsp;&nbsp;// Закрываем файл</div><div class="code_line">&nbsp;&nbsp;CloseHandle(F);</div></ol></div></div></div></div><br>
<br>
После этого заголовка (в байтах это Bmp.FH.bmOffBits) хранится изображение.<br>
Следует различать две группы bmp-изображений 1, 4, 8-битные и 16, 24, 32-битные.<br>
Для первой группы сначала идет палитра - то есть перечисение цветов в формате<br>
Red-Green-Blue-Alpha (TRGBQuad), содержащая biClrUsed-цветов (обычно это <br>
равно 2 ^ biBitCount), потом идут точки изображения - каждая точка пишется в<br>
соответсвующее количество бит (1, 4, 8) - это просто номер цвета из палитры.<br>
Для второй группы палитры нет, а сразу идут точки - для 24 и 32-битных <br>
изображений - в формате RGB и RGBA (по байту на составляющую, что и дает <br>
соответствующую битность); для 16-битных несколько хитрее, потому опущу описание.<br>
<br>
При загрузке текстуры передаются - ширина, высота изображения и массив RGB точек.<br>
Для 24- и 32- битных bmp файлов - массив получается элементарно. Для 1, 4 и 8-<br>
битных необходимо этот массив формировать на основе палитры.<br>
<br>
Примечания<br>
* Точки изображения пробегаются с нижнего левого угла.<br>
* Цвета в BMp-файле зранятся в последовательности BGR, потому при загрузке в <br>
  тестуру надо менять R и B цвета местами.<br>
* На самом деле, есть еще такое понятие как байтовое выравнивание в точках,<br>
  при ширине изображения кратной 4 (для текстур это разумеется верно) об этом <br>
  можно не беспокоится.<br>
<br>
Пример загрузки 8- и 24-битных изображений можно посмотреть в <br>
MyOpenGL.glLoadTexture.]]></description>
        <author>Zoobastik</author>
        <category>Графика, звук, анимация, игры</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=131816&amp;view=findpost&amp;p=1008502</guid>
        <pubDate>Mon, 06 Feb 2006 18:02:08 +0000</pubDate>
        <title>OpenGL</title>
        <link>https://forum.sources.ru/index.php?showtopic=131816&amp;view=findpost&amp;p=1008502</link>
        <description><![CDATA[Zoobastik: <div class="tag-mod"><div class="tag-mod__prefix">M</div><div class="tag-mod__body">Комментарий автора от 11 апреля 2011&#58;<br>
На данный момент статья не актуальна. С версии OpenGL, на которую все стремительно переходят,<br>
почти все функции, используемые в статье, помечены устаревшими и с версии 3.1 не поддерживаются.<br>
Не зачем смущать устаревшим подходом. Новый совсем другой. </div></div><br>
<br>
Вообщем форум у мя глючит и не создает несколько сообщений подряд - все в одно сливает вне зависимости стоит ли галка сливать или нет. Потому будет сплошняком  :( <br>
P.S. Еще раз поправил текст и обновил прикрепленный фаил. Надеюсь больше багов в тексте не будет.<br>
P.P.S. Все-таки нашлись, поправил.<br>
<br>
*************************************<br>
************ Часть I ****************<br>
*************************************<br>
<br>
00 Введение<br>
===========<br>
<br>
Решив разобраться с OpenGL и просмотрев DRBK, я увидел печальную картину - <br>
то что там есть никак не дает пинка в нужном направлении для написания программ,<br>
использующих OpenGL. Ниже я постарался собрать в пучок результаты моих <br>
исследований и получил этот текст и MyOpenGL.pas. <br>
<br>
Я совсем не претендую на правильность терминов в описании и на то, как надо <br>
писать OpenGL-программы. Но простую OpenGL-программу вы точно сможете написать, <br>
использовав MyOpenGL.pas, после прочтения нижеследующего, как на VCL, так и на <br>
чистом WinAPI.<br>
<br>
Может кому пригодится для начала - написанное достаточно просто &gt;:-)<br>
<br>
Были использованы следующие источники<br>
* Исходники Jan Horn (http://www.sulaco.co.za, http://home.global.co.za/~jhorn)<br>
  В частности Skyboxes и Гаусово размытие. Второе уже есть в DRKB без имени автора<br>
  Работа с графикой и мультимедиа &gt; DerectX, OpenGL &gt; OpenGL - радиальное размытие   <br>
  (названия функций, основа программы и много другое взяты оттуда).<br>
* Учебник по OpenGL (главы 1.3, 1.5) с www.ru-coding.com.<br>
* MS SDK &gt; OpenGL Programmer&#39;s Reference, поставляемый вместе с Delphi <br>
  (общая справка)<br>
* модуль EasyGL.pas Данилова Андрея (http://dasoft.land.ru)<br>
  (своровал пару идей по оформлению VCL).<br>
* Статья по рисованию вращающего сердечка на OpenGL (не помню где брал).<br>
* Перевод Народного учебника по OpenGL от NeHe (http://nehe.gamedev.net). <br>
  Брать тут - http://pmg.org.ru/nehe/nehehtml.zip<br>
  (ну очень хороший учебник, хоть и на C; must see).<br>
<br>
01 Контексты устройства и воспроизведения<br>
=========================================<br>
<br>
&quot;DC (Device Context - контекст устройства). Это то, на чём мы рисуем, <br>
и в Delphi контекст устройства представлен как TCanvas&quot; (см. 1)<br>
Получить его можно следующим образом<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;DC: hDC;</div><div class="code_line">...</div><div class="code_line">&nbsp;DC := GetDC(Form1.Hanle);</div><div class="code_line">или</div><div class="code_line">&nbsp;DC := Form1.Canvas.Handle;</div></ol></div></div></div></div><br>
<br>
&quot;Графическая система OpenGL, как и любое другое приложение Windows, также нуждается <br>
в ссылке на окно, на котором будет осуществляться воспроизведение - специальной <br>
ссылке на контекст воспроизведения - величина типа HGLRC (Handle openGL Rendering <br>
Context, ссылка на контекст воспроизведения OpenGL). Для получения этого контекста <br>
OpenGL нуждается в величине типа HDC (контекст воспроизведения) окна, на который <br>
будет осуществляться вывод.&quot;<br>
Создать его можно следующим образом<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses OpenGL;</div><div class="code_line">...</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;DC: hDC;</div><div class="code_line">&nbsp;&nbsp;RC: hGLRC;</div><div class="code_line">...</div><div class="code_line">&nbsp;&nbsp;DC := GetDC(Form1.Handle); &nbsp; // получаем контекст устройства</div><div class="code_line">&nbsp;&nbsp;SetDCPixelFormat(DC); &nbsp; &nbsp; &nbsp; &nbsp;// устанавливаем формат точки (см. 2)</div><div class="code_line">&nbsp;&nbsp;RC := wglCreateContext(DC); &nbsp;// создать новый контекст воспроизведения</div><div class="code_line">&nbsp;&nbsp;wglMakeCurrent(DC, RC); &nbsp; &nbsp; &nbsp;// устанавливаем его текущим</div></ol></div></div></div></div><br>
Здесь SetDCPixelFormat(DC) самописная функция, код см. в MyOpenGL.pas.<br>
<br>
Дополнительно <br>
1. Работа с графикой и мультимедиа &gt; GDI - графика в Delphi<br>
2. Работа с графикой и мультимедиа &gt; DerectX, OpenGL &gt; Работа с OpenGL - Введение <br>
3. Работа с графикой и мультимедиа &gt; DerectX, OpenGL &gt; Работа с OpenGL - Минимальная программа <br>
<br>
02 Инициализация и завершение работы с OpenGL<br>
=============================================<br>
<br>
Поскольку часть операций при инициализации зависит от размеров окна и должна повторяться<br>
при каждом изменении размеров окна, то эта часть вынесена в отдельную процедуру, которая <br>
выполняется при инициализации и при изменении размеров окна.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">{ &nbsp;Инициализация OpenGL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">procedure glInit(Wnd: hWND);</div><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;// Константы, задающие свойства материала фигур</div><div class="code_line">&nbsp;&nbsp;mat1_amb : array [0..2] of Single = (0.2, 0.2, 0.2);</div><div class="code_line">&nbsp;&nbsp;mat1_dif : array [0..2] of Single = (0.8, 0.8, 0.0);</div><div class="code_line">&nbsp;&nbsp;mat1_spec: array [0..2] of Single = (0.6, 0.6, 0.6);</div><div class="code_line">&nbsp;&nbsp;mat1_shininess = 10;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Константы для источника света</div><div class="code_line">&nbsp;&nbsp;light_pos &nbsp;: array [0..3] of glFloat=(100.0, 100.0, 0.0, 1.0);</div><div class="code_line">&nbsp;&nbsp;light_amb &nbsp;: array [0..3] of glFloat=(0.6, 0.6, 0.6, 1.0);</div><div class="code_line">&nbsp;&nbsp;light_dif &nbsp;: array [0..3] of glFloat=(1.0, 1.0, 1.0, 1.0);</div><div class="code_line">&nbsp;&nbsp;light_spec : array [0..3] of glFloat=(1.0, 1.0, 1.0, 1.0);</div><div class="code_line">&nbsp;&nbsp;light_spot_direction : array [0..3] of glFloat=(1.0, 1.0, 1.0, 1.0);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Цвет тумана</div><div class="code_line">&nbsp;&nbsp;fogColor: array [0..3] of GLfloat = (0, 1.0, 0, 1.0);</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;fogMode: GLint;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// Инициализация контекста воспроизведения OpenGL</div><div class="code_line">&nbsp;&nbsp;DC := GetDC(Wnd); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Получить контекст устройства для окна</div><div class="code_line">&nbsp;&nbsp;SetDCPixelFormat(DC); &nbsp; &nbsp; &nbsp; &nbsp;// Установить формата пикселов</div><div class="code_line">&nbsp;&nbsp;RC := wglCreateContext(DC); &nbsp;// создать новый контекст воспроизведения</div><div class="code_line">&nbsp;&nbsp;wglMakeCurrent(DC, RC); &nbsp; &nbsp; &nbsp;// Установить его текущим</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Свойства материала для режима glEnable(GL_COLOR_MATERIAL)</div><div class="code_line">&nbsp;&nbsp;glMaterialfv(GL_FRONT, GL_AMBIENT, &nbsp;@mat1_amb);</div><div class="code_line">&nbsp;&nbsp;glMaterialfv(GL_FRONT, GL_DIFFUSE, &nbsp;@mat1_dif);</div><div class="code_line">&nbsp;&nbsp;glMaterialfv(GL_FRONT, GL_SPECULAR, @mat1_spec);</div><div class="code_line">&nbsp;&nbsp;glMaterialf (GL_FRONT, GL_SHININESS,mat1_shininess);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Свойства источника света GL_LIGHT1 для режима glEnable(GL_LIGHTING)</div><div class="code_line">&nbsp;&nbsp;// Стандартный источник одна команда: &nbsp;glEnable(GL_LIGHT0);</div><div class="code_line">&nbsp;&nbsp;glLightfv(GL_LIGHT1, GL_POSITION,@light_pos);</div><div class="code_line">&nbsp;&nbsp;glLightfv(GL_LIGHT1, GL_AMBIENT, @light_amb); &nbsp; &nbsp;// направленность</div><div class="code_line">&nbsp;&nbsp;glLightfv(GL_LIGHT1, GL_DIFFUSE, @light_dif); &nbsp; &nbsp;// рассеивание</div><div class="code_line">&nbsp;&nbsp;glLightfv(GL_LIGHT1, GL_SPECULAR, @light_spec);</div><div class="code_line">&nbsp;&nbsp;glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, @light_spot_direction);</div><div class="code_line">&nbsp;&nbsp;// разрешить источник света GL_LIGHT1</div><div class="code_line">&nbsp;&nbsp;glEnable(GL_LIGHT1);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Свойства тумана для режима glEnable(GL_FOG)</div><div class="code_line">&nbsp;&nbsp;fogMode := GL_EXP; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // GL_EXP2, GL_LINEAR</div><div class="code_line">&nbsp;&nbsp;glFogi(GL_FOG_MODE, fogMode); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// установить режим</div><div class="code_line">&nbsp;&nbsp;glFogfv(GL_FOG_COLOR, @fogColor); &nbsp; &nbsp; &nbsp;// цвет тумана</div><div class="code_line">&nbsp;&nbsp;glFogf(GL_FOG_DENSITY, 0.002); &nbsp; &nbsp; &nbsp; &nbsp; // плотность &nbsp;- 0.2%</div><div class="code_line">&nbsp;&nbsp;glHint(GL_FOG_HINT, GL_DONT_CARE); &nbsp; &nbsp; // GL_NICEST, GL_FASTEST.</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;glClearColor(0.0, 0.0, 0.2, 1.0); &nbsp; &nbsp; &nbsp;// Установить цвет фона - синий</div><div class="code_line">&nbsp;&nbsp;glClearDepth(1.0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Очистить буфер глубины</div><div class="code_line">&nbsp;&nbsp;glDepthFunc(GL_LESS); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Тип теста глубины</div><div class="code_line">&nbsp;&nbsp;glShadeModel(GL_SMOOTH); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // плавное цветовое сглаживание</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// glEnable(..) - включить режим, glDisable(..) - отключить</div><div class="code_line">&nbsp;&nbsp;glEnable(GL_LIGHTING); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // разрешить осещенность</div><div class="code_line">&nbsp;&nbsp;//glEnable(GL_FOG); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// разрешить тумана</div><div class="code_line">&nbsp;&nbsp;glEnable(GL_DEPTH_TEST); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // разрешить тест глубины, с использованием</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // функции определенной в glDepthFunc</div><div class="code_line">&nbsp;&nbsp;glEnable(GL_NORMALIZE); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// разрешить нормали (различение передней</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // и задней сторон плоских объектов)</div><div class="code_line">&nbsp;&nbsp;glEnable(GL_COLOR_MATERIAL); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // разрешить использование материалов на объектах</div><div class="code_line">&nbsp;&nbsp;glEnable(GL_TEXTURE_2D); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // разрешить наложение текстур</div><div class="code_line">&nbsp;&nbsp;//glEnable(GL_BLEND); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// разрешить смешивание (напр. прозрачность)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // не совместимо с glEnable(GL_DEPTH_TEST)</div><div class="code_line">&nbsp;&nbsp;glLoadTexture(&#39;1.bmp&#39;, Texture); &nbsp; &nbsp; &nbsp; // загружаем текстуру</div><div class="code_line">end;</div></ol></div></div></div></div><br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">{ &nbsp;Обработчик на изменение размеров окна &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">procedure glOnResize(Width, Height: Integer);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if (Height = 0) then Height := 1; &nbsp; &nbsp; &nbsp; &nbsp;// Предупреждаем деление на 0</div><div class="code_line">&nbsp;&nbsp;glViewport(0, 0, Width, Height); &nbsp; &nbsp; &nbsp; &nbsp; // Устанавливаем область отображения</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // на все окно</div><div class="code_line">&nbsp;&nbsp;// Настройка матрицы проекции</div><div class="code_line">&nbsp;&nbsp;glMatrixMode(GL_PROJECTION); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Выбираем матрицу проекции</div><div class="code_line">&nbsp;&nbsp;glLoadIdentity(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Устанавливаем ее единичной</div><div class="code_line">&nbsp;&nbsp;// Устанавливаем тип проеции - Ортогональный</div><div class="code_line">&nbsp;&nbsp;glOrtho(-Width div 2, Width div 2, -Height div 2, Height div 2, -800, 800); </div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Настройка видовой матрицы</div><div class="code_line">&nbsp;&nbsp;glMatrixMode(GL_MODELVIEW); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Выбираем матрицу проекции</div><div class="code_line">&nbsp;&nbsp;glLoadIdentity(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Устанавливаем ее единичной</div><div class="code_line">end;</div></ol></div></div></div></div><br>
<br>
Инициализация OpenGL производится последовательным вызовом этих двух процедур - <br>
сначала gLInit (в ее начале происходит создание контекста воспроизведения, упомянутого<br>
в первой главе), а потом glOnResize.<br>
Отмечу, что включение/выключение режимов можно делать когда угодно, а не только при<br>
инициализации.<br>
<br>
Завершение работы с OpenGL проводит функция glKill.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">{ &nbsp;Завершение работы с OpenGL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">procedure glKill(Wnd: hWND);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;wglMakeCurrent(DC, 0);</div><div class="code_line">&nbsp;&nbsp;wglDeleteContext(RC);</div><div class="code_line">&nbsp;&nbsp;ReleaseDC(Wnd, DC);</div><div class="code_line">end;</div></ol></div></div></div></div><br>
<br>
03 Создание и рисование примитивов<br>
==================================<br>
<br>
Ниже будет описан процесс отрисовки, использующий таймер. <br>
<br>
Сначала подготавливаем объекты сцены процедурой сферу и треугольник, а<br>
потом командой SwapBuffers(..) выводим сцену на экран.<br>
Для улучшения понимания здесь порезанный вариант MyOpenGL.glDraw.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">{ &nbsp;Создание объектов под отрисовку &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">procedure glDraw();</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;Obj: GLUquadricObj;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// очистка Экрана и буфера глубины</div><div class="code_line">&nbsp;&nbsp;glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Пример рисования разноцветного треугольника</div><div class="code_line">&nbsp;&nbsp;glBegin(GL_POLYGON);</div><div class="code_line">&nbsp;&nbsp; &nbsp;glColor(0.0, 0.5, 0.0, 0.0);</div><div class="code_line">&nbsp;&nbsp; &nbsp;glVertex3F(-50, -sqrt(3)*50, 0); &nbsp; &nbsp; &nbsp; &nbsp;// 1-я вершина</div><div class="code_line">&nbsp;&nbsp; &nbsp;glColor(0.5, 0.0, 0.0, 0.0);</div><div class="code_line">&nbsp;&nbsp; &nbsp;glVertex3F(-100, -sqrt(3)*100, 0); &nbsp; &nbsp; &nbsp;// 2-я вершина</div><div class="code_line">&nbsp;&nbsp; &nbsp;glColor(0.0, 0.0, 0.5, 0.0);</div><div class="code_line">&nbsp;&nbsp; &nbsp;glVertex3F(-125, -sqrt(3)*100, 0); &nbsp; &nbsp; &nbsp;// 3-я вершина</div><div class="code_line">&nbsp;&nbsp;glEnd;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Пример рисования сферы</div><div class="code_line">&nbsp;&nbsp;glColor(1.0, 1.0, 1.0, 0.5); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // установить цвет объекта</div><div class="code_line">&nbsp;&nbsp;Obj := gluNewQuadric;</div><div class="code_line">&nbsp;&nbsp;gluSphere(Obj, 100, 25, 25); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // создать сферу &nbsp;R = 100, детализация - 25х25</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Выводим на экран подготовленную сцену</div><div class="code_line">&nbsp;&nbsp;SwapBuffers(DC);</div><div class="code_line">end;</div></ol></div></div></div></div><br>
<br>
По таймеру выполняем<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp;glDraw();</div></ol></div></div></div></div><br>
<br>
gluNewQuadric используется для создания объемных фигур одной командой<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;Obj : GLUquadricObj;</div><div class="code_line">...</div><div class="code_line">&nbsp;&nbsp;Obj := gluNewQuadric;</div><div class="code_line">&nbsp;&nbsp;// Режимы отображения фигуры</div><div class="code_line">&nbsp;&nbsp;gluQuadricDrawStyle(Obj, GLU_FILL); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// GLU_POINT, GLU_LINE, GLU_SILHOUETTE &nbsp;</div><div class="code_line">&nbsp;&nbsp;gluQuadricOrientation (Obj, GLU_INSIDE); &nbsp; &nbsp; &nbsp; // GLU_OUTSIDE</div><div class="code_line">&nbsp;&nbsp;gluQuadricNormals (Obj, GLU_SMOOTH); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // - нормаль для каждой точки</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // GLU_FLAT - для сегмента</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // GLU_NONE - не строить нормалей </div><div class="code_line">&nbsp;&nbsp;gluQuadricTexture(Obj, GL_TRUE); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // - разрешить наложение текущей текстуры</div><div class="code_line">&nbsp;&nbsp;// Создание фигуры </div><div class="code_line">&nbsp;&nbsp;gluSphere(Obj, 100, 25, 25); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // сфера &nbsp;R = 100, детализация - 25х25</div><div class="code_line">или</div><div class="code_line">&nbsp;&nbsp;gluCylinder(Obj, 10, 100, 150, 30, 1); &nbsp; &nbsp; &nbsp; &nbsp; // цилиндр - R0 = 10, R1 = 100, H = 150, детализация - 30 плоскостей</div><div class="code_line">или</div><div class="code_line">&nbsp;&nbsp;gluDisk(Obj, 10, 100, 30, 1); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Диск - R0 = 10, R1 = 100, детализация - 100</div><div class="code_line">или &nbsp;</div><div class="code_line">&nbsp;&nbsp;gluPartialDisk(Obj, 10, 100, 30, 100, 0, 120); // треть диска с параметрами как у верхнего</div><div class="code_line">...</div><div class="code_line">&nbsp;&nbsp;//Освобождаем память</div><div class="code_line">&nbsp;&nbsp;gluDeleteQuadric(Obj);</div></ol></div></div></div></div><br>
 <br>
Quadric-объекты являются надстройкой над конструкцией glBegin-glEnd.<br>
Для glBegin определены следующие константы<br>
(подробнее см. SDK OpenGL)<br>
GL_POINTS          - последовательность точек<br>
GL_LINES           - линии (пара точек; пара точек)  <br>
GL_LINE_STRIP      - ломаная (аналог последовательности lineto)<br>
GL_LINE_LOOP       - замкнутая <br>
GL_TRIANGLES       - треугольник<br>
GL_TRIANGLE_STRIP  - объединенная группа треугольников<br>
GL_TRIANGLE_FAN<br>
GL_QUADS           - четырехугольник<br>
GL_QUAD_STRIP      - объединенная группа четырехугольников<br>
GL_POLYGON         - плоский полигон <br>
Так же стоит обратить внимание на glPolygonMode, позволяющий по различному отображать<br>
строемую фигуру (см. код для Quadric)<br>
<br>
04 Преобразования координат и проекции<br>
======================================<br>
<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '><br>
Q: Возникла такая ситуация. Есть несколько объектов. Hyжно повеpнyть<br>
   некотоpые из  них. Функция glRotate() повоpачивает всю сценy. Сyществyет<br>
   ли функция, котоpая  повоpачивает только некотоpые (не все) вершины?<br>
</div></div> <br>
<br>
&quot;Для задания различных преобразований объектов сцены в OpenGL используются <br>
операции над матрицами, при этом различают три типа матриц: видовая, проекций <br>
и текстуры. Все они имеют размер 4x4&quot;<br>
<br>
В каждый момент можем работать только с одним из типов матрицы. Выбрать нужную <br>
можно следующим образом<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;// mode = </div><div class="code_line">&nbsp;&nbsp;// GL_MODELVIEW &nbsp;- выбрать видовую матрицу</div><div class="code_line">&nbsp;&nbsp;// GL_PROJECTION - выбрать матрицу проекций</div><div class="code_line">&nbsp;&nbsp;// GL_TEXTURE &nbsp; &nbsp;- выбрать матрицу текстур &nbsp;</div><div class="code_line">&nbsp;&nbsp;glMatrixMode(&#60;mode&#62;);</div></ol></div></div></div></div> <br>
<br>
По умолчанию все матрицы нулевые, поэтому при инициализации их заполняем,<br>
разумеется выбрав сначала тип матрицы.<br>
Можно заполнить какой-то конкретной или просто единичной, как в MyOpenGL.glInit.<br>
(Единичная - это та, у которой на диагонали единицы, а остальные нули).<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;// отличие glLoadMatrixf от glLoadMatrixg заключается в том, как будет </div><div class="code_line">&nbsp;&nbsp;// восприниматься входной массив, определяющий матрицу</div><div class="code_line">&nbsp;&nbsp;// так - &#60;строка1&#62;, &#60;строка2&#62;, &#60;строка3&#62;, &#60;строка4&#62;</div><div class="code_line">&nbsp;&nbsp;// или так - &#60;столбец1&#62;, &#60;столбец2&#62;, &#60;столбец3&#62;, &#60;столбец4&#62; </div><div class="code_line">&nbsp;&nbsp;glLoadMatrixf(&#60;указатель на массив из 16 элементов типа double&#62;); </div><div class="code_line">или</div><div class="code_line">&nbsp;&nbsp;glLoadMatrixg(&#60;указатель на массив из 16 элементов типа double&#62;); </div><div class="code_line">или</div><div class="code_line">&nbsp;&nbsp;glLoadIdentity(); &nbsp; &nbsp; &nbsp; &nbsp;// заполнение единичной</div></ol></div></div></div></div> <br>
<br>
&quot; Часто нужно сохранить содержимое текущей матрицы для дальнейшего использования, <br>
для чего используют команды&quot;<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;glPushMatrix(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// сохранить матрицу (в стеке) &nbsp;</div><div class="code_line">&nbsp;&nbsp;glPopMatrix(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // извлечь матрицу (из стека)</div></ol></div></div></div></div><br>
(Вспоминаем, что такое стек :))<br>
Для GL_MODELVIEW-матриц глубина стека не менее 32, для других типов не менее 2. <br>
<br>
Далее попробую объяснить для чего нужны различные матрицы и как их использовать.<br>
Итак, задача такова, что надо создать трехмерную фигуру, изменить ее и потом <br>
отобразить на плоскость окна. Реализация OpenGL такова, что при этом имеем четыре<br>
перехода из одних координат в другие.<br>
Координаты объекта (4D) =&gt; Видовые координаты (4D) =&gt; Усеченные координаты (4D) =&gt; <br>
Нормализованные координаты (3D) =&gt; Оконные координаты (2D)<br>
(4D - это точка имеет 4 координаты, первые 3 - ее 3D координаты, последняя <br>
дополнительная составляющая).<br>
Переход от координат объекта к видовым осуществляется при использовании GL_MODELVIEW<br>
матрицы. По видовым координатам вычисляются усеченные координаты, используя GL_PROJECTION <br>
матрицу (название усеченные координаты идет от того, что для любой точки фигуры <br>
(x1, x2, x3, x4), верно -1 &lt;= x_i &lt;= 1, то есть GL_PROJECTION матрица отображает фигуру <br>
в 4D-куб c длиной стороны 2 и центром в (0, 0, 0, 0)). Нормализванные координаты <br>
получаются из усеченных следующим преобразованием <br>
(x1&#39;, x2&#39;, x3&#39;) = (x1/x4, x2/x4, x3/x4).<br>
Размер окна, куда будет отображаться фигура заданная в нормализованных координатах, <br>
определяется функцией glViewPort. <br>
<br>
Теперь, думаю, код glOnResize достаточно понятен.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;// 1</div><div class="code_line">&nbsp;&nbsp;glViewport(0, 0, Width, Height); &nbsp; &nbsp; &nbsp; &nbsp; // Устанавливаем область отображения</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // на все окно</div><div class="code_line">&nbsp;&nbsp;// 2</div><div class="code_line">&nbsp;&nbsp;// Настройка матрицы проекции</div><div class="code_line">&nbsp;&nbsp;glMatrixMode(GL_PROJECTION); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Выбираем матрицу проекции</div><div class="code_line">&nbsp;&nbsp;glLoadIdentity(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Устанавливаем ее единичной</div><div class="code_line">&nbsp;&nbsp;// Устанавливаем тип проеции - Ортогональный</div><div class="code_line">&nbsp;&nbsp;glOrtho(-Width div 2, Width div 2, -Height div 2, Height div 2, -800, 800); </div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// 3</div><div class="code_line">&nbsp;&nbsp;// Настройка видовой матрицы</div><div class="code_line">&nbsp;&nbsp;glMatrixMode(GL_MODELVIEW); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Выбираем матрицу проекции</div><div class="code_line">&nbsp;&nbsp;glLoadIdentity(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Устанавливаем ее единичной</div></ol></div></div></div></div><br>
Блоки 1, 2 и 3 можно менять местами. Единственное отличие, если поменять местами 2 и 3, то<br>
что текущая матрица будет не GL_MODELVIEW, а GL_PROJECTION.<br>
<br>
Примечание: GL_PROJECTION матрицу лучше выбирать так, чтобы <br>
* GL_MODELVIEW была единичной;<br>
* исходные размеры объекта были в пределах отрезка [-1; 1].<br>
<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '><br>
A: Для того, чтобы пpименить pазные пpеобpазования к pазным объектам сцены, надо<br>
делать так:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;glMatrixMode(GL_MODELVIEW);</div><div class="code_line">&nbsp;&nbsp;glLoadIdentity();</div><div class="code_line">&nbsp;&nbsp;glRotate, glScale, glTranslate // ... --- в общем, всё что нyжно...</div></ol></div></div></div></div><br>
Затем pисyешь объекты...<br>
После того, как наpисовал, yказываешь новое пpеобpазование:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;glLoadIdentity(); glRotate, glScale, glTranslate // ...</div></ol></div></div></div></div><br>
Снова pисyешь объекты. И так повтоpяешь, сколько надо.<br>
</div></div><br>
<br>
А теперь все это так, как было бы в коде (напр. в MyOpenGL.glDraw)<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;// Указываем, что работать будем с видовой матрицей</div><div class="code_line">&nbsp;&nbsp;// Если она и так была текущей, то можно не выполнять </div><div class="code_line">&nbsp;&nbsp;glMatrixMode(GL_MODELVIEW);</div><div class="code_line">&nbsp;&nbsp;// Сбрасываем до единичной</div><div class="code_line">&nbsp;&nbsp;// (Считаем, что GL_PROJECTION подобрана, как указано выше)</div><div class="code_line">&nbsp;&nbsp;glLoadIdenty(); </div><div class="code_line">&nbsp;&nbsp;glTranslatef(100.0, 0.0, 0.0); &nbsp;// Добавим к матрице перенос на 100 вдоль ОХ</div><div class="code_line">&nbsp;&nbsp;glPushMatrix; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // сохраняем матрицу в стек - она нам еще понадобится</div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">&nbsp;&nbsp;// Рисуем какую-нить фигуру1</div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">&nbsp;&nbsp;glRotate (-90, 0.0 , 1.0, 0.0); // Поворот на -90 градусов вокруг оси OY</div><div class="code_line">&nbsp;&nbsp;glRotate(60, 1.0, 0.0, 0.0); &nbsp; &nbsp;// Поворот на 60 градусов вокруг оси OX. &nbsp; </div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">&nbsp;&nbsp;// Рисуем фигуру2</div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">&nbsp;&nbsp;glPopMatrix; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// восстанавливаем матрицу из стека</div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">&nbsp;&nbsp;glTranslatef(0.0, 10.0, 0.0); &nbsp; // двигаем на 10 по оси OX</div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">&nbsp;&nbsp;// Рисуем фигуру3</div><div class="code_line">&nbsp;&nbsp;...</div></ol></div></div></div></div><br>
После этого имеем - фигура1 перенесена от центра на 100 по оси ОХ. Фигура2 имеет <br>
матрицу - соответствующую следующим последовательным действиям: перенос на 100, поворот, <br>
поворот. glPopMatrix - возвращает нас к исходной матрице, содержащей только перенос на 100, <br>
потому GL_MODELVIEW-матрица у фигуры3 - это перенос на 100 + перенос на 10 по оси ОY.<br>
Вообще говоря, последовательность неких действий - это домножение исходной матрицы на<br>
матрицы, отвечающие этим действиям. Поскольку умножение матриц некоммуникативно (AB &lt;&gt; BA),<br>
то и при смене чередовании элементов последовательности, получим другой результат. <br>
<br>
Дополнительно - www.ru-coding.com/ogl_1_3.php<br>
<br>
04а GL_PROJECTION<br>
=================<br>
<br>
Считаем, что GL_MODELVIEW матрица единичная.<br>
<br>
Задание матрицы проекции, которое могло быть напр. в MyOpenGL.glOnResize<br>
Перспективная проекция<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;glFrustum( - Width div 2, Width div 2, - Height div 2, Height div 2, 100, 300);</div><div class="code_line">&nbsp;&nbsp;glTranslatef(0, 0, -200);</div></ol></div></div></div></div><br>
<br>
Ортогональная проекция<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;glOrtho(- Width div 2, Width div 2, -Height div 2, Height div 2, -800, 800);</div></ol></div></div></div></div><br>
<br>
Примерный смысл для параметров команд glFrustum и glOrtho. <br>
Первые четыре, расписанные как  (left, top) и (right, bottom) определяют прямоугольник.<br>
Лучше представить его как окно, через которое мы смотрим на мир (т. е. на группу объектов,<br>
которые были получены при преобразовании их исходных координат их GL_MODELVIEW-матрицами). <br>
Чем оно больше (больше значения параметров), тем больше объекты (по размерам) можем <br>
видеть (по другому - как будто отходим назад от объектов). При симметричных координатах - <br>
смотрим на центр.<br>
Если провести через все углы линии ортогональные прямоугольнику, то высекаемый ими объем <br>
будет тем, что мы видим в мире. Поскольку объекты в бесконечности никого не интересуют <br>
(напр. не  видны из-за малого размера при перспективной проекции), то логично ввести <br>
плоскость, параллельную плоскости окна и если объект оказался за ней, то забыть о его <br>
существовании - это сильно упрощает OpenGL расчеты. Логично ввести такую же плоскость и <br>
для объектов сблизи (хотя бы из соображений симметрии ;-)), т. е. если объект ближе чем <br>
она, то он не выводится. Пятый и шестой параметры - как раз и задают расположение второй <br>
и первой плоскости: при перспективной проекции - как растояние от окна до требуемых <br>
плоскостей (следствие: всегда пятый параметр меньше шестого и оба больше 0), при <br>
ортогональной - расстояние от начала координат (поскольку при ортогональной проекции <br>
нет искажении из-за того как далеко от нас находится центр, то можно представить его <br>
где-либо перед нами и соответсвенно задать координаты плоскостей отсечения).<br>
Если мы рисуем объекты вокруг центра координат, напр. так создаются Quadric-объекты, то <br>
для перспективной проекции также надо добавить сдвиг, помещающий центр координат МЕЖДУ<br>
плоскостями отсечения (этот же сдвиг можно сделать и в GL_MODELVIEW матрице). <br>
Для ортогональной этого делать не надо - центр и так где-то перед нами.<br>
Другой способ задавать перспективную проекцию - это воспользоваться gluPerspective. <br>
Примечание: чем меньше расстояние между плоскостями отсечения, тем быстрее все считается. <br>
<br>
05 Текструры<br>
============<br>
<br>
Текстуру сначала надо загрузить и получить ее идентификатор (хендл). <br>
перед созданием объекта текстура выбирается по своему идентификатору<br>
(делается текущей) и автоматом прилепляется к объекту (GLUquadricObj).<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses </div><div class="code_line">&nbsp;&nbsp;OpenGL;</div><div class="code_line">...</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;Texture: glUint; </div><div class="code_line">...</div><div class="code_line">// функция для установки текущей текстуры по идентификатору texture</div><div class="code_line">// в openGL.pas ее почему то нет :(, потому импортируем</div><div class="code_line">procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external opengl32;</div><div class="code_line">...</div><div class="code_line">// Где-то вначале программы, перед использованием glDraw</div><div class="code_line">LoadTexture(&#39;1.bmp&#39;, Texture);</div><div class="code_line">...</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">{ &nbsp;Создание объектов под отрисовку &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="code_line">{------------------------------------------------------------------} </div><div class="code_line">procedure glDraw();</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;Obj : GLUquadricObj;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">&nbsp;&nbsp;// 1-ый вариант</div><div class="code_line">&nbsp;&nbsp;glBindTexture(GL_TEXTURE_2D, Texture); // устанавливаем текущую текстуру Texture</div><div class="code_line">&nbsp;&nbsp;Obj:=gluNewQuadric;</div><div class="code_line">&nbsp;&nbsp;gluQuadricTexture(Obj, GL_TRUE); &nbsp; &nbsp; &nbsp; // при создании объекта наложить текущую текстуру</div><div class="code_line">&nbsp;&nbsp;gluSphere(Obj, 100, 25, 25); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // создать сферу &nbsp;R = 100, детализация - 25х25</div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">или так</div><div class="code_line">&nbsp;&nbsp;...</div><div class="code_line">&nbsp;&nbsp;// 2-ой вариант</div><div class="code_line">&nbsp;&nbsp;glBindTexture(GL_TEXTURE_2D, Texture); // устанавливаем текущую текстуру Texture</div><div class="code_line">&nbsp;&nbsp;// Рисуем фигуру, на которую наложится текстура при помощи glTexCoord2f</div><div class="code_line">&nbsp;&nbsp;glBegin(GL_QUADS);</div><div class="code_line">&nbsp;&nbsp; &nbsp;glNormal3f( 0.0, 0.0, 1.0);</div><div class="code_line">&nbsp;&nbsp; &nbsp;// 1-я точка текстуры + 1-я точка объекта</div><div class="code_line">&nbsp;&nbsp; &nbsp;glTexCoord2f(0.0, 0.0); </div><div class="code_line">&nbsp;&nbsp; &nbsp;glVertex3f(-100.0, -100.0, &nbsp;0.0); &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// 3-я точка текстуры + 2-я точка объекта</div><div class="code_line">&nbsp;&nbsp; &nbsp;glTexCoord2f(1.0, 0.0); </div><div class="code_line">&nbsp;&nbsp; &nbsp;glVertex3f( 100.0, -100.0, &nbsp;0.0);</div><div class="code_line">&nbsp;&nbsp; &nbsp;// 3-я точка текстуры + 3-я точка объекта</div><div class="code_line">&nbsp;&nbsp; &nbsp;glTexCoord2f(1.0, 1.0); </div><div class="code_line">&nbsp;&nbsp; &nbsp;glVertex3f( 100.0, &nbsp;100.0, &nbsp;0.0);</div><div class="code_line">&nbsp;&nbsp; &nbsp;// 1-я точка текстуры + 1-я точка объекта</div><div class="code_line">&nbsp;&nbsp; &nbsp;glTexCoord2f(0.0, 1.0); </div><div class="code_line">&nbsp;&nbsp; &nbsp;glVertex3f(-100.0, &nbsp;100.0, &nbsp;0.0);</div><div class="code_line">&nbsp;&nbsp;glEnd();</div></ol></div></div></div></div><br>
<br>
При этом должен быть разрешен режим наложения текстур (по умолчанию - отключен) <br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;glEnable(GL_TEXTURE_2D);</div></ol></div></div></div></div><br>
<br>
Примечание:<br>
Функция MyOpenGL.glLoadTexture поддерживает загрузку только 8 и 24-битных изображений. <br>
<br>
Дополнительно<br>
  www.ru-coding.com/ogl_1_5.php<br>
<br>
06 Unit MyOpenGL.pas<br>
====================<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">unit MyOpenGL;</div><div class="code_line">&nbsp;</div><div class="code_line">interface</div><div class="code_line">&nbsp;</div><div class="code_line">uses windows, OpenGL;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure glOnResize(Width, Height : Integer);</div><div class="code_line">procedure glInit(Wnd: hWND);</div><div class="code_line">procedure glKill(Wnd: hWND);</div><div class="code_line">procedure glDraw();</div><div class="code_line">procedure glLoadTexture(Filename: String; var Texture: GLuint);</div><div class="code_line">&nbsp;</div><div class="code_line">implementation</div><div class="code_line">&nbsp;</div><div class="code_line">procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external opengl32;</div><div class="code_line">function &nbsp;gluBuild2DMipmaps(Target: GLenum; Components, Width, Height: GLint; Format, atype: GLenum; Data: Pointer): GLint; stdcall; external glu32;</div><div class="code_line">procedure glGenTextures(n: GLsizei; var textures: GLuint); stdcall; external opengl32;</div><div class="code_line">procedure SetDCPixelFormat(DC: hDC); forward;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;DC: hDC; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // контекст устройства</div><div class="code_line">&nbsp;&nbsp;RC: hGLRC; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // контекст воспроизведения</div><div class="code_line">&nbsp;&nbsp;Texture: GLuint; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // хэндл текстуры</div><div class="code_line">&nbsp;&nbsp;Angle: Integer = 0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// угол поворота сферы</div><div class="code_line">&nbsp;</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">{ &nbsp;Обработчик на изменение размеров окна &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">procedure glOnResize(Width, Height: Integer);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;if (Height = 0) then Height := 1; &nbsp; &nbsp; &nbsp; &nbsp;// Предупреждаем деление на 0</div><div class="code_line">&nbsp;&nbsp;glViewport(0, 0, Width, Height); &nbsp; &nbsp; &nbsp; &nbsp; // Устанавливаем область отображения</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // на все окно</div><div class="code_line">&nbsp;&nbsp;// Настройка матрицы проекции</div><div class="code_line">&nbsp;&nbsp;glMatrixMode(GL_PROJECTION); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Выбираем матрицу проекции</div><div class="code_line">&nbsp;&nbsp;glLoadIdentity(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Устанавливаем ее единичной</div><div class="code_line">&nbsp;&nbsp;// Устанавливаем тип проеции - Ортогональный</div><div class="code_line">&nbsp;&nbsp;glOrtho(-Width div 2, Width div 2, -Height div 2, Height div 2, -800, 800);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Настройка видовой матрицы</div><div class="code_line">&nbsp;&nbsp;glMatrixMode(GL_MODELVIEW); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Выбираем матрицу проекции</div><div class="code_line">&nbsp;&nbsp;glLoadIdentity(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Устанавливаем ее единичной</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">{ &nbsp;Инициализация OpenGL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">procedure glInit(Wnd: hWND);</div><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;// Константы, задающие свойства материала фигур</div><div class="code_line">&nbsp;&nbsp;mat1_amb : array [0..2] of Single = (0.2, 0.2, 0.2);</div><div class="code_line">&nbsp;&nbsp;mat1_dif : array [0..2] of Single = (0.8, 0.8, 0.0);</div><div class="code_line">&nbsp;&nbsp;mat1_spec: array [0..2] of Single = (0.6, 0.6, 0.6);</div><div class="code_line">&nbsp;&nbsp;mat1_shininess = 10;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Константы для источника света</div><div class="code_line">&nbsp;&nbsp;light_pos &nbsp;: array [0..3] of glFloat = (100.0, 100.0, 0.0, 1.0);</div><div class="code_line">&nbsp;&nbsp;light_amb &nbsp;: array [0..3] of glFloat = (0.6, 0.6, 0.6, 1.0);</div><div class="code_line">&nbsp;&nbsp;light_dif &nbsp;: array [0..3] of glFloat = (1.0, 1.0, 1.0, 1.0);</div><div class="code_line">&nbsp;&nbsp;light_spec : array [0..3] of glFloat = (1.0, 1.0, 1.0, 1.0);</div><div class="code_line">&nbsp;&nbsp;light_spot_direction : array [0..3] of glFloat = (1.0, 1.0, 1.0, 1.0);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Цвет тумана</div><div class="code_line">&nbsp;&nbsp;fogColor: array [0..3] of GLfloat = (0, 1.0, 0, 1.0);</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;fogMode: GLint;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// Инициализация контекста воспроизведения OpenGL</div><div class="code_line">&nbsp;&nbsp;DC := GetDC(Wnd); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Получить контекст устройства для окна</div><div class="code_line">&nbsp;&nbsp;SetDCPixelFormat(DC); &nbsp; &nbsp; &nbsp; &nbsp;// Установить формата пикселов</div><div class="code_line">&nbsp;&nbsp;RC := wglCreateContext(DC); &nbsp;// создать новый контекст воспроизведения</div><div class="code_line">&nbsp;&nbsp;wglMakeCurrent(DC,RC); &nbsp; &nbsp; &nbsp; // Установить его текущим</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Свойства материала для режима glEnable(GL_COLOR_MATERIAL)</div><div class="code_line">&nbsp;&nbsp;glMaterialfv(GL_FRONT, GL_AMBIENT, &nbsp;@mat1_amb);</div><div class="code_line">&nbsp;&nbsp;glMaterialfv(GL_FRONT, GL_DIFFUSE, &nbsp;@mat1_dif);</div><div class="code_line">&nbsp;&nbsp;glMaterialfv(GL_FRONT, GL_SPECULAR, @mat1_spec);</div><div class="code_line">&nbsp;&nbsp;glMaterialf (GL_FRONT, GL_SHININESS,mat1_shininess);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Свойства источника света GL_LIGHT1 для режима glEnable(GL_LIGHTING)</div><div class="code_line">&nbsp;&nbsp;// Стандартный источник одна команда: &nbsp;glEnable(GL_LIGHT0);</div><div class="code_line">&nbsp;&nbsp;glLightfv(GL_LIGHT1, GL_POSITION,@light_pos);</div><div class="code_line">&nbsp;&nbsp;glLightfv(GL_LIGHT1, GL_AMBIENT, @light_amb); &nbsp; &nbsp;// направленность</div><div class="code_line">&nbsp;&nbsp;glLightfv(GL_LIGHT1, GL_DIFFUSE, @light_dif); &nbsp; &nbsp;// рассеивание</div><div class="code_line">&nbsp;&nbsp;glLightfv(GL_LIGHT1, GL_SPECULAR, @light_spec);</div><div class="code_line">&nbsp;&nbsp;glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, @light_spot_direction);</div><div class="code_line">&nbsp;&nbsp;// разрешить источник света GL_LIGHT1</div><div class="code_line">&nbsp;&nbsp;glEnable(GL_LIGHT1);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Свойства тумана для режима glEnable(GL_FOG)</div><div class="code_line">&nbsp;&nbsp;fogMode := GL_EXP; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // GL_EXP2, GL_LINEAR</div><div class="code_line">&nbsp;&nbsp;glFogi(GL_FOG_MODE, fogMode); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// установить режим</div><div class="code_line">&nbsp;&nbsp;glFogfv(GL_FOG_COLOR, @fogColor); &nbsp; &nbsp; &nbsp;// цвет тумана</div><div class="code_line">&nbsp;&nbsp;glFogf(GL_FOG_DENSITY, 0.002); &nbsp; &nbsp; &nbsp; &nbsp; // плотность &nbsp;- 0.2%</div><div class="code_line">&nbsp;&nbsp;glHint(GL_FOG_HINT, GL_DONT_CARE); &nbsp; &nbsp; // GL_NICEST, GL_FASTEST.</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;glClearColor(0.0, 0.0, 0.2, 1.0); &nbsp; &nbsp; &nbsp;// Установить цвет фона - синий</div><div class="code_line">&nbsp;&nbsp;glClearDepth(1.0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Очистить буфер глубины</div><div class="code_line">&nbsp;&nbsp;glDepthFunc(GL_LESS); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Тип теста глубины</div><div class="code_line">&nbsp;&nbsp;glShadeModel(GL_SMOOTH); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // плавное цветовое сглаживание</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// glEnable(..) - включить режим, glDisable(..) - отключить</div><div class="code_line">&nbsp;&nbsp;glEnable(GL_LIGHTING); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // разрешить осещенность</div><div class="code_line">&nbsp;&nbsp;//glEnable(GL_FOG); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// разрешить тумана</div><div class="code_line">&nbsp;&nbsp;glEnable(GL_DEPTH_TEST); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // разрешить тест глубины, с использованием</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // функции определенной в glDepthFunc</div><div class="code_line">&nbsp;&nbsp;glEnable(GL_NORMALIZE); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// разрешить нормали (различение передней</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // и задней сторон плоских объектов)</div><div class="code_line">&nbsp;&nbsp;glEnable(GL_COLOR_MATERIAL); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // разрешить использование материалов на объектах</div><div class="code_line">&nbsp;&nbsp;glEnable(GL_TEXTURE_2D); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // разрешить наложение текстур</div><div class="code_line">&nbsp;&nbsp;//glEnable(GL_BLEND); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// разрешить смешивание (напр. прозрачность)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // не совместимо с glEnable(GL_DEPTH_TEST)</div><div class="code_line">&nbsp;&nbsp;glLoadTexture(&#39;1.bmp&#39;, Texture); &nbsp; &nbsp; &nbsp; // загружаем текстуру</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">{ &nbsp;Завершение работы с OpenGL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">procedure glKill(Wnd: hWND);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;wglMakeCurrent(DC, 0);</div><div class="code_line">&nbsp;&nbsp;wglDeleteContext(RC);</div><div class="code_line">&nbsp;&nbsp;ReleaseDC(Wnd, DC);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">{ &nbsp;Создание объектов под отрисовку &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">procedure glDraw();</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;Obj: GLUquadricObj;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// очистка Экрана и буфера глубины</div><div class="code_line">&nbsp;&nbsp;glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;glMatrixMode(GL_MODELVIEW); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Переключаемся на видовую матрицу</div><div class="code_line">&nbsp;&nbsp;glLoadIdentity; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Сбрасываем все преобразования</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Пример рисования разноцветного треугольника</div><div class="code_line">&nbsp;&nbsp;glBegin(GL_POLYGON);</div><div class="code_line">&nbsp;&nbsp;glColor(0.0, 0.5, 0.0, 0.0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Цвет 1-ой вершины</div><div class="code_line">&nbsp;&nbsp;glVertex3F(-50, -sqrt(3)*50, 0); &nbsp; &nbsp; &nbsp; &nbsp;// 1-я вершина</div><div class="code_line">&nbsp;&nbsp;glColor(0.5, 0.0, 0.0, 0.0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Цвет 2-ой вершины</div><div class="code_line">&nbsp;&nbsp;glVertex3F(-100, -sqrt(3)*100, 0); &nbsp; &nbsp; &nbsp;// 2-я вершина</div><div class="code_line">&nbsp;&nbsp;glColor(0.0, 0.0, 0.5, 0.0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Цвет 3-ей вершины</div><div class="code_line">&nbsp;&nbsp;glVertex3F(-125, -sqrt(3)*100, 0); &nbsp; &nbsp; &nbsp;// 3-я вершина</div><div class="code_line">&nbsp;&nbsp;glEnd;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Следующая фигура будет нарисована повернутой</div><div class="code_line">&nbsp;&nbsp;// Поворачиваем сферу так, чтобы северный полюс на текстуре</div><div class="code_line">&nbsp;&nbsp;// смотрел в нужную сторону</div><div class="code_line">&nbsp;&nbsp;glRotate(-90, 0.0, 1.0, 0.0);</div><div class="code_line">&nbsp;&nbsp;glRotate(60, 1.0, 0.0, 0.0);</div><div class="code_line">&nbsp;&nbsp;// здесь поворот сферы вокруг оси</div><div class="code_line">&nbsp;&nbsp;glRotate(-Angle, 0.0, 0.0, 1.0);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Пример рисования сферы</div><div class="code_line">&nbsp;&nbsp;glColor(1.0, 1.0, 1.0, 0.5); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // установить цвет объекта</div><div class="code_line">&nbsp;&nbsp;glBlendFunc(GL_SRC_ALPHA,GL_ONE); &nbsp; &nbsp; &nbsp;// Функция смешивания для непрозрачности,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // базирующаяся на значении альфы</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Отрабатывает только при glEnable(GL_BLEND)</div><div class="code_line">&nbsp;&nbsp;glBindTexture(GL_TEXTURE_2D, Texture); // установить текущую текстуру Texture</div><div class="code_line">&nbsp;&nbsp;Obj:=gluNewQuadric;</div><div class="code_line">&nbsp;&nbsp;gluQuadricTexture(Obj, GL_TRUE); &nbsp; &nbsp; &nbsp; // разрешить наложить текущую текстуру на</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // создаваемый объект</div><div class="code_line">&nbsp;&nbsp;gluSphere(Obj, 100, 25, 25); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // создать сферу &nbsp;R = 100, детализация - 25х25</div><div class="code_line">&nbsp;&nbsp;gluDeleteQuadric(Obj); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Освобождаем память</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Angle := (Angle + 5) mod 360;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Выводим на экран подготовленную сцену</div><div class="code_line">&nbsp;&nbsp;SwapBuffers(DC);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">{ &nbsp;Выбор приемлемого формата точки для данного DC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">procedure SetDCPixelFormat(DC: hDC);</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;pfd: TPixelFormatDescriptor;</div><div class="code_line">&nbsp;&nbsp;nPixelFormat: Integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;FillChar(pfd, SizeOf(pfd), 0);</div><div class="code_line">&nbsp;&nbsp;with pfd do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;nSize &nbsp; &nbsp; &nbsp;:= sizeof(pfd);</div><div class="code_line">&nbsp;&nbsp; &nbsp;nVersion &nbsp; := 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp;dwFlags &nbsp; &nbsp;:= PFD_DRAW_TO_WINDOW or</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PFD_SUPPORT_OPENGL or</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PFD_DOUBLEBUFFER;</div><div class="code_line">&nbsp;&nbsp; &nbsp;iPixelType := PFD_TYPE_RGBA;</div><div class="code_line">&nbsp;&nbsp; &nbsp;cColorBits := 16;</div><div class="code_line">&nbsp;&nbsp; &nbsp;cDepthBits := 64;</div><div class="code_line">&nbsp;&nbsp; &nbsp;iLayerType := PFD_MAIN_PLANE;</div><div class="code_line">&nbsp;&nbsp; end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;nPixelFormat := ChoosePixelFormat(DC, @pfd);</div><div class="code_line">&nbsp;&nbsp;SetPixelFormat(DC, nPixelFormat, @pfd);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">{ &nbsp;Загрузка 8 или 24-битного bmp-файла текстуры &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">{------------------------------------------------------------------}</div><div class="code_line">procedure glLoadTexture(Filename: String; var Texture: GLuint);</div><div class="code_line">type BitmapHeader=</div><div class="code_line">&nbsp;&nbsp; &nbsp; record</div><div class="code_line">&nbsp;&nbsp; &nbsp; FH: BitmapFileHeader;</div><div class="code_line">&nbsp;&nbsp; &nbsp; IH: BitmapInfoHeader;</div><div class="code_line">&nbsp;&nbsp; &nbsp; end;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;ColorTable: array of TRGBQuad;</div><div class="code_line">&nbsp;&nbsp;Data: array of Byte;</div><div class="code_line">&nbsp;&nbsp;RGBData: array of TRGBTriple;</div><div class="code_line">&nbsp;&nbsp;Bmp: BitmapHeader;</div><div class="code_line">&nbsp;&nbsp;tmp, i, L: Cardinal;</div><div class="code_line">&nbsp;&nbsp;F: hFile;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;F := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);</div><div class="code_line">&nbsp;&nbsp;if F = INVALID_HANDLE_VALUE then</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;MessageBox(0,PChar(&#39;File &#39;+ FileName + &#39; not found&#39;), &#39;glLoadTexture&#39;,0);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;exit;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;ReadFile(F, Bmp, sizeof(BitmapHeader),tmp, nil );</div><div class="code_line">&nbsp;&nbsp;L := Bmp.IH.biWidth * Bmp.IH.biHeight;</div><div class="code_line">&nbsp;&nbsp;SetLength(RGBData, L);</div><div class="code_line">&nbsp;&nbsp;case Bmp.IH.biBitCount of</div><div class="code_line">&nbsp;&nbsp; &nbsp;8:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;SetLength(ColorTable, round(exp(Bmp.IH.biBitCount*Ln(2))));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ReadFile(F, ColorTable[0], SizeOf(TRGBQuad) * round(exp(Bmp.IH.biBitCount*Ln(2))), tmp, nil);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;SetLength(Data, L);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ReadFile(F, Data[0], SizeOf(Byte) * L, tmp, nil);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;for i := 0 to L - 1 do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;RGBData[L - i - 1].rgbtRed &nbsp; := ColorTable[Data[i]].rgbBlue;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;RGBData[L - i - 1].rgbtGreen := ColorTable[Data[i]].rgbGreen;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;RGBData[L - i - 1].rgbtBlue &nbsp;:= ColorTable[Data[i]].rgbRed;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;24:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;SetLength(Data, L * 3);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ReadFile(F, Data[0], SizeOf(Byte) * L * 3, tmp, nil);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;for i := 0 to L - 1 do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;RGBData[L - i - 1].rgbtRed &nbsp; := Data[3 * i];</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;RGBData[L - i - 1].rgbtGreen := Data[3 * i + 1];</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;RGBData[L - i - 1].rgbtBlue &nbsp;:= Data[3 * i + 2];</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;else MessageBox(0, &#39;Format not support&#39;, &#39;glLoadTexture&#39;, 0);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end; { end case}</div><div class="code_line">&nbsp;&nbsp;CloseHandle(F);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Далее код из BMP.pas от Jan Horn</div><div class="code_line">&nbsp;&nbsp;glGenTextures(1, Texture);</div><div class="code_line">&nbsp;&nbsp;glBindTexture(GL_TEXTURE_2D, Texture);</div><div class="code_line">&nbsp;&nbsp;glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); &nbsp;{Texture blends with object background}</div><div class="code_line">&nbsp;&nbsp;// &nbsp;glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); &nbsp;{Texture does NOT blend with object background}</div><div class="code_line">&nbsp;&nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp;Select a filtering type. BiLinear filtering produces very good results with little performance impact</div><div class="code_line">&nbsp;&nbsp; &nbsp;GL_NEAREST &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - Basic texture (grainy looking texture)</div><div class="code_line">&nbsp;&nbsp; &nbsp;GL_LINEAR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- BiLinear filtering</div><div class="code_line">&nbsp;&nbsp; &nbsp;GL_LINEAR_MIPMAP_NEAREST - Basic mipmapped texture</div><div class="code_line">&nbsp;&nbsp; &nbsp;GL_LINEAR_MIPMAP_LINEAR &nbsp;- BiLinear Mipmapped texture</div><div class="code_line">&nbsp;&nbsp;}</div><div class="code_line">&nbsp;&nbsp;glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); { only first two can be used }</div><div class="code_line">&nbsp;&nbsp;glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); { all of the above can be used }</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;gluBuild2DMipmaps(GL_TEXTURE_2D, 3, Bmp.IH.biWidth, Bmp.IH.biHeight, GL_RGB, GL_UNSIGNED_BYTE, RGBData);</div><div class="code_line">&nbsp;&nbsp;// Use when not wanting mipmaps to be built by openGL</div><div class="code_line">&nbsp;&nbsp;// glTexImage2D(GL_TEXTURE_2D, 0, 3, Bmp.IH.biWidth, Bmp.IH.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, RGBData);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
<br>
07 Собранный пример VCL<br>
=======================<br>
<br>
На форме таймер, в проект включен MyOpenGL.pas. В той же папке лежит 8 или <br>
24-битный bmp-фаил.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">unit Unit1;</div><div class="code_line">&nbsp;</div><div class="code_line">interface</div><div class="code_line">&nbsp;</div><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,</div><div class="code_line">&nbsp;&nbsp;Dialogs, ExtCtrls, MyOpenGL;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TForm1 = class(TForm)</div><div class="code_line">&nbsp;&nbsp; &nbsp;Timer1: TTimer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure FormDestroy(Sender: TObject);</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure FormResize(Sender: TObject);</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure Timer1Timer(Sender: TObject);</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure FormCreate(Sender: TObject);</div><div class="code_line">&nbsp;&nbsp;private</div><div class="code_line">&nbsp;&nbsp; &nbsp;{ Private declarations }</div><div class="code_line">&nbsp;&nbsp;public</div><div class="code_line">&nbsp;&nbsp; &nbsp;{ Public declarations }</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;Form1: TForm1;</div><div class="code_line">implementation</div><div class="code_line">{$R *.dfm}</div><div class="code_line">&nbsp;</div><div class="code_line">procedure TForm1.FormDestroy(Sender: TObject);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;glKill(Form1.Handle);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure TForm1.FormResize(Sender: TObject);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;glOnResize(Form1.ClientWidth,Form1.ClientHeight);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure TForm1.Timer1Timer(Sender: TObject);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;glDraw();</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure TForm1.FormCreate(Sender: TObject);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;glInit(Form1.Handle);</div><div class="code_line">&nbsp;&nbsp;glOnResize(Form1.ClientWidth,Form1.ClientHeight);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
<br>
08 Собранный пример WinApi<br>
==========================<br>
<br>
В той же папке лежит 8 или 24-битный bmp-фаил.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">program a;</div><div class="code_line">&nbsp;</div><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;windows,</div><div class="code_line">&nbsp;&nbsp;messages,</div><div class="code_line">&nbsp;&nbsp;MyOpenGL in &#39;MyOpenGL.pas&#39;;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;MainWnd: hWND;</div><div class="code_line">&nbsp;</div><div class="code_line">function WindowProc(Wnd: HWND; Msg: Integer; wParam: wParam; lParam:lParam):lResult;stdcall;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;case Msg of</div><div class="code_line">&nbsp;&nbsp; &nbsp;WM_DESTROY:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;glKill(MainWnd);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;postquitmessage(0);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;exit;</div><div class="code_line">&nbsp;&nbsp; &nbsp; end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WM_TIMER:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;glDraw(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Рисуем сцену</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WM_SIZE:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// В lParam содержатся размеры клиентской области ;-)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;glOnResize(loWord(lParam), hiWord(lParam));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result := DefWindowProc(Wnd, Msg, wParam, lParam);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;Mesg: TMsg;</div><div class="code_line">&nbsp;&nbsp;wc : TWndClassEx;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;wc.cbSize := sizeof(wc);</div><div class="code_line">&nbsp;&nbsp;wc.style := CS_HREDRAW or CS_VREDRAW;</div><div class="code_line">&nbsp;&nbsp;wc.lpfnWndProc := @WindowProc;</div><div class="code_line">&nbsp;&nbsp;wc.cbClsExtra := 0;</div><div class="code_line">&nbsp;&nbsp;wc.cbWndExtra := 0;</div><div class="code_line">&nbsp;&nbsp;wc.hInstance := hInstance;</div><div class="code_line">&nbsp;&nbsp;wc.hIcon := LoadIcon(0, IDI_WINLOGO);</div><div class="code_line">&nbsp;&nbsp;wc.hCursor := LoadCursor(0, IDC_ARROW);</div><div class="code_line">&nbsp;&nbsp;wc.hbrBackground := COLOR_BTNFACE+2;</div><div class="code_line">&nbsp;&nbsp;wc.lpszMenuName := nil;</div><div class="code_line">&nbsp;&nbsp;wc.lpszClassName := &#39;aWnd&#39;;</div><div class="code_line">&nbsp;&nbsp;RegisterClassEx(wc);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Создаем окно 400х400</div><div class="code_line">&nbsp;&nbsp;MainWnd := CreateWindowEx (0, &#39;aWnd&#39;, &#39;MyOpenGL&#39;, WS_OVERLAPPEDWINDOW or WS_VISIBLE, 100, 100, 400, 400, 0, 0, hInstance, nil);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Создаем контекст воспроизведения OpenGL и его параметры</div><div class="code_line">&nbsp;&nbsp;glInit(MainWnd);</div><div class="code_line">&nbsp;&nbsp;// Задаем матрицы OpenGL для размера окна 400х400</div><div class="code_line">&nbsp;&nbsp;glOnResize(400, 400);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Устанавливаем таймер 10мс для перерисовки сцены</div><div class="code_line">&nbsp;&nbsp;SetTimer(MainWnd, 1, 10, nil);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;while GetMessage(Mesg, 0, 0, 0) do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;TranslateMessage(Mesg);</div><div class="code_line">&nbsp;&nbsp; &nbsp;DispatchMessage(Mesg);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end.</div></ol></div></div></div></div>]]></description>
        <author>Zoobastik</author>
        <category>Графика, звук, анимация, игры</category>
      </item>
	
      </channel>
      </rss>
	