基于Qt的OpenGL编程(3.x以上GLSL可编程管线版)---(十七)阴影映射

未完成!!!!

黑近白远


oglmanager.h

#ifndef OGLMANAGER_H
#define OGLMANAGER_H

#include <QOpenGLFunctions_3_3_Core>
#include "camera.h"
#include "shader.h"
#include <QOpenGLTexture>
#include "texture2d.h"

class OGLManager
{
//     Q_OBJECT
public:
    OGLManager(GLuint w, GLuint h);
    ~OGLManager();

    void init();
    void processInput(GLfloat dt);
    void update(GLfloat dt);
    void resize(GLuint w, GLuint h);
    void draw(GLfloat dt);


    GLboolean keys[1024];
    Camera *camera;
private:
    QOpenGLFunctions_3_3_Core *core;
    GLuint width;
    GLuint height;

    void RenderScene();
    void RenderCube();
    void RenderQuad();
//private slots:
//    void updateModel();

};

#endif // OGLMANAGER_H

oglmanager.cpp

#include "oglmanager.h"
#include <QKeyEvent>
#include <QDebug>
#include "resourcemanager.h"
#include <QOpenGLFramebufferObject>
#include <QOpenGLFramebufferObjectFormat>
//#include "cube.h"
#include <QTime>

const QVector3D CAMERA_POSITION(0.0f, 0.0f, 3.0f);
const QVector3D LIGHT_POSITION(-2.0f, 4.0f, -1.0f);

const GLuint SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024;
const GLuint SCR_WIDTH = 800, SCR_HEIGHT = 600;
const GLfloat near_plane = 1.0f, far_plane = 7.5f;

void RenderScene(Shader &shader);
void RenderCube();
void RenderQuad();
GLuint planeVAO;
GLuint quadVAO = 0;
GLuint quadVBO;
GLuint cubeVAO = 0;
GLuint cubeVBO = 0;
GLuint depthMapFBO;
GLuint depthMap;
  GLuint planeVBO;

//Cube *cube;
QOpenGLFramebufferObject *fbo;
QOpenGLFramebufferObjectFormat *fbof;
QOpenGLTexture *depTex;
QOpenGLTexture *tex;
QTimer *timer;

OGLManager::OGLManager(GLuint w, GLuint h){
  this->width = w;
  this->height = h;
  for(GLuint i = 0; i != 1024; ++i)
    keys[i] = GL_FALSE;

}

OGLManager::~OGLManager(){
  delete this->camera;
  ResourceManager::clear();
}

void OGLManager::init(){
  //开启状态
//    qDebug() << width << " "<< height;
  core = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
  core->glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
  core->glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT);
  core->glEnable(GL_DEPTH_TEST);
//  core->glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

//  cube = new Cube();

  this->camera = new Camera(CAMERA_POSITION);

//  depTex = new QOpenGLTexture(QOpenGLTexture::Target2D);
//  cube->init();

  ResourceManager::loadTexture("wood", ":/textures/res/textures/container2.png");
  ResourceManager::loadShader("shadow_mapping_depth", ":/shaders/res/shaders/shadow_mapping_depth.vert", ":/shaders/res/shaders/shadow_mapping_depth.frag");
  ResourceManager::loadShader("debug_quad", ":/shaders/res/shaders/debug_quad.vert", ":/shaders/res/shaders/debug_quad_depth.frag");

  GLfloat planeVertices[] = {
      // Positions          // Normals         // Texture Coords
      25.0f, -0.5f, 25.0f, 0.0f, 1.0f, 0.0f, 25.0f, 0.0f,
      -25.0f, -0.5f, -25.0f, 0.0f, 1.0f, 0.0f, 0.0f, 25.0f,
      -25.0f, -0.5f, 25.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,

      25.0f, -0.5f, 25.0f, 0.0f, 1.0f, 0.0f, 25.0f, 0.0f,
      25.0f, -0.5f, -25.0f, 0.0f, 1.0f, 0.0f, 25.0f, 25.0f,
      - 25.0f, -0.5f, -25.0f, 0.0f, 1.0f, 0.0f, 0.0f, 25.0f
  };

  core->glGenVertexArrays(1, &planeVAO);
  core->glGenBuffers(1, &planeVBO);

    core->glBindBuffer(GL_ARRAY_BUFFER, planeVBO);
    core->glBufferData(GL_ARRAY_BUFFER, sizeof(planeVertices), &planeVertices, GL_STATIC_DRAW);
    core->glEnableVertexAttribArray(0);
    core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
    core->glEnableVertexAttribArray(1);
    core->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    core->glEnableVertexAttribArray(2);
    core->glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));



  core->glGenFramebuffers(1, &depthMapFBO);
  // - Create depth texture

  core->glGenTextures(1, &depthMap);
  core->glBindTexture(GL_TEXTURE_2D, depthMap);;


  core->glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
  core->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  core->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  core->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  core->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

  core->glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
  core->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
  core->glDrawBuffer(GL_NONE);
  core->glReadBuffer(GL_NONE);
  if (core->glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
          qDebug() << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << endl;
  core->glBindFramebuffer(GL_FRAMEBUFFER, 0);

  QMatrix4x4 lightProjection, lightView;
  QMatrix4x4 lightSpaceMatrix;

  lightProjection.ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane);
  lightView.lookAt(LIGHT_POSITION, QVector3D(0.0f, 0.0f, 0.0f), QVector3D(0.0, 1.0, 0.0));
  lightSpaceMatrix = lightProjection * lightView;
  // - render scene from light's point of view
  QMatrix4x4 model;
  ResourceManager::getShader("shadow_mapping_depth").use().setMatrix4f("lightSpaceMatrix", lightSpaceMatrix);


  core->glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
  core->glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
    core->glClear(GL_DEPTH_BUFFER_BIT);
    ResourceManager::getShader("shadow_mapping_depth").use();
    RenderScene();
  core->glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

void OGLManager::processInput(GLfloat dt){
  if (keys[Qt::Key_W])
    camera->processKeyboard(FORWARD, dt);
  if (keys[Qt::Key_S])
    camera->processKeyboard(BACKWARD, dt);
  if (keys[Qt::Key_A])
    camera->processKeyboard(LEFT, dt);
  if (keys[Qt::Key_D])
    camera->processKeyboard(RIGHT, dt);
  if (keys[Qt::Key_E])
    camera->processKeyboard(UP, dt);
  if (keys[Qt::Key_Q])
    camera->processKeyboard(DOWN, dt);
}

//GLfloat time = 0.0f;

void OGLManager::update(GLfloat dt){

}

void OGLManager::resize(GLuint w, GLuint h){
  core->glViewport(0, 0, w, h);
}

void OGLManager::draw(GLfloat dt)
{


  core->glViewport(0, 0, SCR_WIDTH,  SCR_HEIGHT);
  core->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BITS);

  ResourceManager::getShader("debug_quad").use();
  core->glActiveTexture(GL_TEXTURE0);
  core->glBindTexture(GL_TEXTURE_2D, depthMap);
//  ResourceManager::getTexture("wood").bind();
  RenderQuad();

//  core->glDeleteTextures(1, &depthMap);
//  core->glDeleteFramebuffers(1, &depthMapFBO);

}

void OGLManager::RenderScene()
{
    // Floor
    QMatrix4x4 model;
    ResourceManager::getShader("shadow_mapping_depth").use().setMatrix4f("model", model);
    //core->glBindVertexArray(planeVAO);
    core->glBindBuffer(GL_ARRAY_BUFFER, planeVBO);
    core->glEnableVertexAttribArray(0);
    core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
    core->glEnableVertexAttribArray(1);
    core->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    core->glEnableVertexAttribArray(2);
    core->glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
      core->glDrawArrays(GL_TRIANGLES, 0, 6);

    core->glBindVertexArray(0);
    model.setToIdentity();
    model.translate(0.0f, 1.5f, 0.0);
    ResourceManager::getShader("shadow_mapping_depth").use().setMatrix4f("model", model);
    RenderCube();

    model.setToIdentity();
    model.translate(2.0f, 0.0f, 1.0);
    ResourceManager::getShader("shadow_mapping_depth").use().setMatrix4f("model", model);
    RenderCube();

    model.setToIdentity();
    model.translate(-1.0f, 0.0f, 2.0);
    model.rotate(60.0f, QVector3D(1.0, 0.0, 1.0));
    model.scale(0.5);
    ResourceManager::getShader("shadow_mapping_depth").use().setMatrix4f("model", model);
    RenderCube();
}


void OGLManager::RenderCube()
{
    // Initialize (if necessary)
    if (cubeVAO == 0)
    {
        GLfloat vertices[] = {
            // Back face
            -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, // Bottom-left
            0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, // top-right
            0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, // bottom-right
            0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,  // top-right
            -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,  // bottom-left
            -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,// top-left
            // Front face
            -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom-left
            0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,  // bottom-right
            0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,  // top-right
            0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // top-right
            -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,  // top-left
            -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,  // bottom-left
            // Left face
            -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-right
            -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top-left
            -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,  // bottom-left
            -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-left
            -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,  // bottom-right
            -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-right
            // Right face
            0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-left
            0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-right
            0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top-right
            0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,  // bottom-right
            0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,  // top-left
            0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom-left
            // Bottom face
            -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, // top-right
            0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, // top-left
            0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,// bottom-left
            0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom-left
            -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom-right
            -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, // top-right
            // Top face
            -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,// top-left
            0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom-right
            0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top-right
            0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom-right
            -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,// top-left
            -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f // bottom-left
        };
        core->glGenVertexArrays(1, &cubeVAO);
        core->glGenBuffers(1, &cubeVBO);
        // Fill buffer
        core->glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
        core->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
        // Link vertex attributes
        core->glBindVertexArray(cubeVAO);
          core->glEnableVertexAttribArray(0);
          core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
          core->glEnableVertexAttribArray(1);
          core->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
          core->glEnableVertexAttribArray(2);
          core->glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
          core->glBindBuffer(GL_ARRAY_BUFFER, 0);
        core->glBindVertexArray(0);
    }
    // Render Cube
    core->glBindVertexArray(cubeVAO);
    core->glDrawArrays(GL_TRIANGLES, 0, 36);
    core->glBindVertexArray(0);
}

