Форум программистов, компьютерный форум, киберфорум
Наши страницы

Пишу игровой движок на C++. 026. Матрицы, камера.

Войти
Регистрация
Восстановить пароль
Сайт движка - gost.imsoftworks.info
Исходные коды движка - https://github.com/532235/GoST
Документация
Примеры кода программ - https://github.com/532235/GoST/wiki

Другой хобби-проект в группе в вк https://vk.com/club154291467
Оценить эту запись

Пишу игровой движок на C++. 026. Матрицы, камера.

Запись от 532235 размещена 31.12.2017 в 12:49

Нужно сделать так, чтобы при рисовании объекта, вызывалась callback функция, в которой будут устаналиваться параметры для шейдера.
Это наконец позволит нормально создавать свои собственные шейдеры.

Для шейдера нужны минимум 3 матрицы (чтобы 3д объекты отображались корректно)

World matrix - мировая, это позиция конкретного объекта, его масштаб и ориентация.

View matrix - видовая матрица активной камеры
Projection matrix - проекционная матрица активной камеры

Сперва, нужно знать какая камера активна. Обновить её позицию, и построить эти 2 матрицы.

Конкретный алгоритм действий.
Сначала нужно обновить все объекты сцены.
Потом нужно отреднерить активную камеру (она будет строить видовую и проекционную матрицы).
Эти матрицы сохраняются (либо сохраняются указатели на них).
Потом идёт черёд объектов сцены.
Каждый объект хранит матрицу трансформации(позиция ориентация масштаб).
Перед рисованием, эта матрица либо копируется полностью либо копируется указатель, и передаётся в коллбэк-метод.
Модель состоит из суб моделей. Циклом рендерятся суб модели.
В нужный момент вызывается коллбэк-метод, в него передаётся дополнительная информация (материал объекта и т.д.).
В коллбэк функции берутся ранее созданные матрицы.
Далее идут необходимые вычисления и передача матриц в шейдер и т.д.

-----------------------------------
Матрицы.
В принципе матрица это всё что угодно, но в 3Д графике в основном используются
2Д массивы размером 3на3 и 4на4

Буду использовать рамер 4на4

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
#pragma once
#ifndef __GT_MATRIX_H__
#define __GT_MATRIX_H__
 
/*
*/
 
namespace gost{
    
    class gtMatrix4{
 
        v4f m_data[ 4u ];
 
    public:
 
        gtMatrix4( void ){
            identity();
        }
 
        gtMatrix4( const gtMatrix4& m ){
            *this = m;
        }
 
        gtMatrix4( f32 v ){
            fill( v );
        }
 
        gtMatrix4( const v4f& x, const v4f& y, const v4f& z, const v4f& w ){
            m_data[ 0 ] = x;
            m_data[ 1 ] = y;
            m_data[ 2 ] = z;
            m_data[ 3 ] = w;
        }
 
        void        fill( f32 v ){
            m_data[ 0u ].fill( v );
            m_data[ 1u ].fill( v );
            m_data[ 2u ].fill( v );
            m_data[ 3u ].fill( v );
        }
 
        void        zero( void ){
            fill( 0.f );
        }
 
            //  main diagonal - главная диагональ = 1
        void        identity( void ){
            auto * p = this->getPtr();
            p[ 0u ] = 1.f;
            p[ 1u ] = 0.f;
            p[ 2u ] = 0.f;
            p[ 3u ] = 0.f;
 
            p[ 4u ] = 0.f;
            p[ 5u ] = 1.f;
            p[ 6u ] = 0.f;
            p[ 7u ] = 0.f;
 
            p[ 8u ] = 0.f;
            p[ 9u ] = 0.f;
            p[ 10u ] = 1.f;
            p[ 11u ] = 0.f;
 
            p[ 12u ] = 0.f;
            p[ 13u ] = 0.f;
            p[ 14u ] = 0.f;
            p[ 15u ] = 1.f;
 
        }
 
        f32 *       getPtr( void ){
            return reinterpret_cast<f32*>(&m_data);
        }
 
        v4f& operator[]( u32 i ){
            return m_data[ i ];
        }
 
        const v4f& operator[]( u32 i ) const {
            return m_data[ i ];
        }
 
        gtMatrix4 operator+( const gtMatrix4& m ) const {
            gtMatrix4 out = *this;
 
            out[ 0u ] += m[ 0u ];
            out[ 1u ] += m[ 1u ];
            out[ 2u ] += m[ 2u ];
            out[ 3u ] += m[ 3u ];
 
            return out;
        }
 
        gtMatrix4 operator-( const gtMatrix4& m ) const {
            gtMatrix4 out = *this;
 
            out[ 0u ] -= m[ 0u ];
            out[ 1u ] -= m[ 1u ];
            out[ 2u ] -= m[ 2u ];
            out[ 3u ] -= m[ 3u ];
 
            return out;
        }
 
        gtMatrix4 operator*( const gtMatrix4& m ) const {
            return gtMatrix4(
                m_data[ 0 ] * m[0][0] + m_data[ 1 ] * m[0][1] + m_data[ 2 ] * m[0][2] + m_data[ 3 ] * m[0][3],
                m_data[ 0 ] * m[1][0] + m_data[ 1 ] * m[1][1] + m_data[ 2 ] * m[1][2] + m_data[ 3 ] * m[1][3],
                m_data[ 0 ] * m[2][0] + m_data[ 1 ] * m[2][1] + m_data[ 2 ] * m[2][2] + m_data[ 3 ] * m[2][3],
                m_data[ 0 ] * m[3][0] + m_data[ 1 ] * m[3][1] + m_data[ 2 ] * m[3][2] + m_data[ 3 ] * m[3][3]
            );
        }
 
        gtMatrix4 operator/( const gtMatrix4& m ) const {
            gtMatrix4 out = *this;
 
            out[ 0u ] /= m[ 0u ];
            out[ 1u ] /= m[ 1u ];
            out[ 2u ] /= m[ 2u ];
            out[ 3u ] /= m[ 3u ];
 
            return out;
        }
 
