Программирование для Mac OS X пишем OpenGL-приложение с использованием GLUT

В этой статье мы рассмотрим как написать программу на С/С++, использующую графическую библиотеку OpenGL и библиотеку GLUT для организации платформенно-независимого ввода/вывода под Mac OS X.

В Mac OS X (в отличии от убогих форточек) сразу установлена последняя версия OpenGL (2.0) - поэтому в частности не нужно никаких дополнительных библиотек для работы с расширениями OpenGL и шейдерами - это все сразу доступно.

Более того, установив среду разработки, Вы устанавливаете не только библиотеку OpenGL (OpenGL.framework), но и библиотеку GLUT (GLUT.framework). Библиотека GLUT позволяет Вам писать программы с использованием OpenGL, не вникая во все сложности оконной системы (т.е. она предоставляет Вам некоторый платформенно-независимый API).

Итак мы сейчас рассмотрим написание простого OpenGL-приложения на С/С++ (работа с OpenGL через Cocoa и шейдеры будут рассмотрены в следующих статьях).

Итак, запускаем XCode и создаем новое приложение, выбрав в качестве его типа 'C++ Tool'/

Рис 1. Создание проекта.

Далее зададим имя проекту - Glut-Example и место для него.

Рис 2. Задание имени проекта.

После создания проекта необходимо подключить к нему две библиотеки - OpenGL и GLUT. Для этого в popup-меню корня проекта выберем Add/Existing Frameworks....

Рис 3. Добавляем библиотеки к проекту.

После чего добавим библиотеку /System/Library/Frameworks/OpenGL.framework.

Рис 4. Добавление OpenGL.framework.

Аналогичным образом добавляем GLUT.framework (из того же каталога).

Рис 5. Добавление библиотеки GLUT.

Аналогичным образом добавим к проекту файлы Vector3D.h и Vector3D.cpp (их использование несколько облегчит написание программ).

Основным отличием нашего приложения от обычных программ с использованием GLUT'а будет строка, подключающая файл glut.h:

#include	<GLUT/glut.h>

В остальном можно использовать код практически любого примера для GLUT.

Рис 6.

Изменим стандартный файл main.cpp на приведенный ниже (все файлы и готовый проект для XCode можно скачать по ссылке в конце статьи).

#include <GLUT/glut.h>
#include <stdlib.h>
#include "Vector3D.h"

Vector3D    eye   ( 7, 5, 7 );              // camera position
Vector3D    light ( 5, 0, 4 );              // light position
float       angle = 0;
Vector3D    rot ( 0, 0, 0 );
int         mouseOldX = 0;
int         mouseOldY = 0;

void init ()
{
    glClearColor ( 0.5, 0.5, 0.5, 1.0 );
    glEnable     ( GL_DEPTH_TEST );
    glDepthFunc  ( GL_LEQUAL );

    glHint ( GL_POLYGON_SMOOTH_HINT,         GL_NICEST );
    glHint ( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
}

void display ()
{
    glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

                                            // draw the light
    glMatrixMode ( GL_MODELVIEW );
    glPushMatrix ();

    glTranslatef       ( light.x, light.y, light.z );
    glColor4f          ( 1, 1, 1, 1 );
    glutSolidSphere    ( 0.07f, 15, 15 );
    glPopMatrix        ();

    glMatrixMode   ( GL_MODELVIEW );
    glPushMatrix   ();

    glRotatef ( rot.x, 1, 0, 0 );
    glRotatef ( rot.y, 0, 1, 0 );
    glRotatef ( rot.z, 0, 0, 1 );
    glColor3f ( 1, 1, 0 );

    glutSolidTeapot ( 2.5 );
    
    glPopMatrix ();

    glutSwapBuffers ();
}

void reshape ( int w, int h )
{
   glViewport     ( 0, 0, (GLsizei)w, (GLsizei)h );
   glMatrixMode   ( GL_PROJECTION );
                                            // factor all camera ops into projection matrix
   glLoadIdentity ();
   gluPerspective ( 60.0, (GLfloat)w/(GLfloat)h, 1.0, 60.0 );
   gluLookAt      ( eye.x, eye.y, eye.z,    // eye
                    0, 0, 0,                // center
                    0.0, 0.0, 1.0 );        // up

   glMatrixMode   ( GL_MODELVIEW );
   glLoadIdentity ();
}

void motion ( int x, int y )
{
    rot.y -= ((mouseOldY - y) * 180.0f) / 200.0f;
    rot.z -= ((mouseOldX - x) * 180.0f) / 200.0f;
    rot.x  = 0;

    if ( rot.z > 360 )
        rot.z -= 360;

    if ( rot.z < -360 )
        rot.z += 360;

    if ( rot.y > 360 )
        rot.y -= 360;

    if ( rot.y < -360 )
        rot.y += 360;

    mouseOldX = x;
    mouseOldY = y;

    glutPostRedisplay ();
}

void mouse ( int button, int state, int x, int y )
{
    if ( state == GLUT_DOWN )
    {
        mouseOldX = x;
        mouseOldY = y;
    }
}

void key ( unsigned char key, int x, int y )
{
    if ( key == 27 || key == 'q' || key == 'Q' )    // quit requested
        exit ( 0 );
}

void animate ()
{
    angle   = 0.004f * glutGet ( GLUT_ELAPSED_TIME );
    light.x = 2*cos ( angle );
    light.y = 3*sin ( 1.4 * angle );
    light.z = 3 + 0.5 * sin ( angle / 3 );

    glutPostRedisplay ();
}

int main ( int argc, char * argv [] )
{
                                // initialize glut
    glutInit            ( &argc, argv );
    glutInitDisplayMode ( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
    glutInitWindowSize  ( 500, 500 );

                                // create window
    glutCreateWindow ( "Simple GLUT Example" );

                                // register handlers
    glutDisplayFunc  ( display );
    glutReshapeFunc  ( reshape );
    glutKeyboardFunc ( key     );
    glutMouseFunc    ( mouse   );
    glutMotionFunc   ( motion  );
    glutIdleFunc     ( animate );

    glutMainLoop ();

    return 0;
}

Запустив проект на компиляцию и выполнение мы получим полноценное работающее OpenGL/GLUT-приложение.

Рис 7. Работающее приложение.

Весь исходный код можно скачать по этой ссылке.

В ближайшее время на сайте steps3d.narod.ru будут выложены исходные коды примеров к книгам Расширения OpenGL и Разработка и отладка шейдеров портированных для Mac OS X (т.е. они могут быть откомпилированы и запущены под Mac OS X/Linux/Win32)(правда РРС Маки не поддерживаются :((.

Valid HTML 4.01 Transitional

Напиши мне
Используются технологии uCoz