forked from drahosp/ppgso
-
Notifications
You must be signed in to change notification settings - Fork 5
/
gl5_projection.cpp
138 lines (114 loc) · 4.2 KB
/
gl5_projection.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
// Example gl5_projection
// - Demonstrates the use of perspective and parallel projection
// - Animates object rotation
// - Useful for demonstrating culling and depth test concepts
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#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 projections
*/
class ProjectionWindow : public ppgso::Window {
private:
// Load shader program, geometry and texture
ppgso::Shader program = {texture_vert_glsl, texture_frag_glsl};
ppgso::Mesh quad = {"quad.obj"};
ppgso::Texture texture = {ppgso::image::loadBMP("lena.bmp")};
// Model matrix for each quad
glm::mat4 quad1ModelMatrix, quad2ModelMatrix;
// Mode switch
enum class Mode {
PERSPECTIVE,
PARALLEL,
END,
} mode = Mode::PERSPECTIVE;
/*!
* Set ProjectionMatrix and ViewMatrix depending on the current mode
*/
void setProjection() {
switch (mode) {
case Mode::PERSPECTIVE:
// Create projection matrix (field of view (radians), aspect ratio, near plane distance, far plane distance)
// You can think of this as the camera objective settings
program.setUniform("ProjectionMatrix", glm::perspective((ppgso::PI / 180.f) * 60.0f, 1.0f, 0.1f, 10.0f));
// Create view matrix (translate camera a bit backwards, so we can see the geometry)
program.setUniform("ViewMatrix", glm::translate(glm::mat4{1.0f}, {0.0f, 0.0f, -3.0f}));
break;
case Mode::PARALLEL:
// Create projection matrix (field of view (radians), aspect ratio, near plane distance, far plane distance)
// You can think of this as the camera objective settings
program.setUniform("ProjectionMatrix", glm::ortho(-2.0f, 2.0f, -2.0f, 2.0f, 0.1f, 10.0f));
// Create view matrix using the glm::lookAt function
// This can be seen as the camera position/rotation in space
program.setUniform("ViewMatrix", glm::lookAt(glm::vec3{2.0f, 2.0f, 2.0f}, glm::vec3{0.0f, 0.0f, 0.0f}, glm::vec3{0.0f, 1.0f, 0.0f}));
break;
default:
break;
}
}
public:
/*!
* Create and set up new custom window
*/
ProjectionWindow() : Window{"gl5_projection", SIZE, SIZE} {
// Set up OpenGL options
// Enable Z-buffer
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
// Enable polygon culling
//glEnable(GL_CULL_FACE);
//glFrontFace(GL_CW);
//glCullFace(GL_BACK);
// Set texture as program uniform input
program.setUniform("Texture", texture);
// Quad positions
// Coordinates in world coordinates
quad1ModelMatrix = translate(glm::mat4{1.0f}, {0, 0, 1});
quad2ModelMatrix = translate(glm::mat4{1.0f}, {0, 0, -1});
}
/*!
* 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 {
// Update time and create a rotation matrix
auto time = glfwGetTime();
auto rotateMat = rotate(glm::mat4{1.0f}, (float)time, {0, 1, 0});
// Set up projection and view matrix
setProjection();
// Set gray background
glClearColor(.5f, .5f, .5f, 0);
// Clear depth and color buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw two quads with rotation
program.setUniform("ModelMatrix", rotateMat * quad1ModelMatrix);
quad.render();
program.setUniform("ModelMatrix", rotateMat * quad2ModelMatrix);
quad.render();
}
};
int main() {
// Initialize our window
ProjectionWindow window;
// Poll window events
while (window.pollEvents()) {}
return EXIT_SUCCESS;
}