forked from drahosp/ppgso
-
Notifications
You must be signed in to change notification settings - Fork 5
/
gl4_transform.cpp
171 lines (147 loc) · 4.64 KB
/
gl4_transform.cpp
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
// Example gl4_transform
// - This example demonstrates basic transformations
// - Notice that the glm library uses column major order when declaring matrices
// - Example combines multiple transformation using multiplication
// - Press SPACE to see each transformation
#include <iostream>
#include <ppgso/ppgso.h>
#include <shaders/texture_vert_glsl.h>
#include <shaders/texture_frag_glsl.h>
const unsigned int SIZE = 512;
/*!
* Custom window for demonstrating transformations
*/
class TransformWindow : public ppgso::Window {
private:
// Set up needed resources
ppgso::Shader program = {texture_vert_glsl, texture_frag_glsl};
ppgso::Texture texture = {ppgso::image::loadBMP("lena.bmp")};
ppgso::Mesh quad = {"quad.obj"};
// Mode switch
enum class Mode {
IDENTITY,
SCALE,
SQUASH,
ROTATE,
TRANSLATE,
ROTATE_TOP_RIGHT,
ROTATE_TOP_LEFT,
END,
} mode = Mode::SCALE;
/*!
* Generate transformation matrix
* @param time Time to use as parameter or matrix generation
* @return Model transformation matrix
*/
glm::mat4 getModelTransformationMatrix(float time) {
// Create transformation matrix
// NOTE: glm matrices are declared column major !
switch (mode) {
case Mode::IDENTITY:
return glm::mat4({
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
});
case Mode::SCALE:
return glm::mat4({
sin(time), 0.0, 0.0, 0.0,
0.0, sin(time), 0.0, 0.0,
0.0, 0.0, sin(time), 0.0,
0.0, 0.0, 0.0, 1.0,
});
case Mode::SQUASH:
return glm::mat4({
sin(time), 0.0, 0.0, 0.0,
0.0, cos(time), 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
});
case Mode::ROTATE:
return glm::mat4({
cos(time), sin(time), 0.0, 0.0,
-sin(time), cos(time), 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
});
case Mode::TRANSLATE:
return glm::mat4({
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
sin(time) / 2.0, cos(time) / 2.0, 0.0, 1.0,
});
case Mode::ROTATE_TOP_RIGHT:
return glm::mat4({ // Move back
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
1.0, 1.0, 0.0, 1.0,
}) * glm::mat4({ // Rotate
cos(time), sin(time), 0.0, 0.0,
-sin(time), cos(time), 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
}) * glm::mat4({ // Move to origin
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
-1.0, -1.0, 0.0, 1.0,
});
case Mode::ROTATE_TOP_LEFT:
return translate(glm::mat4{1.0f}, glm::vec3{-1, 1, 0})
* rotate(glm::mat4{1.0f}, time, glm::vec3{0, 0, 1})
* glm::translate(glm::mat4{1.0f}, -glm::vec3{-1, 1, 0});
default:
break;
}
return glm::mat4{1.0f};
}
public:
/*!
* Create new custom window
*/
TransformWindow() : Window{"gl4_transform", SIZE, SIZE} {
// Set program input for texture uniform
program.setUniform("Texture", texture);
// Set Matrices to identity so there are no projections/transformations applied in the vertex shader
program.setUniform("ViewMatrix", glm::mat4{1.0f});
program.setUniform("ProjectionMatrix", glm::mat4{1.0f});
}
/*!
* Handles pressed key when the window is focused
* @param key Key code of the key being pressed/released
* @param scanCode Scan code of the key being pressed/released
* @param action Action indicating the key state change
* @param mods Additional modifiers to consider
*/
void onKey(int key, int scanCode, int action, int mods) override {
// When SPACE is pressed advance mode to the next state
if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) {
int next_mode = ((int)mode+1) % (int)Mode::END;
mode = Mode(next_mode % 8);
}
};
/*!
* Window update implementation that will be called automatically from pollEvents
*/
void onIdle() override {
// Set gray background
glClearColor(.5f, .5f, .5f, 0);
// Clear depth and color buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
auto time = glfwGetTime();
// Generate and set the transformation matrix
program.setUniform("ModelMatrix", getModelTransformationMatrix((float)time));
// Render geometry
quad.render();
}
};
int main() {
// Create our window
TransformWindow window;
// Main execution loop
while (window.pollEvents()) {}
return EXIT_SUCCESS;
}