        gtMatrix4& operator+=( const gtMatrix4& m ){
            m_data[ 0u ] += m[ 0u ];
            m_data[ 1u ] += m[ 1u ];
            m_data[ 2u ] += m[ 2u ];
            m_data[ 3u ] += m[ 3u ];
            return *this;
        }
 
        gtMatrix4& operator-=( const gtMatrix4& m ){
            m_data[ 0u ] -= m[ 0u ];
            m_data[ 1u ] -= m[ 1u ];
            m_data[ 2u ] -= m[ 2u ];
            m_data[ 3u ] -= m[ 3u ];
            return *this;
        }
 
        gtMatrix4& operator*=( const gtMatrix4& m ){
            m_data[ 0u ] *= m[ 0u ];
            m_data[ 1u ] *= m[ 1u ];
            m_data[ 2u ] *= m[ 2u ];
            m_data[ 3u ] *= m[ 3u ];
            return *this;
        }
 
        gtMatrix4& operator/=( const gtMatrix4& m ){
            m_data[ 0u ] /= m[ 0u ];
            m_data[ 1u ] /= m[ 1u ];
            m_data[ 2u ] /= m[ 2u ];
            m_data[ 3u ] /= m[ 3u ];
            return *this;
        }
 
        GT_FORCE_INLINE void transpose( void ){
            gtMatrix4 tmp;
            tmp[ 0 ][ 0 ] = this->m_data[ 0 ][ 0 ]; //0
            tmp[ 0 ][ 1 ] = this->m_data[ 1 ][ 0 ]; //1
            tmp[ 0 ][ 2 ] = this->m_data[ 2 ][ 0 ]; //2
            tmp[ 0 ][ 3 ] = this->m_data[ 3 ][ 0 ]; //3
 
            tmp[ 1 ][ 0 ] = this->m_data[ 0 ][ 1 ]; //4
            tmp[ 1 ][ 1 ] = this->m_data[ 1 ][ 1 ]; //5
            tmp[ 1 ][ 2 ] = this->m_data[ 2 ][ 1 ]; //6
            tmp[ 1 ][ 3 ] = this->m_data[ 3 ][ 1 ]; //7
 
            tmp[ 2 ][ 0 ] = this->m_data[ 0 ][ 2 ]; //8
            tmp[ 2 ][ 1 ] = this->m_data[ 1 ][ 2 ]; //9
            tmp[ 2 ][ 2 ] = this->m_data[ 2 ][ 2 ]; //10
            tmp[ 2 ][ 3 ] = this->m_data[ 3 ][ 2 ]; //11
 
            tmp[ 3 ][ 0 ] = this->m_data[ 0 ][ 3 ]; //12
            tmp[ 3 ][ 1 ] = this->m_data[ 1 ][ 3 ]; //13
            tmp[ 3 ][ 2 ] = this->m_data[ 2 ][ 3 ]; //14
            tmp[ 3 ][ 3 ] = this->m_data[ 3 ][ 3 ]; //15
            this->m_data[ 0 ] = tmp[ 0 ];
            this->m_data[ 1 ] = tmp[ 1 ];
            this->m_data[ 2 ] = tmp[ 2 ];
            this->m_data[ 3 ] = tmp[ 3 ];
        }
    };
 
    namespace math{
 
        GT_FORCE_INLINE void  makePerspectiveLHMatrix( gtMatrix4& in_out, const f32& FOV, const f32& aspect,
            const f32& Near, const f32& Far){
            f32 S   =   std::sin( 0.5f * FOV );
            f32 C   =   std::cos( 0.5f * FOV );
            f32 H = C / S;
            f32 W = H / aspect;
            in_out[0] = v4f(IL_BEGIN W, 0.f, 0.f, 0.f IL_END);
            in_out[1] = v4f(IL_BEGIN 0.f, H, 0.f, 0.f IL_END);
            in_out[2] = v4f(IL_BEGIN 0.f, 0.f, Far / (Near - Far), 1.f IL_END);
            in_out[3] = v4f(IL_BEGIN 0.f, 0.f, -in_out[2][2] * Near, 0.f IL_END);
        }
 
        GT_FORCE_INLINE void  makePerspectiveRHMatrix( gtMatrix4& in_out, const f32& FOV, const f32& aspect,
            const f32& Near, const f32& Far){
            f32 S   =   std::sin( 0.5f * FOV );
            f32 C   =   std::cos( 0.5f * FOV );
            f32 H = C / S;
            f32 W = H / aspect;
            in_out[0] = v4f(IL_BEGIN W, 0.f, 0.f, 0.f IL_END);
            in_out[1] = v4f(IL_BEGIN 0.f, H, 0.f, 0.f IL_END);
            in_out[2] = v4f(IL_BEGIN 0.f, 0.f, Far / (Near - Far), -1.f IL_END);
            in_out[3] = v4f(IL_BEGIN 0.f, 0.f, in_out[2][2] * Near, 0.f IL_END);
        }
 
        GT_FORCE_INLINE void  makeLookAtRHMatrix( gtMatrix4& in_out, const v3f& eye, const v3f& center, const v3f& up ){
            v3f f( center - eye );
            f.normalize();
            
            v3f s( math::cross( f, up ) );
            s.normalize();
 
            v3f u( math::cross( s, f ) );
 
            in_out.identity();
 
            in_out[0][0] = s.x_;
            in_out[1][0] = s.y_;
            in_out[2][0] = s.z_;
            in_out[0][1] = u.x_;
            in_out[1][1] = u.y_;
            in_out[2][1] = u.z_;
            in_out[0][2] =-f.x_;
            in_out[1][2] =-f.y_;
            in_out[2][2] =-f.z_;
            in_out[3][0] =-math::dot( s, eye );
            in_out[3][1] =-math::dot( u, eye );
            in_out[3][2] = math::dot( f, eye );
        }
 
