Ю.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (DOC) (1124366), страница 15
Текст из файла (страница 15)
151
Пример класса окна, рисование в которое осуществляется при помощи OpenGL.
class OpenGLWindow : public CWnd
{ public :
OpenGLWindow () ; // открытые члены класса
private :
// закрытые члены класса
// сигнатуры этих методов определены заранее MFC
// и должны выглядеть именно так
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct );
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnPaintQ;
afx_msg void OnDestroy ();
// объявление карты сообщений Windows DECLARE_MESSAGE_MAP ()
// класс для хранения контекстов OpenGL GLRC* m_pGLRC;
};
Реализация методов:
// конструктор
OpenGLWindow : : OpenGLWindow ()
: m_pGLRC(NULL)
{ }
// заполнение карты сообщений BEGIN_MESSAGE_MAP (OpenGLWindow, CWnd)
// стандартные макросы MFC
ON_WM_CREATE()
ON_WM_PAMT()
152
Глава П. Использование OPENGL в MFC и VCL
ON_WM_DESTROY() ON_WM_ERASEBKGND () END_MES3AGE_MAP ()
// в этом методе реализуем инициализацию afx_msg int OpenGLWindow : : OnCreate (
IPCREATESTRUCT lpCreateStruct) {
m_pGLRC = new GLRC(GetSafeHwnd ()); bool res = m_pGLRG->Create (); if (! res)
return FALSE;
return CWnd: : OnCreate (lpCreateStruct ) ; }
// запрещаем заливку фона
afx_msg BOOL OpenGLWindow :: OnEraseBkgnd (CDC* pDC)
{
return FALSE;
}
// здесь рисуем
afx_msg void OpenGLWindow : : OnPaint ()
{
CWnd:: OnPaint ();
// делаем текущим m_glRC->MakeCurrent () ;
g 1С1 e ar (GL_COLOR_BUFFER_Bir | GL_DEPTH_BUFFER_BrT) ;
// рисуем то, что хотим нарисовать <методы рисования OpenGL>
11.6. Использование OPENGL С VCL
153
m_glRC—>SwapBuffers (); }
// здесь происходит освобождение ресурсов afx_msg void OpenGLWindow : : OnDestroy ()
{
m_glRC—>Destroy () ; delete m_glRC;
CWnd: : OnDestroy () ; }
11.6. Использование OpenGL с VCL
Использование OpenGL с VCL — другой популярной библиотекой для разработки Windows-приложений, отличается от предыдущего примера только деталям и названиями классов.
Вот пример минимального кода на C++, который добавит OpenGL к форме (окну) VCL:
class OpenGLForm : public TForm
{ public :
fastcall OpenGLForm(TComponent* owner);
// открытые, члены класса
private :
// закрытые члены класса GLRC* m_pGLRC;
// контекст устройства окна published :
// сигнатуры этих методов определены заранее.
void fastcall FormCreate ( TObject * sender);
void fastcall FormDestroy (TObject * sender);
154 Глава П. Использование OPENGL в MFC и VCL
void fastcall FormPaint ( TObject * sender);
};
// конструктор
fastcall OpenGLForm : : OpenGLForm(
TComponent* owner) : TForm( owner ) ,
m_pGLRC(NULL) { }
// в этом методе реализуем инициализацию
void fastcall OpenGLForm :: FormCreate (
TObject* sender)
{
m_pGLRC = new GLRC( Handle ); bool res = m_pGLRG->Create ();
assert(res ); }
// здесь рисуем
void fastcall OpenGLForm :: FormPaint (
TObject* sender)
{
// делаем текущим m_glRC->MakeCurrent () ;
g 1С1 e ar (GL_COLOR_BUFFER_Brr | GL_DEPTH_BUFFER_Brr) ;
// рисуем то, что хотим нарисовать <методы рисования OpenGL>
m_glRC—>SwapBuffers () ; }
// здесь происходит деинициализация
11.6. Использование OPENGL С VCL 155
void fastcall OpenGLForm : : FormDestroy ()
{
m_glRC->Destroy () ;
delete m_glRC; }
Глава 12.
OpenGL в .NET
В этом разделе рассматривается построение оконного приложения с поддержкой OpenGL на платформе Microsoft .NET.
Несмотря на то, что OpenGL не имеет встроенной поддержки в .NET, в настоящее время существует достаточно много решений, позволяющих подключать OpenGL к .NET-программам. Мы рассмотрим работу с одной из них — свободно-распространяемой библиотекой Tao Framework.
Tao Framework (http://www.taoframework.com) реализует промежуточный уровень между .NET приложением и различными \Ут32-библиотеками, в частности GL, GLU, GLUT, WGL.
12.1. GLUT в среде Microsoft Visual C# 2005
Простейшим способом создания OpenGL-приложения с среде .NET можно считать использование библиотеки GLUT, доступной через .NET-компоненту Tao.FreeGlut.
Далее приводятся шаги, необходимые для создания консольного .NET-приложения в среде Microsoft Visual C# 2005 на С# с GLUT и OpenGL:
157
158
Глава 12. OPENGL в .NET
-
Убедиться, что на машине установлен GLUT (glut32.dll лежит в Windows\System32).
-
Создание проекта консольного приложения: File—>New—> Projects—)► Visual C#—^Windows—^Console Application, набрать имя проекта, ОК.
-
Добавление Тао к проекту: Project—>Add Reference—>.NET, найти в списке «Тао Framework OpenGL Binding For .NET» и «Тао Framework FreeGLUT Binding For .NET», выделить оба, ОК. Если компонент нет в списке, необходимо найти их в инсталляционном каталоге библиотеки Тао Framework и добавить через вкладку Browse.
Программирование с использование GLUT и OpenGL в .NET на С^ практически не отличается от варианта для Win32 и C++. Ниже приведен пример простой программы, аналогичной примеру из п.2.5:
Программа 12.1. Простой пример OpenGL в Causing Тао. FreeGlut ; using Тао . OpenGl;
namespace gl_glut_net {
class Program
{
private static int Width = 512; private static int Height = 512; public const int CubeSize = 200;
static void DisplayQ
{ _
int left , right , top, bottom;
12.1. GLUT в среде MICROSOFT VISUAL C# 2005 159
left = (Width - CubeSize) / 2; right = left + CubeSize; bottom = (Height — CubeSize) / 2; top = bottom + CubeSize ;
Gl Gl
Gl Gl Gl Gl Gl Gl Gl
glClearColor(0.7f, 0.7f, 0.7f, 1); g 1С1 e ar (Gl. GL_COLOR_BUFFER_BIT);
glColor3ub(255, 0, 0); glBegin (Gl .GL_QUADS); glVertex2f (left , bottom); glVertex2f (left , top ); glVertex2f( right , top); glVertex2f( right , bottom); glEnd();
Gl. glFinish ();
}
static void Reshape (int w, int h)
{
Width = w;
Height = h;
Gl. glViewport (0 , 0, w, h);
Gl. glMatrixMode (Gl.GL_PROJECTION);
Gl. glLoadldentity () ;
Gl.glOrtho(0, w, 0, h, -1.0, 1.0);
Gl. glMatrixMode (Gl .GL_MODELVIEW); Gl. glLoadldentity () ; }
static void Keyboard(byte key, int x, int y)
160
Глава 12. OPENGL в .NET
{
const int ESCAPE = 2 7;
if (key = ESCAPE)
Glut. glutLeaveMainLoop (); }
static void Main( string [] args) {
Glut.glutlnit () ;
Glut. glutlnitDisplayMode (Glut .GLUT_RGB); Glut . glutlnitWindowSize (Width , Height ); Glut. glutCreateWindow ("Red^square^example");
Glut .glutDisplayFunc( Display); Glut. glutReshapeFunc (Reshape ); Glut . glutKeyboardFunc (Keyboard );
Glut . glutMainLoop () ;
} }
}
Обратите внимание, что все команды и константы GL, GLU и GLUT находятся в пространствах имен Gl, Glu и Glut, соответственно.
12.2. Использование OpenGL в WindowsForms
OpenGL в WindowsForms требует инициализации, аналогичной рассмотренной для библиотек MFC и VCL (см. п. 11). В Tao Framework уже реализован простой класс окна OpenGL — Tao.Platform. Windows.SimpleOpenGlControl.
Рассмотрим последовательность действий, необходимую для
12.2. Использование OPENGL в WINDOWSFORMS 161
создания простого оконного приложения в WindowsForms и с поддержкой OpenGL:
-
Создание проекта приложения: File—>New—>Projects—>Visual C#—> Windows—> Windows Application, набрать имя проекта, ОК.
-
Добавление Тао к проекту: Project—>Add Reference—>.NET, найти в списке «Тао Framework OpenGL Binding For .NET» и «Тао Framework Windows Platform API Binding For .NET», выделить оба, ОК. Если компонент нет в списке, необходимо найти их в инсталляционном каталоге библиотеки Тао Framework и добавить через вкладку Browse.
-
Чтобы удобно создать окно OpenGL, необходимо добавить соответствующий объект на панель инструментов. Для этого нужно в контекстном меню панели «Toolbox» выбрать пункт «Choose Items...», в появившемся списке найти «SimpleOpenGLControl», поставить галочку около него, ОК.
-
Добавление окна OpenGL на форму: на панели «Toolbox» найдите «SimpleOpenGLControl» и перетащите на форму приложения. Окно должно заполняться черным цветом.
-
Инициализация OpenGL: в конструкторе формы после вызова InitializeComponentQ добавить вызов функции создания контекста simpleOpenGlControll.InitializeContexts().
Функции рисования OpenGL можно добавлять в обработчик события Paint окна OpenGL (не путать с Paint формы).
Часть IV Приложения
163
Приложение А.
Примитивы библиотек GLU и GLUT
Рассмотрим стандартные команды построения примитивов, которые реализованы в библиотеках GLU и GLUT.
Чтобы построить примитив из библиотеки GLU, надо сначала создать указатель на quadric-объект с помощью команды gluNewQuadricQ, а затем вызвать одну из команд gluSphereQ, gluCylinderQ, gluDisk(), gluPartialDisk(). Рассмотрим эти команды отдельно:
void gluSphere (GLUquadricObj *qobj , GLdouble radius , GLint slices , GLint stacks)
Эта функция строит сферу с центром в начале координат и радиусом radius. При этом число разбиений сферы вокруг оси z задается параметром slices , а вдоль оси ъ — параметром stacks.
void gluCylinder (GLUquadricObj *qobj , GLdouble baseRadius , GLdouble topRadius , GLdouble height , GLint slices , GLint stacks)
165
166 Приложение А. Примитивы библиотек GLU и GLUT
Данная функция строит цилиндр без оснований (кольцо), продольная ось параллельна оси z, заднее основание имеет радиус baseRadius, и расположено в плоскости z = О, переднее основание имеет радиус topRadius и расположено в плоскости z = height. Если задать один из радиусов равным нулю, то будет построен конус. Параметры slices и stacks имеют аналогичный смысл, что и в предыдущей команде.
void gluDisk (GLUquadricObj *qobj , GLdouble innerRadius , GLdouble outerRadius , GLint slices , GLint loops)
Функция строит плоский диск (круг) с центром в начале координат и радиусом outerRadius. Если значение innerRadius отлично от нуля, то в центре диска будет находиться отверстие радиусом innerRadius. Параметр slices задает число разбиений диска вокруг оси z, а параметр loops — число концентрических колец, перпендикулярных оси z.
void gluPartialDisk (GLUquadricObj *qobj ,
GLdouble innerRadius , GLdouble outerRadius , GLint slices , GLint loops , GLdouble startAngle , GLdouble sweepAngle);
Отличие этой команды от предыдущей заключается в том, что она строит сектор круга, начальный и конечный углы которого отсчитываются против часовой стрелки от положительного направления оси у и задаются параметрами startAngle и sweepAngle. Углы измеряются в градусах.
Команды, проводящие построение примитивов из библиотеки GLUT, реализованы через стандартные примитивы OpenGL
167
и GLU. Для построения нужного примитива достаточно произвести вызов соответствующей команды.
void glutSolidSphere (GLdouble radius ,
GLint slices , GLint stacks) void glutWireSphere (GLdouble radius,
GLint slices , GLint stacks)
Команда glutSolidSphereQ строит сферу, a glutWireSphereQ — каркас сферы радиусом radius. Остальные параметры те же, что и в предыдущих командах.
void glutSolidCube (GLdouble size) void glutWireCube (GLdouble size)
Команды строят куб или каркас куба с центром в начале координат и длиной ребра size.
void glutSolidCone (GLdouble base , GLdouble height ,
GLint slices , GLint stacks) void glutWireCone (GLdouble base , GLdouble height ,