"Подать сюда MFС!!! – кричил он, топая всеми 4-мя лапами."
Сижу тут как-то, программку сочиняю, тут смотрю, царь зверей пожаловал. Вопрос задать пришел. Спрашивает как же OpenGL в MFC то вставить? Сначала думал отмажусь, потом смотрю, настойчивый такой царь попался. Письма шлет, желает знать как же все-таки её туда вставить-то. Вот и решил я примерчик на MFC состроить дабы цари меньше утруждали себя, а больше на солнышке бы нежились, чтоб у царей спокойно и хорошо все было, тогда и нам, простым зверушкам жить хорошо будет. И так поехали.
Для начала сделаем приложение MFC как диалог. Я назвал его BitScroll. Как это делать? Смотрите шаги по MFC.
Теперь, при помощи визарда добавим функцию
>BOOL CBitScrollDlg::PreCreateWindow(CREATESTRUCT& cs) {
> cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
> return CDialog::PreCreateWindow(cs);
>}
Помните, мы устанавливали слиль окна в функции CreateWindow? Так вот это действие по смыслу тоже самое. Напомню как это выглядело в Win32API:
>hWnd = CreateWindow("Skeleton", "Skeleton", WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 50, 50, 700, 400, NULL, NULL, hInst, NULL);
Теперь обратимся к функции OnInitDialog(). В ней сначала вызывается функция базового класса, т.е. CDialog, а потом устанавливаются иконки для диалога. Давайте вставим наш код между иконками и CDialog::OnInitDialog().
>SetWindowPos(&wndTop, 0, 0, WIDTH, HEIGHT, SWP_NOMOVE);
>pDC = GetDC();
>CenterWindow();
>Init(); SetTimer(1,SPEED, NULL);
Теперь посмотрим, что мы сделали. Сначала сделаем окно нужного нам размера (макросы WIDTH и HEIGHT объявлены так #define WIDTH 640 и #define HEIGHT 480 в заголовочном файле).
Затем получим контекст для рисования. Установимся в центр вселенной и… вот, тут самое интересное, тут мы вызываем нашу собственную функцию, которая будет инициализировать OpenGL (напоминаю, что тоже самое делала функция Initial в программе на Win32API).
А потом включаем таймер, чтобы обеспечить анимацию. Обратимся теперь к Init(). Выглядит она итак:
>void CBitScrollDlg::Init() {
> CRect rect;
> HGLRC hrc;
> if (!bSetupPixelFormat()) return;
> hrc = wglCreateContext(pDC->GetSafeHdc());
> ASSERT(hrc != NULL);
> wglMakeCurrent(pDC->GetSafeHdc(), hrc);
> GetClientRect(&rect);
> glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
> glClearDepth(1.0);
> glDepthFunc(GL_LESS);
> glEnable(GL_DEPTH_TEST);
> glShadeModel(GL_SMOOTH);
> glMatrixMode(GL_PROJECTION);
> glLoadIdentity();
> gluPerspective(45.0f, (GLfloat)rect.right / (GLfloat)rect.bottom, 0.1f, 100.0f);
> glMatrixMode(GL_MODELVIEW);
>}
Что мы тут делаем? Прежде всего вызываем ф-ию SetupPixelFormat(), это опять наша функция и мы посмотрим ее чуть позже.
Далее, как и раньше, получаем контекст рендеринга (маленькая деталь, ранее pDC(а точнее эта переменная называлась hDC) была объявлена как static HDC hDC, сейчас контекст рисования является пременной типа CDC, а ф-ция wglCreateContext и другие функции OpenGL требуют в качестве аргумента переменную типа HDC. Поэтому мы получаем этот hardware context с помощью pDC->GetSafeHdc()).
Затем делаем этот контекст текущим и настраиваем область отображения, так как это делалось в Initial() (Win32API)
Функция bSetupPixelFormat() содержит следующее:
>BOOL CBitScrollDlg::bSetupPixelFormat() {
> static PIXELFORMATDESCRIPTOR pfd = {
> sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
> 1, // version number
> PFD_DRAW_TO_WINDOW | // support window
> PFD_SUPPORT_OPENGL | // support OpenGL
> PFD_DOUBLEBUFFER, // double buffered
> PFD_TYPE_RGBA, // RGBA type
> 24, // 24-bit color depth
> 0, 0, 0, 0, 0, 0, // color bits ignored
> 0, // no alpha buffer
> 0, // shift bit ignored
> 0, // no accumulation buffer
> 0, 0, 0, 0, // accum bits ignored
> 32, // 32-bit z-buffer
> 0, // no stencil buffer
> 0, // no auxiliary buffer
> PFD_MAIN_PLANE, // main layer
> 0, // reserved
> 0, 0, 0 // layer masks ignored
> };
> int pixelformat;
> if ((pixelformat = ChoosePixelFormat(pDC->GetSafeHdc(), &pfd)) == 0) {
> MessageBox("ChoosePixelFormat failed");
> return FALSE;
> }
> if (SetPixelFormat(pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE) {
> MessageBox("SetPixelFormat failed");