        GT_FORCE_INLINE void  makeLookAtLHMatrix( gtMatrix4& in_out, const v3f& eye, const v3f& center,const v3f& up){
            v3f f( center - eye );
            f.normalize();
            
            v3f s( math::cross( up, f ) );
            s.normalize();
 
            v3f u( math::cross( f, s ) );
 
            in_out.identity();
 
            in_out[0][0] = s.x_;
            in_out[1][0] = s.y_;
            in_out[2][0] = s.z_;
            in_out[0][1] = u.x_;
            in_out[1][1] = u.y_;
            in_out[2][1] = u.z_;
            in_out[0][2] = f.x_;
            in_out[1][2] = f.y_;
            in_out[2][2] = f.z_;
            in_out[3][0] =-math::dot( s, eye );
            in_out[3][1] =-math::dot( u, eye );
            in_out[3][2] =-math::dot( f, eye );
        }
 
            //  нужно чтобы у матрицы была главная диагональ = 1
        GT_FORCE_INLINE void makeTranslationMatrix( gtMatrix4& in_out, const v3f& position ){
            in_out[ 3 ][ 0 ] = position.x_;
            in_out[ 3 ][ 1 ] = position.y_;
            in_out[ 3 ][ 2 ] = position.z_;
        }
 
    }//end math::
 
}//end gost::
 
#endif
Так же добавил новый namespace - math
В нём будут находится всякие вычисления.
Вычисления связанные с матрицей будут находится в том же файле что и матрица, ниже.
Вычисления связанные с вектором будут находится в файле с вектором.
Для прочих вычислений будет новый файл gtMath.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#pragma once
#ifndef __GT_MATH_H__
#define __GT_MATH_H__
 
/*Doom 3*/
enum{
    LOOKUP_BITS             = 8,                            
    EXP_POS                 = 23,                           
    EXP_BIAS                = 127,                          
    LOOKUP_POS              = (EXP_POS-LOOKUP_BITS),
    SEED_POS                = (EXP_POS-8),
    SQRT_TABLE_SIZE         = (2<<LOOKUP_BITS),
    LOOKUP_MASK             = (SQRT_TABLE_SIZE-1)
};
 
/*здесь заранее вычесленные значения для invSqrt*/
#include "iSqrt_table.hpp" 
 
/*
    //  по большей части код взят у Doom 3
*/
 
namespace gost{
 
    namespace math{
 
        /*Doom 3*/
        union _flint{
            s32 i;
            f32 f;
        };
 
            /* Быстрый обратный корень. Doom 3 */
        GT_FORCE_INLINE f32 invSqrt( f32 x ){
            s32 a = ((union _flint*)(&x))->i;
            union _flint seed;
            f64 y = x * 0.5f;
            seed.i = (( ( (3*EXP_BIAS-1) - ( (a >> EXP_POS) & 0xFF) ) >> 1)<<EXP_POS) | iSqrt[(a >> (EXP_POS-LOOKUP_BITS)) & LOOKUP_MASK];
            f64 r = seed.f;
            r = r * ( 1.5f - r * r * y );
            r = r * ( 1.5f - r * r * y );
            return (f32) r;
        }
    }
 
}
 
#endif
-----------------------------------
Создам класс камеры.

Каждый игровой объект должен наследоваться от одного базового класса. Каждый объект может иметь одинаковые методы, например, установку позиции, обновление матриц и т.д.
Разные объекты можно прикрепить друг к другу, указав родителя/потомка.
Например камеру прикрепить к корпусу автомобиля.

Пусть будет общий класс gtGameObject - типа как в Unity.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#pragma once
#ifndef __GT_GAME_OBJECT_H__
#define __GT_GAME_OBJECT_H__
 
/*
*/
 
namespace gost{
 
        //  тип объекта
    enum class gtObjectType{
        camera
    };
 
    class gtGameObject : public gtRefObject{
 
        gtStringA   m_name;
 
        s32 m_id;
 
    public:
 
        virtual ~gtGameObject( void ){}
 
            //  Возвратит тип объекта
        virtual gtObjectType        getType( void ) = 0;
 
            //  Возвратит позицию
        virtual const v3f&          getPosition( void ) = 0;
 
            //  Возвратит масштаб
        virtual const v3f&          getScale( void ) = 0;
 
            //  Возвратит вращение
        virtual const gtQuaternion& getRotation( void ) = 0;
 
            //  Установит позицию
        virtual void                setPosition( const v3f& ) = 0;
 
            //  Установит масштаб
        virtual void                setScale( const v3f& ) = 0;
 
            //  Установит вращение
        virtual void                setRotation( const gtQuaternion& ) = 0;
 
            //  Обновит информацию о позиции/вращении/масштабе
        virtual void                update( void ) = 0;
 
            //  Нарисует объект (если он рисуемый (например не 3D аудио))
        virtual void                render( void ) = 0;
 
            //  Возвратит имя
        virtual const gtStringA&    getName( void ){
            return m_name;
        }
 
            //  Установит имя
        virtual void                setName( const gtStringA& n ){
            m_name = n;
        }
 
            //  Возвратит ID
        virtual s32                 getID( void ){
            return m_id;
        }
 
            //  Установит ID
        virtual void                setID( s32 i ){
            m_id = i;
        }
 
    };
 
}
 
#endif
 
/*все объекты будут указываться здесь*/
#include "gtCamera.h"
У каждого объекта обязательно может быть имя и номер.
Не у каждого объекта могут быть координаты позиции, ориентация, масштаб.
Например, у 3D звука есть только позиция, нет смысла его масштабировать и вращать.

В методе update будет строится WORLD матрица.
В render, если это модель, будет вызываться метод рисования модели.
если это камера то будут строится VIEW и PROJECT матрицы.

класс камеры
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#pragma once
#ifndef __GT_CAMERA_H__
#define __GT_CAMERA_H__
 
/*
*/
 
namespace gost{
 
    enum class gtCameraType{
        CT_LOOK_AT,
        CT_2D
    };
 
    class gtCamera : public gtGameObject{
    public:
 
            //  Вернёт тип камеры
        virtual const gtCameraType& getCameraType( void ) = 0;
 
