Для начала сделаем несколько определений . Рендеринг - это процесс ,
с помощью которых компьютер создает образы обьектов .
Обьекты состоят из геометрических примитивов - точек , линий ,
полигонов , которые определяются с помощью вершин .
Пиксел - элементарный наименьший видимый элемент дисплея .
Информация о пикселах хранится в памяти в форме bitplane - областей ,
где на каждый пиксел отводится по 1 биту .
Bitplanes организованы в framebuffer .
Рассмотрим простой пример - как нарисовать белый прямоугольник
на черном фоне :
main() {
glClearColor (0.0, 0.0, 0.0, 0.0);
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
glBegin(GL_POLYGON);
glVertex3f (0.25, 0.25, 0.0);
glVertex3f (0.75, 0.25, 0.0);
glVertex3f (0.75, 0.75, 0.0);
glVertex3f (0.25, 0.75, 0.0);
glEnd();
glFlush();
}
glClearColor() устанавливает черный цвет фона , glClear() очищает фон .
В дальнейшем , всякий раз , когда glClear () будет вызываться ,
она будет очищать окно в черный цвет .
glColor3f() устанавливает цвет прорисовки - белый цвет .
glOrtho() определяет координатную систему .
glBegin() и glEnd() определяют обьект , который будет прорисован .
glVertex3f() определяет вершины полигона , в качестве параметров - 3 координаты x,y,z .
glFlush() гарантирует нам , что прорисовка полигона будет выполнена немедленно .
Все команды OpenGL начинаются с префикса gl , все константы также
начинаются с префикса GL_ .
Например , в команде glColor3f() цифра 3 говорит о том , что координат 3 ,
а префикс 'f' говорит о том , что аргумент имеет тип floating-point .
Вообще , в OpenGL имеется 8 сновных типов Data Type :
1. 8-bit integer
2. 16-bit integer
3. 32-bit integer
4. 32-bit floating-point
5. 64-bit floating-point
6. 8-bit unsigned integer
7. 16-bit unsigned integer
8. 32-bit unsigned integer
Так , 2 команды glVertex2i(1, 3) и glVertex2f(1.0, 3.0) фактически эквивалентны ,
хоть и имеют различные типы .
Некоторые команды имееют последним символом 'v' , что указывает на вектор .
Например :
glColor3f(1.0, 0.0, 0.0);
GLfloat color_array[] = {1.0, 0.0, 0.0};
glColor3fv(color_array);
Здесь определяем массив и даем векторный указатель на него .
Доступ к этому массиву определяется с помощью часто употребляемой команды GLvoid() .
Как только мы установили цвет с помощью glColor3f() , все последующие обьекты
будут выводиться именно установленным цветом , пока мы его не поменяем вновь .
К числу базовых понятий относятся current viewing , projection transformations,
line , polygon stipple patterns, polygon drawing modes,
pixel-packing conventions, positions и characteristics lights, material properties .
Доступ к переменным можно осуществить с помощью glEnable() или glDisable().
Функции glGetBooleanv(), glGetDoublev(), glGetFloatv(), glGetIntegerv(), glGetPointerv(),
glIsEnabled() - устанавливают тип данных .
glPushAttrib() и glPushClientAttrib() пишут в стек , glPopAttrib() и glPopClientAttrib()
восстанавливают .
OpenGL очень четко организован в смысле очередности выполнения операций .
GLUT
Как правило , все OpenGL-исходники имеют в заголовке 2 хидера :
#include
#include
При использовании GLUT также указывается
. В библиотеку GLUT встроен интерфейс взаимодействия с операционной
системой на уровне API . GLUT рекомендован на начальном этапе изучения OpenGL .
Window Management :
· glutInit(int *argc, char **argv) - самая первая команда инициализации
· glutInitDisplayMode(unsigned int mode) - устанавливает цветовую модель
- RGBA или color-index .
Например , glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH) -
устанавливает двойной буфер , цветовую модель RGB .
· glutInitWindowPosition(int x, int y) - установим начало координат окна
· glutInitWindowSize(int width, int size) - размер окна
· int glutCreateWindow(char *string) - создает окно
- glutDisplayFunc() - вызывается всякий раз при перерисовке окна .
- glutMainLoop(void) - эта функция вызывается после всех остальных .
Небольшой пример :
#include < GL/gl.h >
#include < GL/glut.h >
void display(void)
{
/* стираем */
glClear (GL_COLOR_BUFFER_BIT);
/* рисуем белый прямоугольник
* (0.25, 0.25, 0.0) and (0.75, 0.75, 0.0)
*/
glColor3f (1.0, 1.0, 1.0);
glBegin(GL_POLYGON);
glVertex3f (0.25, 0.25, 0.0);
glVertex3f (0.75, 0.25, 0.0);
glVertex3f (0.75, 0.75, 0.0);
glVertex3f (0.25, 0.75, 0.0);
glEnd();
/* поехали ! */
glFlush ();
}
void init (void)
{
/* установим черный фон */
glClearColor (0.0, 0.0, 0.0, 0.0);
/* инициализация viewing values */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
/*
Определим параметры окна , display mode
* (single buffer and RGBA). Откроем окно с фразой "hello"
* в title bar.
*/
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (250, 250);
glutInitWindowPosition (100, 100);
glutCreateWindow ("hello");
init ();
glutDisplayFunc(display);
glutMainLoop();
return 0; /* ISO C requires main to return int. */
}
В GLUT встроена прорисовка 3-мерных обьектов :
cone icosahedron teapot
Cube octahedron tetrahedron
Dodecahedron sphere torus
Следующий пример показывает работу команды glutSwapBuffers() , делающий
свопинг буффера .
Имеется 2 буффера , и пока на экран не выводится полностью один из них ,
второй остается полностью за кадром , и не произойдет наложения одного на
другой .
Double-Buffered Program: double.c
#include < GL/gl.h >
#include < GL/glu.h >
#include < GL/glut.h >
#include < stdlib.h >
static GLfloat spin = 0.0;
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotatef(spin, 0.0, 0.0, 1.0);
glColor3f(1.0, 1.0, 1.0);
glRectf(-25.0, -25.0, 25.0, 25.0);
glPopMatrix();
glutSwapBuffers();
}
void spinDisplay(void)
{
spin = spin + 2.0;
if (spin > 360.0)
spin = spin - 360.0;
glutPostRedisplay();
}
void reshape(int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void mouse(int button, int state, int x, int y)
{
switch (button) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(spinDisplay);
break;
case GLUT_MIDDLE_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(NULL);
break;
default:
break;
}
}
/*
* double buffer display mode.
* Register mouse input callback functions
*/
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (250, 250);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}
|