В теле следующей функции 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;
}
В данный момент можно запустить приложение, и
оно должно работать. Для создания рисунка мы
изменили цвет фона на белый, так как в книге
этот вариант считается более предпочтительным.
Попробуйте изменить размеры окна. Изображение
поверхности должно пропорционально изменить свои
размеры. Оцените качество интерполяции цветов
внутренних точек примитивов и степень влияния
освещения. Позже мы создадим диалог для
управления параметрами света и отражающих
свойств материала. А сейчас отметим, что
напрашивается введение возможности управлять
ориентацией и местоположением поверхности с
помощью мыши. Для того чтобы убедиться в
сложности автомата состояний OpenGL, a также в
том, что все в нем взаимосвязано, временно
поменяйте местами две строки программы:
glVertexSf (xi, yi, zi); и glVertex3f (xn, yn,
zn);. Вы найдете их в теле функции DrawScene. |