            //  Вернёт видовую матрицу
        virtual const gtMatrix4&    getViewMatrix( void ) = 0;
 
            //  Вернут проекционную мтрицу
        virtual const gtMatrix4&    getProjectionMatrix( void ) = 0;
 
            //  Вернёт цель если это look at камера
        virtual const v3f&          getTarget( void ) = 0;
 
            //  Установит цель если это look at камера
        virtual void                setTarget( const v3f& ) = 0;
        
            //  Вернёт up вектор look at камеры
        virtual const v3f&          getUpVector( void ) = 0;
 
            //  Установит up вектор look at камеры
        virtual void                setUpVector( const v3f& ) = 0;
 
            //  Установит ближнюю границу с которой начинается рисование
        virtual void                setNear( f32 ) = 0;
 
            //  Установит дальнюю границу после которой рисование заканчивается
        virtual void                setFar( f32 ) = 0;
 
            //  Установит соотношение сторон (напр. aspect = 800 : 600 )
        virtual void                setAspect( f32 ) = 0;
 
            //  Установит поле зрения (field of view)
        virtual void                setFOV( f32 ) = 0;
 
 
            //  Вернёт ближнюю границу с которой начинается рисование
        virtual f32                 getNear( void ) = 0;
 
            //  Вернёт дальнюю границу после которой рисование заканчивается
        virtual f32                 getFar( void ) = 0;
 
            //  Вернёт соотношение сторон
        virtual f32                 getAspect( void ) = 0;
 
            //  Вернёт поле зрения (field of view)
        virtual f32                 getFOV( void ) = 0;
    };
 
}
 
#endif
---------------------------------------------
Реализация камеры.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#pragma once
#ifndef __GT_CAMERA_IMPL_H__
#define __GT_CAMERA_IMPL_H__
 
namespace gost{
 
    class gtCameraImpl : public gtCamera{
/*gtQuaternion пока не реализован. будет использоваться для другого типа камеры*/
        gtQuaternion    m_rotation;
 
        gtMatrix4       m_worldMatrix, m_worldMatrixAbsolute;
        gtMatrix4       m_viewMatrix;
        gtMatrix4       m_projectionMatrix;
 
        v3f             m_position;
        v3f             m_target;
        v3f             m_up;
 
        f32             m_fov;
        f32             m_near, m_far;
        f32             m_aspect;
 
        gtObjectType    m_type;
        gtCameraType    m_cameraType;
 
        gtGameObject*   m_parent;
        
        /*тут в будущем будет список дочерних объектов*/
        
    public:
 
        gtCameraImpl( void );
        ~gtCameraImpl( void );
 
 
        //  =================================                   gtGameObject
            //  Возвратит тип объекта
        gtObjectType        getType( void );
 
            //  Возвратит позицию
        const v3f&          getPosition( void );
 
            //  Возвратит масштаб
        const v3f&          getScale( void );
 
            //  Возвратит вращение
        const gtQuaternion& getRotation( void );
 
            //  Установит позицию
        void                setPosition( const v3f& );
 
            //  Установит масштаб
        void                setScale( const v3f& );
 
            //  Установит вращение
        void                setRotation( const gtQuaternion& );
 
            //  Обновит информацию о позиции/вращении/масштабе
        void                update( void );
 
            //  Нарисует объект (если он рисуемый (например не 3D аудио))
        void                render( void );
        
            //  Вернёт матрицу с трансформациями относительно мира
        const gtMatrix4&    getAbsoluteWorldMatrix( void );
 
            //  Вернёт матрицу с трансформациями относительно мира либо родителя если он указан
        const gtMatrix4&    getWorldMatrix( void );
 
        //  ====================================                gtCamera
            //  Вернёт тип камеры
         const gtCameraType&    getCameraType( void );
 
            //  Вернёт видовую матрицу
         const gtMatrix4&   getViewMatrix( void );
 
            //  Вернут проекционную мтрицу
         const gtMatrix4&   getProjectionMatrix( void );
 
            //  Вернёт цель если это look at камера
         const v3f&         getTarget( void );
 
            //  Установит цель если это look at камера
         void               setTarget( const v3f& );
 
            //  Вернёт up вектор look at камеры
        const v3f&          getUpVector( void );
 
            //  Установит up вектор look at камеры
        void                setUpVector( const v3f& );
 
            //  Установит ближнюю границу с которой начинается рисование
         void               setNear( f32 );
 
            //  Установит дальнюю границу после которой рисование заканчивается
         void               setFar( f32 );
 
            //  Установит соотношение сторон (напр. aspect = 800 : 600 )
         void               setAspect( f32 );
 
            //  Установит поле зрения (field of view)
         void               setFOV( f32 );
 
            //  Вернёт ближнюю границу с которой начинается рисование
         f32                    getNear( void );
 
            //  Вернёт дальнюю границу после которой рисование заканчивается
         f32                    getFar( void );
 
            //  Вернёт соотношение сторон
         f32                    getAspect( void );
 
            //  Вернёт поле зрения (field of view)
         f32                    getFOV( void );
    };
 
}
 
#endif
реализация
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
gtCameraImpl::gtCameraImpl( void ):
    m_fov( 0.785398185f ),
    m_near( 1.f ),
    m_far( 100.f ),
    m_aspect( 1.333333333f ),
    m_type( gtObjectType::CAMERA ),
    m_cameraType( gtCameraType::CT_LOOK_AT ),
    m_parent( nullptr ),
    m_up({0.f,1.f,0.f})
{
}
 
gtCameraImpl::~gtCameraImpl( void ){
}
 
 
//  =================================                   gtGameObject
            //  Возвратит тип объекта
gtObjectType        gtCameraImpl::getType( void ){
    return m_type;
}
 
            //  Возвратит позицию
const v3f&          gtCameraImpl::getPosition( void ){
    return m_position;
}
 
            //  Возвратит масштаб
const v3f&          gtCameraImpl::getScale( void ){
    return v3f( 1.f );
}
 
            //  Возвратит вращение
