Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.11.2011, 18:08   #1
_PROGRAMM_
Участник клуба
 
Аватар для _PROGRAMM_
 
Регистрация: 30.07.2009
Сообщений: 1,601
По умолчанию Освещение в OpenGL

Сегодня решил отойти от своих дел и вспомнить работу с освещением, которую я так и не разобрал. За основу взял книгу Краснова. Вроде бы все правильно, но ничего не заметно.
Код:
const
position:array[0..3] of GlFloat = (0,0,1,1);

begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glClearColor(0,0,0,0);
glViewPort(0,0,Form1.Width,Form1.Height);
glPushMatrix;
glMatrixMode(GL_PROJECTION);
glLoadidEntity;
glFrustum(-1,1,-1,1,1,10);
glMatrixMode(GL_MODELVIEW);
glLoadidEntity;

glTranslated(0,0,-2);
glRotated(angle,0,1,0);
glColor3f(1,1,0);

glDisable(GL_LIGHTING);

glLightfv(GL_LIGHT0,GL_POSITION,@position);

glBegin(GL_QUADS);
glNormal3f(0,0,1);   // к лицевой
glVertex3f(0.5,0.5,0);
glVertex3f(-0.5,0.5,0);
glVertex3f(-0.5,-0.5,0);
glVertex3f(0.5,-0.5,0);
glEnd;


glBegin(GL_QUADS);
glnormal3f(1,0,0);   // к правой стороне
glVertex3f(0.5,0.5,-1);
glVertex3f(0.5,0.5,0);
glVertex3f(0.5,-0.5,0);
glVertex3f(0.5,-0.5,-1);
glEnd;


glBegin(GL_QUADS);
glnormal3f(-1,0,0);   // к левой стороне
glVertex3f(-0.5,0.5,-1);
glVertex3f(-0.5,0.5,0);
glVertex3f(-0.5,-0.5,0);
glVertex3f(-0.5,-0.5,-1);
glEnd;

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

glPopMatrix;
swapBuffers(DC);
Конечно, еще есть код для вращения и инициализации, но он тут не нужен.
Заранее спасибо.

В мире нет вечных двигателей, зато есть вечные тормоза...

Блог
_PROGRAMM_ вне форума Ответить с цитированием
Старый 12.11.2011, 15:18   #2
_PROGRAMM_
Участник клуба
 
Аватар для _PROGRAMM_
 
Регистрация: 30.07.2009
Сообщений: 1,601
По умолчанию

Неужели никто не знает?

В мире нет вечных двигателей, зато есть вечные тормоза...

Блог
_PROGRAMM_ вне форума Ответить с цитированием
Старый 12.11.2011, 20:16   #3
Kostia
Участник клуба
 
Аватар для Kostia
 
Регистрация: 21.11.2007
Сообщений: 1,690
По умолчанию

glDisable(GL_LIGHTING);
И
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
Нужно местами поменять.

Код:
glViewPort(0,0,Form1.Width,Form1.Height);
glPushMatrix;
glMatrixMode(GL_PROJECTION);
glLoadidEntity;
glFrustum(-1,1,-1,1,1,10);
glMatrixMode(GL_MODELVIEW);
glLoadidEntity;
Вынести в функцию изменения размеров окна и убрать glPushMatrix; glPopMatrix;

Последний раз редактировалось Kostia; 12.11.2011 в 20:26.
Kostia вне форума Ответить с цитированием
Старый 13.11.2011, 15:01   #4
_PROGRAMM_
Участник клуба
 
Аватар для _PROGRAMM_
 
Регистрация: 30.07.2009
Сообщений: 1,601
По умолчанию

Цитата:
и убрать glPushMatrix; glPopMatrix;
Зачем? Речь идет о освещении.
Вот чего я добился.
Код:
glBegin(GL_QUADS);
glNormal3f(0,0,0.1);   // к лицевой
glVertex3f(0.5,0.5,0);
glVertex3f(-0.5,0.5,0);
glVertex3f(-0.5,-0.5,0);
glVertex3f(0.5,-0.5,0);
glEnd;


