Pull to refresh

Программирование на OpenGl(freeglut), рисование примитивов

Reading time 4 min
Views 19K
Приветствую тебя Хабраюзер! Сегодня в своей первой статье расскажу о программирование на OpenGl.

//Замечание: Вы также вместо freeglut'a(открытая альтернатива glut'у) можете использовать glut.

Для начала немного напишу о том что нужно скачать и установить, для того чтобы начать кодить на opengl(freeglut'e).

Для рисования на opengl мы будем использовать библиотеку freeglut(OpenGL Utility Toolkit — так сказать обертка для opengl). Файлы freeglut'a можно найти тут. Там же есть инструкции как это поставить на linux и windows(MSVC и MinGW). На linux freeglut ставится в несколько команд, а в windows в несколько кликов. Если возникнут проблемы с установкой можете написать мне, я распишу подробней как установить freeglut.

Подробнее под катом.

И так в начале давайте познакомимся с начальной инициализацией кода.
Обычно любой проект на freeglut содержит следующий код:
#include <GL/freeglut.h>//собственно нужный нам заголовочный файл
void display()
     {
       /* рисуем что нибудь */
     }           
int main(int argc, char **argv)
{
    glutInit(&argc, argv);//начальная инициализация окна
    glutInitDisplayMode(GLUT_DOUBLE);//установка режима отображения
    glutInitWindowSize(400,400);//размер окна
    glutInitWindowPosition(200, 200);//начальная позиция на экране
    //вы заметили что вначале идут функции с приставкой glutInit...?, так вот они должны быть первыми, а потом уже все остальные ф-ии.
    glutCreateWindow("Window");//заголовок окна
    glClearColor(1, 1, 1, 0);//цвет фона

    // настройка проекции, с этими двумя ф-ми познакомимся поближе чуть позже.
    glMatrixMode(GL_PROJECTION);//режим матрицы
    glLoadIdentity();//отчищает матрицу

    glOrtho(-100, 100, -100, 100, -100, 100);//cоздаем пространство нашей сцены, в данном случае 3D пространство с высотой, шириной и глубиной в 200 едениц.
    glutDisplayFunc(display);//функция которой мы передаем имя функции для отрисовки окна. 
    glutMainLoop();//запускаем всё проинициализированное, проще говоря та же ф-я main, только в данном случае glut'овская ф-я main.
    return 0;
}


Разберем некоторые из вышеперечисленных функции поподробней:
Ф-я glutInitDisplayMode() может принимать разные параметры, но пока мы будем использовать только некоторые из них:

GLUT_RGB — Использование режима RGB(red|green|blue — красный|зеленый|синий — соответственно). Используется по умолчанию.
GLUT_SINGLE — окно с одиночным буфером. Этот режим используется также по умолчанию.
GLUT_DOUBLE — окно с двойным буфером.

Буфер — это область в которой временно хранятся данные.

Возникает вопрос, чем же одиночный буфер отличается от двойного? Двойной буфер работает слудующим образом: Есть два буфера, пока первый буфер отрисовывается на экране, второй буфер подготавливается и отрисовывается после того как отрисуется полностью первый буфер. Потом точно так же, только буферы меняются местами. Т.е. буферы отрисовываются по очереди. Зачем это нужно? Для того чтобы не возникало мерцания на экране. Думаю из выше написанного можно понять что значит одиночный буфер.

Ф-я glOrtho(left, right, bottom, top, zNear, zFar) — задает систему координат
параметр left означает на сколько единиц двинимся влево по оси oX
параметр right означает на сколько единиц двинимся вправо по оси oX
параметр bottom означает на сколько единиц двинимся вниз по оси oY
параметр top означает на сколько единиц двинимся вверх по оси oY
параметр zNear означает на сколько единиц двинимся вглубь по оси oZ
параметр zFar означает на сколько единиц двинимся вперед по оси oZ
Для более легкого понимания накатал рисунок:

Программирование примитивов на opengl:
Давайте приступим непосредственно к кодингу.
Небольшой код, который отрисовывает линию:
#include <GL/freeglut.h>
void display()
     {
       glClear(GL_COLOR_BUFFER_BIT);//очищаем буфер
       glColor3f(1.0f,0.0f,0.0f);//задаем цвет рисования
       glLineWidth(3);//задаем толщину линии
       glBegin(GL_LINES);//говорим что будем рисовать линию
       glVertex2d(-1, 0);//координата начала отрезка в формате (x,y)
       glVertex2d( 1, 0);//координата конца отрезка
       glEnd();//говорим что закончили рисовать линию
       glutSwapBuffers();//прорисовываем буфер на экран
     }                 
int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE);
    glutInitWindowSize(200, 200);
    glutInitWindowPosition(200, 200);
    glutCreateWindow("Window");
    glClearColor(1, 1, 1, 0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-10, 10, -10, 10, 0, 0);
    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}


image

В ф-ии glBegin() задаем то, что хотим начать рисовать, она может принимать такие параметры как:

GL_POINTS — говорит программе о том что будем рисовать точку
GL_LINES — будем рисовать линию
GL_TRIANGLES — будем рисовать треугольник
GL_QUADS — будем рисовать прямоугольник

и другие параметры, с помощью которых можно объединять линии, рисовать группы треугольников, четырехугольников и многоугольники.
Ф-я glEnd() завершает рисование объета(ов)

Теперь давайте с помощью glBegin(GL_POINTS), glBegin(GL_LINES), glBegin(GL_TRIANGLES), glBegin(GL_QUADS) отрисуем точку, линию, треугольник и прямоугольник.

#include <GL/freeglut.h>
void display()
     {
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
       
       glPointSize(6);
       glColor3f(0.0f,0.0f,0.0f);
       glBegin(GL_POINTS);//рисуем черную точку
       glVertex2f(-0.5f, 0.2f);
       glEnd();
       
       glLineWidth(3);
       glColor3f(1.0f,0.0f,0.0f);
       glBegin(GL_LINES);//рисуем красную линию
       glVertex2d(-1,  1);
       glVertex2d( 1, -1);
       glEnd();

       glColor3f(0.0f, 1.0f,0.0f);
       glBegin(GL_TRIANGLES);//рисуем зеленый треугольник
       glVertex2d(0,   0);
       glVertex2f(0.5, 1);
       glVertex2d(1,   0);
       glEnd();
       
       glColor3f(0.0f, 0.0f, 1.0f);//рисуем синий треугольник
       glBegin(GL_QUADS);
       glVertex2d(-1, -1);
       glVertex2d(-1,  0);
       glVertex2d( 0,  0);
       glVertex2d( 0, -1);
       glEnd();
       
       glutSwapBuffers();//прорисовываем буфер на экран
     }               
int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE);
    glutInitWindowSize(200, 200);
    glutInitWindowPosition(200, 200);
    glutCreateWindow("Window");
    glClearColor(1, 1, 1, 0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-1, 1, -1, 1, 0, 0);
    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}


image

На этом думаю пора закончить, остальное опишу в следующих статьях. Если у вас есть, какие либо замечания, вопросы, пишите мне в личку или в комментариях. Если вы нашли какую то ошибку в описании или в коде прошу сообщить мне.
Tags:
Hubs:
-1
Comments 8
Comments Comments 8

Articles