const gtQuaternion& gtCameraImpl::getRotation( void ){
    return m_rotation;
}
 
            //  Установит позицию
void                gtCameraImpl::setPosition( const v3f& p ){
    m_position = p;
}
 
            //  Установит масштаб
void                gtCameraImpl::setScale( const v3f& ){}
 
            //  Установит вращение
void                gtCameraImpl::setRotation( const gtQuaternion& q ){
    m_rotation = q;
}
 
    //  Обновит информацию о позиции/вращении/масштабе
void                gtCameraImpl::update( void ){
 
    if( m_parent )
        m_worldMatrix = m_parent->getAbsoluteWorldMatrix();
    else{
        
        gtMatrix4 translationMatrix;
 
        math::makeTranslationMatrix( translationMatrix, m_position );
 
            // в будущем возможно появится rotation матрица для указания ориетнтации (не для CT_LOOKAT)
            // пока будет  так
        m_worldMatrix = translationMatrix;
    }
 
    m_worldMatrixAbsolute = m_worldMatrix;
 
}
 
    //  Нарисует объект (если он рисуемый (например не 3D аудио))
void                gtCameraImpl::render( void ){
    switch( m_cameraType ){
    case gost::gtCameraType::CT_LOOK_AT:{
        math::makePerspectiveRHMatrix( 
            m_projectionMatrix,
            m_fov,
            m_aspect,
            m_near,
            m_far );
        math::makeLookAtRHMatrix(
            m_viewMatrix,
            m_position,
            m_target,
            m_up
        );
    }break;
    case gost::gtCameraType::CT_2D:{
 
    }break;
    }
}
 
    //  Вернёт матрицу с трансформациями относительно мира
const gtMatrix4&    gtCameraImpl::getAbsoluteWorldMatrix( void ){
    return m_worldMatrixAbsolute;
}
 
    //  Вернёт матрицу с трансформациями относительно мира либо родителя если он указан
const gtMatrix4&    gtCameraImpl::getWorldMatrix( void ){
    return m_worldMatrix;
}
 
        //  ====================================                gtCamera
    //  Вернёт тип камеры
const gtCameraType& gtCameraImpl::getCameraType( void ){
    return m_cameraType;
}
 
const gtMatrix4&    gtCameraImpl::getViewMatrix( void ){
    return m_viewMatrix;
}
 
const gtMatrix4&    gtCameraImpl::getProjectionMatrix( void ){
    return m_projectionMatrix;
}
 
const v3f&          gtCameraImpl::getTarget( void ){
    return m_target;
}
 
void                gtCameraImpl::setTarget( const v3f& t ){
    m_target = t;
}
 
    //  Вернёт up вектор look at камеры
const v3f&          gtCameraImpl::getUpVector( void ){
    return m_up;
}
 
    //  Установит up вектор look at камеры
void                gtCameraImpl::setUpVector( const v3f& v ){
    m_up = v;
}
 
    //  Установит ближнюю границу с которой начинается рисование
void                gtCameraImpl::setNear( f32 v ){
    m_near = v;
}
 
    //  Установит дальнюю границу после которой рисование заканчивается
void                gtCameraImpl::setFar( f32 v ){
    m_far = v;
}
 
    //  Установит соотношение сторон (напр. aspect = 800 : 600 )
void                gtCameraImpl::setAspect( f32 v ){
    m_aspect = v;
}
 
    //  Установит поле зрения (field of view)
void                gtCameraImpl::setFOV( f32 v ){
    m_fov = v;
}
 
    //  Вернёт ближнюю границу с которой начинается рисование
f32                 gtCameraImpl::getNear( void ){
    return m_near;
}
 
    //  Вернёт дальнюю границу после которой рисование заканчивается
f32                 gtCameraImpl::getFar( void ){
    return m_far;
}
 
    //  Вернёт соотношение сторон
f32                 gtCameraImpl::getAspect( void ){
    return m_aspect;
}
 
    //  Вернёт поле зрения (field of view)
f32                 gtCameraImpl::getFOV( void ){
    return m_fov;
}
-------------------------------------------
Теперь нужно сделать коллбэк функции для шейдеров

В коллбэке нужно вызывать функции типа
ПослатьВПиксельныйШейдерТекстуру()
ПослатьВВершинныйШейдерМатрицу()

У разных графических API это происходит по разному, по этому сделаю общий класс, который будет заниматься этим.
Добавлю его в gtShader.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class gtShaderProcessing{
    public:
 
        gtShaderProcessing(){}
        virtual ~gtShaderProcessing(){}
 
            // Послать в шейдер значение float
        virtual void    setFloat( const gtStringA& uniformName, f32 a ){}
 
            // Послать в шейдер значение int
        virtual void    setInt( const gtStringA& uniformName, s32 a ){}
 
            // Послать в шейдер матрицу
        virtual void    setMatrix4x4( const gtStringA& uniformName, gtMatrix4& matrix ){}
 
            // Послать в шейдер вектор3
        virtual void    setVec3f( const gtStringA& uniformName, v3f& vec3 ){}
 
            // Послать в шейдер вектор4
        virtual void    setVec4f( const gtStringA& uniformName, v4f& vec4 ){}
 
            // Послать в шейдер текстуру
            // id - номер текстуры в материале
        virtual void    setTexture( const gtStringA& uniformName, s32 id ){}
 
            //  для константных буферов
            //  slot - номер очереди для вершинного шейдера. Начинается с нуля.
            //  если посылается в пиксельный, то там нужно тоже начинать с нуля.
            //  id - это номер буфера (созданного через вызов createShaderObject)
            //  буфер можно послать как в VS так и в PS, по этому slot и id могут различаться
            //  напр.   
            //  sendDataVS(data, 0, 0);
            //  sendDataPS(data, 0, 1);
            //  или
            //  sendDataVS(data, 0, 0);     //  sendDataVS(data, 0, 0); <-\
            //  sendDataVS(data, 1, 1);     //  sendDataVS(data, 1, 1);     |- 1 буфер и туда и туда
            //  sendDataPS(data, 0, 2);     //  sendDataPS(data, 0, 0); <-/
            //  sendDataPS(data, 1, 3);     //  sendDataPS(data, 1, 2);
        virtual void    sendDataVS( void* data, s32 slot, u32 id ){}
 
            //  см. описание sendDataVS
        virtual void    sendDataPS( void* data, s32 slot, u32 id ){}
    };
