Современные графические технологии ИЛИ OpenGL и графические процессоры 2010
Методы создания изображений Точность и реалистичность: Трассировка лучей Излучательность Фотонные карты Скорость: Полигональная графика
Полигональное представление объектов Для каждой вершины заданы: Координаты вершины Нормаль Координаты текстуры И много чего еще... Объект задан набором вершин, которые объединены в плоские грани, чаще всего – треугольные.
GPU vs. CPU > 3 млрд. транзисторов Тактовая частота 700Mhz 1.5GB GDDR5 памяти ??? транзисторов Тактовая частота 825Mhz 1-2GB 1300 MHz памяти Тактовая частота 3.3Ghz 1.17 млрд. транзисторов (six core) GF100 RV870 Core i7-980X
GPU vs. CPU (4 года назад) 120 млн. транзисторов Тактовая частота 500Mhz 128MB 500MHz памяти 107 млн. транзисторов Тактовая частота 325Mhz 128MB 310MHz памяти Тактовая частота 1.6Ghz – 3.06Ghz 42 млн. Транзисторов (core) NV30 R300
Архитектура GF100
Буфер кадра Буфер кадра – прямоугольный массив структур
2D-ускорители Копирование и перемещение прямоугольных блоков Отрисовка курсора мыши Отрисовка прямых линий и других примитивов Масштабирование прямоугольных блоков Прикладная программа Win32 APIДрайверВидеокарта
Графический конвейер T&L: Преобразование и освещение Rasterization: Разбиение примитивов на пиксели Pixel Ops: Запись пиксела в буфер кадра V i ={P,n,…} F j ={V 1,V 2,V 3 } V i={P,RGBA,…} { x i,y i,z i,RGBA i } F j={V 1,V 2,V 3 }
3D-ускорители T&L Rasterization Pixel Ops Прикладная программа OpenGL Direct3D ДрайверВидеокарта Ускоряются этапы T&L и растеризации Взаимодействие с программой при помощи специальных API
Поколение 4: Шейдеры R250-R580 T&L Rasterization Pixel Ops NV25-NV47 dp4 r0.x, v0, c[0] dp4 r0.y, v0, c[1] dp4 r0.z, v0, c[2] dp4 r0.w, v0, c[3] mov oD0, c[4] ; Output color mov oPos, r0 ; Output vertex ps.1.0 // DX8 Version. tex t0 // n-map. texm3x3pad t1, t0_bx2 texm3x3pad t2, t0_bx2 v0_bx2 texm3x3tex t3, t0_bx2 dp3_sat r0, t3_bx2,
OpenGL – многоплатформенная библиотека функций для создания интерактивных 2D и 3D приложений. GLut – многоплатформенная библиотека вспомогательных функций для создания оконных приложений, использующих OpenGL Позволяет скрыть особенности программирования под данную оконную систему. Отраслевой стандарт с 1992 года
OpenGL: клиент-сервер /* прикладная программа */ #include … glEnable(GL_TEXTURE_2D); glBegin(GL_TRIANGLES); … glTexCoord2d(0.5,0.5); glVertex3f(1.0,0.5,-0.2); … glEnd(); … Сервер OpenGL Буфер кадра, Буфер глубины, Буфер трафарета, Буфер аккумулятора.
Что нужно для работы с OpenGL.cpp opengl32.lib gl.h glu32.lib glu.h glut32.lib glut.h opengl32.dll glu32.dll glut32.dll.exe C++
Литература (1/5) Ю. Тихомиров. OpenGL. Программирование трехмерной графики, БХВ – Петербург, 2002 Эдвард Энджел. Интерактивная компьютерная графика. Вводный курс на базе OpenGL, 2-е изд., Вильямс, 2001
Литература (2/5) Ву Мейсон, Нейдер Джеки, Девис Том, Шрайнер Дейв. OpenGL. Руководство по программиста. Диа-Софт, Френсис Хилл. OpenGL. Программирование компьютерной графики. Для профессионалов. Питер. 2002
Литература (3/5) Гайдуков С.OpenGL. Профессиональное программирование трехмерной графики на C++. - БХВ-Петербург, 2004
Литература (4/5) Боресков А.В. Расширения OpenGL. - СПб.: БХВ-Петербург, 2005 Дж. Рост OpenGL. Трехмерная графика и язык программирования шейдеров - СПб.: Питер, 2005
Литература (5/5) Миллер Т. DirectX 9 с управляемым кодом. Программирование игр и графика. – КомБук, Горнаков С. DirectX 9. Уроки программирования на C++. – БХВ, 2004.
Где взять GLut? documentation/glut/index.html Где прочитать про GLut? - работа с GLut
Самая простая программа #include void reshape(int w, int h) { /* Здесь обрабатываем изменение размеров окна */ } void display(void) { /* Здесь помещаются команды рисования */ } void idle(void) { /* Здесь происходит анимация */ } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB); // GLUT_DOUBLE|GLUT_DEPTH|GLUT_STENCIL|GLUT_ACCUM glutCreateWindow(Самая простая программа); glutDisplayFunc(display); glutReshapeFunc(reshape); glutIdleFunc(idle); glutMainLoop(); return 0; }
Работа с буфером кадра void glClear(GLenum buffers); buffers = GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT| GL_ACCUM_BUFFER_BIT| GL_STENCIL_BUFFER_BIT void glClearColor(GLclampf red,GLclampf green, GLclampf blue,GLclampf alpha); Задание цвета для заполнения буфера кадра Заполнение экранных буферов Представление цвета в OpenGL
Преобразование координат: viewport void glViewport(GLint x,GLint y, GLsizei w,GLsizei h); w h void glDepthRange(GLclampd n,GLclampd f);
Рисуем куб x y z Видимые грани: Невидимые грани:
Команды OpenGL glVertex3fv ( v ) 2 – (x, y) 3 – (x, y, z) 4 – (x, y, z, w) Число компонент B – byte ub – unsigned byte s – short us – unsigned short I – int ui – unsigned int f – float d – double Тип данных «v» отсутствует для скалярных форм. Пример: glVertex2f(x,y) Вектор
Модель begin/end void glMatrixMode(…); void glLoadIdentity(); void glMultMatrixd(…); void glBegin(GLenum type); void glVertex(…); void glNormal(…); void glColor(…); void glEnd(); T&L Rasterization Pixel Ops void glTexture2d(…); void glTexEnv(…); void glPolygonMode(…); void glDepthFunc(…); void glBlendFunc(…); void glStencilOp(…);
Формирование граней из вершин GL_TRIANGLES: GL_QUADS: GL_POLYGON:
Однородные координаты Общее аффинное преобразование сводится к умножению на матрицу Проецирование также сводится к умножению на матрицу
Преобразование координат Отсечение: Viewport V i ={P s,RGBA,…}
Матрицы преобразований void glMatrixMode(Glenum mode); mode={GL_MODELVIEW|GL_PROJECTION} void glLoadIdentity(); void glMultMatrixd(GLdouble c[16]); Выбираем матрицу преобразований для изменения: Две основные операции над матрицами:
Матрицы преобразований. Продолжение void glTranslated(GLdouble x, GLdouble y, GLdouble z); void glScaled(GLdouble x, GLdouble y, GLdouble z); void glRotated(GLdouble angle, GLdouble ax, GLdouble ay, GLdouble az); void gluPerspective(GLdouble fov, GLdouble aspect, GLdouble znear, GLdouble zfar);
Как работает gluPerspective? X Y Z 0 O1O1 O2O2 A1A1 B1B1 C1C1 D1D1 A2A2 B2B2 C2C2 D2D2 void gluPerspective(GLdouble fov, GLdouble aspect, GLdouble znear, GLdouble zfar); fov = D 1 OA 1 (в градусах) aspect = C 1 D 1 /D 1 A 1 znear = |OO 1 | zfar = |OO 2 |
gluPerspective: продолжение
Уменьшение количества вершин GL_TRIANGLE_FAN: 3n vs. 1+n, n> GL_TRIANGLE_STRIP: 3n vs. 2+n GL_QUAD_STRIP: 4n vs. 2+2n
Виртуальная камера gluLookAt( eye x, eye y, eye z, aim x, aim y, aim z, up x, up y, up z ) Настройка виртуальной камеры eye – координаты наблюдателя aim – координаты цели up – направление вверх (up x, up y, up z ) (aim x, aim y, aim z ) ( eye x, eye y, eye z )
Лицевые и нелицевые грани void glFrontFace(GLenum type); type = {GL_CW|GL_CCW} void glCullFace(GLenum type); type = {GL_FRONT|GL_BACK (по умолчанию)} glEnable(GL_CULL_FACE); glDisable(GL_CULL_FACE); x y z A1A1 A2A2 A3A3 A1A1 A3A3 A2A2 e2e2 e1e1 e2e2 e1e1
Дисплейные списки GLuint n = glGenLists(1); glNewList(n,GL_COMPILE); glEndList(); Дисплейный список (display list) – запомненная последовательность команд OpenGL. Находим неиспользуемый номер дисплейного списка Сохраняем последовательность команд Освобождаем номер дисплейного списка glCallList(n); Воспроизводим сохраненную последовательность команд (с теми же самыми параметрами!) glDeleteLists(n,1);
Z-буфер Необходимо создать z-буфер glutDisplayMode(GLUT_DEPTH|/*…*/); Перед рисованием сцены очистить z-буфер glClear(GL_DEPTH_BUFFER_BIT|/*…*/); Включить или выключить сравнение z координат glEnable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST); Возможно задать операцию сравнения glDepthFunc(GLenum type); type = {GL_ALWAYS|GL_NEVER|GL_LESS|GL_GREATER| GL_EQUAL|GL_NOTEQUAL|GL_LEQUAL|GL_GEQUAL} Возможно включить или выключить запись в z-буфер glDepthMask(TRUE); или glDepthMask(FALSE);
Стек матриц glLoadIdentity(); glTranslated(…); glPushMatrix(); glRotated(…); glPopMatrix(); glPushMatrix(); glRotataed(…); glPopMatrix(); E T T T*R1 T T*R2 T
Рисуем тор x y z 0 X Z Y P Q Q i,j Q i+1,j Q i+1,j+1 Q i,j+1
Уравнение освещенности по Фонгу l n r P e Фоновое освещение не имеет источника и зависит только от сцены При диффузном освещении свет от источника равномерно рассеивается во всех направлениях. При зеркальном освещении свет от источника отражается от повехности.в одном направлении. Зеркальная освещенность дополнительно зависит от положения наблюдателя..
Модели Блинна и Шлика Вычисление отраженного вектора – трудоемкая операция (Блинн) Возведение в степень также работает не очень быстро... (Шлик) l n r P e
Уравнение освещенности OpenGL е m,a m, s m, d m, h m – свойства материала a i,s i,d i – свойства i -го источника освещения a s – фоновое освещение att i – коэффициент затухания spot i – коэффициент направленности -l vivi P
Установка параметров освещения в OpenGL void glMaterialfv(GLenum face,GLеnum param,GLfloat *value); face = {GL_FRONT|GL_BACK} param = {GL_AMBIENT|GL_DIFFUSE|GL_EMISSIVE|GL_SPECULAR} value = float[4] // RGBA void glMaterialf(GLenum face,GL_SHININESS,GLfloat value); void glLightModelfv(GLеnum param,GLfloat *value); param = LIGHT_MODEL_AMBIENT value = float[4] // RGBA void glLightfv(GLenum light,GLеnum param,GLfloat *value); face = {GL_LIGHT0|GL_LIGHT1|…} param = {GL_AMBIENT|GL_DIFFUSE|GL_SPECULAR} value = float[4] // RGBA Задаем параметры материала: Задаем цвет источника освещения: Задаем цвет фонового освещения:
Установка параметров освещения. Часть 2. void glLightfv(GLenum light, GL_POSITION,GLfloat *value); face = {GL_LIGHT0|GL_LIGHT1|…} value = float[4] // x,y,z,w Задаем положение источника освещения: Координаты источника освещения преобразуются текущей матрицей модельного преобразования! Включаем расчет освещенности void glEnable(GLenum type); type = GL_LIGHTING; Включаем требуемые источники освещения void glEnable(GLenum type); type = GL_LIGHT0; Включаем требуемые источники освещения void glShadeModel(GLenum type); type = GL_FLAT; - плоская закраска грани type = GL_SMOOTH - закраска по Гуро
Интерполяция цвета Вычислить цвет (RGB) в каждой вершине. Вычислить цвет в точках P1 и P2: s = ||P1 - B|| / ||A - B|| C(P1) = s(C(A)) - (1-s)(C(B)) Вычислить цвет в т. Р: s = ||P - P2|| / ||P1 - P2|| C(P) = s(C(P1))-(1-s)(C(P2))
Недостатки закраски по Гуро
Интерполяция нормали Вычислить нормали (RGB) в каждой вершине. Вычислить нормаль в точках P1 и P2: s = ||P1 - B|| / ||A - B|| N(P1) = s(N(A)) + (1-s)(N(B)) Вычислить нормаль в т. Р: s = ||P - P2|| / ||P1 - P2|| N(P) = s(т(P1))-(1-s)(N(P2)) Вычислить цвет в точке Р.
Массивы вершин void glVertexPointer(GLint size,GLenum type, GLsizei stride,const GLvoid *pointer; Задаем массив вершин, нормалей и текстурных координат: Задаем последовательность номеров вершин 2376 … void glDrawElements(GLenum mode,GLsizei count, GLenum type, const GLvoid *indices); Возможно полностью избежать дублирования вершин
Растеризация V1V1 V2V2 V3V3 Интерполяция цвета вдоль примитива - закраска по Гуро Интерполяция координаты z
I=0 I=1 I=0 I=1 Ошибки линейной интерполяции Освещенность зависит от способа разбиения на примитивы Поле нормалей лучше задавать в виде текстуры!
Текстурирование u v 0 x y 0 Перспективное текстурирование: 1 1 x 1,y 1,u 1,v 1 x 2,y 2,u 2,v 2 x 3,y 3,u 3,v 3
Текстурирование в OpenGL GLuint texture; glGenTextures(1,&texture); Создаем текстуру - прямоугольный массив с цветами пикселов. Высота и ширина должны быть степенями двойки. RGB NM …RGB 1M RGB 0M ………… RGB N1 …RGB 11 RGB 01 RGB N0 …RGB 10 RGB 00 Получаем номер текстурного объекта: Активизируем текстурный объект: glBindTexture(texture);
Текстурирование в OpenGL: часть 2 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); Загружаем текстуру из памяти в текстурный объект: Устанавливаем режимы текстурирования: glPixelStorei(GL_UNPACK_ALIGNMENT,1); glTexImage2D(GL_TEXTURE_2D, 0, // Mip-level GL_RGB, // Формат текстуры tex_width,tex_height, 0, // Ширина границы GL_RGB, // Формат исходных данных GL_UNSIGNED_BYTE, // Тип данных tex_bits); // Исходные данные
Текстурирование в OpenGL: часть 3 Разрешаем текстурирования Задаем текстурные координаты (обычно для каждой вершины) glEnable(GL_TEXTURE_2D); glTexCoord2d(u,v); Возможно, потребуется включить режим перспективного текстурирования glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); Возвращаем номер текстурного объекта в список свободных glDeleteTextures(1,&texture);
Как загрузить картинку из файла? Воспользоваться любой другой сторонней библиотекой Функции BmpLoad из примеров: Классы из NV SDK: unsigned char *LoadIndexedBMPFile (const char *path,int *width,int *height); unsigned char *LoadTrueColorBMPFile (const char *path,int *width,int *height); namespace jpeg { extern int read(const char *filename, int *width,int *height, unsigned char **pixels, int *components); }
Фильтрация текстур Выборка ближайшего текселя GL_NEAREST: Линейная комбинация 4-x соседних пикселей GL_LINEAR:
Свертка текстурных координат glTexParameteri(…,GL_REPEAT); glTexParameteri(…,GL_CLAMP); glTexParameteri(…,GL_REPEAT); glTexParameteri(…,GL_CLAMP);
Фильтрация текстур: mipmapping увеличение текстуры масштаб 1:1 уменьшение текстуры увеличение текстуры масштаб 1:1 уменьшение текстуры в 2 раз
Фильтрация текстур: mipmapping. Часть 2 256x x64 216x16 4 Трилинейная фильтрация GL_LINEAR_MIPMAP_LINEAR
Анизотропная фильтрация Экран Расширение GL_EXT_texture_filter_anisotropic
Текстура и освещение RGBA f из модуля T&LRGBA t текстурыRGBA с результат += Модулирование GL_MODULATE (по умолчанию) Смешение GL_DECAL,GL_BLEND Замещение GL_REPLACE Demo
Генерация текстурных координат Линейная зависимость Environment mapping - эффект отражающей поверхности r n hP (u,v)
Генерация текстурных координат. Продолжение Включаем автоматическую генерацию текстурных координат (для первыхдвух координат) glEnable(GL_TEX_GEN_S); glEnable(GL_TEX_GEN_T); Включаем автоматическую генерацию текстурных координат (для первых двух координат) glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
Использование текстуры как фонового изображения Устанавливаем ортогональную проекцию glMatrixMode(GL_PROJECTION); glLoadIndentity(); glOrtho(-1,1,-1,1,-1,1); Устанавливаем ортогональную проекцию glMatrixMode(GL_MODELVIEW); glLoadIndentity(); Рисуем прямоугольник glEnable(GL_TEXTURE_2D); glBindTexture(bktex); glBegin(GL_QUADS); glTexCoord2f(0,0); glVertex2f(-1,-1); glTexCoord2f(1,0); glVertex2f(1,-1); glTexCoord2f(1,1); glVertex2f(1,1); glTexCoord2f(0,1); glVertex2f(-1,1); glEnd();
Преобразование текстурных координат Работаем с матрицей T точно также как с M и P. glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMultMatrix(…); Позволяет существенно изменять вид объекта не изменяя геометрии
Пиксельные операции T&L Rasterization Pixel Ops Буфер кадра Буфер глубины Буфер трафарета Буфер аккумулятора
Пиксельные операции. Продолжение. Scissor testAlpha test Stencil testDepth testBlending Stencil Buffer: S ij Z Buffer: Z ij Frame buffer: RGBA ij
Scissor & Alpha test Не записывать пиксел Нет Да glScissor(x,y,w,h); glEnable(GL_SCISSOR_TEST); glDisable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST); glDisable(GL_SCISSOR_TEST); glAlphaFunc(GL_GREATER,0.5);
Смешение цветов glEnable(GL_BLEND); glDisable(GL_BLEND); glBlendFunc(sfactor,dfactor) Команды OpenGL: glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA): glBlendFunc(GL_ONE_MINUS_SRC_ALPHA,GL_SRC_ALPHA): glBlendFunc(GL_ZERO,GL_SRC_COLOR):
Карты освещенности (lightmaps) (i,j) Карта освещенности: Мультитекстурирование: Экономия количества примитивов при динамическом освещении Экономия текстур при статическом освещении Возможен предварительный расчет освещения
Смещение вершин При использовании буфера глубины могут возникнуть проблемы с рисование граней, лежащих в одной плоскости. Z Y Возможно задать смещение глубины для каждой вершины void glPolygonOffset(GLfloat factor, GLfloat units);
Мультитекстурирование F(RGBA c,RGBA 0 ) RGBA 0 Texture 0 Lighting RGBA c RGBA 1 Texture 1 RGBA f F(RGBA f,RGBA 1 ) Объединение текстуры объекта и текстуры среды
Расширения OpenGL Читаем спецификацию расширения (ARB_multitexture) Определяем константы … #define GL_TEXTURE0_ARB 0x84C0 #define GL_TEXTURE1_ARB 0x84C1 #define GL_TEXTURE2_ARB 0x84C2 #define GL_TEXTURE3_ARB 0x84C3 … Определяем указатели на функции … void (APIENTRY * glMultiTexCoord2d)(GLenum target, GLdouble s, GLdouble t); void (APIENTRY * glActiveTexture)(GLenum target); …
Расширения OpenGL. Продолжение Получаем список доступных расширений char *extensions = glGetString(GL_EXTENSIONS);
Расширения OpenGL. Часть 3. Получаем указатели на функции … glActiveTexture = wglGetProcAddress("glActiveTextureARB"); glMultiTexCoord2d = wglGetProcAddress("glMultiTexCoord2dARB"); … Задаем текстурные объекты для каждого текстурного блока … (*glActiveTexture)(GL_TEXTURE0_ARB); glEnable(GL_TEXTURE_2D); glBindTexture(…); … (*glActiveTexture)(GL_TEXTURE1_ARB); glEnable(GL_TEXTURE_2D); glBindTexture(…); …
Расширения OpenGL. Часть 4. Задаем смешение цвета освещения и цвета первой текстуры … (*glActiveTexture)(GL_TEXTURE0_ARB); glTexEnvi(…); … Задаем текстурные координаты для каждого текстурного блока … (*glMultiTexCoord2d)(GL_TEXTURE0_ARB,0.5,0.5); (*glMultiTexCoord2d)(GL_TEXTURE1_ARB,0.2,0.3); … Задаем смешение цвета первого блока и второй текстуры … (*glActiveTexture)(GL_TEXTURE1_ARB); glTexEnvi(…); …
Полупрозрачные объекты Полупрозрачная грань - грань через часть пикселов которой видно лежащие за ней грани. Полупрозрачные грани необходимо выводить в порядке back-to-front. Применение метода Z-буфера ведет к визуальным артефактам -глюкам :) Для выпуклых объектов можно выводить сначала нелицевые грани, а затем - лицевые. Объекты можно выводить методом художника - сортировать по убыванию координат Z центров.
Буфер трафарета и буфер глубины RGBA x,y =F(RGBA x,y,RGBA f ) Изменение S x,y Да Нет Не записывать пиксел void glStencilOp(GLenum failOp, GLenum zfailOp, GLenum zpassOp); failOp: zfailOp: zpassOp: void glStencilFunc(GLenum func, GLint ref, GLuint mask); func:
Буфер трафарета: видимость пикселей true S x,y =1 для грани F - Запись пикселя Да Нет F F S x,y == 1 S x,y == 0 glStencilFunc(GL_KEEP, GL_KEEP, GL_REPLACE); glStencilOp(GL_ALWAYS, 1,1);
Буфер трафарета: обработка пикселей S x,y ==1? - - Запись пикселя Да Нет - F F S x,y == 1 S x,y == 0 glStencilOp(GL_EQUAL, 1,1); glStencilFunc(GL_KEEP, GL_KEEP, GL_KEEP);
Буфер трафарета: тени и отражения Отбрасывание тени на плоскую грань ПравильноНеправильно Отражения и порталы
Буфер трафарета: теневые объемы Строим теневой объем Рисуем затеняемый объект со включенным Z-буфером Z Y … glEnable(GL_DEPTH_TEST); glCallList(object); …
Теневые объемы. Продолжение. Рисуем нелицевые грани теневого объема Z Y … glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS,1,1); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glColorMask(0,0,0,0); glDepthMask(0); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glCallList(shadow); …
Теневые объемы. Часть 3. Рисуем лицевые грани теневого объема Z Y … glStencilFunc(GL_ALWAYS,1,1); glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glCallList(shadow); glColorMask(1,1,1,1); glDepthMask(1); …
Теневые объемы. Часть 4. Возможен вывод граней теневого объема в произвольном порядке. Z Y … glStencilFunc(GL_ALWAYS,1,1); glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); glDisable(GL_CULL_FACE); glColorMask(0,0,0,0); glDepthMask(0); glCallList(shadow); glColorMask(1,1,1,1); glDepthMask(1); …
Теневые объемы. Часть 5. Рисуем затененную часть объекта Z Y … glStencilFunc(GL_EQUAL,1,1); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); … glCallList(object); … glDisable(GL_STENCIL_TEST); ……
Кубические карты: определение. V t R Точка R = R(t), t = (p,q,r) определяет одну из шести текстур и текстурные координаты. (p,q,r)->RGBA Расширение GL_EXT_cube_map C вершиной V связано три текстурные координаты (p,q,r). x y z
Кубические карты среды. n P е r R Необходимо применить к текстурным координатам преобразование, обратное модельно-видовому! x y z
Кубические карты освещения. t P Пусть источники освещения находятся далеко от объекта. Тогда освещение в точке объекта зависит только от нормали. x y z Заранее запишем результат расчета освещенности для нормали n в элемент кубической текстуры с координатами n.
Построение отражающего объекта. O Переносим наблюдателя в центр отражающего объекта и строим изображение, полученное при взгляде в направлении нормали к одной из сторон. Сохраняем изображение на экране как текстуру! void glCopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, Glsizei width, GLsizei height, GLint border ); Рисуем объект с кубическими картами отражения.