Skip to content

Instantly share code, notes, and snippets.

@amoshyc
Last active December 30, 2018 07:55
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 amoshyc/a4bfe37c13ea668b80399d8a7d6cfe3b to your computer and use it in GitHub Desktop.
Save amoshyc/a4bfe37c13ea668b80399d8a7d6cfe3b to your computer and use it in GitHub Desktop.
#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;
}
#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;
}
#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