среда, 11 июля 2012 г.

CodeBlocks 8.02 и OpenGL в Ubuntu 10.04

В данном посте мне бы хотелось рассказать как скомпилировать шаблонный пример OpenGL идущий со средой CodeBlocks 8.02

Внимание: Прежде чем начать, убедитесь что у вас установлены драйвера на вашу видео карту и работает 3D ускорение. Проверить это можно поставив 3D игрушку в Ubuntu или программой glxgears.

Установите IDE CodeBlocks из репозитория Ubuntu. На момент написания поста использовалась среда CodeBlocks 8.02. Запустите Ubuntu Software Center и в поле поиска введите CodeBlocks, потом установите программу.


Создайте в домашнем каталоге папку Projects и вложенную в нее папку OpenGL, здесь будем хранить наш проект. У меня это (~/Projects/OpenGL), где ~ домашний каталог вашего пользователя.

Запустите среду разработки CodeBlocks и создайте новый проект из меню File → New → Project... В мастере создания нового проекта из шаблона выберите категорию 2D/3D Graphics. Выделите шаблон OpenGL project и нажмите кнопку Go.


Далее вас поприветствует мастер создания нового OpenGL проекта поэтому нажмем кнопку Next, следующим шагом необходимо указать название проекта, например ogl_p1, там же укажите название каталога, где будет создан проект. На последнем шаге нажмите Finish.

Если вы попробовали скомпилировать шаблонный код который нам предложил мастер по завершению свой работы, то у вас, возможно, как и у меня отобразилось сообщение о том, что не найдены заголовочные файлы OpenGL.

Теперь нам необходимо установить заголовочный файлы и библиотеку OpenGL. В Ubuntu OpenGL реализован через проект Mesa. Поэтому установить нам надо пакет libgl1-mesa-dev
Свободная реализация OpenGL API -- GLX файлы разработки. В терминале вводим:

sudo apt-get install libgl1-mesa-dev

Данный пакет должен потянуть кучу других пакетов, у меня это:

libdrm-dev
libgl1-mesa-dev (этот пакет)
libpthread-stubs0
libpthread-stubs0-dev
libx11-dev
libxau-dev
libxdmcp-dev
mesa-cammon-dev
x11proto-core-dev
x11proto-input-dev
x11proto-kb-dev
xtrans-dev

Я не знаю для чего нужны эти пакеты, поэтому примем это как должное и неотъемлемое.

После установки библиотеки OpenGL еще раз пробуем скомпилировать. Но нет, проект не компилируется, выдает сообщение, что не найден компилятор g++.

Пробуем поставить компилятор g++. Следующая команда установит компилятор:

sudo apt-get install g++

Еще раз построим проект, нажмите кнопку Build, потом нажмите Run. У вас должно появится окно похожее на это:



Нажатие левой кнопки мыши вращение куба вокруг координаты X. Нажатие средней кнопки мыши вращение куба вокруг координаты Y. Нажатие правой кнопки мыши вращение куба вокруг координаты Z. Нажмите ESC чтобы завершить программу.

Ниже расположен весь код шаблонного проекта поставляемый со средой CodeBlocks 8.02. 

/* A simple program to show how to set up an X window for OpenGL rendering.
* X86 compilation: gcc -o -L/usr/X11/lib main main.c -lGL -lX11
* X64 compilation: gcc -o -L/usr/X11/lib64 main main.c -lGL -lX11
*/
#include <stdio.h>
#include <stdlib.h>

#include <GL/glx.h> /* this includes the necessary X headers */
#include <GL/gl.h>

#include <X11/X.h> /* X11 constant (e.g. TrueColor) */
#include <X11/keysym.h>

static int snglBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, None};
static int dblBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None};

Display *dpy;
Window win;
GLfloat xAngle = 42.0, yAngle = 82.0, zAngle = 112.0;
GLboolean doubleBuffer = GL_TRUE;

void fatalError(char *message)
{
fprintf(stderr, "main: %s\n", message);
exit(1);
}

void redraw(void)
{
static GLboolean displayListInited = GL_FALSE;

if (displayListInited)
{
/* if display list already exists, just execute it */
glCallList(1);
}
else
{
/* otherwise compile and execute to create the display list */
glNewList(1, GL_COMPILE_AND_EXECUTE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/* front face */
glBegin(GL_QUADS);
glColor3f(0.0, 0.7, 0.1); /* green */
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
glVertex3f(-1.0, -1.0, 1.0);

/* back face */
glColor3f(0.9, 1.0, 0.0); /* yellow */
glVertex3f(-1.0, 1.0, -1.0);
glVertex3f(1.0, 1.0, -1.0);
glVertex3f(1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, -1.0);

/* top side face */
glColor3f(0.2, 0.2, 1.0); /* blue */
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, -1.0);
glVertex3f(-1.0, 1.0, -1.0);

/* bottom side face */
glColor3f(0.7, 0.0, 0.1); /* red */
glVertex3f(-1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, -1.0);
glEnd();
glEndList();
displayListInited = GL_TRUE;
}
if (doubleBuffer)
glXSwapBuffers(dpy, win);/* buffer swap does implicit glFlush */
else
glFlush(); /* explicit flush for single buffered case */
}

int main(int argc, char **argv)
{
XVisualInfo *vi;
Colormap cmap;
XSetWindowAttributes swa;
GLXContext cx;
XEvent event;
GLboolean needRedraw = GL_FALSE, recalcModelView = GL_TRUE;
int dummy;

/*** (1) open a connection to the X server ***/

dpy = XOpenDisplay(NULL);
if (dpy == NULL)
fatalError("could not open display");

/*** (2) make sure OpenGL's GLX extension supported ***/

if(!glXQueryExtension(dpy, &dummy, &dummy))
fatalError("X server has no OpenGL GLX extension");

/*** (3) find an appropriate visual ***/

/* find an OpenGL-capable RGB visual with depth buffer */
vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);
if (vi == NULL)
{
vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf);
if (vi == NULL) fatalError("no RGB visual with depth buffer");
doubleBuffer = GL_FALSE;
}
if(vi->class != TrueColor)
fatalError("TrueColor visual required for this program");

/*** (4) create an OpenGL rendering context ***/

/* create an OpenGL rendering context */
cx = glXCreateContext(dpy, vi, /* no shared dlists */ None,
/* direct rendering if possible */ GL_TRUE);
if (cx == NULL)
fatalError("could not create rendering context");

/*** (5) create an X window with the selected visual ***/

/* create an X colormap since probably not using default visual */
cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
swa.colormap = cmap;
swa.border_pixel = 0;
swa.event_mask = KeyPressMask | ExposureMask
| ButtonPressMask | StructureNotifyMask;
win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0,
300, 300, 0, vi->depth, InputOutput, vi->visual,
CWBorderPixel | CWColormap | CWEventMask, &swa);
XSetStandardProperties(dpy, win, "main", "main", None,
argv, argc, NULL);

/*** (6) bind the rendering context to the window ***/

glXMakeCurrent(dpy, win, cx);

/*** (7) request the X window to be displayed on the screen ***/

XMapWindow(dpy, win);

/*** (8) configure the OpenGL context for rendering ***/

glEnable(GL_DEPTH_TEST); /* enable depth buffering */
glDepthFunc(GL_LESS); /* pedantic, GL_LESS is the default */
glClearDepth(1.0); /* pedantic, 1.0 is the default */

/* frame buffer clears should be to black */
glClearColor(0.0, 0.0, 0.0, 0.0);

/* set up projection transform */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10.0);
/* establish initial viewport */
/* pedantic, full window size is default viewport */
glViewport(0, 0, 300, 300);

printf( "Press left mouse button to rotate around X axis\n" );
printf( "Press middle mouse button to rotate around Y axis\n" );
printf( "Press right mouse button to rotate around Z axis\n" );
printf( "Press ESC to quit the application\n" );

/*** (9) dispatch X events ***/

while (1)
{
do
{
XNextEvent(dpy, &event);
switch (event.type)
{
case KeyPress:
{
KeySym keysym;
XKeyEvent *kevent;
char buffer[1];
/* It is necessary to convert the keycode to a
* keysym before checking if it is an escape */
kevent = (XKeyEvent *) &event;
if ( (XLookupString((XKeyEvent *)&event,buffer,1,&keysym,NULL) == 1)
&& (keysym == (KeySym)XK_Escape) )
exit(0);
break;
}
case ButtonPress:
recalcModelView = GL_TRUE;
switch (event.xbutton.button)
{
case 1: xAngle += 10.0;
break;
case 2: yAngle += 10.0;
break;
case 3: zAngle += 10.0;
break;
}
break;
case ConfigureNotify:
glViewport(0, 0, event.xconfigure.width,
event.xconfigure.height);
/* fall through... */
case Expose:
needRedraw = GL_TRUE;
break;
}
} while(XPending(dpy)); /* loop to compress events */

if (recalcModelView)
{
glMatrixMode(GL_MODELVIEW);

/* reset modelview matrix to the identity matrix */
glLoadIdentity();

/* move the camera back three units */
glTranslatef(0.0, 0.0, -3.0);

/* rotate by X, Y, and Z angles */
glRotatef(xAngle, 0.1, 0.0, 0.0);
glRotatef(yAngle, 0.0, 0.1, 0.0);
glRotatef(zAngle, 0.0, 0.0, 1.0);

recalcModelView = GL_FALSE;
needRedraw = GL_TRUE;
}
if (needRedraw)
{
redraw();
needRedraw = GL_FALSE;
}
}

return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1

Комментариев нет:

Отправить комментарий