Skip to content

Commit

Permalink
added task04
Browse files Browse the repository at this point in the history
  • Loading branch information
nobuyuki83 committed May 13, 2024
1 parent e83c559 commit 4588120
Show file tree
Hide file tree
Showing 11 changed files with 262 additions and 21 deletions.
20 changes: 10 additions & 10 deletions .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ jobs:
steps:
- uses: actions/checkout@v2

#- name: install glfw
# run: |
# sudo apt install -y \
# libwayland-dev libxkbcommon-dev wayland-protocols extra-cmake-modules \
# libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev
# git submodule update --init -- external/glfw
# cmake -S external/glfw -B external/glfwbuild
# cd external/glfwbuild
# cmake --build . --config Release
# cmake --install . --prefix ../glfwlib
- name: install glfw
run: |
sudo apt install -y \
libwayland-dev libxkbcommon-dev wayland-protocols extra-cmake-modules \
libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev
git submodule update --init -- external/glfw
cmake -S external/glfw -B external/glfwbuild
cd external/glfwbuild
cmake --build . --config Release
cmake --install . --prefix ../glfwlib
- name: install eigen
run: |
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ jobs:
- uses: actions/checkout@v2


#- name: install glfw
# run: |
# git submodule update --init -- external/glfw
# cmake -S external/glfw -B external/glfwbuild
# cd external/glfwbuild
# cmake --build . --config Release
# cmake --install . --prefix ../glfwlib
- name: install glfw
run: |
git submodule update --init -- external/glfw
cmake -S external/glfw -B external/glfwbuild
cd external/glfwbuild
cmake --build . --config Release
cmake --install . --prefix ../glfwlib
- name: get eigen
run: |
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ project(tasks)
add_subdirectory(task01)
add_subdirectory(task02)
add_subdirectory(task03)
# add_subdirectory(task04)
add_subdirectory(task04)
# add_subdirectory(task05)
# add_subdirectory(task06)
# add_subdirectory(task07)
Expand Down
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Topics:
|(2)<br>Apr. 15| **Parametric curves / surfaces** <br/>**Rasterization in 2D**, Digital Differential Analyzer | [task01](task01) | [[5]](http://nobuyuki-umetani.com/acg2024s/rasterization_2d.pdf) [[6]](http://nobuyuki-umetani.com/acg2024s/barycentric_coordinates.pdf) |
|(3)<br>Apr. 22| **Parametric representation**<br/>Bézier curve, polynominal | [task02](task02) | [[7] ](http://nobuyuki-umetani.com/acg2024s/parametric_curve.pdf) [[8]](http://nobuyuki-umetani.com/acg2024s/polynominal.pdf) |
|(5)<br>May 7| **Coordinate transformation**<br>Affine, homography transformation | [task03](task03) | [[9]](http://nobuyuki-umetani.com/acg2024s/transformation.pdf) [[10]](http://nobuyuki-umetani.com/acg2024s/transformation_homogeneous_2d.pdf) [[11]](http://nobuyuki-umetani.com/acg2024s/transformation_homogeneous_3d.pdf) |
|(4)<br>May 13| **Graphics pipeline**<br>depth buffer method, shading, shadow, anti aliasing | task04 | |
|(4)<br>May 13| **Graphics pipeline**<br>depth buffer method, shading, shadow, anti aliasing | [task04](task04) | [[12]](http://nobuyuki-umetani.com/acg2024s/rasterization_3d.pdf)[[13]](http://nobuyuki-umetani.com/acg2024s/graphics_pipeline.pdf)[[14]](http://nobuyuki-umetani.com/acg2024s/shading.pdf) |
|(6)<br>May 20| **Ray Casting 1**<br/>spatial data structure | task05 | |
|(7)<br>May 27| **Ray Casting 2**<br>Rendering equation, Monte Carlo integration | task06 | |
|(8)<br>June 3| **Character animation**<br> Linear blend skinning | task07 | |
Expand Down Expand Up @@ -81,7 +81,7 @@ Look at the following document.
| [task01](task01) | **Rasterization of lines and polygons**<br>DDA, winding number | <img src="task01/preview.png" width=100px> |
| [task02](task02) | **Rasterization of parametric curves**<br> Quadratic Bézier curve, root of polynominal | <img src="task02/preview.png" width=100px> |
| [task03](task03) | **Perspectively-correct texture mapping**<br>rasterization of triangle, barycentric coordinate | <img src="task03/preview.png" width=100px> |
| task04 | **Vertex shader practice** <br>Rendering pipeline, mirror reflection, OpenGL | <img src="task04/preview.png" width=100px> |
| [task04](task04) | **Vertex shader practice** <br>Rendering pipeline, mirror reflection, OpenGL | <img src="task04/preview.png" width=100px> |
| task05 | **Fragment shader practice**<br>Ray marching method, CSG modeling, implicit modeling | <img src="task05/preview.png" width=100px> |
| task06 | **Monte Carlo integration**<br>Multiple importance sampling, path tracing, rendering equation | <img src="task06/preview.png" width=100px> |
| task07 | TBD | |
Expand Down Expand Up @@ -110,7 +110,10 @@ Look at the following document.
- [[9] Coordinate Transformation](http://nobuyuki-umetani.com/acg2024s/transformation.pdf)
- [[10] 2D Homogeneous Transformation](http://nobuyuki-umetani.com/acg2024s/transformation_homogeneous_2d.pdf)
- [[11] 3D Homogeneous Transformation](http://nobuyuki-umetani.com/acg2024s/transformation_homogeneous_3d.pdf)
- [[11] 3D Rasterization](http://nobuyuki-umetani.com/acg2024s/rasterization_3d.pdf)
- [[12] 3D Rasterization](http://nobuyuki-umetani.com/acg2024s/rasterization_3d.pdf)
- [[13] Graphics Pipeline](http://nobuyuki-umetani.com/acg2024s/graphics_pipeline.pdf)
- [[14] Shading](http://nobuyuki-umetani.com/acg2024s/shading.pdf)



## Reading Material
Expand Down
53 changes: 53 additions & 0 deletions task04/CMakeLists.txt
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}")
48 changes: 48 additions & 0 deletions task04/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Task04: Vertex Shader Practice (Mirror Reflection)

![preview](preview.png)

**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`

![problem1](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`

![problem2](problem2.png)


## After Doing the Assignment

After modify the code, push the code and submit a pull request.
92 changes: 92 additions & 0 deletions task04/main.cpp
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);
}
Binary file added task04/problem1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added task04/problem2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions task04/shader.frag
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);
}
36 changes: 36 additions & 0 deletions task04/shader.vert
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
}

0 comments on commit 4588120

Please sign in to comment.