diff --git a/.vs/shader3/v14/.suo b/.vs/shader3/v14/.suo index 65dfea0..0d9e83b 100644 Binary files a/.vs/shader3/v14/.suo and b/.vs/shader3/v14/.suo differ diff --git a/FullScreenQuad.cpp b/FullScreenQuad.cpp index 4846be7..3f182b7 100644 --- a/FullScreenQuad.cpp +++ b/FullScreenQuad.cpp @@ -3,23 +3,115 @@ void FullScreenQuad::Init() { - float pos[] = { - -0.5f,-0.5f,-1.0f, - 0.5f,-0.5f,-1.0f, - 0.5f,0.5f,-1.0f, - -0.5f,0.5f,-1.0f - }; glGenBuffers(1, &mVBO); glBindBuffer(GL_ARRAY_BUFFER, mVBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 12, pos, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 20, nullptr, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); } -void FullScreenQuad::Draw(GLint posLoc) +void FullScreenQuad::Draw(GLint posLoc, GLint texcoordLoc) { + //draw fullscreen + float vertices[] = { + -0.5f,-0.5f,-1.0f,0.0f,0.0f, + 0.5f,-0.5f,-1.0f,1.0f,0.0f, + 0.5f,0.5f,-1.0f,1.0f,1.0f, + -0.5f,0.5f,-1.0f,0.0f,1.0f + }; + glBindBuffer(GL_ARRAY_BUFFER, mVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 20, vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ARRAY_BUFFER, mVBO); + glEnableVertexAttribArray(posLoc); + glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0); + glEnableVertexAttribArray(texcoordLoc); + glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*)(sizeof(float) * 3)); + glDrawArrays(GL_QUADS, 0, 4); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void FullScreenQuad::DrawToLeftTop(GLint posLoc, GLint texcoordLoc) +{ + //draw to left top qualter of screen + float vertices[] = { + -0.5f,0.0f,-1.0f,0.0f,0.0f, + 0.0f,0.0f,-1.0f,1.0f,0.0f, + 0.0f,0.5f,-1.0f,1.0f,1.0f, + -0.5f,0.5f,-1.0f,0.0f,1.0f + }; + glBindBuffer(GL_ARRAY_BUFFER, mVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 20, vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ARRAY_BUFFER, mVBO); + glEnableVertexAttribArray(posLoc); + glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0); + glEnableVertexAttribArray(texcoordLoc); + glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*)(sizeof(float) * 3)); + glDrawArrays(GL_QUADS, 0, 4); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void FullScreenQuad::DrawToLeftBottom(GLint posLoc, GLint texcoordLoc) +{ + float vertices[] = { + -0.5f,-0.5f,-1.0f,0.0f,0.0f, + 0.0f,-0.5f,-1.0f,1.0f,0.0f, + 0.0f,0.0f,-1.0f,1.0f,1.0f, + -0.5f,0.0f,-1.0f,0.0f,1.0f + }; + glBindBuffer(GL_ARRAY_BUFFER, mVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 20, vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ARRAY_BUFFER, mVBO); + glEnableVertexAttribArray(posLoc); + glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0); + glEnableVertexAttribArray(texcoordLoc); + glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*)(sizeof(float) * 3)); + glDrawArrays(GL_QUADS, 0, 4); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void FullScreenQuad::DrawToRightTop(GLint posLoc, GLint texcoordLoc) +{ + float vertices[] = { + 0.0f,-0.0f,-1.0f,0.0f,0.0f, + 0.5f,-0.0f,-1.0f,1.0f,0.0f, + 0.5f,0.5f,-1.0f,1.0f,1.0f, + 0.0f,0.5f,-1.0f,0.0f,1.0f + }; + glBindBuffer(GL_ARRAY_BUFFER, mVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 20, vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ARRAY_BUFFER, mVBO); + glEnableVertexAttribArray(posLoc); + glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0); + glEnableVertexAttribArray(texcoordLoc); + glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*)(sizeof(float) * 3)); + glDrawArrays(GL_QUADS, 0, 4); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void FullScreenQuad::DrawToRightBottom(GLint posLoc, GLint texcoordLoc) +{ + float vertices[] = { + 0.0f,-0.5f,-1.0f,0.0f,0.0f, + 0.5f,-0.5f,-1.0f,1.0f,0.0f, + 0.5f,0.0f,-1.0f,1.0f,1.0f, + 0.0f,0.0f,-1.0f,0.0f,1.0f + }; + glBindBuffer(GL_ARRAY_BUFFER, mVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 20, vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, mVBO); glEnableVertexAttribArray(posLoc); - glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, 0); + glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0); + glEnableVertexAttribArray(texcoordLoc); + glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*)(sizeof(float) * 3)); glDrawArrays(GL_QUADS, 0, 4); glBindBuffer(GL_ARRAY_BUFFER, 0); } \ No newline at end of file diff --git a/FullScreenQuad.h b/FullScreenQuad.h index de066d0..3761c5c 100644 --- a/FullScreenQuad.h +++ b/FullScreenQuad.h @@ -7,5 +7,10 @@ public: GLuint mVBO; public: void Init(); - void Draw(GLint posLoc); + void Draw(GLint posLoc, GLint texcoordLoc); + + void DrawToLeftTop(GLint posLoc, GLint texcoordLoc); + void DrawToRightTop(GLint posLoc, GLint texcoordLoc); + void DrawToLeftBottom(GLint posLoc, GLint texcoordLoc); + void DrawToRightBottom(GLint posLoc, GLint texcoordLoc); }; \ No newline at end of file diff --git a/main.cpp b/main.cpp index 14b537d..9233a85 100644 --- a/main.cpp +++ b/main.cpp @@ -41,7 +41,14 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ wndClass.style = CS_VREDRAW | CS_HREDRAW; ATOM atom = RegisterClassEx(&wndClass); - HWND hwnd = CreateWindowEx(NULL, "OpenGL", "RenderWindow", WS_OVERLAPPEDWINDOW, 100, 100, 800, 600, NULL, NULL, hInstance, NULL); + RECT rect; + rect.left = 0; + rect.top = 0; + rect.right = 800; + rect.bottom = 600; + AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE); + + HWND hwnd = CreateWindowEx(NULL, "OpenGL", "RenderWindow", WS_OVERLAPPEDWINDOW, 100, 100, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, hInstance, NULL); HDC dc = GetDC(hwnd); PIXELFORMATDESCRIPTOR pfd; memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); @@ -60,7 +67,20 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ HGLRC rc = wglCreateContext(dc); wglMakeCurrent(dc, rc); + GetClientRect(hwnd, &rect); + int viewportWidth = rect.right - rect.left, viewportHeight = rect.bottom - rect.top; + glewInit(); + + //init fsqgpu program + GPUProgram fsqProgram; + fsqProgram.AttachShader(GL_VERTEX_SHADER, "res/shader/fullscreenquad.vs"); + fsqProgram.AttachShader(GL_FRAGMENT_SHADER, "res/shader/fullscreenquad.fs"); + fsqProgram.Link(); + fsqProgram.DetectAttribute("pos"); + fsqProgram.DetectAttribute("texcoord"); + fsqProgram.DetectUniform("U_MainTexture"); + //init gpu program GPUProgram gpuProgram; gpuProgram.AttachShader(GL_VERTEX_SHADER, "res/shader/test.vs"); @@ -111,19 +131,46 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ float specularMaterial[] = { 1.0f,1.0f,1.0f,1.0f }; float eyePos[] = { 0.0f,0.0f,0.0f }; + glm::mat4 model1 = glm::translate(-2.0f, 0.0f, -6.0f) * glm::rotate(-30.0f , 1.0f, 1.0f, 1.0f); - glm::mat4 model2 = glm::translate(0.0f, 0.0f, -6.0f) * glm::rotate(-30.0f, 1.0f, 1.0f, 1.0f); - glm::mat4 model3 = glm::translate(2.0f, 0.0f, -6.0f) * glm::rotate(-30.0f, 1.0f, 1.0f, 1.0f); + glm::mat4 model2 = glm::translate(2.0f, 0.0f, -6.0f) * glm::rotate(-30.0f, 1.0f, 1.0f, 1.0f); + glm::mat4 model3 = glm::translate(6.0f, 0.0f, -6.0f) * glm::rotate(-30.0f, 1.0f, 1.0f, 1.0f); + + glm::mat4 viewMatrix1 = glm::lookAt(glm::vec3(-0.0f, 1.5f, -3.0f), glm::vec3(-2.0f, 0.0f, -6.0f), glm::vec3(0.0f, 1.0f, 0.0f)); + glm::mat4 viewMatrix2 = glm::lookAt(glm::vec3(3.0f, 1.5f, -3.0f), glm::vec3(2.0f, 0.0f, -6.0f), glm::vec3(0.0f, 1.0f, 0.0f)); + glm::mat4 viewMatrix3 = glm::lookAt(glm::vec3(7.0f, 1.5f, -3.0f), glm::vec3(6.0f, 0.0f, -6.0f), glm::vec3(0.0f, 1.0f, 0.0f)); + glm::mat4 projectionMatrix = glm::perspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f); glm::mat4 normalMatrix1 = glm::inverseTranspose(model1); glm::mat4 normalMatrix2 = glm::inverseTranspose(model2); glm::mat4 normalMatrix3 = glm::inverseTranspose(model3); + //³õʼ»¯fsq + FullScreenQuad fsq; + fsq.Init(); + + //³õʼ»¯FBO + FBO fboDirectionLight; + fboDirectionLight.AttachColorBuffer("color", GL_COLOR_ATTACHMENT0, GL_RGBA, viewportWidth, viewportHeight); + fboDirectionLight.AttachDepthBuffer("depth", viewportWidth, viewportHeight); + fboDirectionLight.Finish(); + + FBO fboPointerLight; + fboPointerLight.AttachColorBuffer("color", GL_COLOR_ATTACHMENT0, GL_RGBA, viewportWidth, viewportHeight); + fboPointerLight.AttachDepthBuffer("depth", viewportWidth, viewportHeight); + fboPointerLight.Finish(); + + FBO fboSpotLight; + fboSpotLight.AttachColorBuffer("color", GL_COLOR_ATTACHMENT0, GL_RGBA, viewportWidth, viewportHeight); + fboSpotLight.AttachDepthBuffer("depth", viewportWidth, viewportHeight); + fboSpotLight.Finish(); + glClearColor(41.0f/255.0f, 71.0f/255.0f, 121.0f / 255.0f, 1.0f); ShowWindow(hwnd, SW_SHOW); UpdateWindow(hwnd); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); MSG msg; while (true) { @@ -136,13 +183,12 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ TranslateMessage(&msg); DispatchMessage(&msg); } - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); glUseProgram(gpuProgram.mProgram); - glUniformMatrix4fv(gpuProgram.GetLocation("V"), 1, GL_FALSE, identity); + glUniformMatrix4fv(gpuProgram.GetLocation("P"), 1, GL_FALSE, glm::value_ptr(projectionMatrix)); glUniform4fv(gpuProgram.GetLocation("U_AmbientLightColor"), 1,ambientLightColor); @@ -155,6 +201,8 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ glUniform3fv(gpuProgram.GetLocation("U_EyePos"), 1, eyePos); //left + fboDirectionLight.Bind(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); lightPos[0] = 0.0f; lightPos[1] = 1.5f; lightPos[2] = 0.0f; @@ -165,11 +213,16 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ glUniform1f(gpuProgram.GetLocation("U_DiffuseIntensity"), diffuseIntensity); glUniform1f(gpuProgram.GetLocation("U_Cutoff"), spotLightCutoff); glUniformMatrix4fv(gpuProgram.GetLocation("M"), 1, GL_FALSE, glm::value_ptr(model1)); + glUniformMatrix4fv(gpuProgram.GetLocation("V"), 1, GL_FALSE, glm::value_ptr(viewMatrix1)); glUniformMatrix4fv(gpuProgram.GetLocation("NM"), 1, GL_FALSE, glm::value_ptr(normalMatrix1)); cube.Bind(gpuProgram.GetLocation("pos"), gpuProgram.GetLocation("texcoord"), gpuProgram.GetLocation("normal")); cube.Draw(); + fboDirectionLight.Unbind(); + //middle + fboPointerLight.Bind(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); lightPos[0] = 0.0f; lightPos[1] = 3.0f; lightPos[2] = -6.0f; @@ -180,12 +233,16 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ glUniform1f(gpuProgram.GetLocation("U_DiffuseIntensity"), diffuseIntensity); glUniform1f(gpuProgram.GetLocation("U_Cutoff"), spotLightCutoff); glUniformMatrix4fv(gpuProgram.GetLocation("M"), 1, GL_FALSE, glm::value_ptr(model2)); + glUniformMatrix4fv(gpuProgram.GetLocation("V"), 1, GL_FALSE, glm::value_ptr(viewMatrix2)); glUniformMatrix4fv(gpuProgram.GetLocation("NM"), 1, GL_FALSE, glm::value_ptr(normalMatrix2)); cube.Bind(gpuProgram.GetLocation("pos"), gpuProgram.GetLocation("texcoord"), gpuProgram.GetLocation("normal")); cube.Draw(); + fboDirectionLight.Unbind(); //right - lightPos[0] = 2.0f; + fboSpotLight.Bind(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + lightPos[0] = 6.0f; lightPos[1] = 3.0f; lightPos[2] = -6.0f; lightPos[3] = 1.0f; @@ -195,12 +252,35 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ glUniform1f(gpuProgram.GetLocation("U_DiffuseIntensity"), diffuseIntensity); glUniform1f(gpuProgram.GetLocation("U_Cutoff"), spotLightCutoff); glUniformMatrix4fv(gpuProgram.GetLocation("M"), 1, GL_FALSE, glm::value_ptr(model3)); + glUniformMatrix4fv(gpuProgram.GetLocation("V"), 1, GL_FALSE, glm::value_ptr(viewMatrix3)); glUniformMatrix4fv(gpuProgram.GetLocation("NM"), 1, GL_FALSE, glm::value_ptr(normalMatrix3)); cube.Bind(gpuProgram.GetLocation("pos"), gpuProgram.GetLocation("texcoord"), gpuProgram.GetLocation("normal")); cube.Draw(); + fboSpotLight.Unbind(); glUseProgram(0); - glFinish(); + glFlush(); + + + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glUseProgram(fsqProgram.mProgram); + glActiveTexture(GL_TEXTURE0); + + glBindTexture(GL_TEXTURE_2D, fboDirectionLight.GetBuffer("color")); + glUniform1i(fsqProgram.GetLocation("U_MainTexture"), 0); + fsq.DrawToLeftTop(fsqProgram.GetLocation("pos"), fsqProgram.GetLocation("texcoord")); + + glBindTexture(GL_TEXTURE_2D, fboSpotLight.GetBuffer("color")); + glUniform1i(fsqProgram.GetLocation("U_MainTexture"), 0); + fsq.DrawToLeftBottom(fsqProgram.GetLocation("pos"), fsqProgram.GetLocation("texcoord")); + + glBindTexture(GL_TEXTURE_2D, fboPointerLight.GetBuffer("color")); + glUniform1i(fsqProgram.GetLocation("U_MainTexture"), 0); + fsq.DrawToRightTop(fsqProgram.GetLocation("pos"), fsqProgram.GetLocation("texcoord")); + glFlush(); + SwapBuffers(dc); } return 0; diff --git a/res/shader/fullscreenquad.vs b/res/shader/fullscreenquad.vs index 996b3da..1e06305 100644 --- a/res/shader/fullscreenquad.vs +++ b/res/shader/fullscreenquad.vs @@ -1,10 +1,11 @@ attribute vec3 pos; +attribute vec2 texcoord; varying vec2 V_Texcoord; void main() { vec4 worldPos=vec4(pos,1.0); - V_Texcoord=pos.xy+vec2(0.5,0.5); + V_Texcoord=texcoord; worldPos.x*=2.0; worldPos.y*=2.0; gl_Position=worldPos; diff --git a/shader3.vcxproj b/shader3.vcxproj index dca363b..7be876a 100644 --- a/shader3.vcxproj +++ b/shader3.vcxproj @@ -82,6 +82,8 @@ + + diff --git a/shader3.vcxproj.filters b/shader3.vcxproj.filters index cc11adc..6a57a6b 100644 --- a/shader3.vcxproj.filters +++ b/shader3.vcxproj.filters @@ -52,5 +52,11 @@ src + + src + + + src + \ No newline at end of file