-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
220 lines (178 loc) · 7.84 KB
/
main.cpp
File metadata and controls
220 lines (178 loc) · 7.84 KB
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
#include <iostream>
#include <math.h>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <shader/shader.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stb/stb_image.h>
// window settings
const unsigned int WINDOW_W = 1024;
const unsigned int WINDOW_H = 768;
// [DONE] Objective 1: Make sure only the happy face looks in the other/reverse direction by changing the fragment shader.
// [DONE] Objective 2: See if you can display 4 smiley faces on a single container image clamped at its edge.
// [DONE] Objective 3: Try to display only the center pixels of the texture image on the rectangle in such a way that
// the individual pixels are getting visible by changing the texture coordinates. Try to set the texture
// filtering method to GL_NEAREST to see the pixels more clearly.
// [DONE] Objective 4: Use a uniform variable as the mix function's third parameter to vary the amount the two textures
// are visible. Use the up and down arrow keys to change how much the container or the smiley face
// is visible.
float vertices_colors_txtcoords[] = {
// vertices // colors // texture coordinates
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 2.0f, 2.0f, // top right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 2.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 2.0f // top left
};
unsigned int indices[] = {
0, 1, 3,
3, 2, 1
};
float texture_mix = 0.0;
// functions from other files
void h3w_linkShaderProgram(unsigned int &shaderProgram);
// callbacks
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
glViewport(0, 0, width, height);
}
// input function
void processInput(GLFWwindow* window) {
// 0 key exits the program
if(glfwGetKey(window, GLFW_KEY_0) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
// change texture zoom mode
if(glfwGetKey(window, GLFW_KEY_1) == GLFW_PRESS) {
vertices_colors_txtcoords[6] = 2.0f;
vertices_colors_txtcoords[7] = 2.0f;
vertices_colors_txtcoords[14] = 2.0f;
vertices_colors_txtcoords[15] = 0.0f;
vertices_colors_txtcoords[22] = 0.0f;
vertices_colors_txtcoords[23] = 0.0f;
vertices_colors_txtcoords[30] = 0.0f;
vertices_colors_txtcoords[31] = 2.0f;
}
if(glfwGetKey(window, GLFW_KEY_2) == GLFW_PRESS) {
vertices_colors_txtcoords[6] = 0.55f;
vertices_colors_txtcoords[7] = 0.55f;
vertices_colors_txtcoords[14] = 0.55f;
vertices_colors_txtcoords[15] = 0.45f;
vertices_colors_txtcoords[22] = 0.45f;
vertices_colors_txtcoords[23] = 0.45f;
vertices_colors_txtcoords[30] = 0.45f;
vertices_colors_txtcoords[31] = 0.55f;
}
// change mix values
if(glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS && texture_mix < 1.0) {
texture_mix += 0.01;
}
if(glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS && texture_mix > 0.0) {
texture_mix -= 0.01;
}
}
int main() {
// Initialize GLFW
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // For macOS
// Create GLFW window
GLFWwindow* window = glfwCreateWindow(WINDOW_W, WINDOW_H, "Hello, 3D World!", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
// Initialize GLAD
if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
// "Textures" chapter - create OpenGL texture
unsigned int textures[2];
glGenTextures(2, textures);
for(unsigned int texture : textures) {
glBindTexture(GL_TEXTURE_2D, texture);
// set texture wrapping and filtering options
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
// ditto - load image via stb_image library
stbi_set_flip_vertically_on_load(true);
int width, height, nrChannels;
unsigned char* data = stbi_load("./textures/container.jpg", &width, &height, &nrChannels, 0);
if(data) {
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
} else {
std::cout << "E: failed to load texture" << std::endl;
}
data = stbi_load("./textures/awesomeface.png", &width, &height, &nrChannels, 0);
if(data) {
glBindTexture(GL_TEXTURE_2D, textures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
} else {
std::cout << "E: failed to load texture" << std::endl;
}
stbi_image_free(data);
// "Shader" chapter - use the shader header file to process vertex and fragment shaders
h3w_shader ourShader("./shaders/shader.vert", "./shaders/shader.frag");
ourShader.use();
glUniform1i(glGetUniformLocation(ourShader.ID, "texture1"), 0);
glUniform1i(glGetUniformLocation(ourShader.ID, "texture2"), 1);
unsigned int VAO, VBO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
// ditto - pass vertices data to VBO and indices data to EBO
glBindVertexArray(VAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices_colors_txtcoords), vertices_colors_txtcoords, GL_DYNAMIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// specify how OpenGL should interpret the vertex buffer data
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// render (update?) loop
while(!glfwWindowShouldClose(window)) {
processInput(window);
glClearColor(0.5f, 0.5f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// rendering
ourShader.use();
ourShader.setFloat("texture_mix", texture_mix);
// "Textures" chapter - bind texture
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices_colors_txtcoords), vertices_colors_txtcoords, GL_DYNAMIC_DRAW);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
// Clean exit
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
ourShader.clean_delete();
glfwTerminate();
return 0;
}