Last active
December 30, 2018 07:55
-
-
Save amoshyc/a4bfe37c13ea668b80399d8a7d6cfe3b to your computer and use it in GitHub Desktop.
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
#version 410 core | |
uniform sampler2D tex0; | |
uniform sampler2D tex1; | |
uniform sampler2D tex2; | |
out vec4 color; | |
in VS_OUT | |
{ | |
vec2 texcoord; | |
} fs_in; | |
void main(void) | |
{ | |
vec4 color0 = texture(tex0, fs_in.texcoord); | |
vec4 color1 = texture(tex1, fs_in.texcoord); | |
vec4 color2 = texture(tex2, fs_in.texcoord); | |
color = color0; | |
} |
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
#version 410 core | |
layout (location = 0) in vec2 position; | |
layout (location = 1) in vec2 texcoord; | |
out VS_OUT | |
{ | |
vec2 texcoord; | |
} vs_out; | |
void main(void) | |
{ | |
gl_Position = vec4(position,1.0,1.0); | |
vs_out.texcoord = texcoord; | |
} |
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
#include "../Externals/Include/Include.h" | |
#include "Object.hpp" | |
#define sz(x) (int(x.size())) | |
using namespace glm; | |
using namespace std; | |
#define SHADOW_MAP_SIZE 2048 | |
Object quad; | |
Object suit; | |
vec3 light_pos = vec3(-31.75, 26.05, -97.72); | |
struct { | |
struct { | |
mat4 view; | |
mat4 proj; | |
} eye; | |
} matrices; | |
struct { | |
struct { | |
GLint mvp; | |
} light; | |
struct { | |
GLuint shadow_tex; | |
GLuint skybox_tex; | |
GLint mv_matrix; | |
GLint proj_matrix; | |
GLint shadow_matrix; | |
GLint light_pos; | |
GLint is_quad; | |
} view; | |
struct { | |
GLuint view; | |
GLuint proj; | |
} skybox; | |
struct { | |
GLuint tex0; | |
GLuint tex1; | |
GLuint tex2; | |
} fuse; | |
} uniforms; | |
struct { | |
GLuint fbo; | |
GLuint depthMap; | |
} shadowBuffer; | |
struct { | |
int width; | |
int height; | |
} viewportSize; | |
struct { | |
GLuint vao; | |
GLuint vbo; | |
GLuint tex; | |
} skybox; | |
struct { | |
int cur_mode = 4; | |
GLuint vao; | |
GLuint vbo; | |
GLuint fbo[3]; | |
GLuint tex[3]; | |
} stage; | |
GLuint depthProg; | |
GLuint blinnPhongProg; | |
GLuint skyboxProg; | |
GLuint fuseProg; | |
float skyboxVertices[] = { | |
-1.0f, +1.0f, -1.0f, -1.0f, -1.0f, -1.0f, +1.0f, -1.0f, -1.0f, | |
+1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, -1.0f, +1.0f, -1.0f, | |
-1.0f, -1.0f, +1.0f, -1.0f, -1.0f, -1.0f, -1.0f, +1.0f, -1.0f, | |
-1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, -1.0f, +1.0f, | |
+1.0f, -1.0f, -1.0f, +1.0f, -1.0f, +1.0f, +1.0f, +1.0f, +1.0f, | |
+1.0f, +1.0f, +1.0f, +1.0f, +1.0f, -1.0f, +1.0f, -1.0f, -1.0f, | |
-1.0f, -1.0f, +1.0f, -1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, | |
+1.0f, +1.0f, +1.0f, +1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, | |
-1.0f, +1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f, +1.0f, | |
+1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, -1.0f, | |
-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, -1.0f, | |
+1.0f, -1.0f, -1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f}; | |
GLuint createProgram(string name) { | |
auto vs_path = "shaders/" + name + ".vs.glsl"; | |
auto fs_path = "shaders/" + name + ".fs.glsl"; | |
auto program = glCreateProgram(); | |
auto vs_shader = glCreateShader(GL_VERTEX_SHADER); | |
auto fs_shader = glCreateShader(GL_FRAGMENT_SHADER); | |
char **vs_source = loadShaderSource(vs_path.c_str()); | |
char **fs_source = loadShaderSource(fs_path.c_str()); | |
glShaderSource(vs_shader, 1, vs_source, NULL); | |
glShaderSource(fs_shader, 1, fs_source, NULL); | |
freeShaderSource(vs_source); | |
freeShaderSource(fs_source); | |
cout << "Compiling " << vs_path << endl; | |
glCompileShader(vs_shader); | |
shaderLog(vs_shader); | |
cout << "Compiling " << fs_path << endl; | |
glCompileShader(fs_shader); | |
shaderLog(fs_shader); | |
glAttachShader(program, vs_shader); | |
glAttachShader(program, fs_shader); | |
glLinkProgram(program); | |
return program; | |
} | |
void My_Init() { | |
glEnable(GL_DEPTH_TEST); | |
glDepthFunc(GL_LEQUAL); | |
depthProg = createProgram("shadow"); | |
uniforms.light.mvp = glGetUniformLocation(depthProg, "mvp"); | |
// ----- End Initialize Depth Shader Program ----- | |
skyboxProg = createProgram("skybox"); | |
uniforms.skybox.proj = glGetUniformLocation(skyboxProg, "proj"); | |
uniforms.skybox.view = glGetUniformLocation(skyboxProg, "view"); | |
// ----- Begin Initialize Blinn-Phong Shader Program ----- | |
blinnPhongProg = createProgram("blinnphong"); | |
uniforms.view.proj_matrix = | |
glGetUniformLocation(blinnPhongProg, "proj_matrix"); | |
uniforms.view.mv_matrix = glGetUniformLocation(blinnPhongProg, "mv_matrix"); | |
uniforms.view.shadow_matrix = | |
glGetUniformLocation(blinnPhongProg, "shadow_matrix"); | |
uniforms.view.shadow_tex = | |
glGetUniformLocation(blinnPhongProg, "shadow_tex"); | |
uniforms.view.skybox_tex = | |
glGetUniformLocation(blinnPhongProg, "skybox_tex"); | |
uniforms.view.light_pos = glGetUniformLocation(blinnPhongProg, "light_pos"); | |
uniforms.view.is_quad = glGetUniformLocation(blinnPhongProg, "is_quad"); | |
// ----- End Initialize Blinn-Phong Shader Program ----- | |
fuseProg = createProgram("fuse"); | |
uniforms.fuse.tex0 = glGetUniformLocation(fuseProg, "tex0"); | |
uniforms.fuse.tex1 = glGetUniformLocation(fuseProg, "tex1"); | |
uniforms.fuse.tex2 = glGetUniformLocation(fuseProg, "tex2"); | |
quad = Object("quad.obj"); | |
quad.model = mat4(); | |
quad.model = translate(quad.model, vec3(-10, -13, -8)); | |
quad.model = translate(quad.model, vec3(+3, 0, +8)); | |
quad.model = scale(quad.model, vec3(1.1, 1, 1.5)); | |
suit = Object("nanosuit.obj"); | |
suit.model = mat4(); | |
suit.model = translate(suit.model, vec3(-10, -13, -8)); | |
suit.model = scale(suit.model, vec3(0.5, 0.35, 0.5)); | |
// Skybox | |
cout << "Loading Skybox" << endl; | |
vector<string> filenames = {"right.jpg", "left.jpg", "top.jpg", | |
"bottom.jpg", "front.jpg", "back.jpg"}; | |
glGenTextures(1, &skybox.tex); | |
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox.tex); | |
for (int i = 0; i < 6; i++) { | |
auto name = filenames[i]; | |
auto path = "boxes/" + name; | |
int w, h, c; | |
unsigned char *data = stbi_load(path.c_str(), &w, &h, &c, 0); | |
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, w, h, 0, | |
GL_RGB, GL_UNSIGNED_BYTE, data); | |
stbi_image_free(data); | |
cout << "\t" << name << ": " << w << ", " << h << endl; | |
} | |
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); | |
glGenVertexArrays(1, &skybox.vao); | |
glBindVertexArray(skybox.vao); | |
glGenBuffers(1, &skybox.vbo); | |
glBindBuffer(GL_ARRAY_BUFFER, skybox.vbo); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, | |
GL_STATIC_DRAW); | |
glEnableVertexAttribArray(0); | |
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); | |
// ----- Begin Initialize Shadow Framebuffer Object ----- | |
glGenFramebuffers(1, &shadowBuffer.fbo); | |
glBindFramebuffer(GL_FRAMEBUFFER, shadowBuffer.fbo); | |
glGenTextures(1, &shadowBuffer.depthMap); | |
glBindTexture(GL_TEXTURE_2D, shadowBuffer.depthMap); | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, SHADOW_MAP_SIZE, | |
SHADOW_MAP_SIZE, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, | |
GL_COMPARE_REF_TO_TEXTURE); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); | |
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, | |
shadowBuffer.depthMap, 0); | |
// ----- End Initialize Shadow Framebuffer Object ----- | |
static const GLfloat window_positions[] = { | |
1.0f, -1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 0.0f, | |
-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f}; | |
glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
glGenVertexArrays(1, &stage.vao); | |
glBindVertexArray(stage.vao); | |
glGenBuffers(1, &stage.vbo); | |
glBindBuffer(GL_ARRAY_BUFFER, stage.vbo); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(window_positions), &window_positions, | |
GL_STATIC_DRAW); | |
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT) * 4, 0); | |
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT) * 4, | |
(const GLvoid *)(sizeof(GL_FLOAT) * 2)); | |
glEnableVertexAttribArray(0); | |
glEnableVertexAttribArray(1); | |
for (int i = 0; i < 3; i++) { | |
glGenFramebuffers(1, &stage.fbo[i]); | |
glBindFramebuffer(GL_FRAMEBUFFER, stage.fbo[i]); | |
glGenTextures(1, &stage.tex[i]); | |
glBindTexture(GL_TEXTURE_2D, stage.tex[i]); | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, viewportSize.width, | |
viewportSize.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, | |
GL_COMPARE_REF_TO_TEXTURE); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); | |
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | |
GL_TEXTURE_2D, stage.tex[i], 0); | |
} | |
} | |
void renderShadow(const mat4 &light_vp_matrix) { | |
glUseProgram(depthProg); | |
glBindFramebuffer(GL_FRAMEBUFFER, shadowBuffer.fbo); | |
glClear(GL_DEPTH_BUFFER_BIT); | |
glViewport(0, 0, SHADOW_MAP_SIZE, SHADOW_MAP_SIZE); | |
glEnable(GL_POLYGON_OFFSET_FILL); | |
glPolygonOffset(4.0f, 4.0f); | |
glUniformMatrix4fv(uniforms.light.mvp, 1, GL_FALSE, | |
value_ptr(light_vp_matrix * quad.model)); | |
quad.render(); | |
glUniformMatrix4fv(uniforms.light.mvp, 1, GL_FALSE, | |
value_ptr(light_vp_matrix * suit.model)); | |
suit.render(); | |
glDisable(GL_POLYGON_OFFSET_FILL); | |
glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glViewport(0, 0, viewportSize.width, viewportSize.height); | |
} | |
void renderObject(const mat4 &shadow_sbpv_matrix) { | |
glUseProgram(blinnPhongProg); | |
glUniformMatrix4fv(uniforms.view.proj_matrix, 1, GL_FALSE, | |
value_ptr(matrices.eye.proj)); | |
glUniformMatrix4fv(uniforms.view.light_pos, 1, GL_FALSE, | |
value_ptr(light_pos)); | |
glActiveTexture(GL_TEXTURE0); | |
glBindTexture(GL_TEXTURE_2D, shadowBuffer.depthMap); | |
glUniform1i(uniforms.view.shadow_tex, 0); | |
glActiveTexture(GL_TEXTURE1); | |
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox.tex); | |
glUniform1i(uniforms.view.skybox_tex, 1); | |
mat4 quad_mv = matrices.eye.view * quad.model; | |
mat4 shadow_matrix = shadow_sbpv_matrix * quad.model; | |
glUniform1i(uniforms.view.is_quad, 1); | |
glUniformMatrix4fv(uniforms.view.mv_matrix, 1, GL_FALSE, | |
value_ptr(quad_mv)); | |
glUniformMatrix4fv(uniforms.view.shadow_matrix, 1, GL_FALSE, | |
value_ptr(shadow_matrix)); | |
quad.render(); | |
mat4 suit_mv = matrices.eye.view * suit.model; | |
shadow_matrix = shadow_sbpv_matrix * suit.model; | |
glUniform1i(uniforms.view.is_quad, 0); | |
glUniformMatrix4fv(uniforms.view.mv_matrix, 1, GL_FALSE, | |
value_ptr(suit_mv)); | |
glUniformMatrix4fv(uniforms.view.shadow_matrix, 1, GL_FALSE, | |
value_ptr(shadow_matrix)); | |
suit.render(); | |
} | |
void renderSkybox() { | |
glDepthFunc(GL_LEQUAL); | |
glUseProgram(skyboxProg); | |
mat4 view = mat4(mat3(matrices.eye.view)); | |
mat4 proj = matrices.eye.proj; | |
glUniformMatrix4fv(uniforms.skybox.view, 1, GL_FALSE, value_ptr(view)); | |
glUniformMatrix4fv(uniforms.skybox.proj, 1, GL_FALSE, value_ptr(proj)); | |
glBindVertexArray(skybox.vao); | |
glActiveTexture(GL_TEXTURE0); | |
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox.tex); | |
glDrawArrays(GL_TRIANGLES, 0, 36); | |
glDepthFunc(GL_LESS); | |
} | |
void renderS1() { | |
mat4 scale_bias_matrix = translate(mat4(), vec3(0.5f, 0.5f, 0.5f)) * | |
scale(mat4(), vec3(0.5f, 0.5f, 0.5f)); | |
const float shadow_range = 15.0f; | |
mat4 light_proj_matrix = ortho(-shadow_range, shadow_range, -shadow_range, | |
shadow_range, 0.0f, 500.0f); | |
mat4 light_view_matrix = | |
lookAt(light_pos, vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f)); | |
mat4 light_vp_matrix = light_proj_matrix * light_view_matrix; | |
mat4 shadow_sbpv_matrix = scale_bias_matrix * light_vp_matrix; | |
// renderShadow(light_vp_matrix); | |
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, stage.fbo[0]); | |
glDrawBuffer(GL_COLOR_ATTACHMENT0); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
renderObject(shadow_sbpv_matrix); | |
glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
} | |
void renderS2() { ; } | |
void renderS3() { ; } | |
void renderS4() { | |
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glClearColor(0.1f, 0.1f, 0.1f, 1.0f); | |
glUseProgram(fuseProg); | |
glActiveTexture(GL_TEXTURE0); | |
glBindTexture(GL_TEXTURE_2D, stage.tex[0]); | |
glUniform1i(uniforms.fuse.tex0, 0); | |
glActiveTexture(GL_TEXTURE1); | |
glBindTexture(GL_TEXTURE_2D, stage.tex[1]); | |
glUniform1i(uniforms.fuse.tex1, 1); | |
glActiveTexture(GL_TEXTURE2); | |
glBindTexture(GL_TEXTURE_2D, stage.tex[2]); | |
glUniform1i(uniforms.fuse.tex2, 2); | |
glBindVertexArray(stage.vao); | |
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | |
} | |
void My_Display() { | |
// mat4 scale_bias_matrix = | |
// translate(mat4(), vec3(0.5f, 0.5f, 0.5f)) * | |
// scale(mat4(), vec3(0.5f, 0.5f, 0.5f)); | |
// const float shadow_range = 15.0f; | |
// mat4 light_proj_matrix = ortho(-shadow_range, shadow_range, | |
// -shadow_range, shadow_range, 0.0f, 500.0f); mat4 light_view_matrix = | |
// lookAt(light_pos, vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f)); mat4 | |
// light_vp_matrix = light_proj_matrix * light_view_matrix; mat4 | |
// shadow_sbpv_matrix = scale_bias_matrix * light_vp_matrix; | |
// renderShadow(light_vp_matrix); | |
// glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
// glViewport(0, 0, viewportSize.width, viewportSize.height); | |
// renderObject(shadow_sbpv_matrix); | |
// renderSkybox(); | |
renderS1(); | |
// renderS2(); | |
// renderS3(); | |
renderS4(); | |
glutSwapBuffers(); | |
} | |
void My_Reshape(int width, int height) { | |
viewportSize.width = width; | |
viewportSize.height = height; | |
float viewportAspect = (float)width / (float)height; | |
matrices.eye.proj = | |
perspective(radians(80.0f), viewportAspect, 0.1f, 1000.0f); | |
matrices.eye.view = lookAt(vec3(0.0f, 0.0f, 0.0f), vec3(-1.0f, -1.0f, 0.0f), | |
vec3(0.0f, 1.0f, 0.0f)); | |
} | |
void My_Timer(int val) { | |
glutPostRedisplay(); | |
glutTimerFunc(16, My_Timer, val); | |
} | |
int main(int argc, char *argv[]) { | |
// Initialize GLUT and GLEW, then create a window. | |
//////////////////// | |
glutInit(&argc, argv); | |
#ifdef _MSC_VER | |
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); | |
#else | |
glutInitDisplayMode(GLUT_3_2_CORE_PROFILE | GLUT_RGBA | GLUT_DOUBLE | | |
GLUT_DEPTH); | |
#endif | |
glutInitWindowPosition(100, 100); | |
glutInitWindowSize(1440 * 2 / 3, 900 * 2 / 3); | |
glutCreateWindow(__FILENAME__); // You cannot use OpenGL functions before | |
// this line; The OpenGL context must be | |
// created first by glutCreateWindow()! | |
#ifdef _MSC_VER | |
glewInit(); | |
#endif | |
dumpInfo(); | |
My_Init(); | |
//////////////////// | |
// Register GLUT callback functions. | |
/////////////////////////////// | |
glutDisplayFunc(My_Display); | |
glutReshapeFunc(My_Reshape); | |
glutTimerFunc(16, My_Timer, 0); | |
/////////////////////////////// | |
// Enter main event loop. | |
////////////// | |
glutMainLoop(); | |
////////////// | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment