Перейти к содержимому


Свернуть чат Чат Открыть чат во всплывающем окне

Yakim (Watco... : (14 Июль 2018 - 00:06) :D
Yakim (Watco... : (14 Июль 2018 - 00:06) nope
Yandersen : (13 Июль 2018 - 22:07) Айаяй. Поди Якимко заспамил чат стикерами. :)
Yandersen : (13 Июль 2018 - 22:06) Да лан, тут каждый день кто-нить из админов заглядывает. Как пропустили?
Nextovoy : (13 Июль 2018 - 01:04) Я писал
Гость : (10 Июль 2018 - 22:42) Сорьки, что так у нас. Чего три года так и не попытался в чат писнуть? :)
Nextovoy : (06 Июль 2018 - 16:15) Спасибо
lz : (04 Июль 2018 - 19:44) Активировал.
Гость : (03 Июль 2018 - 16:30) Активируйте его.
Гость : (03 Июль 2018 - 16:30) Мой профиль - Nextovoy
Гость : (03 Июль 2018 - 16:25) Написать в чат. Профиль в ручную админы активируют.
Гость : (03 Июль 2018 - 15:47) Ох уж эта дурацкая привычка писать всё раздельно засоряя чат. Это всё классно, конечно, но ребята, одменестраторы, так называемые. Третий год пытаюсь зарегистрироваться (буквально, третий) на этом форуме, но ПИСЬМО С ПОДТВЕРЖДЕНИЕМ НА ПОЧТУ ТАК И НЕ ПРИХОДИТ. Что делать?
Гость : (03 Июль 2018 - 15:46) Перешёл я всё же по ссылке Redoctor'a...
Гость : (03 Июль 2018 - 15:41) Пора уже M4
Гость : (29 Июнь 2018 - 00:18) итак м3
lz : (28 Июнь 2018 - 16:01) Мы тебе и тут передадим.
Гость : (28 Июнь 2018 - 13:13) Зачем в телеграмме делать?!Я вот например не могу зайти,написать в чат,подписаться и не только у меня это.
Redoctor : (24 Июнь 2018 - 19:35) https://vk.com/away....0_23001&cc_key=
Redoctor : (24 Июнь 2018 - 19:34) Тогда в телеграмме в поисковике набери Механоиды 3
Гость : (24 Июнь 2018 - 19:05) Не открывается.
Redoctor : (24 Июнь 2018 - 18:00) https://t.me/mechanoids3 Для тех кто в танке.
Yakim (Watco... : (15 Июнь 2018 - 01:33) КРУЗИИИС!!!11

Изображение
lz : (15 Июнь 2018 - 00:09) КРУЗИС!
lz : (15 Июнь 2018 - 00:09) ЗИС
lz : (15 Июнь 2018 - 00:09) КРУ
Yakim (Watco... : (14 Июнь 2018 - 14:50) Крузис и Королева тоже не в моем вкусе, а проигрывать нечего =D
lz : (14 Июнь 2018 - 13:55) Конечно, полюбить - так королеву, проиграть - так миллион, сделать - так крузис.
smt005 : (14 Июнь 2018 - 00:22) И от третьего лица тоже можно сделать простенькую игру. Простая игра это лучше чем ничего.
smt005 : (14 Июнь 2018 - 00:21) А, ты хочеш что-бы хит был, с "Crysis" графоном и контентом на 100500 часов игры?
Yakim (Watco... : (14 Июнь 2018 - 00:18) Ни топдовншутеры, ни стратежки)
Yakim (Watco... : (14 Июнь 2018 - 00:15) Не, спасибо, не в моем вкусе=)
smt005 : (13 Июнь 2018 - 23:13) Помнится за пару недель от скуки сделал. Делал по вечерам.
smt005 : (13 Июнь 2018 - 23:13)
smt005 : (13 Июнь 2018 - 23:11) Или например такое, только с моделями из игры -> https://youtu.be/RFDdN5dcX8s
smt005 : (13 Июнь 2018 - 23:07) Yakim, да сами себя пните... :) Сделайте что-то, хотя бы уровня "Scrolling TopDown Shooter".
Yakim (Watco... : (12 Июнь 2018 - 22:17) так что, думаю завтра с утреца стартану марафон)
Yakim (Watco... : (12 Июнь 2018 - 22:15) хе-хе, не сомневайся, я в чате по уе уже поинтересовался, сказали обалденный сериал)))
Yandersen : (12 Июнь 2018 - 20:56) Оооооо, поди ща залипнет на пару дней, стопудофф. :)
Yakim (Watco... : (12 Июнь 2018 - 18:28) Окей гляну)
Yandersen : (12 Июнь 2018 - 16:23) Сериал Пространство посмотри. Не по части Мехов, просто шикарен, авось ману доставит.
Yakim (Watco... : (11 Июнь 2018 - 18:50) Дуст и ты уже закаленные и пустые, надож где-то ману доставать)))
Yakim (Watco... : (11 Июнь 2018 - 18:49) Думаю, кого быть пнуть, что-бы тот пнул в ответ да по сильнее.
Yakim (Watco... : (11 Июнь 2018 - 18:48) Давненько и не маленько хе-хе, делать нечего, прокрастинирую =)
Yandersen : (11 Июнь 2018 - 17:46) Якимка, ты там шо, упоролсо маленько? Чиво картинами опспамилсо?
Yakim (Watco... : (09 Июнь 2018 - 22:27) Изображение

Фотография
- - - - -

[Camera.hpp] - камера с реалистичными свойствами

OpenGL Camera FBO Deferred shading

  • Авторизуйтесь для ответа в теме
В этой теме нет ответов

#1 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 21 Апрель 2015 - 02:18

Класс камеры CCamera, реализующий перспективную проекцию с реалистичными свойствами (нет дальней плоскости отсечения, сверхмалая ближняя плоскость отсечения):

 

Camera.hpp

 

:!: Требует LoadGL.h, GLSL.hpp, Origin.hpp, FBO.hpp. Плюс необходима поддержка OpenGL4.5 (DSA, ARB_clip_control).

 

Кидаем файл в проект, подключаем:

#include "Camera.hpp"

Изменяем настройку glClipControl:

glClipControl(<...>, GL_ZERO_TO_ONE);

:!: С дефолтной настройкой (GL_NEGATIVE_ONE_TO_ONE) камера не будет работать корректно!

 

Каждая камера класса CCamera имеет свой собственный FBO и использует floating-point depth buffer (буффер глубины). Буффера трафарета (stencil buffer) нет. Цветовых буфферов может быть до 8. В качестве буфферов используются текстуры (создаются и удаляются классом CCamera):

GLuint CCamera::AddDepthBuffer(int Width, int Height, bool WithMipmaps = true);
GLuint CCamera::AddColorBuffer(unsigned ID, GLenum internalFormat,
                               int Width, int Height, bool WithMipmaps = true);

Width и Height - размеры требуемого буффера, флаг WithMipmaps определяет, будут ли у текстуры мипмапы (если false, то мипмапов не будет). В случае создания буффера цвета нужно указать индекс ID создаваемого буффера (0...7) и формат пикселя текстуры (значения internalFormat см. тут). Возвращённое значение - имя созданной текстуры или 0 если создать текстуру не удалось.

:!: Свойства текстуры позволяется менять (glTexPartameter), но изменять размеры или удалять - нельзя. Для удаления требуемого буффера используйте 0 в качестве аргумента Width или Height.

 

Для изменения размеров сразу всех буфферов используйте

bool CCamera::ResizeBuffers(int Width, int Height);

:!: Все свойства каждого из буфферов будут воссозданы, но имена текстур могут измениться.

Чтобы узнать имя текстуры конкретного буффера используйте

inline GLuint GetColorBufferTextureName(unsigned ID)const;
inline GLuint GetDepthBufferTextureName()const;

Эффективные размеры фреймбуффера равны минимуму размеров всех его буфферов. Узнать можно так:

inline ivec2 GetFrameSize()const;

Геометрические свойства камеры показаны на следующей схеме:

 

Camera.png

 

Используемая матрица перспективной проекции имеет следующий вид:

     | 2*zNear                      |
     | -------    0      0      0   |
     |  xSize                       |
     |         2*zNear              |
     |    0    -------   0      0   |
     |          ySize               |
 P = |                              |
     |    0       0      0    zNear |
     |                              |
     |                              |
     |    0       0     -1      0   |
     |                              |

Перспектива задаётся следующей функцией:

inline bool CCamera::SetupPerspective(float FOVy, float NearClippingPlane);

FOVy - угол обзора (по вертикали). NearClippingPlane - это расстояние до ближней плоскости отсечения (zNear на рисунке). FOVy должен быть больше 0 и меньше 180 градусов, а NearClippingPlane (zNear) - больше нуля. Геометрические размеры проекционной плоскости (xSize, ySize) будут вычислены автоматически и их отношение будет соответствовать отношению ширины и высоты фреймбуффера.

:!: При изменении размеров фреймбуффера размеры проекционной плоскости и zNear могут измениться, однако угол обзора по вертикали останется тем же.

 

Угол обзора можно менять так:

inline void CCamera::ChangeFOV(float FOVy);

Изменение угла обзора будет достигнуто за счёт приближения/удаления проекционной плоскости (изменение zNear); размеры проекционной плоскости (xSize, ySize) при этом останутся неизменными.

Узнать размеры проекционной плоскости можно так:

inline vec2 CCamera::GetPlaneSize()const;

Изменить размеры проекционной плоскости можно функцией SetPlaneSize, принимающей в качестве параметра желаемый размер проекционной плоскости - её текущие размеры будут отмасштабированы таким образом, что наибольшее из измерений станет равно заданной величине:

CCamera MyCamera;
... //Setup buffers, configure perspective
vec2 Dims = MyCamera.GetPlaneSize(); //Assume that Dims.x==640.f, Dims.y==480.f

float SquareApertureWidth = 0.01f; //Aperture has square shape, 1cm in width
MyCamera.SetPlaneSize(SquareApertureWidth);
Dims = MyCamera.GetPlaneSize(); //Dims.x==0.01f, Dims.y==0.0075f

:!: zNear при этом изменится, а угол обзора останется прежним.

 

Расстояние до проекционной плоскости (ближняя плоскость отсечения, zNear) читается так:

inline float CCamera::GetNearClippingPlane()const;

Угол обзора по диагонали всегда больше угла обзора по вертикали. Узнать его можно так:

float CCamera::GetViewAngleMax()const;

:!: Половина этого значения - это угол между высотой и образующей конуса видимости, в который вписана усечённая пирамида видимого камерой объёма.

 

Класс CCamera содержит указатель на объект класса COriginf (система координат). Ориентация камеры в пространстве привязана к ориентации системы координат Origin. Если указателя нет, то используется ориентация по-умолчанию: Ox={1,0,0}, Oy={0,1,0},Oz={0,0,1}, Center={0,0,0}.

Направление взгляда - это ось -Oz, направление направо - ось Ox, вверх - Oy. Узнать направление взгляда можно так:

inline vec3 CCamera::GetViewDirection()const;

Узнать координаты вектора, соответствующего направлению от центра координат до пикселя фреймбуффера с указанными координатами можно так:

inline vec3 CCamera::PixelToRay(const ivec2& PixelCoordinates)const;

:!: Учтите, что перед вычислением этого направления указанные координаты пикселя будут ограничены нулём, шириной и высотой фреймбуффера.

 

CCamera умеет работать с тремя матрицами:

mat4 ModelViewMatrix: трансформация из мировой системы координат в систему координат камеры (поворот, смещение);

mat4 ProjectionMatrix: из системы координат камеры в проеционное пространство (проекция);

mat4 TransformationMatrix: из мировой системы координат в проекционное пространство (поворот, смещение, проекция).

А также соответствующими им обратными матрицами ModelViewMatrixInverse, ProjectionMatrixInverse, TransformationMatrixInverse.

Конструируют эти матрицы следующие функции класса:

//Return ModelView matrix
inline mat4 CCamera::GetModelViewMatrix()const;
//Return Inverse of the ModelView matrix
inline mat4 CCamera::GetModelViewMatrixInverse()const;
//Return the Projection matrix
mat4 CCamera::GetProjectionMatrix()const;
//Return inverse of the Projection matrix
mat4 CCamera::GetProjectionMatrixInverse()const;
//Return the full transformation matrix
inline mat4 CCamera::GetTranformationMatrix()const;
//Return inverse of the full transformation matrix
inline mat4 CCamera::GetTranformationMatrixInverse()const;

Перенаправляем рендер во фреймбуффер требуемой камеры так:

inline void CCamera::StartCapturing()const;

Очистка буфферов:

//Clear one of the color buffers (it's index is specified as BufferID); color
//must be specified as vec4, ivec4 or uvec4
template<class T>
inline void CCamera::ClearColorBuffer(unsigned int ID, const T& tvecRGBA);
//Clear all of the color buffers simultaneously with the same value
inline void CCamera::ClearColorBuffers(const vec4& vecRGBA){ FBO.ClearColor(vecRGBA); }
//Clear the depth buffer
inline void CCamera::ClearDepthBuffer(GLfloat Value=0.f){ FBO.ClearDepth(Value); }
//Clear all of the color buffers and the depth buffer
inline void CCamera::ClearBuffers(const vec4& ColorRGBA, float Depth=0.f);

По оканчании рендера скопировать картинку на экран можно с помощью этой функции:

inline void CCamera::ShowFrame(unsigned ColorBufferID=0,
                               GLint ScreenWidth=0, GLint ScreenHeight=0)const;

Тут ColorBufferID - индекс буффера цвета, в котором находится желаемое изображение. ScreenWidth, ScreenHeight - размеры экрана: если указаны (отличны от нуля), то картинка будет растянута/сжата под размер экрана; если же размер экрана не указан, то копирование пойдёт пиксель-в-пиксель, и если размеры фреймбуффера камеры и экрана не равны, картинка либо обрежется, либо не замостит весь экран.







Темы с аналогичным тегами OpenGL, Camera, FBO, Deferred shading

Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных