From 783b308990e7c4ef0837a102a138778f73e4d2b7 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Sun, 15 Feb 2015 15:23:19 -0500 Subject: Added bloom! --- CMakeLists.txt | 2 ++ maps/bigmap.txt | 1 - shaders/bloom1.fragment | 53 +++++++++++++++++++++++++++++++++++ shaders/bloom1.vertex | 11 ++++++++ shaders/bloom2.fragment | 57 ++++++++++++++++++++++++++++++++++++++ shaders/bloom2.vertex | 11 ++++++++ shaders/final.fragment | 50 ++++++++++++++++++++++++++++----- shaders/final.vertex | 23 ++++++++++++++-- src/main.cpp | 44 +---------------------------- src/renderer.cpp | 73 +++++++++++++++++++++++++++++++++++++++++++++++-- 10 files changed, 269 insertions(+), 56 deletions(-) create mode 100644 shaders/bloom1.fragment create mode 100644 shaders/bloom1.vertex create mode 100644 shaders/bloom2.fragment create mode 100644 shaders/bloom2.vertex diff --git a/CMakeLists.txt b/CMakeLists.txt index c0e0339..54aee1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,4 +30,6 @@ find_package(GLFW REQUIRED) set(CMAKE_BUILD_TYPE Debug) add_executable(Aromatherapy src/main.cpp src/map.cpp src/renderer.cpp) target_link_libraries(Aromatherapy ${OPENGL_LIBRARY} ${GLEW_LIBRARY} ${GLFW_LIBRARY}) +add_executable(translate_font src/translate_font.cpp src/renderer.cpp) +target_link_libraries(translate_font ${OPENGL_LIBRARY} ${GLEW_LIBRARY} ${GLFW_LIBRARY}) install(TARGETS Aromatherapy RUNTIME DESTINATION ${BIN_DIR}) diff --git a/maps/bigmap.txt b/maps/bigmap.txt index ac5e9e2..00ab68e 100644 --- a/maps/bigmap.txt +++ b/maps/bigmap.txt @@ -21,5 +21,4 @@ XXX XXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX \ No newline at end of file diff --git a/shaders/bloom1.fragment b/shaders/bloom1.fragment new file mode 100644 index 0000000..77031f2 --- /dev/null +++ b/shaders/bloom1.fragment @@ -0,0 +1,53 @@ +#version 330 core + +in vec2 UV; + +out vec3 color; + +uniform sampler2D screenTex; +uniform float iGlobalTime; + +float nrand(vec2 n) +{ + return fract(sin(dot(n.xy, vec2(19.9898, 78.233))) * 43758.5453); +} + +vec2 rot2d(vec2 p, float a) +{ + vec2 sc = vec2(sin(a), cos(a)); + return vec2(dot(p, vec2(sc.y, -sc.x)), dot(p, sc.xy)); +} + +void main() +{ + const int NUM_TAPS = 12; + float max_siz = 1.0; + + vec2 fTaps_Poisson[NUM_TAPS]; + fTaps_Poisson[0] = vec2(-.326, -.406); + fTaps_Poisson[1] = vec2(-.840, -.074); + fTaps_Poisson[2] = vec2(-.696, .457); + fTaps_Poisson[3] = vec2(-.203, .621); + fTaps_Poisson[4] = vec2( .962, -.195); + fTaps_Poisson[5] = vec2( .473, -.480); + fTaps_Poisson[6] = vec2( .519, .767); + fTaps_Poisson[7] = vec2( .185, -.893); + fTaps_Poisson[8] = vec2( .507, .064); + fTaps_Poisson[9] = vec2( .896, .412); + fTaps_Poisson[10] = vec2(-.322, -.933); + fTaps_Poisson[11] = vec2(-.792, -.598); + + vec4 sum = vec4(0); + float rnd = 6.28 * nrand(UV + fract(iGlobalTime)); + vec4 basis = vec4(rot2d(vec2(1,0), rnd), rot2d(vec2(0,1), rnd)); + for (int i=0; i 0.0) + { + vec3 viewDir = normalize(-vertPos); + vec3 halfDir = normalize(camDirNorm + viewDir); + float specAngle = max(dot(halfDir, normnorm), 0.0); + colorspec = vec4(0.25,0.25,0.25,1) * pow(specAngle, Tuning_Spec_Power) * Tuning_Spec_Brightness; + }*/ + + vec4 emissive = sampleCRT(UV); + + vec4 nearfinal = colorfres + colordiff + colorspec + emissive; + vec4 final = nearfinal * mix(vec4(1,1,1,1), vec4(0,0,0,0), Tuning_Dimming); + + color = final.rgb; } diff --git a/shaders/final.vertex b/shaders/final.vertex index 825eb49..dda8626 100644 --- a/shaders/final.vertex +++ b/shaders/final.vertex @@ -4,11 +4,28 @@ layout(location = 0) in vec3 vertexPosition_modelspace; layout(location = 1) in vec3 vertexNormal; out vec2 UV; -out vec3 norm; +out vec3 normIn; +out vec3 camDirIn; +out vec3 lightDirIn; +//out vec3 vertPos; + +uniform mat4 MVP; +uniform mat4 worldMat; + +const vec3 Tuning_LightPos = vec3(1, 1, 1.0); void main() { - gl_Position = vec4(vertexPosition_modelspace,1); + gl_Position = MVP * vec4(vertexPosition_modelspace,1); UV = (vertexPosition_modelspace.xy+vec2(1,1))/2.0; - norm = vertexNormal; + normIn = vertexNormal; + + mat3 invWorldRot = transpose(mat3(worldMat[0].xyz, worldMat[1].xyz, worldMat[2].xyz)); + //mat3 invWorldRot = mat3(1.0f); + vec3 worldPos = (worldMat * vec4(vertexPosition_modelspace,1)).xyz; + camDirIn = invWorldRot * (vec3(0,0,1) - worldPos); + //camDir = worldPos; + lightDirIn = invWorldRot * (Tuning_LightPos - worldPos); + //vec4 vertPos4 = vec4(vertexPosition_modelspace,1); + //vertPos = vec3(vertPos4) / vertPos4.w; } diff --git a/src/main.cpp b/src/main.cpp index 7c1a21f..e1e1aa2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,26 +5,6 @@ using namespace::std; -#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS__) || defined(__TOS_WIN__) - - #include - - inline void delay( unsigned long ms ) - { - Sleep( ms ); - } - -#else /* presume POSIX */ - - #include - - inline void delay( unsigned long ms ) - { - usleep( ms * 1000 ); - } - -#endif - const int FRAMES_PER_SECOND = 60; bool holding_left = false; bool holding_right = false; @@ -81,21 +61,8 @@ int main() Texture* tiles = loadTextureFromBMP("../res/tiles.bmp"); - double lastTime = glfwGetTime(); - int nbFrames = 0; - while (!quit) { - /* - double currentTime = glfwGetTime(); - nbFrames++; - if ( currentTime - lastTime >= 1.0 ){ // If last prinf() was more than 1 sec ago - // printf and reset timer - printf("%f ms/frame\n", 1000.0/double(nbFrames)); - nbFrames = 0; - lastTime += 1.0; - }*/ - if (holding_left && player->x_vel >= 0) { player->x_vel = -2; @@ -125,20 +92,11 @@ int main() Rectangle dst_rect(player->x, player->y, player->w, player->h); //blitTexture(tiles, buffer, &src_rect, &dst_rect); - fillTexture(buffer, &dst_rect, 85, 85, 255); - //fillTexture(buffer, NULL, 85, 85, 0); + fillTexture(buffer, &dst_rect, 255, 255, 255); renderScreen(buffer); - //fuckThePolice(buffer); - glfwPollEvents(); - - // Regulate frame rate - /*if ((clock() - frame_start) < CLOCKS_PER_SEC / FRAMES_PER_SECOND) - { - //delay(((CLOCKS_PER_SEC / FRAMES_PER_SECOND) - clock() + frame_start) * CLOCKS_PER_SEC / 1000); - }*/ } delete map; diff --git a/src/renderer.cpp b/src/renderer.cpp index ca356f3..3011e8f 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -14,6 +14,8 @@ static GLuint ntscShader; // The NTSC shader static GLuint finalShader; // The passthrough shader static GLuint blitShader; // The blitting shader static GLuint fillShader; // The fill shader +static GLuint bloom1Shader; +static GLuint bloom2Shader; // The buffers for the NTSC rendering process static GLuint renderedTex1; @@ -22,6 +24,8 @@ static GLuint renderedTexBufs[2]; static int curBuf; static GLuint artifactsTex; static GLuint scanlinesTex; +static GLuint preBloomTex; +static GLuint bloomPassTex; GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path) { @@ -246,6 +250,23 @@ GLFWwindow* initRenderer() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); renderedTexBufs[1] = renderedTex2; + // Set up bloom rendering buffers + glGenTextures(1, &preBloomTex); + glBindTexture(GL_TEXTURE_2D, preBloomTex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 768, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glGenTextures(1, &bloomPassTex); + glBindTexture(GL_TEXTURE_2D, bloomPassTex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 64, 48, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + curBuf = 0; artifactsTex = loadBMP_custom("../res/artifacts.bmp"); @@ -256,6 +277,8 @@ GLFWwindow* initRenderer() finalShader = LoadShaders("../shaders/final.vertex", "../shaders/final.fragment"); blitShader = LoadShaders("../shaders/blit.vertex", "../shaders/blit.fragment"); fillShader = LoadShaders("../shaders/fill.vertex", "../shaders/fill.fragment"); + bloom1Shader = LoadShaders("../shaders/bloom1.vertex", "../shaders/bloom1.fragment"); + bloom2Shader = LoadShaders("../shaders/bloom2.vertex", "../shaders/bloom2.fragment"); rendererInitialized = true; @@ -275,12 +298,16 @@ void destroyRenderer() glDeleteProgram(finalShader); glDeleteProgram(blitShader); glDeleteProgram(fillShader); + glDeleteProgram(bloom1Shader); + glDeleteProgram(bloom2Shader); // Delete the NTSC rendering buffers glDeleteTextures(1, &renderedTex1); glDeleteTextures(1, &renderedTex2); glDeleteTextures(1, &artifactsTex); glDeleteTextures(1, &scanlinesTex); + glDeleteTextures(1, &preBloomTex); + glDeleteTextures(1, &bloomPassTex); // Delete the framebuffer glDeleteFramebuffers(1, &FramebufferName); @@ -578,8 +605,9 @@ void renderScreen(Texture* tex) glBindBuffer(GL_ARRAY_BUFFER, g_norms); glBufferData(GL_ARRAY_BUFFER, sizeof(g_norms_data), g_norms_data, GL_STATIC_DRAW); - // We're going to output to the window now - glBindFramebuffer(GL_FRAMEBUFFER, 0); + // We're going to render the screen now + //glBindFramebuffer(GL_FRAMEBUFFER, 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, preBloomTex, 0); glViewport(0,0,1024,768); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(finalShader); @@ -606,6 +634,7 @@ void renderScreen(Texture* tex) mat4 v_matrix = lookAt(vec3(0,0,1), vec3(0,0,0), vec3(0,1,0)); mat4 m_matrix = mat4(1.0f); mat4 mvp_matrix = p_matrix * v_matrix * m_matrix; + //mat4 mv_matrix = v_matrix * m_matrix; glUniformMatrix4fv(glGetUniformLocation(finalShader, "MVP"), 1, GL_FALSE, &mvp_matrix[0][0]); glUniformMatrix4fv(glGetUniformLocation(finalShader, "worldMat"), 1, GL_FALSE, &m_matrix[0][0]); @@ -622,6 +651,46 @@ void renderScreen(Texture* tex) glDisableVertexAttribArray(1); glDisableVertexAttribArray(0); + // Do the first pass of bloom (downsampling and tapping) + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, bloomPassTex, 0); + glViewport(0, 0, 64, 48); + glClear(GL_COLOR_BUFFER_BIT); + glUseProgram(bloom1Shader); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, preBloomTex); + glUniform1i(glGetUniformLocation(bloom1Shader, "screenTex"), 0); + + glUniform1f(glGetUniformLocation(bloom1Shader, "iGlobalTime"), glfwGetTime()); + + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); + glDrawArrays(GL_TRIANGLES, 0, 6); + glDisableVertexAttribArray(0); + + // Do the second pass of bloom and render to screen + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, 1024, 768); + glClear(GL_COLOR_BUFFER_BIT); + glUseProgram(bloom2Shader); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, preBloomTex); + glUniform1i(glGetUniformLocation(bloom2Shader, "screenTex"), 0); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, bloomPassTex); + glUniform1i(glGetUniformLocation(bloom2Shader, "downsampledTex"), 1); + + glUniform1f(glGetUniformLocation(bloom2Shader, "iGlobalTime"), glfwGetTime()); + + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); + glDrawArrays(GL_TRIANGLES, 0, 6); + glDisableVertexAttribArray(0); + glfwSwapBuffers(window); glDeleteBuffers(1, &g_norms); -- cgit 1.4.1