В теле следующей функции ReadData мы создадим файловый диалог, в контексте которого пользователь выбирает файл с новыми данными графика, затем вызовем функцию непосредственного чтения данных (DoRead) и создадим новую сцену на основе прочитанных данных. Попутно мы демонстрируем, как обрабатывать ошибки и работать с файловым диалогом, созданным с помощью функций API. Стандартный диалог открытия файла в этом случае более управляем, и ему можно придать множество сравнительно новых стилей. Стиль OFN_EXPLORER работает только в Windows 2000:
void COGView: : ReadData ()
{
//=== Строка, в которую будет помещен файловый путь
TCHAR szFile[MAX_PATH] = { 0 } ;
//====== Строка фильтров демонстрации файлов
TCHAR *szFilter =TEXT ("Graphics Files (*.dat)\0")
TEXT("*.dat\0")
TEXT ("All FilesNO")
TEXT ( " * . * \ 0 " ) ;
//====== Выявляем текущую директорию
TCHAR szCurDir[MAX_PATH] ;
: :GetCurrentDirectory (MAX_PATH-1, szCurDir) ;
//== Структура данных, используемая файловым диалогом
OPENFILENAME ofn;
ZeroMemory (&ofn,sizeof (OPENFILENAME) ) ;
//====== Установка параметров будущего диалога
ofn.lStructSize = sizeof (OPENFILENAME) ;
и * . *, текстовые описания которых можно увидеть в одном из окон стандартного диалога поиска и открытия файлов:
//====== Функция непосредственного чтения данных
bool COGView: : DoRead ( HANDLE hFile) {
//====== Сначала узнаем размер файла
DWORD nSize = GetFileSize (hFile, 0) ;
//=== Если не удалось определить размер, GetFileSize
//====== возвращает 0xFFFFFFFF
if (nSize == 0xFFFFFFFF)
{
GetLastError () ;
MessageBox (_T ("Некорректный размер файла"));
CloseHandle (hFile) ;
return false;
//=== Создаем временный буфер размером в весь файл BYTE
*buff = new BYTE [nSize+1] ;
//====== Обработка отказа выделить память
if (Ibuff) {
MessageBox (_T ("Слишком большой размер файла"))
CloseHandle (hFile) ;
return false;
//====== Реальный размер файла
DWORD nBytes;
//====== Попытка прочесть файл
ReadFile (hFile, buff, nSize, &nBytes, 0) ; CloseHandle (hFile) ;
//====== Если реально прочитано меньшее число байт
if (nSize != nBytes)
{
MessageBox (_T ("Ошибка при чтении файла"));
return false;
}
//====== Генерация точек изображения
SetGraphPoints (buff, nSize) ;
//====== Освобождение временного буфера
delete [] buff;
// ====== Возвращаем успех
return true;
}
В данный момент можно запустить приложение, и оно должно работать. В окне вы должны увидеть изображение поверхности, которое приведено на рис. 7.1. Для создания рисунка мы изменили цвет фона на белый, так как в книге этот вариант считается более предпочтительным. Попробуйте изменить размеры окна. Изображение поверхности должно пропорционально изменить свои размеры. Оцените качество интерполяции цветов внутренних точек примитивов и степень влияния освещения. Позже мы создадим диалог для управления параметрами света и отражающих свойств материала. А сейчас отметим, что напрашивается введение возможности управлять ориентацией и местоположением поверхности с помощью мыши. Для того чтобы убедиться в сложности автомата состояний OpenGL, a также в том, что все в нем взаимосвязано, временно поменяйте местами две строки программы: glVertexSf (xi, yi, zi); и glVertex3f (xn, yn, zn);. Вы найдете их в теле функции DrawScene.