void OGLManager::RenderQuad()
{
    if (quadVAO == 0)
    {
        GLfloat quadVertices[] = {
            // Positions        // Texture Coords
            -1.0f,  1.0f, 0.0f,  0.0f, 1.0f,
            -1.0f, -1.0f, 0.0f,  0.0f, 0.0f,
             1.0f,  1.0f, 0.0f,  1.0f, 1.0f,
             1.0f, -1.0f, 0.0f,  1.0f, 0.0f,
        };
        // Setup plane VAO
        core->glGenVertexArrays(1, &quadVAO);
        core->glGenBuffers(1, &quadVBO);
        core->glBindVertexArray(quadVAO);
          core->glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
          core->glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
          core->glEnableVertexAttribArray(0);
          core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
          core->glEnableVertexAttribArray(1);
          core->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
        core->glBindVertexArray(0);
    }
//    core->glBindVertexArray(quadVAO);
              core->glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
    core->glEnableVertexAttribArray(0);
    core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
    core->glEnableVertexAttribArray(1);
    core->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
      core->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
      //    core->glBindVertexArray(0);
}

//void OGLManager::updateModel()
//{

//}

二,初步阴影

有阴影失真的问题

shadow_mapping.vert

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;

out vec2 TexCoords;

out VS_OUT {
    vec3 FragPos;
    vec3 Normal;
    vec2 TexCoords;
    vec4 FragPosLightSpace;
} vs_out;

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
uniform mat4 lightSpaceMatrix;

void main()
{
    vs_out.FragPos = vec3(model * vec4(aPos, 1.0));
    vs_out.Normal = transpose(inverse(mat3(model))) * aNormal;
    vs_out.TexCoords = aTexCoords;
    vs_out.FragPosLightSpace = lightSpaceMatrix * vec4(vs_out.FragPos, 1.0);
    gl_Position = projection * view * model * vec4(aPos, 1.0);
}

shadow_mapping.frag

#version 330 core
out vec4 FragColor;

in VS_OUT {
    vec3 FragPos;
    vec3 Normal;
    vec2 TexCoords;
    vec4 FragPosLightSpace;
} fs_in;

uniform sampler2D diffuseTexture;
uniform sampler2D shadowMap;

uniform vec3 lightPos;
uniform vec3 viewPos;

float ShadowCalculation(vec4 fragPosLightSpace)
{
    // perform perspective divide
    vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
    // transform to [0,1] range
    projCoords = projCoords * 0.5 + 0.5;
    // get closest depth value from light's perspective (using [0,1] range fragPosLight as coords)
    float closestDepth = texture(shadowMap, projCoords.xy).r; 
    // get depth of current fragment from light's perspective
    float currentDepth = projCoords.z;

				float shadow = currentDepth > closestDepth ? 1.0f : 0.0f;
    return shadow;
}

void main()
{           
    vec3 color = texture(diffuseTexture, fs_in.TexCoords).rgb;
    vec3 normal = normalize(fs_in.Normal);
    vec3 lightColor = vec3(0.3);
    // ambient
				vec3 ambient = 0.15 * color;
    // diffuse
    vec3 lightDir = normalize(lightPos - fs_in.FragPos);
    float diff = max(dot(lightDir, normal), 0.0);
    vec3 diffuse = diff * lightColor;
    // specular
    vec3 viewDir = normalize(viewPos - fs_in.FragPos);
    vec3 reflectDir = reflect(-lightDir, normal);
    float spec = 0.0;
    vec3 halfwayDir = normalize(lightDir + viewDir);  
    spec = pow(max(dot(normal, halfwayDir), 0.0), 64.0);
    vec3 specular = spec * lightColor;    
    // calculate shadow
    float shadow = ShadowCalculation(fs_in.FragPosLightSpace);                      
    vec3 lighting = (ambient + (1.0 - shadow) * (diffuse + specular)) * color;    
    
    FragColor = vec4(lighting, 1.0);
}

shadow_mapping_depth.vert

#version 330 core
layout (location = 0) in vec3 aPos;

uniform mat4 lightSpaceMatrix;
uniform mat4 model;

void main()
{
	gl_Position = lightSpaceMatrix * model * vec4(aPos, 1.0);
}

shadow_mapping_depth.frag
#version 330 core

void main()
{             
//					gl_FragDepth = gl_FragCoord.z;
//	gl_FragDepth = 0.3;
}

三,解决阴影失真问题




最后上传完整代码的百度云


猜你喜欢

转载自blog.csdn.net/z136411501/article/details/80370245