Skip to content

Instantly share code, notes, and snippets.

@chengluyu
Created July 7, 2018 15:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chengluyu/cda78bb6041967bd05e1e57032e630c5 to your computer and use it in GitHub Desktop.
Save chengluyu/cda78bb6041967bd05e1e57032e630c5 to your computer and use it in GitHub Desktop.
Computer Graphics Experiment 2
#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