void COpenGL::DefaultGraphic()
{
m_xSize = m_zSize = 33;
UINT
nz = m_zSize - 1,
nx = m_xSize - 1;
DWORD nSize = m_xSize * m_zSize * sizeof(float) + 2*sizeof(UINT);
BYTE *buff = new BYTE[nSize+1];
UINT *p = (UINT*)buff;
*p++ = m_xSize;
*p++ = m_zSize;
float *pf = (float*)p;
double fi = atan(1.)*12, kx=fi/nx, kz=fi/nz;
for (UINT i=0; i<m_zSize; i++)
for (UINT j=0; j<m_xSize; j++)
*pf++ = float (exp(-(i+20.*j)/256)*sin(kz*(i-nz/2.))*sin(kx*(j-nx/2.)));
DWORD nBytes;
HANDLE hFile = CreateFile(_T("exp.dat"), GENERIC_WRITE,
0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
WriteFile (hFile,(LPCVOID)buff, nSize, &nBytes, 0);
CloseHandle(hFile);
SetGraphPoints (buff, nSize);
delete [] buff;
}
void COpenGL::SetGraphPoints (BYTE* buff, DWORD nSize)
{
UINT *p = (UINT*)buff;
m_xSize = *p;
m_zSize = *++p;
if (m_xSize<2 || m_zSize<2 || m_xSize*m_zSize*sizeof(float)
+2 * sizeof(UINT) != nSize)
{
MessageBox(_T("Wrong file format"));
return;
}
m_cPoints.resize (m_xSize * m_zSize);
if (m_cPoints.empty())
{
MessageBox(_T("No graphics data"));
return;
}
float
x, z,
*pf = (float*)++p,
fMinY = *pf,
fMaxY = *pf,
right = (m_xSize-1)/2.f,
left = -right,
rear = (m_zSize-1)/2.f,
front = -rear,
range = (right + rear)/2.f;
UINT i, j, n;
m_fRangeY = range;
m_fRangeX = float(m_xSize);
m_fRangeZ = float(m_zSize);
m_zTrans = -1.5f*m_fRangeZ;
for (z=front, i=0, n=0; i<m_zSize; i++, z+=1.f)
{
for (x=left, j=0; j<m_xSize; j++, x+=1.f, n++)
{
MinMax (*pf, fMinY, fMaxY);
m_cPoints[n] = Point3D(x,z,*pf++);
}
}
float zoom = fMaxY > fMinY ? range/(fMaxY-fMinY) : 1.f;
for (n=0; n<m_xSize*m_zSize; n++)
m_cPoints[n].y = zoom*(m_cPoints[n].y - fMinY) - range/2.f;
}
Внимание. Следующий код надо вставить внутрь уже существующей заготовки метода ReadData, который является не простым методом класса, а методом интерфейса IOpenGL (поэтому он и возвращает HRESULT). Он предоставлен клиентам (реализован) с помощью класса COpenGL.
TCHAR szFile[MAX_PATH] = { 0 }, szCurDir[MAX_PATH];
::GetCurrentDirectory (MAX_PATH-1, szCurDir);
OPENFILENAME ofn =
{
sizeof(OPENFILENAME),
m_hWnd, GetModuleHandle(0), // Dialog Owner, App Instance
_T("Dat Files (*.dat)\0*.dat\0"), 0, 0, 1, // Filter, Custom Filter and Filter Index
szFile, MAX_PATH, 0, 0, // Recieve File Name, File Name Buffer
szCurDir, _T("Open a graphics data file"), // InitialDir, Dialog Title
OFN_EXPLORER | OFN_OVERWRITEPROMPT, // Flags
0, 0, "dat", 0, 0, 0, // Offsets, Default extension, CustData, Hook, TemplateName
#if (_WIN32_WINNT >= 0x0500)
0, 0, 0 // Reserved, Reserved, FlagsEx
#endif
};
if (GetOpenFileName(&ofn))
{
HANDLE hFile = CreateFile (ofn.lpstrFile, GENERIC_READ,
FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == (HANDLE)-1)
{
MessageBox(_T("Could not open this file"));
return S_FALSE;
}
if (!DoRead(hFile))
return S_FALSE;
DrawScene();
FireViewChange();
}
return S_OK;
Метод FireViewChange унаследован от шаблона классов CComControl. Если компонент активен, то метод уведомляет клиента о необходимости перерисовать весь элемент, если нет, то он уведомляет зарегистрированный сток (sink) о том, что облик компонента изменился. Слушающий клиент услышит и, возможно, отреагирует, а не слушающий не имеет стока. Далее опять идет простой (то есть наш) метод, который не виден клиентскому приложению.
bool COpenGL::DoRead (HANDLE hFile)
{
DWORD nSize = GetFileSize (hFile, 0);
if (nSize == 0xFFFFFFFF)
{
GetLastError();
MessageBox(_T("The file is too big"));
CloseHandle(hFile);
return false;
}
BYTE *buff = new BYTE[nSize+1];
if (!buff)
{
MessageBox(_T("No core"));
CloseHandle(hFile);
return false;
}
DWORD nBytes;
ReadFile (hFile, buff, nSize, &nBytes, 0);
CloseHandle(hFile);
if (nSize != nBytes)
{
MessageBox(_T("Wrong file data"));
return false;
}
SetGraphPoints (buff, nSize);
delete [] buff;
return true;
}
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.