daily pastebin goal
55%
SHARE
TWEET

tings

a guest May 21st, 2018 69 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "Shadows.h"
  2. #include "Gizmos.h"
  3. #include "Utilities.h"
  4. #include "gl_core_4_4.h"
  5. #include <GLFW/glfw3.h>
  6. #include <glm/ext.hpp>
  7. #include <iostream>
  8. #include "imgui.h"
  9. #include "imgui_tabs.h"
  10.  
  11. #define DEFAULT_SCREENWIDTH 1280
  12. #define DEFAULT_SCREENHEIGHT 720
  13.  
  14. #define SHADOW_BUFFER_SIZE 1024
  15.  
  16. Shadows::Shadows()
  17. {
  18.  
  19. }
  20.  
  21. Shadows::~Shadows()
  22. {
  23.  
  24. }
  25.  
  26. bool Shadows::onCreate()
  27. {
  28.     // initialise the Gizmos helper class
  29.     Gizmos::create();
  30.  
  31.     //Load the shaders for this program
  32.     unsigned int vertexShader = Utility::loadShader("./shaders/vertex.glsl", GL_VERTEX_SHADER);
  33.     unsigned int fragmentShader = Utility::loadShader("./shaders/fragment.glsl", GL_FRAGMENT_SHADER);
  34.     //Define the input and output varialbes in the shaders
  35.     //Note: these names are taken from the glsl files -- added in inputs for UV coordinates
  36.     const char* szInputs[] = { "Position", "Colour", "Normal","Tex1" };
  37.     const char* szOutputs[] = { "FragColor" };
  38.     //bind the shaders to create our shader program
  39.     m_programID = Utility::createProgram(
  40.         vertexShader,
  41.         0,
  42.         0,
  43.         0,
  44.         fragmentShader,
  45.         4, szInputs, 1, szOutputs);
  46.  
  47.     glDeleteShader(vertexShader);
  48.     glDeleteShader(fragmentShader);
  49.  
  50.     //Load the shaders for rendering the shadows
  51.     vertexShader = Utility::loadShader("./shaders/vertex_shadow.glsl", GL_VERTEX_SHADER);
  52.     fragmentShader = Utility::loadShader("./shaders/fragment_shadow.glsl", GL_FRAGMENT_SHADER);
  53.     //Define the input and output varialbes in the shaders
  54.     //Note: these names are taken from the glsl files -- added in inputs for UV coordinates
  55.     const char* szInputs2[] = { "Position", "Colour", "Normal","Tex1" };
  56.     const char* szOutputs2[] = { "FragDepth" };
  57.     //bind the shaders to create our shader program
  58.     m_shadowProgramID = Utility::createProgram(
  59.         vertexShader,
  60.         0,
  61.         0,
  62.         0,
  63.         fragmentShader,
  64.         4, szInputs2, 1, szOutputs2);
  65.  
  66.     glDeleteShader(vertexShader);
  67.     glDeleteShader(fragmentShader);
  68.  
  69.  
  70.     m_fbxModel = new FBXFile();
  71.     m_fbxModel->load("./models/ruinedtank/tank.fbx", FBXFile::UNITS_DECIMETER);
  72.  
  73.     //Generate our OpenGL Vertex and Index Buffers for rendering our FBX Model Data
  74.     // OPENGL: genorate the VBO, IBO and VAO
  75.     glGenBuffers(1, &m_vbo);
  76.     glGenBuffers(1, &m_ibo);
  77.     glGenVertexArrays(1, &m_vao);
  78.  
  79.     // OPENGL: Bind  VAO, and then bind the VBO and IBO to the VAO
  80.     glBindVertexArray(m_vao);
  81.     glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
  82.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
  83.  
  84.     //There is no need to populate the vbo & ibo buffers with any data at this stage
  85.     //this can be done when rendering each mesh component of the FBX model
  86.  
  87.     // enable the attribute locations that will be used on our shaders
  88.     glEnableVertexAttribArray(0); //Pos
  89.     glEnableVertexAttribArray(1); //Col
  90.     glEnableVertexAttribArray(2); //Norm
  91.     glEnableVertexAttribArray(3); //Tex1
  92.  
  93.  
  94.                                   // tell our shaders where the information within our buffers lie
  95.     glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(FBXVertex), ((char *)0) + FBXVertex::PositionOffset);
  96.     glVertexAttribPointer(1, 4, GL_FLOAT, GL_TRUE, sizeof(FBXVertex), ((char *)0) + FBXVertex::ColourOffset);
  97.     glVertexAttribPointer(2, 4, GL_FLOAT, GL_TRUE, sizeof(FBXVertex), ((char *)0) + FBXVertex::NormalOffset);
  98.     glVertexAttribPointer(3, 2, GL_FLOAT, GL_TRUE, sizeof(FBXVertex), ((char *)0) + FBXVertex::TexCoord1Offset);
  99.  
  100.     // finally, where done describing our mesh to the shader
  101.     // we can describe the next mesh
  102.     glBindVertexArray(0);
  103.     glBindBuffer(GL_ARRAY_BUFFER, 0);
  104.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  105.  
  106.     //\===========================================================================================================
  107.     //\Set up the frame buffer for rendering our shadows into
  108.     m_FBO_texture = -1;
  109.     SetupFrameBuffer(m_FBO, SHADOW_BUFFER_SIZE, SHADOW_BUFFER_SIZE, m_FBO_texture, m_FBO_depth_texture);
  110.     //\===========================================================================================================
  111.     //create a texture to hold the linear depth buffer samples
  112.     //texture for linear depth buffer visualisation
  113.    
  114.     // create a world-space matrix for a camera
  115.     m_cameraMatrix = glm::inverse(glm::lookAt(glm::vec3(10, 10, 10), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)));
  116.  
  117.     // create a perspective projection matrix with a 90 degree field-of-view and widescreen aspect ratio
  118.     m_projectionMatrix = glm::perspective(glm::pi<float>() * 0.25f, DEFAULT_SCREENWIDTH / (float)DEFAULT_SCREENHEIGHT, 0.1f, 1000.0f);
  119.  
  120.     m_modelMatrix = glm::mat4();
  121.  
  122.     // set the clear colour and enable depth testing and backface culling
  123.     glClearColor(0.25f, 0.25f, 0.25f, 1.f);
  124.     glEnable(GL_DEPTH_TEST);
  125.     glEnable(GL_CULL_FACE);
  126.  
  127.     m_lightPos = glm::vec4(50.f, 25.f, 0.f, 1.f);
  128.  
  129.     return true;
  130. }
  131.  
  132. void Shadows::Update(float a_deltaTime)
  133. {
  134.     // update our camera matrix using the keyboard/mouse
  135.     Utility::freeMovement(m_cameraMatrix, a_deltaTime, 10);
  136.  
  137.     // clear all gizmos from last frame
  138.     Gizmos::clear();
  139.  
  140.     // add an identity matrix gizmo
  141.     Gizmos::addTransform(glm::mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1));
  142.  
  143.     // rotate point
  144.     float s = sinf(a_deltaTime * 0.2f);
  145.     float c = cosf(a_deltaTime * 0.2f);
  146.     glm::vec4 temp = m_lightPos;
  147.     m_lightPos.x = temp.x * c - temp.z * s;
  148.     m_lightPos.z = temp.x * s + temp.z * c;
  149.     m_lightPos.w = 0;
  150.     m_lightPos = glm::normalize(m_lightPos) * 25.f;
  151.     Gizmos::addBox(m_lightPos.xyz, glm::vec3(0.2f, 0.2f, 0.2f), true, glm::vec4(1.0f, 0.85f, 0.05f, 1.f));
  152.  
  153.     //Update the shadow projection view matrix
  154.     glm::mat4 depthViewMatrix = glm::lookAt(glm::vec3(m_lightPos.xyz),
  155.         glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
  156.     glm::mat4 depthProjectionMatrix = glm::ortho<float>(-20, 20, -20, 20, -100, 100);
  157.  
  158.     m_shadowProjectionViewMatrix = depthProjectionMatrix * depthViewMatrix;
  159.  
  160.     //Update our FBX model
  161.     for (unsigned int i = 0; i < m_fbxModel->getMeshCount(); ++i)
  162.     {
  163.         // get the current mesh
  164.         FBXMeshNode *mesh = m_fbxModel->getMeshByIndex(i);
  165.         // if you move an object around within your scene
  166.         // children nodes are not updated until this function is called.
  167.         mesh->updateGlobalTransform();
  168.     }
  169.  
  170.     //\==========================================================================================================
  171.     //\ ImGui render view to show what is held in the FBO texture position
  172.     //\==========================================================================================================
  173.     ImGui::Begin("Frame Rate");
  174.     ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
  175.     ImGui::End();
  176.  
  177.     ImGui::SetNextWindowPos(ImVec2(DEFAULT_SCREENWIDTH - DEFAULT_SCREENWIDTH*0.3, DEFAULT_SCREENHEIGHT - DEFAULT_SCREENHEIGHT*0.4));
  178.     ImGui::SetNextWindowSize(ImVec2(DEFAULT_SCREENWIDTH*0.3, DEFAULT_SCREENHEIGHT* 0.4));
  179.     ImGui::Begin("Framebuffer");
  180.     ImGui::BeginTabBar("FrameBuffer Textures");
  181.     ImGui::DrawTabsBackground();
  182.     if (ImGui::AddTab("Colour Buffer")) {
  183.         ImTextureID texID = (void *)(intptr_t)m_FBO_texture;
  184.         ImGui::Image(texID, ImVec2(DEFAULT_SCREENWIDTH*0.25, DEFAULT_SCREENHEIGHT*0.25), ImVec2(0, 1), ImVec2(1, 0));
  185.     }
  186.     if (ImGui::AddTab("Depth Buffer")) {
  187.         ImTextureID texID = (void *)(intptr_t)m_FBO_depth_texture;
  188.         ImGui::Image(texID, ImVec2(DEFAULT_SCREENWIDTH*0.25, DEFAULT_SCREENHEIGHT*0.25), ImVec2(0, 1), ImVec2(1, 0));
  189.  
  190.     }
  191.     ImGui::EndTabBar();
  192.  
  193.  
  194.     ImGui::End();
  195.  
  196.     // quit our application when escape is pressed
  197.     if (glfwGetKey(m_window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
  198.         quit();
  199. }
  200.  
  201.  
  202. void Shadows::Draw()
  203. {
  204.     // clear the backbuffer
  205.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  206.  
  207.     //\===============================================================================
  208.     //\ Draw the scene from the POV of the light
  209.     //\===============================================================================
  210.     glBindFramebuffer(GL_FRAMEBUFFER, m_FBO);
  211.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  212.     glViewport(0, 0, SHADOW_BUFFER_SIZE, SHADOW_BUFFER_SIZE);
  213.     DrawScene(m_shadowProgramID);
  214.  
  215.     //\===============================================================================
  216.     //\ Draw the scene from the regular POV of the camera
  217.     //\===============================================================================
  218.     glBindFramebuffer(GL_FRAMEBUFFER, 0);
  219.     glViewport(0, 0, DEFAULT_SCREENWIDTH, DEFAULT_SCREENHEIGHT);
  220.     DrawScene(m_programID);
  221.  
  222.     // get the view matrix from the world-space camera matrix
  223.     glm::mat4 viewMatrix = glm::inverse(m_cameraMatrix);
  224.     // draw the gizmos from this frame
  225.     Gizmos::draw(viewMatrix, m_projectionMatrix);
  226.     //\===============================================================================
  227. }
  228.  
  229. void Shadows::DrawScene(unsigned int a_programID)
  230. {
  231.     //bing our shader program
  232.     glUseProgram(a_programID);
  233.     // get the view matrix from the world-space camera matrix
  234.     glm::mat4 viewMatrix = glm::inverse(m_cameraMatrix);
  235.     //bind our vertex array object
  236.     glBindVertexArray(m_vao);
  237.  
  238.     unsigned int shadowProjectionViewUniform = glGetUniformLocation(a_programID, "ShadowProjectionView");
  239.     glUniformMatrix4fv(shadowProjectionViewUniform, 1, false, glm::value_ptr(m_shadowProjectionViewMatrix));
  240.  
  241.     //get our shaders uniform location for our projectionViewMatrix and then use glUniformMatrix4fv to fill it with the correct data
  242.     unsigned int projectionViewUniform = glGetUniformLocation(a_programID, "ProjectionView");
  243.     glUniformMatrix4fv(projectionViewUniform, 1, false, glm::value_ptr(m_projectionMatrix * viewMatrix));
  244.  
  245.     //pass throught the view matrix
  246.     unsigned int viewMatrixUniform = glGetUniformLocation(a_programID, "ViewMatrix");
  247.     glUniformMatrix4fv(viewMatrixUniform, 1, false, glm::value_ptr(viewMatrix));
  248.  
  249.     //pass our camera position to our fragment shader uniform
  250.     unsigned int cameraPosUniform = glGetUniformLocation(a_programID, "cameraPosition");
  251.     glUniform4fv(cameraPosUniform, 1, glm::value_ptr(m_cameraMatrix[3]));
  252.  
  253.     //pass the directional light direction to our fragment shader
  254.     glm::vec4 lightDir = -m_lightPos;
  255.     lightDir.w = 0.f;
  256.     lightDir = glm::normalize(lightDir);
  257.     unsigned int lightDirUniform = glGetUniformLocation(a_programID, "lightDirection");
  258.     glUniform4fv(lightDirUniform, 1, glm::value_ptr(lightDir));
  259.  
  260.     //Set the shadow texture
  261.     unsigned int shadowTexUniformID = glGetUniformLocation(a_programID, "ShadowTexture");
  262.     glUniform1i(shadowTexUniformID, 1);
  263.     //Set our active texture, and bind our loaded texture
  264.     glActiveTexture(GL_TEXTURE1);
  265.     glBindTexture(GL_TEXTURE_2D, m_FBO_depth_texture);
  266.  
  267.     //Draw our FBX Model
  268.     // for each mesh in the model...
  269.     for (unsigned int i = 0; i < m_fbxModel->getMeshCount(); ++i)
  270.     {
  271.         // get the current mesh
  272.         FBXMeshNode *pMesh = m_fbxModel->getMeshByIndex(i);
  273.  
  274.         // send the Model
  275.         glm::mat4 m4Model = pMesh->m_globalTransform;// *m_modelMatrix;
  276.         unsigned int modelUniform = glGetUniformLocation(a_programID, "Model");
  277.         glUniformMatrix4fv(modelUniform, 1, false, glm::value_ptr(m4Model));
  278.         //send the normal matrix
  279.         //this is only beneficial if a model has a non-uniform scale or non-orthoganal model matrix
  280.         glm::mat4 m4Normal = glm::transpose(glm::inverse(pMesh->m_globalTransform));// *m_modelMatrix;
  281.         unsigned int normalMatrixUniform = glGetUniformLocation(a_programID, "NormalMatrix");
  282.         glUniformMatrix4fv(normalMatrixUniform, 1, false, glm::value_ptr(m4Normal));
  283.  
  284.         // Bind the texture to one of the ActiveTextures
  285.         // if your shader supported multiple textures, you would bind each texture to a new Active Texture ID here
  286.         //bind our textureLocation variable from the shaders and set it's value to 0 as the active texture is texture 0
  287.         unsigned int texUniformID = glGetUniformLocation(a_programID, "DiffuseTexture");
  288.         glUniform1i(texUniformID, 0);
  289.         //set our active texture, and bind our loaded texture
  290.         glActiveTexture(GL_TEXTURE0);
  291.         glBindTexture(GL_TEXTURE_2D, pMesh->m_material->textureIDs[FBXMaterial::DiffuseTexture]);
  292.  
  293.         // Send the vertex data to the VBO
  294.         glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
  295.         glBufferData(GL_ARRAY_BUFFER, pMesh->m_vertices.size() * sizeof(FBXVertex), pMesh->m_vertices.data(), GL_STATIC_DRAW);
  296.  
  297.         // send the index data to the IBO
  298.         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
  299.         glBufferData(GL_ELEMENT_ARRAY_BUFFER, pMesh->m_indices.size() * sizeof(unsigned int), pMesh->m_indices.data(), GL_STATIC_DRAW);
  300.  
  301.         glDrawElements(GL_TRIANGLES, pMesh->m_indices.size(), GL_UNSIGNED_INT, 0);
  302.     }
  303.     glBindVertexArray(0);
  304.     glUseProgram(0);
  305. }
  306.  
  307. void Shadows::Destroy()
  308. {
  309.  
  310.     m_fbxModel->unload();
  311.     delete m_fbxModel;
  312.  
  313.     glDeleteBuffers(1, &m_vbo);
  314.     glDeleteBuffers(1, &m_ibo);
  315.     glDeleteVertexArrays(1, &m_vao);
  316.     glDeleteProgram(m_programID);
  317.    
  318.     Gizmos::destroy();
  319. }
  320.  
  321. void Shadows::SetupFrameBuffer(unsigned int& a_fbo,
  322.     unsigned int a_targetWidth,
  323.     unsigned int a_targetHeight,
  324.     unsigned int& a_renderTexture,
  325.     unsigned int& a_depthTexture)
  326. {
  327.     //\======================================================================================
  328.     // Create our frame buffer object
  329.     //\=====================================================================================
  330.     // this would be within your onCreate() function
  331.     glGenFramebuffers(1, &a_fbo);
  332.  
  333.     // bind the framebuffer for editing
  334.     glBindFramebuffer(GL_FRAMEBUFFER, a_fbo);
  335.  
  336.     if (a_renderTexture != -1)
  337.     {
  338.         // create a texture to be attached to the framebuffer, stored in the derived app class as a member
  339.         glGenTextures(1, &a_renderTexture);
  340.  
  341.         // bind the texture for editing
  342.         glBindTexture(GL_TEXTURE_2D, a_renderTexture);
  343.  
  344.         // create the texture. Note, the width and height are the dimensions of the screen and the final
  345.         // data pointer is 0 as we aren't including any initial data
  346.         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, a_targetWidth, a_targetHeight,
  347.             0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
  348.  
  349.         // set the filtering if we intend to sample within a shader
  350.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  351.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  352.  
  353.         glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, a_renderTexture, 0);
  354.     }
  355.     // m_FBO_depth would be a member for the derived application class
  356.     glGenTextures(1, &a_depthTexture);
  357.     glBindTexture(GL_TEXTURE_2D, a_depthTexture);
  358.  
  359.     // note the use of GL_DEPTH_COMPONENT32F and GL_DEPTH_COMPONENT
  360.     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, a_targetWidth,
  361.         a_targetHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
  362.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  363.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  364.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  365.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  366.  
  367.     // attach it as a GL_DEPTH_ATTACHMENT
  368.     // attach the texture to the 0th color attachment of the framebuffer
  369.     glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, a_depthTexture, 0);
  370.  
  371.     // Here we tell the framebuffer which color attachments we will be drawing to and how many
  372.     if (a_renderTexture != -1)
  373.     {
  374.         GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 };
  375.         glDrawBuffers(1, drawBuffers);
  376.     }
  377.     else
  378.     {
  379.         glDrawBuffer(GL_NONE);
  380.     }
  381.     // if Status doesn't equal GL_FRAMEBUFFER_COMPLETE there has been an error when creating it
  382.     GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  383.     if (status != GL_FRAMEBUFFER_COMPLETE)
  384.         printf("Framebuffer Error!\n");
  385.  
  386.     // binding 0 to the framebuffer slot unbinds the framebuffer and means future render calls will be sent to
  387.     // the back buffer
  388.     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
  389.  
  390. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top