diff options
| -rw-r--r-- | source/main.cpp | 251 | ||||
| -rw-r--r-- | source/shaders/fbo.fs.glsl | 2 | 
2 files changed, 242 insertions, 11 deletions
| diff --git a/source/main.cpp b/source/main.cpp index 650799d..ede861f 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -559,10 +559,16 @@ int main(int argc, char* argv[])    char* blend_shader_source = (char*)SDL_LoadFile("./source/shaders/blend_test.fs.glsl", &read_count);    char* fbo_vs = (char*)SDL_LoadFile("./source/shaders/fbo.vs.glsl", &read_count);    char* fbo_fs = (char*)SDL_LoadFile("./source/shaders/fbo.fs.glsl", &read_count); +  char* cubemap_vs = (char*)SDL_LoadFile("./source/shaders/cubemap.vs.glsl", &read_count); +  char* cubemap_fs = (char*)SDL_LoadFile("./source/shaders/cubemap.fs.glsl", &read_count); +  char* refl_vs = (char*)SDL_LoadFile("./source/shaders/refl.vs.glsl", &read_count); +  char* refl_fs = (char*)SDL_LoadFile("./source/shaders/refl.fs.glsl", &read_count);    u32 shader_program = gl_shader_program(vertex_source, fragment_source);  	u32 blend_shader_program = gl_shader_program(vertex_source, blend_shader_source);  	u32 fbo_shader_program = gl_shader_program(fbo_vs, fbo_fs); +  u32 cubemap_shader_program = gl_shader_program(cubemap_vs, cubemap_fs); +  u32 refl_shader_program = gl_shader_program(refl_vs, refl_fs);  	printf("Successfully compiled shaders.\n"); @@ -610,7 +616,8 @@ int main(int argc, char* argv[])      -0.5f,  0.5f, -0.5f,  0.0f, 1.0f, // top-left      -0.5f,  0.5f,  0.5f,  0.0f, 0.0f  // bottom-left         }; -    float planeVertices[] = { + +   float planeVertices[] = {        // positions          // texture Coords (note we set these higher than 1 (together with GL_REPEAT as texture wrapping mode). this will cause the floor texture to repeat)        // BottomFace        -5.0f, -1.0f, -5.0f,  0.0f, 2.0f, // top-right @@ -627,6 +634,7 @@ int main(int argc, char* argv[])        -5.0f, -0.5f, -5.0f,  0.0f, 2.0f, // top-left        -5.0f, -0.5f,  5.0f,  0.0f, 0.0f  // bottom-left           }; +    float quadVertices[] = {        // Front face        -0.5f, -0.5f,  0.0f, 0.0f, // bottom-left @@ -643,6 +651,7 @@ int main(int argc, char* argv[])        -0.5f, -0.5f,  0.0f, 0.0f, // bottom-left        -0.5f,  0.5f,  0.0f, 1.0f, // top-left      }; +    float fboVertices[] = {        -1.0f, -1.0f,  0.0f, 0.0f, // bottom-left         1.0f, -1.0f,  1.0f, 0.0f, // bottom-right @@ -651,9 +660,108 @@ int main(int argc, char* argv[])        -1.0f,  1.0f,  0.0f, 1.0f, // top-left        -1.0f, -1.0f,  0.0f, 0.0f, // bottom-left    }; + +  float skyboxVertices[] = { +    // positions           +    -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 +  }; +  float reflVertices[] = { +    // positions          // texture Coords (note we set these higher than 1 (together with GL_REPEAT as texture wrapping mode). this will cause the floor texture to repeat) +    // Top face +    //-5.0f,  0.5f, -5.0f,  0.0f, 1.0f, 0.0f,// top-left +    // 5.0f,  0.5f,  5.0f,  0.0f, 1.0f, 0.0f,// bottom-right +    // 5.0f,  0.5f, -5.0f,  0.0f, 1.0f, 0.0f,// top-right      +    // 5.0f,  0.5f,  5.0f,  0.0f, 1.0f, 0.0f,// bottom-right +    //-5.0f,  0.5f, -5.0f,  0.0f, 1.0f, 0.0f,// top-left +    //-5.0f,  0.5f,  5.0f,  0.0f, 1.0f, 0.0f,// bottom-left      +    // Back face +    -0.5f, -0.5f, -0.5f,  0.0f, 0.0f, -1.0f, // Bottom-left +     0.5f,  0.5f, -0.5f,  0.0f, 0.0f, -1.0f, // top-right +     0.5f, -0.5f, -0.5f,  0.0f, 0.0f, -1.0f, // bottom-right          +     0.5f,  0.5f, -0.5f,  0.0f, 0.0f, -1.0f, // top-right +    -0.5f, -0.5f, -0.5f,  0.0f, 0.0f, -1.0f, // bottom-left +    -0.5f,  0.5f, -0.5f,  0.0f, 0.0f, -1.0f, // top-left +    // Front face +    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f, 1.0f, // bottom-left +     0.5f, -0.5f,  0.5f,  0.0f, 0.0f, 1.0f, // bottom-right +     0.5f,  0.5f,  0.5f,  0.0f, 0.0f, 1.0f, // top-right +     0.5f,  0.5f,  0.5f,  0.0f, 0.0f, 1.0f, // top-right +    -0.5f,  0.5f,  0.5f,  0.0f, 0.0f, 1.0f, // top-left +    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f, 1.0f, // bottom-left +    // Left face +    -0.5f,  0.5f,  0.5f,  -1.0f, 0.0f, 0.0f, // top-right +    -0.5f,  0.5f, -0.5f,  -1.0f, 0.0f, 0.0f, // top-left +    -0.5f, -0.5f, -0.5f,  -1.0f, 0.0f, 0.0f, // bottom-left +    -0.5f, -0.5f, -0.5f,  -1.0f, 0.0f, 0.0f, // bottom-left +    -0.5f, -0.5f,  0.5f,  -1.0f, 0.0f, 0.0f, // bottom-right +    -0.5f,  0.5f,  0.5f,  -1.0f, 0.0f, 0.0f, // top-right +    // Right face +     0.5f,  0.5f,  0.5f,   1.0f, 0.0f, 0.0f, // top-left +     0.5f, -0.5f, -0.5f,   1.0f, 0.0f, 0.0f, // bottom-right +     0.5f,  0.5f, -0.5f,   1.0f, 0.0f, 0.0f, // top-right          +     0.5f, -0.5f, -0.5f,   1.0f, 0.0f, 0.0f, // bottom-right +     0.5f,  0.5f,  0.5f,   1.0f, 0.0f, 0.0f, // top-left +     0.5f, -0.5f,  0.5f,   1.0f, 0.0f, 0.0f, // bottom-left      +    // Bottom face +    -0.5f, -0.5f, -0.5f,  0.0f, -1.0f, 0.0f, // top-right +     0.5f, -0.5f, -0.5f,  0.0f, -1.0f, 0.0f, // top-left +     0.5f, -0.5f,  0.5f,  0.0f, -1.0f, 0.0f, // bottom-left +     0.5f, -0.5f,  0.5f,  0.0f, -1.0f, 0.0f, // bottom-left +    -0.5f, -0.5f,  0.5f,  0.0f, -1.0f, 0.0f, // bottom-right +    -0.5f, -0.5f, -0.5f,  0.0f, -1.0f, 0.0f, // top-right +    // Top face +    -0.5f,  0.5f, -0.5f,  0.0f,  1.0f, 0.0f, // top-left +     0.5f,  0.5f,  0.5f,  0.0f,  1.0f, 0.0f, // bottom-right +     0.5f,  0.5f, -0.5f,  0.0f,  1.0f, 0.0f, // top-right      +     0.5f,  0.5f,  0.5f,  0.0f,  1.0f, 0.0f, // bottom-right +    -0.5f,  0.5f, -0.5f,  0.0f,  1.0f, 0.0f, // top-left +    -0.5f,  0.5f,  0.5f,  0.0f,  1.0f, 0.0f  // bottom-left       +  }; +    stbi_set_flip_vertically_on_load(1); -	u32 cube_vao, cube_vbo, plane_vao, plane_vbo, quad_vao, quad_vbo, fbo_vao, fbo_vbo; +	u32 cube_vao, cube_vbo, plane_vao, plane_vbo, quad_vao, quad_vbo, fbo_vao, fbo_vbo,  +      skybox_vao, skybox_vbo, refl_vao, refl_vbo;  	glGenVertexArrays(1, &cube_vao);  	glGenBuffers(1, &cube_vbo); @@ -704,6 +812,30 @@ int main(int argc, char* argv[])    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2*sizeof(float)));    glBindVertexArray(0); +  // skybox objects +	glGenVertexArrays(1, &skybox_vao); +	glGenBuffers(1, &skybox_vbo); + +	glBindVertexArray(skybox_vao); +  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), (void*)0); +  glBindVertexArray(0); + +  // reflective surface objects +	glGenVertexArrays(1, &refl_vao); +	glGenBuffers(1, &refl_vbo); + +	glBindVertexArray(refl_vao); +  glBindBuffer(GL_ARRAY_BUFFER, refl_vbo); +  glBufferData(GL_ARRAY_BUFFER, sizeof(reflVertices), &reflVertices, GL_STATIC_DRAW); +  glEnableVertexAttribArray(0); +  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); +  glEnableVertexAttribArray(1); +  glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3*sizeof(float))); +  glBindVertexArray(0); +    u32 window_tex_id;    glGenTextures(1, &window_tex_id);    glActiveTexture(GL_TEXTURE2); @@ -752,12 +884,13 @@ int main(int argc, char* argv[])  	// objects  	Vec3 model_translations[] = { -		Vec3{  0.5, 0.0,  0.0}, //origin square -		Vec3{ -1.0, 0.0, -1.0}, // plane -		Vec3{ -1.0, 0.0, -0.5}, // window between squares -		Vec3{  0.0, 0.0,  3.0}, //window infront of origin square -		Vec3{ -2.5, 0.0, -0.5}, // square to the left -		Vec3{ -1.0, 0.0, -1.5}, // random square behind window between squares +		Vec3{  0.5, 0.0,  0.0}, // 0: origin square +		Vec3{ -1.0, 0.0, -1.0}, // 1: plane +		Vec3{ -1.0, 0.0, -0.5}, // 2: window between squares +		Vec3{  0.0, 0.0,  3.0}, // 3: window infront of origin square +		Vec3{ -2.5, 0.0, -0.5}, // 4: square to the left +		Vec3{ -1.0, 0.0, -1.5}, // 5: random square behind window between squares +    Vec3{ -1.0, 0.0, -8.0}, // 6: reflective plane  	};  	r32 FOV = 90.0; @@ -788,6 +921,15 @@ int main(int argc, char* argv[])    glUseProgram(blend_shader_program);  	proj_loc = glGetUniformLocation(blend_shader_program, "Projection");  	glUniformMatrix4fv(proj_loc, 1, GL_TRUE, proj.buffer); + +  glUseProgram(cubemap_shader_program); +	proj_loc = glGetUniformLocation(cubemap_shader_program, "Projection"); +	glUniformMatrix4fv(proj_loc, 1, GL_TRUE, proj.buffer); + +  glUseProgram(refl_shader_program); +	proj_loc = glGetUniformLocation(refl_shader_program, "Projection"); +	glUniformMatrix4fv(proj_loc, 1, GL_TRUE, proj.buffer); +  	glEnable(GL_DEPTH_TEST);    glEnable(GL_BLEND); @@ -826,6 +968,60 @@ int main(int argc, char* argv[])    }    glBindFramebuffer(GL_FRAMEBUFFER, 0); +  // generate_cubemap +  const char *cm_face_right = "assets/skybox/right.jpg"; +  const char *cm_face_left = "assets/skybox/left.jpg"; +  const char *cm_face_top = "assets/skybox/top.jpg"; +  const char *cm_face_bottom = "assets/skybox/bottom.jpg"; +  const char *cm_face_back = "assets/skybox/back.jpg"; +  const char *cm_face_front = "assets/skybox/front.jpg"; + +  u32 cm_tex_id; +  { +    stbi_set_flip_vertically_on_load(0); +    glGenTextures(1, &cm_tex_id); +    glBindTexture(GL_TEXTURE_CUBE_MAP, cm_tex_id); +    int cm_width, cm_height, cm_nrChannels; +    unsigned char *data; +    // right face +    data = stbi_load(cm_face_right, &cm_width, &cm_height, &cm_nrChannels, 0); +    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + 0, 0, GL_RGB, cm_width, cm_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); +    // left face +    data = stbi_load(cm_face_left, &cm_width, &cm_height, &cm_nrChannels, 0); +    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + 1, 0, GL_RGB, cm_width, cm_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); +    // top face +    data = stbi_load(cm_face_top, &cm_width, &cm_height, &cm_nrChannels, 0); +    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + 2, 0, GL_RGB, cm_width, cm_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); +    // bottom face +    data = stbi_load(cm_face_bottom, &cm_width, &cm_height, &cm_nrChannels, 0); +    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + 3, 0, GL_RGB, cm_width, cm_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); +    // back face +    data = stbi_load(cm_face_back, &cm_width, &cm_height, &cm_nrChannels, 0); +    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + 4, 0, GL_RGB, cm_width, cm_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); +    // front face +    data = stbi_load(cm_face_front, &cm_width, &cm_height, &cm_nrChannels, 0); +    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + 5, 0, GL_RGB, cm_width, cm_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + +    // texture filtering methods +    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_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); + +    glUseProgram(cubemap_shader_program); +    glActiveTexture(GL_TEXTURE0); +    s32 skybox_loc = glGetUniformLocation(cubemap_shader_program, "skybox"); +    glUniform1i(skybox_loc, 0); +    stbi_set_flip_vertically_on_load(1); +  } + +  { +    glUseProgram(refl_shader_program); +    s32 skybox_loc = glGetUniformLocation(refl_shader_program, "skybox"); +    glUniform1i(skybox_loc, 0); +  } +  	u8 game_running = true;    u8 hold_lshift = false; @@ -953,14 +1149,25 @@ int main(int argc, char* argv[])      view_loc = glGetUniformLocation(blend_shader_program, "View");  		glUniformMatrix4fv(view_loc, 1, GL_TRUE, view.buffer); +    glUseProgram(refl_shader_program); +    view_loc = glGetUniformLocation(refl_shader_program, "View"); +		glUniformMatrix4fv(view_loc, 1, GL_TRUE, view.buffer); + +    glUseProgram(cubemap_shader_program); +    view_loc = glGetUniformLocation(cubemap_shader_program, "View"); +    view.xyzw[0].w = 0.0f; +    view.xyzw[1].w = 0.0f; +    view.xyzw[2].w = 0.0f; +		glUniformMatrix4fv(view_loc, 1, GL_TRUE, view.buffer); +  		time_prev = time_curr;  		// OUTPUT      glBindFramebuffer(GL_FRAMEBUFFER, fbo); -    glEnable(GL_DEPTH_TEST);  		glClearColor(1.0f, 0.6f, .6f, 1.0f);  		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +    glEnable(GL_DEPTH_TEST);      glDisable(GL_BLEND);      { //plane        glUseProgram(shader_program); @@ -1022,6 +1229,31 @@ int main(int argc, char* argv[])        glBindTexture(GL_TEXTURE_2D, cube_tex_id);        glDrawArrays(GL_TRIANGLES, 0, 36);      } +    { // reflective plane +      glUseProgram(refl_shader_program); +      Vec3 translation_iter = model_translations[6]; +      Mat4 model = init_value4m(1.0); +      Mat4 model_translation = translation_matrix4m(translation_iter.x, translation_iter.y, translation_iter.z); + +      model = multiply4m(model_translation, model); +      uint32_t model_loc = glGetUniformLocation(refl_shader_program, "Model"); +      glUniformMatrix4fv(model_loc, 1, GL_TRUE, model.buffer); + +      uint32_t camera_pos_loc = glGetUniformLocation(refl_shader_program, "cameraPos"); +      glUniform3fv(camera_pos_loc, 1, camera_pos.data); +      glBindVertexArray(refl_vao); +      glDrawArrays(GL_TRIANGLES, 0, 36); +    } +    { +      glDepthFunc(GL_LEQUAL); +      glUseProgram(cubemap_shader_program); +      glActiveTexture(GL_TEXTURE0); +      glBindVertexArray(skybox_vao); +      glBindTexture(GL_TEXTURE_CUBE_MAP, cm_tex_id); +      glDrawArrays(GL_TRIANGLES, 0, 36); +      glDepthFunc(GL_LESS); +    } +      // @note: this is to demonstrate the limitations of blending with the depth buffer.      // Currently, this will show a weird behavior where since we render the transparent object      // closest to the camera first, the second window, further from the player will be discarded by the  @@ -1059,7 +1291,6 @@ int main(int argc, char* argv[])        glDrawArrays(GL_TRIANGLES, 0, 12);      }      glBindFramebuffer(GL_FRAMEBUFFER, 0); -      // draw everything to a framebuffer object      glDisable(GL_DEPTH_TEST);      glClearColor(1.0f, 1.0f, 1.0f, 1.0f);  diff --git a/source/shaders/fbo.fs.glsl b/source/shaders/fbo.fs.glsl index afb9e08..e12ad33 100644 --- a/source/shaders/fbo.fs.glsl +++ b/source/shaders/fbo.fs.glsl @@ -68,5 +68,5 @@ vec4 filter_kernal_effects()  }  void main() { -    FragColor = filter_kernal_effects(); +    FragColor = texture(TexId, TexCoords);  } | 
