diff --git a/.vs/shader3/v14/.suo b/.vs/shader3/v14/.suo index b065015..eed7516 100644 Binary files a/.vs/shader3/v14/.suo and b/.vs/shader3/v14/.suo differ diff --git a/FBO.cpp b/FBO.cpp index 2ce8490..79625f0 100644 --- a/FBO.cpp +++ b/FBO.cpp @@ -13,7 +13,13 @@ void FBO::AttachColorBuffer(const char*bufferName, GLenum attachment, GLenum dat glBindTexture(GL_TEXTURE_2D, colorBuffer); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, dataType, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + if (dataType == GL_RGBA16F) { + glTexImage2D(GL_TEXTURE_2D, 0, dataType, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT, NULL); + } + else { + glTexImage2D(GL_TEXTURE_2D, 0, dataType, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + } glBindTexture(GL_TEXTURE_2D, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, colorBuffer, 0); diff --git a/main.cpp b/main.cpp index eca83af..7e7abe0 100644 --- a/main.cpp +++ b/main.cpp @@ -81,23 +81,14 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ originalProgram.DetectAttribute("texcoord"); originalProgram.DetectUniform("U_MainTexture"); - //init vertical program - GPUProgram verticalProgram; - verticalProgram.AttachShader(GL_VERTEX_SHADER, "res/shader/fullscreenquad.vs"); - verticalProgram.AttachShader(GL_FRAGMENT_SHADER, "res/shader/fullscreenquad_gaussian_vertical.fs"); - verticalProgram.Link(); - verticalProgram.DetectAttribute("pos"); - verticalProgram.DetectAttribute("texcoord"); - verticalProgram.DetectUniform("U_MainTexture"); - - //init horizontal program - GPUProgram horizontalProgram; - horizontalProgram.AttachShader(GL_VERTEX_SHADER, "res/shader/fullscreenquad.vs"); - horizontalProgram.AttachShader(GL_FRAGMENT_SHADER, "res/shader/fullscreenquad_gaussian_horizontal.fs"); - horizontalProgram.Link(); - horizontalProgram.DetectAttribute("pos"); - horizontalProgram.DetectAttribute("texcoord"); - horizontalProgram.DetectUniform("U_MainTexture"); + //init hdr program + GPUProgram hdrProgram; + hdrProgram.AttachShader(GL_VERTEX_SHADER, "res/shader/fullscreenquad.vs"); + hdrProgram.AttachShader(GL_FRAGMENT_SHADER, "res/shader/hdrrender.fs"); + hdrProgram.Link(); + hdrProgram.DetectAttribute("pos"); + hdrProgram.DetectAttribute("texcoord"); + hdrProgram.DetectUniform("U_MainTexture"); //init dilation program GPUProgram gaussianProgram; @@ -111,7 +102,7 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ //init gpu program GPUProgram gpuProgram; gpuProgram.AttachShader(GL_VERTEX_SHADER, "res/shader/test.vs"); - gpuProgram.AttachShader(GL_FRAGMENT_SHADER, "res/shader/test.fs"); + gpuProgram.AttachShader(GL_FRAGMENT_SHADER, "res/shader/hdr.fs"); gpuProgram.Link(); gpuProgram.DetectAttribute("pos"); @@ -175,10 +166,10 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ fbo.AttachDepthBuffer("depth", viewportWidth, viewportHeight); fbo.Finish(); - FBO fbo2; - fbo2.AttachColorBuffer("color", GL_COLOR_ATTACHMENT0, GL_RGBA, viewportWidth, viewportHeight); - fbo2.AttachDepthBuffer("depth", viewportWidth, viewportHeight); - fbo2.Finish(); + FBO HDRfbo; + HDRfbo.AttachColorBuffer("color", GL_COLOR_ATTACHMENT0, GL_RGBA16F, viewportWidth, viewportHeight); + HDRfbo.AttachDepthBuffer("depth", viewportWidth, viewportHeight); + HDRfbo.Finish(); ShowWindow(hwnd, SW_SHOW); UpdateWindow(hwnd); @@ -199,7 +190,7 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ glEnable(GL_DEPTH_TEST); - fbo.Bind(); + HDRfbo.Bind(); glUseProgram(gpuProgram.mProgram); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUniform4fv(gpuProgram.GetLocation("U_AmbientLightColor"), 1, ambientLightColor); @@ -220,40 +211,27 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ obj.Bind(gpuProgram.GetLocation("pos"), gpuProgram.GetLocation("texcoord"), gpuProgram.GetLocation("normal")); obj.Draw(); glUseProgram(0); - fbo.Unbind(); - - //blur * 2 - fbo2.Bind(); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glUseProgram(gaussianProgram.mProgram); - glBindTexture(GL_TEXTURE_2D, fbo.GetBuffer("color")); - glUniform1i(gaussianProgram.GetLocation("U_MainTexture"), 0); - fsq.Draw(gaussianProgram.GetLocation("pos"), gaussianProgram.GetLocation("texcoord")); - fbo2.Unbind(); + HDRfbo.Unbind(); glFlush(); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, fbo.GetBuffer("color")); - glUniform1i(originalProgram.GetLocation("U_MainTexture"), 0); glUseProgram(originalProgram.mProgram); + glBindTexture(GL_TEXTURE_2D, HDRfbo.GetBuffer("color")); + glUniform1i(originalProgram.GetLocation("U_MainTexture"), 0); fsq.DrawToLeftTop(originalProgram.GetLocation("pos"), originalProgram.GetLocation("texcoord")); - - glUseProgram(verticalProgram.mProgram); - fsq.DrawToRightTop(verticalProgram.GetLocation("pos"), verticalProgram.GetLocation("texcoord")); - - glUseProgram(horizontalProgram.mProgram); - fsq.DrawToLeftBottom(horizontalProgram.GetLocation("pos"), horizontalProgram.GetLocation("texcoord")); + glUseProgram(hdrProgram.mProgram); + glBindTexture(GL_TEXTURE_2D, HDRfbo.GetBuffer("color")); + glUniform1i(hdrProgram.GetLocation("U_MainTexture"), 0); + fsq.DrawToRightTop(hdrProgram.GetLocation("pos"), hdrProgram.GetLocation("texcoord")); glUseProgram(gaussianProgram.mProgram); - glBindTexture(GL_TEXTURE_2D, fbo2.GetBuffer("color")); - glUniform1i(originalProgram.GetLocation("U_MainTexture"), 0); + glBindTexture(GL_TEXTURE_2D, HDRfbo.GetBuffer("color")); + glUniform1i(gaussianProgram.GetLocation("U_MainTexture"), 0); fsq.DrawToRightBottom(gaussianProgram.GetLocation("pos"), gaussianProgram.GetLocation("texcoord")); SwapBuffers(dc); diff --git a/res/shader/hdr.fs b/res/shader/hdr.fs new file mode 100644 index 0000000..4b12c09 --- /dev/null +++ b/res/shader/hdr.fs @@ -0,0 +1,70 @@ +uniform vec4 U_AmbientLightColor; +uniform vec4 U_AmbientMaterial; +uniform vec4 U_LightPos; +uniform vec4 U_LightDirection; +uniform float U_Cutoff; +uniform float U_DiffuseIntensity; +uniform vec4 U_DiffuseLightColor; +uniform vec4 U_DiffuseMaterial; +uniform vec3 U_EyePos; +uniform vec4 U_SpecularLightColor; +uniform vec4 U_SpecularMaterial; + + +varying vec3 V_Normal; +varying vec3 V_WorldPos; + +void main() +{ + + //common + vec3 N = normalize(V_Normal); + + //ambient + vec4 ambientColor = U_AmbientLightColor * U_AmbientMaterial; + + //diffuse + vec3 L = vec3(0.0); + float attenuation = 1.0; + float diffuseIntensity = 0.0; + if(U_LightPos.w != 0){// 点光 + + L = normalize(U_LightPos.xyz - V_WorldPos); + float distance = length(U_LightPos.xyz - V_WorldPos); + float constantFactor=0.5; + float linearFactor=0.3; + float expFactor=0.1; + attenuation = 1.0 / (constantFactor + linearFactor * distance + expFactor * distance * distance); + + if( U_Cutoff > 0){//聚光 + //角度转弧度 + float radianCutoff = U_Cutoff * 3.14 / 180; + float cosThta = cos(radianCutoff); + vec3 spotLightDirection = normalize(U_LightDirection.xyz); + float currentThta = max(0.0, dot(-L, spotLightDirection)); + + if(currentThta > cosThta){ + if(dot(L,N)>0.0) + { + diffuseIntensity=pow(currentThta,U_LightDirection.w); + } + } + } else { + diffuseIntensity = max(0.0, dot(L,N)); + } + + } else { + // 平行光 + L = normalize(U_LightPos.xyz - vec3(0.0)); + diffuseIntensity = max(0.0, dot(L,N)); + } + + vec4 diffuseColor = U_DiffuseLightColor * U_DiffuseMaterial * attenuation * diffuseIntensity * U_DiffuseIntensity; + + //specualr + vec3 RD = normalize(reflect(-L,N)); + vec3 VD = normalize(U_EyePos - V_WorldPos); + vec4 specularColor = U_SpecularLightColor * U_SpecularMaterial * pow(max(0.0, dot(RD,VD)) ,128); + + gl_FragColor = (ambientColor + diffuseColor) * 10.0; +} \ No newline at end of file diff --git a/res/shader/hdrrender.fs b/res/shader/hdrrender.fs new file mode 100644 index 0000000..e678b3a --- /dev/null +++ b/res/shader/hdrrender.fs @@ -0,0 +1,13 @@ +varying vec2 V_Texcoord; + +uniform sampler2D U_MainTexture; + +void main() +{ + vec4 color = texture2D(U_MainTexture, V_Texcoord); + + if(color.r > 2.0){ + discard; + } + gl_FragColor = color; +} \ No newline at end of file diff --git a/shader3.vcxproj b/shader3.vcxproj index 98875cd..4b9fadf 100644 --- a/shader3.vcxproj +++ b/shader3.vcxproj @@ -82,9 +82,12 @@ + + + diff --git a/shader3.vcxproj.filters b/shader3.vcxproj.filters index 4a9eafe..be527bb 100644 --- a/shader3.vcxproj.filters +++ b/shader3.vcxproj.filters @@ -61,5 +61,14 @@ src + + src + + + src + + + src + \ No newline at end of file diff --git a/utils.cpp b/utils.cpp index 4cbd716..fe2a4f2 100644 --- a/utils.cpp +++ b/utils.cpp @@ -73,4 +73,37 @@ GLuint CreateTextureFromFile(const char*filePath) glBindTexture(GL_TEXTURE_2D, 0); delete imageData; return texture; +} + +void CheckGLError(const char*file, int line) +{ + + GLenum error = glGetError(); + if (error != GL_NO_ERROR) + { + switch (error) + { + case GL_INVALID_ENUM: + printf("GL Error GL_INVALID_ENUM %s : %d\n", file, line); + break; + case GL_INVALID_VALUE: + printf("GL Error GL_INVALID_VALUE %s : %d\n", file, line); + break; + case GL_INVALID_OPERATION: + printf("GL Error GL_INVALID_OPERATION %s : %d\n", file, line); + break; + case GL_STACK_OVERFLOW: + printf("GL Error GL_STACK_OVERFLOW %s : %d\n", file, line); + break; + case GL_STACK_UNDERFLOW: + printf("GL Error GL_STACK_UNDERFLOW %s : %d\n", file, line); + break; + case GL_OUT_OF_MEMORY: + printf("GL Error GL_OUT_OF_MEMORY %s : %d\n", file, line); + break; + default: + printf("GL Error 0x%x %s : %d\n", error, file, line); + break; + } + } } \ No newline at end of file diff --git a/utils.h b/utils.h index 0e76e43..6f6c217 100644 --- a/utils.h +++ b/utils.h @@ -2,4 +2,7 @@ #include "glew.h" char* LoadFileContent(const char*path); unsigned char* LoadBMP(const char*path, int &width, int &height); -GLuint CreateTextureFromFile(const char*filePath); \ No newline at end of file +GLuint CreateTextureFromFile(const char*filePath); + +void CheckGLError(const char* file, int line); +#define GL_CALL(x) do{x;CheckGLError(__FILE__, __LINE__);}while(0) \ No newline at end of file