теперь сам коллбэк для шейдера, туда же.
C++
1
2
3
4
5
6
7
class gtMaterial;
class gtShaderCallback : public gtRefObject{
public:
 
    virtual void onShader( const gtMaterial&, gtShaderProcessing* ) = 0;
 
};
Реализовать эти классы нужны в D3D11 плагине.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#pragma once
#ifndef __GT_SHADER_PROCESSING_D3D11_H__
#define __GT_SHADER_PROCESSING_D3D11_H__
 
namespace gost{
 
 
    class gtShaderProcessingD3D11 : public gtShaderProcessing{
 
        gtShaderImpl * m_shaderD3D11;
        gtMaterial * m_material;
 
        ID3D11DeviceContext*    m_d3d11DevCon;
 
    public:
 
        gtShaderProcessingD3D11( ID3D11DeviceContext* );
        virtual ~gtShaderProcessingD3D11();
 
            // Послать в шейдер значение float
        void    setFloat( const gtStringA& uniformName, f32 a );
 
            // Послать в шейдер значение int
        void    setInt( const gtStringA& uniformName, s32 a );
 
            // Послать в шейдер матрицу
        void    setMatrix4x4( const gtStringA& uniformName, gtMatrix4& matrix );
 
            // Послать в шейдер вектор3
        void    setVec3f( const gtStringA& uniformName, v3f& vec3 );
 
            // Послать в шейдер вектор4
        void    setVec4f( const gtStringA& uniformName, v4f& vec4 );
 
            // Послать в шейдер текстуру
            // id - номер текстуры в материале
        void    setTexture( const gtStringA& uniformName, s32 id ) override;
 
            //  для константных буферов
            //  slot - номер очереди для вершинного шейдера. Начинается с нуля.
            //  если посылается в пиксельный, то там нужно тоже начинать с нуля.
            //  id - это номер буфера (созданного через вызов createShaderObject)
            //  буфер можно послать как в VS так и в PS, по этому slot и id могут различаться
            //  напр.   
            //  sendDataVS(data, 0, 0);
            //  sendDataPS(data, 0, 1);
            //  или
            //  sendDataVS(data, 0, 0);     //  sendDataVS(data, 0, 0); <-\
            //  sendDataVS(data, 1, 1);     //  sendDataVS(data, 1, 1);     |- 1 буфер и туда и туда
            //  sendDataPS(data, 0, 2);     //  sendDataPS(data, 0, 0); <-/
            //  sendDataPS(data, 1, 3);     //  sendDataPS(data, 1, 2);
        void    sendDataVS( void* data, s32 slot, u32 id ) override;
 
            //  см. описание sendDataVS
        void    sendDataPS( void* data, s32 slot, u32 id ) override;
 
        // ==============================================================
        void setShader( gtShader * );
        void setMaterial( gtMaterial * );
 
 
        /* для передачи данных в константный шейдер */
        void mapData( void* data, s32 id );
    };
 
}
 
 
#endif
реализация
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
gtShaderProcessingD3D11::gtShaderProcessingD3D11( ID3D11DeviceContext*  d3d11DevCon ):
    m_shaderD3D11( nullptr ),
    m_material( nullptr ),
    m_d3d11DevCon( d3d11DevCon )
{
}
 
gtShaderProcessingD3D11::~gtShaderProcessingD3D11(){
}
 
            // Послать в шейдер значение float
void    gtShaderProcessingD3D11::setFloat( const gtStringA& uniformName, f32 a ){
}
 
            // Послать в шейдер значение int
void    gtShaderProcessingD3D11::setInt( const gtStringA& uniformName, s32 a ){
}
 
            // Послать в шейдер матрицу
void    gtShaderProcessingD3D11::setMatrix4x4( const gtStringA& uniformName, gtMatrix4& matrix ){
}
 
            // Послать в шейдер вектор3
void    gtShaderProcessingD3D11::setVec3f( const gtStringA& uniformName, v3f& vec3 ){
}
 
            // Послать в шейдер вектор4
void    gtShaderProcessingD3D11::setVec4f( const gtStringA& uniformName, v4f& vec4 ){
}
 
            // Послать в шейдер текстуру
            // id - номер текстуры в материале
void    gtShaderProcessingD3D11::setTexture( const gtStringA& uniformName, s32 id ){
    if( m_material->textureLayer[ id ].texture ){
        gtTextureD3D11* texture = (gtTextureD3D11*)m_material->textureLayer[ id ].texture;
        m_d3d11DevCon->PSSetShaderResources( id, 1, texture->getResourceView() );
        m_d3d11DevCon->PSSetSamplers( id, 1, texture->getSamplerState() );
    }
}
 
void gtShaderProcessingD3D11::mapData( void* data, s32 id ){
        D3D11_MAPPED_SUBRESOURCE mappedResource;
 
        m_d3d11DevCon->Map( m_shaderD3D11->m_constantBuffers[ id ], 0, D3D11_MAP_WRITE_DISCARD, 0, 
            &mappedResource );
    
        D3D11_BUFFER_DESC d;
        m_shaderD3D11->m_constantBuffers[ id ]->GetDesc( &d );
        memcpy( mappedResource.pData, data, d.ByteWidth );
 
        m_d3d11DevCon->Unmap( m_shaderD3D11->m_constantBuffers[ id ], 0 );
}
            //  для константных буферов
            //  slot - номер очереди для вершинного шейдера. Начинается с нуля.
            //  если посылается в пиксельный, то там нужно тоже начинать с нуля.
            //  id - это номер буфера (созданного через вызов createShaderObject)
            //  буфер можно послать как в VS так и в PS, по этому slot и id могут различаться
            //  напр.   
            //  sendDataVS(data, 0, 0);
            //  sendDataPS(data, 0, 1);
            //  или
            //  sendDataVS(data, 0, 0);     //  sendDataVS(data, 0, 0); <-\
            //  sendDataVS(data, 1, 1);     //  sendDataVS(data, 1, 1);     |- 1 буфер и туда и туда
            //  sendDataPS(data, 0, 2);     //  sendDataPS(data, 0, 0); <-/
            //  sendDataPS(data, 1, 3);     //  sendDataPS(data, 1, 2);
