В предыдущем уроке был рассмотрен каркас простейшего win32 приложения. Там же были причины почему нас не удовлетворят возможности glut'а и почему нужно ваять код инициализации самостоятельно. Посему без лишних реверансов приступим к реализации. Основа всего – класс посредством которого будет осуществляться инициализация OpenGL'я:
class		OGLDevice{
	//контекст воспроизведения OpenGL
	HGLRC			hGLrc;
public:
	//функция инициализации
	void			CreateDevice( HWND hWnd );
	//очевидно ))
	void			Release( void );
	//функция переключения буферов
	void			SwapBuffers( void );
};

void			OGLDevice::CreateDevice( HWND hWnd ){
	PIXELFORMATDESCRIPTOR	pfd;
	memset( &pfd , 0 , sizeof( PIXELFORMATDESCRIPTOR ) );
	DEVMODE			devmode;
	memset( &devmode , 0 , sizeof( devmode ) );

	pfd.nSize		=	sizeof(PIXELFORMATDESCRIPTOR);
	//версия структуры  PIXELFORMATDESCRIPTOR
	pfd.nVersion		=	1;
	pfd.dwFlags		=	PFD_DRAW_TO_WINDOW | //вывод в окно
				PFD_SUPPORT_OPENGL | //включена поддержка OGL
				PFD_DOUBLEBUFFER; //двойная буферизация
	pfd.iPixelType	=	PFD_TYPE_RGBA;//формат задания цвета
	pfd.cColorBits	=	32;//глубина цвета в битах
	pfd.cDepthBits	=	32;//разрядность z-буфера
	pfd.iLayerType	=	PFD_MAIN_PLANE;
	
	//находим индекс формата пикселов
	int			PixelFormat = ChoosePixelFormat( GetDC( hWnd ) , &pfd );

	if( PixelFormat == 0 ){
		PixelFormat = 1;
		//находим описатель формата пикселов
		if( DescribePixelFormat( GetDC( hWnd ) , PixelFormat , sizeof( PIXELFORMATDESCRIPTOR ) , &pfd ) == 0 ){
			exit( 0 );
		}
	}

	//устанавливаем формат пикселов
	if( SetPixelFormat( GetDC( hWnd ) , PixelFormat , &pfd  ) == NULL ){
		exit( 0 );
	}

	//создаем контекст
	if( ( hGLrc = wglCreateContext( GetDC( hWnd ) ) ) == NULL ){
		exit( 0 );
	}

	//делаем созданный контекст текущим
	if( wglMakeCurrent( GetDC( hWnd ) , hGLrc ) == false ){
		exit( 0 );
	}

	//осуществляем переход в полноэкранный режим
	if( !EnumDisplaySettings( NULL , ENUM_CURRENT_SETTINGS , &devmode ) ){
		exit( 0 );
	}
	devmode.dmSize = sizeof( DEVMODE );
	devmode.dmPelsWidth		= 800;
	devmode.dmPelsHeight	= 600;
	devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
	if( ChangeDisplaySettings( &devmode , CDS_FULLSCREEN ) != DISP_CHANGE_SUCCESSFUL ){
		exit( 0 );
	}
	
	ShowWindow( hWnd , SW_SHOW );
	SetForegroundWindow( hWnd );
	SetFocus( hWnd );
}
Теперь при разработке своих программ вам надо будет определить объект для инициализации:
OGLDevice		*Device;
Device = new OGLDevice;
Device->CreateDevice( hWnd );
//здесь hWnd – это хендл окна в которое осуществляется вывод
Оставшиеся две функции достаточно просты:
void			OGLDevice::SwapBuffers( void ){
	//переключаем буфер
	::SwapBuffers( wglGetCurrentDC() );
	//устанавливаем цвет которым будет очищаться буфер кадра
	glClearColor( 0 , 0 , 0.5 , 0 );
	//очищаем буферы
	//в данном примере очищаются буфер кадра и z-буфер
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
}

//функция уничтожения OGL окна, тоже в общем-то ничего сложного
void			OGLDevice::Release( void ){
	if( wglGetCurrentContext() != NULL ){
		wglMakeCurrent( NULL , NULL );
	}
	if( hGLrc != NULL ){
		//удаление контекста
		wglDeleteContext( hGLrc );
		hGLrc = NULL;
	}
}
Вот собственно и все.

Исходники можно скачать здесь.

Добавить комментарий