summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGL/GLMatrix.cpp
blob: 8efa4591551c6cddd105b3aeb28ab33620789227 (plain)
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
/*
 * Copyright (c) 2021, Jesse Buhagiar <jooster669@gmail.com>
 * Copyright (c) 2021, Stephan Unverwerth <s.unverwerth@serenityos.org>
 * Copyright (c) 2021, Jelle Raaijmakers <jelle@gmta.nl>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include "AK/Array.h"
#include "GL/gl.h"
#include "GLContext.h"

extern GL::GLContext* g_gl_context;

void glMatrixMode(GLenum mode)
{
    g_gl_context->gl_matrix_mode(mode);
}

/*
 * Push the current matrix (based on the current matrix mode)
 * to its' corresponding matrix stack in the current OpenGL
 * state context
 */
void glPushMatrix()
{
    g_gl_context->gl_push_matrix();
}

/*
 * Pop a matrix from the corresponding matrix stack into the
 * corresponding matrix in the state based on the current
 * matrix mode
 */
void glPopMatrix()
{
    g_gl_context->gl_pop_matrix();
}

/*
 * Transposes input matrices (column-major) to our Matrix (row-major).
 */
template<typename I, typename O>
static constexpr Matrix4x4<O> transpose_input_matrix(I const* matrix)
{
    if constexpr (IsSame<I, O>) {
        // clang-format off
        return {
            matrix[0], matrix[4], matrix[8], matrix[12],
            matrix[1], matrix[5], matrix[9], matrix[13],
            matrix[2], matrix[6], matrix[10], matrix[14],
            matrix[3], matrix[7], matrix[11], matrix[15],
        };
        // clang-format on
    }

    Array<O, 16> elements;
    for (size_t i = 0; i < 16; ++i)
        elements[i] = static_cast<O>(matrix[i]);
    // clang-format off
    return {
        elements[0], elements[4], elements[8], elements[12],
        elements[1], elements[5], elements[9], elements[13],
        elements[2], elements[6], elements[10], elements[14],
        elements[3], elements[7], elements[11], elements[15],
    };
    // clang-format on
}

void glMultMatrixd(GLdouble const* matrix)
{
    g_gl_context->gl_mult_matrix(transpose_input_matrix<double, float>(matrix));
}

void glMultMatrixf(GLfloat const* matrix)
{
    g_gl_context->gl_mult_matrix(transpose_input_matrix<float, float>(matrix));
}

void glLoadMatrixd(GLdouble const* matrix)
{
    g_gl_context->gl_load_matrix(transpose_input_matrix<double, float>(matrix));
}

void glLoadMatrixf(GLfloat const* matrix)
{
    g_gl_context->gl_load_matrix(transpose_input_matrix<float, float>(matrix));
}

void glLoadIdentity()
{
    g_gl_context->gl_load_identity();
}

/**
 * Create a viewing frustum (a.k.a a "Perspective Matrix") in the current matrix. This
 * is usually done to the projection matrix. The current matrix is then multiplied
 * by this viewing frustum matrix.
 *
 * https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glFrustum.xml
 *
 *
 * FIXME: We need to check for some values that could result in a division by zero
 */
void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal)
{
    g_gl_context->gl_frustum(left, right, bottom, top, nearVal, farVal);
}

void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal)
{
    g_gl_context->gl_ortho(left, right, bottom, top, nearVal, farVal);
}

void glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
{
    g_gl_context->gl_rotate(angle, x, y, z);
}

void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
{
    g_gl_context->gl_rotate(angle, x, y, z);
}

void glScaled(GLdouble x, GLdouble y, GLdouble z)
{
    g_gl_context->gl_scale(x, y, z);
}

void glScalef(GLfloat x, GLfloat y, GLfloat z)
{
    g_gl_context->gl_scale(x, y, z);
}

void glTranslated(GLdouble x, GLdouble y, GLdouble z)
{
    g_gl_context->gl_translate(x, y, z);
}

void glTranslatef(GLfloat x, GLfloat y, GLfloat z)
{
    g_gl_context->gl_translate(x, y, z);
}