Created
July 7, 2018 15:31
-
-
Save chengluyu/cda78bb6041967bd05e1e57032e630c5 to your computer and use it in GitHub Desktop.
Computer Graphics Experiment 2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define STB_IMAGE_IMPLEMENTATION | |
#include <glad/glad.h> | |
#include <GLFW/glfw3.h> | |
#include <stb_image.h> | |
#include <glm/glm.hpp> | |
#include <glm/gtc/matrix_transform.hpp> | |
#include <glm/gtc/type_ptr.hpp> | |
#include <iostream> | |
#include <vector> | |
const auto vertex_shader_source = R"( | |
#version 330 core | |
layout (location = 0) in vec3 position; | |
layout (location = 2) in vec2 tex_coord; | |
uniform mat4 model; | |
uniform mat4 view; | |
uniform mat4 projection; | |
out vec2 texture_coord; | |
void main() | |
{ | |
gl_Position = projection * view * model * vec4(position, 1.0); | |
texture_coord = tex_coord; | |
} | |
)"; | |
const auto fragment_shader_source = R"( | |
#version 330 core | |
in vec2 texture_coord; | |
out vec4 color; | |
uniform sampler2D cube_texture; | |
uniform float alpha; | |
void main() | |
{ | |
color = vec4(texture(cube_texture, texture_coord).rgb, alpha); | |
} | |
)"; | |
GLuint compileShader(const char *source, GLuint type) { | |
GLuint shader; | |
shader = glCreateShader(type); | |
glShaderSource(shader, 1, &source, nullptr); | |
glCompileShader(shader); | |
// Check error. | |
GLint success; | |
GLchar infoLog[512]; | |
glGetShaderiv(shader, GL_COMPILE_STATUS, &success); | |
if(!success) { | |
glGetShaderInfoLog(shader, 512, NULL, infoLog); | |
std::cout << "Compile shader failed: \n" << infoLog << std::endl; | |
} | |
return shader; | |
} | |
const auto kWindowWidth = 1024; | |
const auto kWindowHeight = 768; | |
int main() { | |
glfwInit(); | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); | |
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); | |
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); | |
// If remove this, application will fail to create window on macOS. | |
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); | |
auto window = glfwCreateWindow(kWindowWidth, kWindowHeight, "LearnOpenGL", nullptr, nullptr); | |
if (window == nullptr) { | |
std::cout << "Failed to create GLFW window" << std::endl; | |
glfwTerminate(); | |
return -1; | |
} | |
glfwMakeContextCurrent(window); | |
gladLoadGL(); | |
{ // Set the dimension of the window. | |
GLint width, height; | |
glfwGetFramebufferSize(window, &width, &height); | |
glViewport(0, 0, width, height); | |
} | |
glEnable(GL_DEPTH_TEST); | |
glDisable(GL_CULL_FACE); | |
glEnable(GL_BLEND); | |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
GLuint program = glCreateProgram(); | |
{ // Prepare shader program. | |
auto vs = compileShader(vertex_shader_source, GL_VERTEX_SHADER); | |
auto fs = compileShader(fragment_shader_source, GL_FRAGMENT_SHADER); | |
glAttachShader(program, vs); | |
glAttachShader(program, fs); | |
glLinkProgram(program); | |
// Check error. | |
GLint success; | |
GLchar infoLog[512]; | |
glGetProgramiv(program, GL_LINK_STATUS, &success); | |
if(!success) { | |
glGetProgramInfoLog(program, 512, NULL, infoLog); | |
std::cout << "Link shader failed: \n" << infoLog << std::endl; | |
} | |
glDeleteShader(vs); | |
glDeleteShader(fs); | |
} | |
GLuint texture; | |
{ | |
glGenTextures(1, &texture); | |
glBindTexture(GL_TEXTURE_2D, | |
texture); // All upcoming GL_TEXTURE_2D operations now have effect on our texture object | |
// Set our texture parameters | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture wrapping to GL_REPEAT | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | |
// Set texture filtering | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
// Load, create texture and generate mipmaps | |
int width, height, channels; | |
unsigned char *image = stbi_load("/Users/user/Internship/Glitter/Glitter/Sources/container.jpg", &width, | |
&height, &channels, 0); | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); | |
glGenerateMipmap(GL_TEXTURE_2D); | |
stbi_image_free(image); | |
glBindTexture(GL_TEXTURE_2D, 0); | |
} | |
// Uniform locations | |
auto model_location = glGetUniformLocation(program, "model"); | |
auto view_location = glGetUniformLocation(program, "view"); | |
auto projection_location = glGetUniformLocation(program, "projection"); | |
auto texture_location = glGetUniformLocation(program, "cube_texture"); | |
auto alpha_location = glGetUniformLocation(program, "alpha"); | |
GLfloat vertices[] = { | |
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, | |
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, | |
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, | |
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, | |
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, | |
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, | |
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, | |
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, | |
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, | |
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, | |
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, | |
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, | |
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, | |
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, | |
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, | |
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, | |
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, | |
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, | |
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, | |
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, | |
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, | |
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, | |
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, | |
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, | |
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, | |
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, | |
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, | |
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, | |
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, | |
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, | |
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f | |
}; | |
std::vector<glm::vec3> trajectory = { | |
glm::vec3( 0.0f, 0.0f, 0.0f), | |
glm::vec3( 2.0f, 5.0f, -15.0f), | |
glm::vec3(-1.5f, -2.2f, -2.5f), | |
glm::vec3(-3.8f, -2.0f, -12.3f), | |
glm::vec3( 2.4f, -0.4f, -3.5f), | |
glm::vec3(-1.7f, 3.0f, -7.5f), | |
glm::vec3( 1.3f, -2.0f, -2.5f), | |
glm::vec3( 1.5f, 2.0f, -2.5f), | |
glm::vec3( 1.5f, 0.2f, -1.5f), | |
glm::vec3(-1.3f, 1.0f, -1.5f) | |
}; | |
std::size_t stage = 0; | |
auto movement_time = 2.; | |
auto elapsed_time = 0.; | |
auto absolute_time = 0.; | |
auto delta_time = 0.; | |
GLuint VBO, VAO; | |
glGenVertexArrays(1, &VAO); | |
glGenBuffers(1, &VBO); | |
glBindVertexArray(VAO); | |
glBindBuffer(GL_ARRAY_BUFFER, VBO); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); | |
// Position attribute | |
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid *) 0); | |
glEnableVertexAttribArray(0); | |
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid *) (3 * sizeof(GLfloat))); | |
glEnableVertexAttribArray(2); | |
glBindVertexArray(0); // Unbind VAO | |
// The main event loop of OpenGL | |
while (!glfwWindowShouldClose(window)) { | |
{ // Update time. | |
auto current_time = glfwGetTime(); | |
delta_time = current_time - absolute_time; | |
absolute_time = current_time; | |
} | |
glfwPollEvents(); | |
glClearColor(0.9f, 0.9f, 0.9f, 1.0f); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glActiveTexture(GL_TEXTURE0); | |
glBindTexture(GL_TEXTURE_2D, texture); | |
glUniform1i(texture_location, 0); | |
glUseProgram(program); | |
auto view = glm::translate(glm::mat4{1.f}, glm::vec3(0.0f, 0.0f, -3.0f)); | |
auto projection = glm::perspective(45.0f, (GLfloat) kWindowWidth / (GLfloat) kWindowHeight, 0.1f, 100.0f); | |
glUniformMatrix4fv(view_location, 1, GL_FALSE, glm::value_ptr(view)); | |
glUniformMatrix4fv(projection_location, 1, GL_FALSE, glm::value_ptr(projection)); | |
glBindVertexArray(VAO); | |
auto advance = false; | |
auto from = trajectory[stage]; | |
auto to = trajectory[stage + 1 == trajectory.size() ? 0 : stage + 1]; | |
elapsed_time += delta_time; | |
if (elapsed_time >= movement_time) { | |
elapsed_time = movement_time; | |
advance = true; | |
} | |
auto position = from + (to - from) * static_cast<float>(elapsed_time / movement_time); | |
glm::mat4 model = glm::translate(glm::mat4{1.0}, position); | |
glUniform1f(alpha_location, 1.f); | |
glUniformMatrix4fv(model_location, 1, GL_FALSE, glm::value_ptr(model)); | |
glDrawArrays(GL_TRIANGLES, 0, sizeof(vertices) / sizeof(GLfloat) / 3); | |
if (advance) { | |
if (++stage == trajectory.size()) | |
stage = 0; | |
elapsed_time = 0.; | |
} | |
glUniform1f(alpha_location, .3f); | |
//for(GLuint i = 0; i < 10; i++) { | |
model = glm::translate(glm::mat4{1.0}, to); | |
glUniformMatrix4fv(model_location, 1, GL_FALSE, glm::value_ptr(model)); | |
glDrawArrays(GL_TRIANGLES, 0, 36); | |
//} | |
glBindVertexArray(0); | |
glfwSwapBuffers(window); | |
} | |
glDeleteVertexArrays(1, &VAO); | |
glDeleteBuffers(1, &VBO); | |
glfwTerminate(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment