Чтение
данных
В теле следующей
функции 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.
Рис. 7.1.
Вид освещенной поверхности в 3D