未完成!!!!
黑近白远
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;
}
三,解决阴影失真问题
最后上传完整代码的百度云