void    gtShaderProcessingD3D11::sendDataVS( void* data, s32 slot, u32 id ){
    mapData( data, id );
    m_d3d11DevCon->VSSetConstantBuffers( slot, 1, &m_shaderD3D11->m_constantBuffers[ id ] );
}
 
            //  см. описание sendDataVS
void    gtShaderProcessingD3D11::sendDataPS( void* data, s32 slot, u32 id ){
    mapData( data, id );
    m_d3d11DevCon->PSSetConstantBuffers( slot, 1, &m_shaderD3D11->m_constantBuffers[ id ] );
}
 
 
 
void gtShaderProcessingD3D11::setShader( gtShader * s ){
    m_shaderD3D11 = (gtShaderImpl*)s;
}
 
void gtShaderProcessingD3D11::setMaterial( gtMaterial * m ){
    m_material = m;
}


В D3D11 плагине будут коллбэки для стандартных шейдеров. всё в одном .h и одном .cpp файлах
.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#ifndef __GT_SHADER_CALLBACKS_H__
#define __GT_SHADER_CALLBACKS_H__
 
namespace gost{
 
    class gtD3D11StandartShaderCallback : public gtShaderCallback{
 
        gtMainSystem * m_system;
 
    public:
        gtD3D11StandartShaderCallback();
        virtual ~gtD3D11StandartShaderCallback();
 
        void onShader( const gtMaterial&, gtShaderProcessing* );
 
    };
 
}
 
#endif
реализация
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
gtD3D11StandartShaderCallback::gtD3D11StandartShaderCallback():
m_system( nullptr ){
    m_system = gtMainSystem::getInstance();
}
 
gtD3D11StandartShaderCallback::~gtD3D11StandartShaderCallback(){
}
 
void gtD3D11StandartShaderCallback::onShader( const gtMaterial& m, gtShaderProcessing* sp ){
    
 
    /*в будущем в буфер можно добавить ещё поля, по этому сразу всё сунул в структуру*/
    struct cbMatrix_t{
        gtMatrix4 WVP;
    }cbMatrix;
 
    gtMatrix4 W = m_system->getMatrixWorld();
    gtMatrix4 V = m_system->getMatrixView();
    gtMatrix4 P = m_system->getMatrixProjection();
 
    cbMatrix.WVP =  P * V * W;
 
    cbMatrix.WVP.transpose();
 
    sp->sendDataVS( &cbMatrix, 0, 0u );
 
    /* в D3D11 главное правильно установить слот, uniformName не нужен */
    sp->setTexture( "", 0 );
}
При создании шейдера теперь нужно указать коллбэк класс.
gtDriver.h
C++
1
2
3
virtual gtShader *  getShader(
            gtShaderCallback * callback,
            ... /* и т.д. */
Для того чтобы иметь доступ к WORLD VIEW и PROJECTION матрицам в gtMainSystem добавлю методы
C++
1
2
3
4
5
6
virtual const gtMatrix4& getMatrixWorld( void ) = 0;
virtual const gtMatrix4& getMatrixView( void ) = 0;
virtual const gtMatrix4& getMatrixProjection( void ) = 0;
virtual void setMatrixWorld( const gtMatrix4& ) = 0;
virtual void setMatrixView( const gtMatrix4& ) = 0;
virtual void setMatrixProjection( const gtMatrix4& ) = 0;
реализация в common классе
C++
1
gtMatrix4 m_WVP[ 3u ];
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const gtMatrix4& gtMainSystemCommon::getMatrixWorld( void ){
    return m_WVP[ 0u ];
}
 
const gtMatrix4& gtMainSystemCommon::getMatrixView( void ){
    return m_WVP[ 1u ];
}
 
const gtMatrix4& gtMainSystemCommon::getMatrixProjection( void ){
    return m_WVP[ 2u ];
}
 
void gtMainSystemCommon::setMatrixWorld( const gtMatrix4& m ){
    m_WVP[ 0u ] = m;
}
 
void gtMainSystemCommon::setMatrixView( const gtMatrix4& m ){
    m_WVP[ 1u ] = m;
}
 
void gtMainSystemCommon::setMatrixProjection( const gtMatrix4& m ){
    m_WVP[ 2u ] = m;
}
Перед началом рендеринга ОБЪЕКТОВ, нужно сохранить VIEW и PROJECTION матрицы.
Это нужно будет делать в менеджере сцены.
Так как её пока нет, буду делать вручную, в программе, после построения этих матриц
C++
1
2
3
4
camera->update();
camera->render();
my_system->setMatrixProjection( camera->getProjectionMatrix() );
my_system->setMatrixView( camera->getViewMatrix() );
по сути так же нужно сохранить матрицу объекта. только нужно помнить что world матрицу нужно устанавливать постоянно на каждый объект.
C++
1
2
3
4
5
6
/*так как объекта нет и рисуется просто модель, то подойдёт матрица по умолчанию*/
/*главная диагональ используется как значение масштаба*/
/*а конструктор по умолчанию устанавливает это значение = 1.f*/
/*по этому всё будет хорошо*/
my_system->setMatrixWorld( gtMatrix4() );
driver1->drawModel( rModel.data() );

----------------------------
В шейдере добавил константный буфер с матрице WorldViewProjection;
C++
1
2
3
cbuffer cbMatrix{
    float4x4 WVP;
};
Позиция вершины теперь вычисляется так
C++
1
output.position = mul( input.position, WVP );
В D3D11 плагине нельзя забыть создать для него буфер.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*создание m_shader3DStandartCallback*/
    m_shader3DStandartCallback = gtPtrNew<gtD3D11StandartShaderCallback>( new gtD3D11StandartShaderCallback );
    m_shader3DStandart = getShader(
        m_shader3DStandartCallback.data(), /*его указание*/
        u"../shaders/3d_basic.hlsl",
        "VSMain",
        u"../shaders/3d_basic.hlsl",
        "PSMain",
        shaderModel,
        vertexType3D
        );
    if( m_shader3DStandart ){
        //  создание константного буффера.
        if( !m_shader3DStandart->createShaderObject( 16u * sizeof(f32) ) ) return false;
    }
 
    return true;
}

