-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e83c559
commit 4588120
Showing
11 changed files
with
262 additions
and
21 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
cmake_minimum_required(VERSION 3.10) | ||
|
||
############################# | ||
# set C++ detail | ||
enable_language(CXX) | ||
set(CMAKE_CXX_STANDARD 17) | ||
set(CMAKE_CXX_STANDARD_REQUIRED TRUE) | ||
|
||
############################# | ||
|
||
# set project name | ||
project(task04) | ||
|
||
# define a macro to get absolute path in C++ | ||
add_definitions(-DPROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}") | ||
|
||
############################# | ||
# specifying libraries to use | ||
|
||
# use opengl | ||
find_package(OpenGL REQUIRED) | ||
|
||
# use glfw | ||
set(CMAKE_PREFIX_PATH ${PROJECT_SOURCE_DIR}/../external/glfwlib) | ||
find_package(glfw3 REQUIRED) | ||
|
||
######################## | ||
# include, build, & link | ||
|
||
include_directories(${PROJECT_NAME} | ||
${PROJECT_SOURCE_DIR}/../external | ||
${PROJECT_SOURCE_DIR}/../external/glad3/include | ||
${PROJECT_SOURCE_DIR}/../external/eigen | ||
) | ||
|
||
add_executable(${PROJECT_NAME} | ||
main.cpp | ||
${PROJECT_SOURCE_DIR}/../external/glad3/src/glad.c | ||
) | ||
|
||
# https://stackoverflow.com/questions/33678965/need-to-link-cmake-project-to-dl-library | ||
target_link_libraries(${PROJECT_NAME} | ||
OpenGL::GL | ||
glfw | ||
${CMAKE_DL_LIBS} | ||
) | ||
|
||
############################# | ||
# showing status of libraries | ||
|
||
GET_TARGET_PROPERTY(GLFW_INCLUDE_DIR | ||
glfw INTERFACE_INCLUDE_DIRECTORIES) | ||
message(STATUS "task04 glfw include directory: ${GLFW_INCLUDE_DIR}") |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Task04: Vertex Shader Practice (Mirror Reflection) | ||
|
||
 | ||
|
||
**Deadline: May 16th (Thu) at 15:00pm** | ||
|
||
---- | ||
|
||
## Before Doing Assignment | ||
|
||
If you have not done the [task01](../task01), [task02](../task02) do it first to set up the C++ development environment. | ||
|
||
Follow [this document](../doc/submit.md) to submit the assignment, In a nutshell, before doing the assignment, | ||
- make sure you synchronized the `main ` branch of your local repository to that of remote repository. | ||
- make sure you created branch `task04` from `main` branch. | ||
- make sure you are currently in the `task04` branch (use `git branch -a` command). | ||
|
||
Additionally, you need to install `glfw` library. | ||
Follow [this document](../doc/setup_glfw.md) to install glfw. | ||
|
||
Now you are ready to go! | ||
|
||
--- | ||
|
||
## Problem 1 | ||
|
||
1. Build the code using cmake | ||
2. Run the code | ||
3. Take a screenshot image (looks like image at the top) | ||
4. Save the screenshot image overwriting `task04/problem1.png` | ||
|
||
 | ||
|
||
|
||
## Problem 2 | ||
|
||
Write some code (about 5 ~ 10 lines) around `line #29` in `shader.vert` | ||
to define the coordinate transformation for mirror reflection. | ||
Read the instruction in the `shader.vert` for more information. | ||
|
||
Save the screenshot image overwriting `task04/problem2.png` | ||
|
||
 | ||