glBegin(GL_QUADS);
glnormal3f(-0.5,0,0);   // к правой стороне
glVertex3f(0.5,0.5,-1);
glVertex3f(0.5,0.5,0);
glVertex3f(0.5,-0.5,0);
glVertex3f(0.5,-0.5,-1);
glEnd;


glBegin(GL_QUADS);
glnormal3f(0.5,0,0);   // к левой стороне
glVertex3f(-0.5,0.5,-1);
glVertex3f(-0.5,0.5,0);
glVertex3f(-0.5,-0.5,0);
glVertex3f(-0.5,-0.5,-1);
glEnd;
Изменив нормали у меня получилось. Прошу обратить внимание на вторую и третью нормаль. Правильно ли я их провел? Дело в том, что только при таких условиях видно две стороны(точнее, когда во второй нормали первый элемент +, а в третьей -).

В мире нет вечных двигателей, зато есть вечные тормоза...

Блог
_PROGRAMM_ вне форума Ответить с цитированием
Старый 13.11.2011, 20:12   #5
_PROGRAMM_
Участник клуба
 
Аватар для _PROGRAMM_
 
Регистрация: 30.07.2009
Сообщений: 1,601
По умолчанию

Пытаясь узнать свою ошибку понял, я не знаю как строится вектор нормали. Думаю, что Вам объяснить это девятикласснику не составит труда. Изложу свои знания:
Нормальный вектор всегда имеет длину 1.
Он строится перпендикулярно плоскости.
аргументы функции glNormal3f - точка конца вектора
Этот вектор проводится, по идее, от плоскости.

Откуда он исходит?. Из центра? Но тогда как из центра провести нормаль вот к такой плоскости?(на рисунке.Вид как бы сверху) (как ни странно, но в книге Краснова говорится, что нормаль проводится именно К плоскости а не ОТ)
В общем, Вы меня поняли.
P.S. Я не обладаю достаточными знаниями, чтобы усвоить это из того, что дает мне гугл. Хотя пытался.
Изображения
Тип файла: jpg Безымянный.jpg (21.8 Кб, 141 просмотров)

В мире нет вечных двигателей, зато есть вечные тормоза...

Блог
_PROGRAMM_ вне форума Ответить с цитированием
Старый 15.11.2011, 00:43   #6
Вадим Буренков
Участник клуба
 
Аватар для Вадим Буренков
 
Регистрация: 06.03.2009
Сообщений: 1,346
По умолчанию

Вообще нормальный вектор конкретно ниоткуда не исходит. Приложить нормальный вектор можно к любой точке. На самом деле он просто указывает направление, перпендикулярное какой либо плоскости в пространстве. Например имея вектор источника света и нормальный вектор можно накладывать попиксельное освещение.
Формула простого диффузного освещения (пример из шейдеров):
цвет пикселя = цвет текстуры * dot(Normal, vec_light), где dot - скалярное произведение, Normal - вектор нормали точки освещаемого объекта, vec_Light - вектор от источника света в эту точку.
Получается такое изображение:

Как это работает? Дело в том что освещенность конкретной точки зависит от угла, под которым свет падает на нее. Поскольку скалярное произведение единичных векторов (ab = |a|*|b|*cos(a)) как раз и возвращает косинус между векторами (т.к |a|=|b|=1) мы имеем высокую освещенность в тех местах где угол между нормалью и вектором от источника мал (тогда cos(a)~1) и низкую где он большой (cos(a)~0).
Цитата:
Но тогда как из центра провести нормаль вот к такой плоскости?
Все это рассчитывается через нормальное и каноническое уравнения прямой (википедия в помощь). Если надо помочь опиши конкретней условия задачи.
Вадим Буренков вне форума Ответить с цитированием
Старый 15.11.2011, 07:22   #7
_PROGRAMM_
Участник клуба
 
Аватар для _PROGRAMM_
 
Регистрация: 30.07.2009
Сообщений: 1,601
По умолчанию

Цитата:
Как это работает? Дело в том что освещенность конкретной точки зависит от угла, под которым свет падает на нее. Поскольку скалярное произведение единичных векторов (ab = |a|*|b|*cos(a)) как раз и возвращает косинус между векторами (т.к |a|=|b|=1) мы имеем высокую освещенность в тех местах где угол между нормалью и вектором от источника мал (тогда cos(a)~1) и низкую где он большой (cos(a)~0).
Интересно... Спасибо.
Цитата:
цвет пикселя = цвет текстуры * dot(Normal, vec_light), где dot - скалярное произведение, Normal - вектор нормали точки освещаемого объекта, vec_Light - вектор от источника света в эту точку.
Получается такое изображение:
Понятно, а я то думал. Тяжеловато будет vec_Light найти.А разве это не реализовано в GluShare(забыл как шар рисуется)?
Цитата:
Все это рассчитывается через нормальное и каноническое уравнения прямой (википедия в помощь)
Я уже нашел несколько подводных камней. Теперь все понятно.
Но мне очень интересно что же не так в моем коде? Векторы проведены во внутрь куба. Ведь так не должно быть. Если сделать обратное, то стороны становятся черными.

В мире нет вечных двигателей, зато есть вечные тормоза...

Блог
_PROGRAMM_ вне форума Ответить с цитированием
Старый 15.11.2011, 07:53   #8
Warn
Форумчанин
 
Аватар для Warn
 
Регистрация: 03.11.2011
Сообщений: 230
По умолчанию

Цитата:
цвет пикселя = цвет текстуры * dot(Normal, vec_light)
выходит что поверхность(ее нормализированные нормали), которая будет обращена к источнику света под прямым углом 90 будет наиболее освещена.
Изображения
Тип файла: gif Clipboard01.gif (6.3 Кб, 100 просмотров)

Последний раз редактировалось Warn; 15.11.2011 в 08:33.
Warn вне форума Ответить с цитированием
Старый 15.11.2011, 16:20   #9
_PROGRAMM_
Участник клуба
 
Аватар для _PROGRAMM_
 
Регистрация: 30.07.2009
Сообщений: 1,601
По умолчанию

Спасибо всем. У меня появился еще один вопрос, наверное, последний. Мне кажется все из-за этого. Есть массив для освещения position:array[0..3] of GlFloat = (0,0,1,1); Что значит все четыре координаты? В моих знаниях: первые три - точка, а вот что регулирует четвертая? Что-то я не найду информации.

В мире нет вечных двигателей, зато есть вечные тормоза...

Блог
_PROGRAMM_ вне форума Ответить с цитированием
Старый 15.11.2011, 19:47   #10
Warn
Форумчанин
 
Аватар для Warn
 
Регистрация: 03.11.2011
Сообщений: 230
По умолчанию

грубо говоря лампочки бывают разного типа: лампочка(точечный свет(POIN LIGHT) и издалека приходящий (направленный (DIRECTONAL))

хyzw
Если w = 0.0 то хyz трактуется как направление источника, свет направленный.
Если w <> 0.0 то хyz трактуется как позиция точечного источника света.
Изображения
Тип файла: gif Clipboard01.gif (37.6 Кб, 87 просмотров)
Warn вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Освещение в OpenGL - как добиться релистичности, нужен мануал. Karp_13 Общие вопросы C/C++ 4 29.10.2011 00:29
OpenGL - освещение Артэс Общие вопросы C/C++ 0 12.10.2011 20:46
как сделать такое освещение(opengl) ? NiCola999 Общие вопросы C/C++ 3 20.11.2010 15:02
Освещение ноута Lemo Свободное общение 21 30.05.2010 14:55
OpenGL, освещение loozer Мультимедиа в Delphi 3 17.12.2008 19:09