-
Notifications
You must be signed in to change notification settings - Fork 0
/
glxt.c
110 lines (88 loc) · 2.76 KB
/
glxt.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
/*
================================================================
File name : glxt.с
Created : 01.10.2023
Modified : 04.12.2023
Author : bolatulyerdos
Description : OpenGL Extensions (GLXT) implementation
================================================================
*/
#include <math.h>
#if defined(WIN32)
#include <windows.h>
#endif
#include <GL/gl.h>
#include "glxt.h"
// Константы
static const double pi = 3.14159265358979323846264338327950;
typedef struct
{
double x, y, z;
}
Vector3d;
// Конвертеры
static double rad2deg (double val) // Радианы в градусы
{
return val * 180.0 / pi;
}
static double deg2rad (double val) // Градусы в радианы
{
return val * pi / 180.0;
}
// Нормализация вектора
static void normalize (Vector3d* vec)
{
double len = sqrt(vec->x * vec->x + vec->y * vec->y + vec->z * vec->z);
// Проверка на ноль
if (len == 0.0)
return;
vec->x /= len;
vec->y /= len;
vec->z /= len;
}
// Векторное произведение двух векторов
static void cross (Vector3d* vec1, Vector3d* vec2, Vector3d* res)
{
res->x = vec1->y * vec2->z - vec1->z * vec2->y;
res->y = vec1->z * vec2->x - vec1->x * vec2->z;
res->z = vec1->x * vec2->y - vec1->y * vec2->x;
}
// Расширение (аналог gluLookAt)
void glxtLookAt (double eye_x, double eye_y, double eye_z, double center_x, double center_y, double center_z, double up_x, double up_y, double up_z)
{
Vector3d forward, side, up;
up.x = up_x;
up.y = up_y;
up.z = up_z;
// Расчет и нормализация вектора направления (forward)
forward.x = center_x - eye_x;
forward.y = center_y - eye_y;
forward.z = center_z - eye_z;
normalize (&forward);
// Расчет и нормализация бокового вектора (side)
cross (&forward, &up, &side);
normalize (&side);
// Расчет вектора вверх (up)
cross (&side, &forward, &up);
// Создание матрицы преобразования
double matrix[16] =
{
side.x, up.x, -forward.x, 0.0,
side.y, up.y, -forward.y, 0.0,
side.z, up.z, -forward.z, 0.0,
0.0, 0.0, 0.0, 1.0
};
// Загрузка в OpenGL
glMultMatrixd (matrix);
glTranslated (-eye_x, -eye_y, -eye_z);
}
// Расширение (аналог gluPerspective)
void glxtPerspective (double fov_y, double aspect_ratio, double near_plane, double far_plane)
{
if (fov_y <= 0.0 || aspect_ratio <= 0.0 || near_plane <= 0.0 || far_plane <= 0.0 || far_plane - near_plane <= 0.0)
return;
double height = tan(deg2rad(fov_y / 2.0)) * near_plane;
double width = height * aspect_ratio;
// Загрузка в OpenGL
glFrustum (-width, width, -height, height, near_plane, far_plane);
}