|
||
|
||
## After Doing the Assignment | ||
|
||
After modify the code, push the code and submit a pull request. |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#include <iostream> | ||
#include <cstdlib> | ||
#include <glad/glad.h> | ||
#define GL_SILENCE_DEPRECATION | ||
#include <GLFW/glfw3.h> | ||
// | ||
#include "../src/util_opengl.h" | ||
#include "../src/util_triangle_mesh.h" | ||
|
||
/*** | ||
* draw triangle mesh | ||
* @param tri2vtx triangle index | ||
* @param vtx2xyz vertex coordinates | ||
* @param vtx2normal vertex normals | ||
*/ | ||
void draw( | ||
const Eigen::Matrix<unsigned int, 3, Eigen::Dynamic> &tri2vtx, | ||
const Eigen::Matrix3Xf &vtx2xyz, | ||
const Eigen::Matrix3Xf &vtx2normal) { | ||
::glBegin(GL_TRIANGLES); | ||
for (auto i_tri = 0; i_tri < tri2vtx.cols(); ++i_tri) { | ||
const auto i0 = tri2vtx(0, i_tri); | ||
const auto i1 = tri2vtx(1, i_tri); | ||
const auto i2 = tri2vtx(2, i_tri); | ||
::glNormal3fv(vtx2normal.data() + i0 * 3); | ||
::glVertex3fv(vtx2xyz.data() + i0 * 3); | ||
::glNormal3fv(vtx2normal.data() + i1 * 3); | ||
::glVertex3fv(vtx2xyz.data() + i1 * 3); | ||
::glNormal3fv(vtx2normal.data() + i2 * 3); | ||
::glVertex3fv(vtx2xyz.data() + i2 * 3); | ||
} | ||
::glEnd(); | ||
} | ||
|
||
int main() { | ||
const auto file_path = std::filesystem::path(PROJECT_SOURCE_DIR) / ".." / "asset" / "armadillo.obj"; | ||
auto[tri2vtx, vtx2xyz] = acg::read_wavefrontobj_as_3d_triangle_mesh(file_path); | ||
// bounding box | ||
auto aabb_max = vtx2xyz.rowwise().maxCoeff(); | ||
auto aabb_min = vtx2xyz.rowwise().minCoeff(); | ||
auto aabb_center = (aabb_min + aabb_max) * 0.5f; // center of the bounding box | ||
auto aabb_size = (aabb_max - aabb_min).maxCoeff(); // size of the bounding box | ||
// normalize coordinate | ||
vtx2xyz = (vtx2xyz.colwise() - aabb_center) / aabb_size * 1.3; | ||
vtx2xyz = Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()).matrix() * vtx2xyz; | ||
vtx2xyz = vtx2xyz.colwise() + Eigen::Vector3f(0.2, 0.0, 0.0); | ||
// compute normals at vertices | ||
const auto vtx2normal = acg::vertex_normals_of_triangle_mesh(tri2vtx, vtx2xyz); | ||
|
||
if (!glfwInit()) { exit(EXIT_FAILURE); } | ||
// set OpenGL's version (note: ver. 2.1 is very old, but I chose because it's simple) | ||
::glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); | ||
::glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); | ||
// open window | ||
GLFWwindow *window = ::glfwCreateWindow(500, 500, "task04", nullptr, nullptr); | ||
if (!window) { // exit if failed to create window | ||
::glfwTerminate(); | ||
exit(EXIT_FAILURE); | ||
} | ||
::glfwMakeContextCurrent(window); // working on this window | ||
if (!gladLoadGL()) { // glad: load all OpenGL function pointers | ||
std::cout << "Something went wrong in loading OpenGL functions!\n" << std::endl; | ||
exit(-1); | ||
} | ||
|
||
int shaderProgram; | ||
{ // compile shader program | ||
std::string vrt_path = std::filesystem::path(PROJECT_SOURCE_DIR) / "shader.vert"; | ||
std::string frg_path = std::filesystem::path(PROJECT_SOURCE_DIR) / "shader.frag"; | ||
std::string vrt = acg::load_file_as_string(vrt_path); // read source code of vertex shader program | ||
std::string frg = acg::load_file_as_string(frg_path); // read source code of fragment shader program | ||
shaderProgram = acg::create_shader_program(vrt, frg); // compile the shader on GPU | ||
} | ||
::glUseProgram(shaderProgram); // use the shader program | ||
GLint iloc = glGetUniformLocation(shaderProgram, "is_reflection"); // shader program variable | ||
|
||
::glClearColor(1, 1, 1, 1); // set the color to fill the frame buffer when glClear is called. | ||
::glEnable(GL_DEPTH_TEST); | ||
while (!::glfwWindowShouldClose(window)) { | ||
::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||
::glUniform1i(iloc, true); // set value to the shader program (draw reflection of the triangle mesh) | ||
draw(tri2vtx, vtx2xyz, vtx2normal); | ||
::glUniform1i(iloc, false); // set value to the shader program (draw triangle mesh) | ||
draw(tri2vtx, vtx2xyz, vtx2normal); | ||
|
||
::glfwSwapBuffers(window); | ||
::glfwPollEvents(); | ||
} | ||
::glfwDestroyWindow(window); | ||
::glfwTerminate(); | ||
exit(EXIT_SUCCESS); | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#version 120 | ||
|
||
varying vec3 normal; // normal interpolated using baricentric coordinate | ||
|
||
void main() | ||
{ | ||
// draw normal | ||
gl_FragColor = vec4(0.5*normal+0.5,1); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#version 120 | ||
|
||
// see the GLSL 1.2 specification: | ||
// https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.1.20.pdf | ||
|
||
uniform bool is_reflection; // variable of the program | ||
varying vec3 normal; // normal vector pass to the rasterizer and fragment shader | ||
|
||
void main() | ||
{ | ||
normal = vec3(gl_Normal);// set normal and pass it to fragment shader | ||
|
||
// "gl_Vertex" is the *input* vertex coordinate of triangle. | ||
// "gl_Vertex" has type of "vec4", which is homogeneious coordinate | ||
float x0 = gl_Vertex.x/gl_Vertex.w;// x-coord | ||
float y0 = gl_Vertex.y/gl_Vertex.w;// y-coord | ||
float z0 = gl_Vertex.z/gl_Vertex.w;// z-coord | ||
if (is_reflection) { | ||
vec3 nrm = normalize(vec3(0.4, 0.0, 1.0)); // normal of the mirror | ||
vec3 org = vec3(-0.3, 0.0, -0.5); // point on the mirror | ||
// wite code to change the input position (x0,y0,z0). | ||
// the transformed position (x0, y0, z0) should be drawn as the mirror reflection. | ||
// | ||
// make sure the occlusion is correctly computed. | ||
// the mirror is behind the armadillo, so the reflected image should be behind the armadillo. | ||
// furthermore, make sure the occlusion is correctly computed for the reflected image. | ||
//x0 = ??? | ||
//y0 = ??? | ||
//z0 = ??? | ||
} | ||
// do not edit below | ||
|
||
// "gl_Position" is the *output* vertex coordinate in the | ||
// "canonical view volume (i.e.. [-1,+1]^3)" pass to the rasterizer. | ||
gl_Position = vec4(x0, y0, -z0, 1);// opengl actually draw a pixel with *maximum* depth. so invert z | ||
} |