Установка освещения
Параметры освещения будут изменяться с помощью регуляторов, которые мы разместим на новой странице блока Property Pages. Каждую новую страницу этого блока принято реализовывать в виде отдельного интерфейса, раскрываемого специальным объектом (ко-классом) ATL. Однако уже сейчас мы можем дать тело вспомогательной функции SetLight, которая устанавливает параметры освещения, подобно тому как это делалось в уроке, где говорили о графике в рамках MFC.
Параметры освещения будут храниться в массиве m_LightParam, взаимодействовующем с диалогом, размещенным на новой странице свойств:
void COGCOpenGLView::SetLight() { //====== Обе поверхности изображения участвуют //====== при вычислении цвета пикселов при //====== учете параметров освещения glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1); //====== Позиция источника освещения //====== зависит от размеров объекта float fPosf] = { (m_LightParam[0]-50)*m_fRangeX/100, (m_LightParam[l]-50)*m_fRangeY/100, (m_LightParam[2]-50)*m_fRangeZ/100, l.f }; glLightfv(GL__LIGHTO, GL_POSITION, fPos); //====== Интенсивность окружающего освещения float f = m_LightParam[3]/100 .f; float fAmbient[4] = { f, f, f, O.f }; glLightfv(GL_LIGHTO, GL_AMBIENT, fAmbient); //====== Интенсивность рассеянного света f = m_LightParam[4]/lOO.f; float fDiffuse[4] = { f, f, f, O.f }; glLightfv(GL_LIGHTO, GL_DIFFUSE, fDiffuse); //====== Интенсивность отраженного света f = m_LightParam[5]/l00.f; float fSpecular[4] = { f, f, f, 0 .f }; glLightfv(GL_LIGHTO, GL_SPECULAR, f Specular.); //====== Отражающие свойства материала //===== для разных компонентов света f = m_LightParam[61/100.f; float fAmbMat[4] = { f, f, f, O.f }; glMaterialfv(GL_FRONT_AND_BACK, GL__AMBIENT, fAmbMat); f = m_LightParam[7]/l00.f; float fDifMat[4] = { – f, f, f, l.f }; glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fDifMat); f = m_LightParam[8]/lOO.f; float fSpecMat[4] = { f, f, f, 0.f }; glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, fSpecMat); //======= Блесткость материала float fShine = 128 * m_LightParam[9]/100.f; glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, fShine); //======= Излучение света материалом f = m_LightParam[10]/lOO.f; float fEmission[4] = { f, f, f, O.f }; glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, fEmission); }
Параметры освещения
Данные о том, как должна быть освещена сцена, мы будем получать из диалоговой вкладки свойств, которую создадим позже, но сейчас можем дать коды методов обмена данными, которые являются частью интерфейса lOpenGL:
STDMETHODIMP COpenGL::GetLightParams(int* pPos) { //======= Проход по всем регулировкам for (int 1=0; i<ll; i++) //======= Заполняем транспортный массив pPos pPos[i] = m_LightParam[i]; return S_OK; } STDMETHODIMP COpenGL:: SetLightParam (short lp, int nPos) //====== Синхронизируем параметр 1р и устанавливаем //====== его в положение nPos m_LightParam[lp] = nPos; //==== Перерисовываем окно с учетом изменений FireViewChange (); return S_OK; }
Метод CComControl::FireViewChange уведомляет контейнер, что объект хочет перерисовать все свое окно. Если объект в данный момент неактивен, то уведомление с помощью указателя m_spAdviseSink поступает в клиентский сток (sink), который мы рассматривали при обзоре точек соединения.
В данный момент вы можете построить DLL и посмотреть, что получилось, запустив тестовый контейнер. Однако, как это часто бывает в жизни программиста, мы не увидим ничего, кроме пустой рамки объекта. В таком состоянии можно остаться надолго, если не хватает квалификации и опыта отладки СОМ DLL-серверов. Сразу не видны даже пути поиска причины отказа. Никаких грубых промахов вроде бы не совершали. Процесс создания окна внедренного объекта происходит где-то за кадром.