И в конце метод рисования который вызывает коллбэк функцию
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
    //  нарисует gtRenderModel
void gtDriverD3D11::drawModel( gtRenderModel* model ){
    D3D11_MAPPED_SUBRESOURCE mappedResource;
    
    auto * soft = model->getModel();
 
    s32 smc = soft->getSubmodelsCount();
    
    u32 stride = soft->getStride();
 
    gtRenderModelD3D11* d3dm = (gtRenderModelD3D11*)model;
 
    u32 offset = 0u;
 
    for( u32 i( 0u ); i < smc; ++i ){
 
        auto * sub = soft->getSubModel( i );
        gtMaterial& material = sub->m_material;
 
        gtShader * shader = sub->m_material.shader;
        if( !shader ){
            shader = m_shader3DStandart;
        }
 
        m_shaderProcessing->setShader( shader );
        m_shaderProcessing->setMaterial( &material );
        
        gtShaderImpl * shaderD3D11 = ((gtShaderImpl*)shader);
 
        m_d3d11DevCon->IASetInputLayout( ((gtShaderImpl*)shader)->m_vLayout );
        m_d3d11DevCon->VSSetShader( ((gtShaderImpl*)shader)->m_vShader, 0, 0 );
        m_d3d11DevCon->PSSetShader( ((gtShaderImpl*)shader)->m_pShader, 0, 0 );
        m_d3d11DevCon->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
 
        m_d3d11DevCon->IASetVertexBuffers( 0, 1, &d3dm->m_vBuffers[ i ], &stride, &offset );
        m_d3d11DevCon->IASetIndexBuffer( d3dm->m_iBuffers[ i ], DXGI_FORMAT_R16_UINT, 0);
 
        if( shaderD3D11->m_callback )
            shaderD3D11->m_callback->onShader( material, m_shaderProcessing.data() );
 
        m_d3d11DevCon->DrawIndexed( sub->m_iCount, 0, 0 );
 
    }
}


-----------------------------------
Тест.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
gtImage * image1 = my_system->loadImage( gtFileSystem::getProgramPath() + u"png32.png" );
    
    gtPtr<gtTexture> texture1 = gtPtrNew<gtTexture>( driver1->createTexture( image1 ) );
    /* software картинка больше не нужна */
    my_system->removeImage( image1 );
    
    gtMaterial material1;
    material1.flags = gtMaterialFlag::MF_BLEND;
    material1.opacity = 1.f;
    material1.textureLayer[ 0u ].texture = texture1.data();
    
 
    gtPtr<gtModel> model = gtPtrNew<gtModel>( ms->createPlane( 10.f, 10.f ) );
    model->getSubModel(0)->m_material = material1;
 
    gtPtr<gtRenderModel>  rModel = gtPtrNew<gtRenderModel>( driver1->createModel( model.data() ) );
 
 
    gtPtr<gtCamera> camera = gtPtrNew<gtCamera>( my_system->createCamera() );
    camera->setPosition( v3f({10.f,2.f,0.f}) );
 
    while( my_system->update() ){
 
        if( events.isKeyDown( gtKey::K_ESCAPE ) ){
            break;
        }
 
        if( events.isKeyDown( gtKey::K_UP ) ){
            camera->setPosition( camera->getPosition() + v3f({ 0.f, 0.f, 0.01f }) );
        }
        if( events.isKeyDown( gtKey::K_DOWN ) ){
            camera->setPosition( camera->getPosition() - v3f({ 0.f, 0.f, 0.01f }) );
        }
        if( events.isKeyDown( gtKey::K_LEFT ) ){
            camera->setPosition( camera->getPosition() + v3f({ 0.01f, 0.f, 0.f }) );
        }
        if( events.isKeyDown( gtKey::K_RIGHT ) ){
            camera->setPosition( camera->getPosition() - v3f({ 0.01f, 0.f, 0.f }) );
        }
        if( events.isKeyDown( gtKey::K_PGUP ) ){
            camera->setPosition( camera->getPosition() + v3f({ 0.f, 0.01f, 0.f }) );
        }
        if( events.isKeyDown( gtKey::K_PGDOWN ) ){
            camera->setPosition( camera->getPosition() - v3f({ 0.f, 0.01f, 0.f }) );
        }       
 
        if( driver1 ){
            driver1->beginRender(true,gtColor(1.f,0.f,0.f,1.f));
 
            camera->update();
            camera->render();
            my_system->setMatrixProjection( camera->getProjectionMatrix() );
            my_system->setMatrixView( camera->getViewMatrix() );
 
            /*так как объекта нет и рисуется просто модель, то подойдёт матрица по умолчанию*/
            /*главная диагональ используется как значение масштаба*/
            /*а конструктор по умолчанию устанавливает это значение = 1.f*/
            /*по этому всё будет хорошо*/
            my_system->setMatrixWorld( gtMatrix4() );
 
            driver1->drawModel( rModel.data() );
 
            driver1->endRender();
        }
 
    }
Миниатюры
Нажмите на изображение для увеличения
Название: 4YYO7C.gif
Просмотров: 320
Размер:	546.7 Кб
ID:	4608  
Размещено в Игровой движок
Просмотров 244 Комментарии 0
Всего комментариев 0

Комментарии

 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru