分离出彩绘管线
parent
549a91ec72
commit
3a600ec440
|
@ -88,6 +88,7 @@
|
||||||
<ClCompile Include="Camera.cpp" />
|
<ClCompile Include="Camera.cpp" />
|
||||||
<ClCompile Include="Mesh.cpp" />
|
<ClCompile Include="Mesh.cpp" />
|
||||||
<ClCompile Include="Model.cpp" />
|
<ClCompile Include="Model.cpp" />
|
||||||
|
<ClCompile Include="PaintingMesh.cpp" />
|
||||||
<ClCompile Include="RendererWidget.cpp" />
|
<ClCompile Include="RendererWidget.cpp" />
|
||||||
<QtRcc Include="MainWindow.qrc" />
|
<QtRcc Include="MainWindow.qrc" />
|
||||||
<QtUic Include="MainWindow.ui" />
|
<QtUic Include="MainWindow.ui" />
|
||||||
|
@ -103,13 +104,17 @@
|
||||||
<None Include="Shaders\final.vert" />
|
<None Include="Shaders\final.vert" />
|
||||||
<None Include="Shaders\model.frag" />
|
<None Include="Shaders\model.frag" />
|
||||||
<None Include="Shaders\model.vert" />
|
<None Include="Shaders\model.vert" />
|
||||||
|
<None Include="Shaders\painting.frag" />
|
||||||
|
<None Include="Shaders\painting.vert" />
|
||||||
<None Include="Shaders\shader.frag" />
|
<None Include="Shaders\shader.frag" />
|
||||||
<None Include="Shaders\shader.vert" />
|
<None Include="Shaders\shader.vert" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Camera.h" />
|
<ClInclude Include="Camera.h" />
|
||||||
|
<ClInclude Include="Drawable.h" />
|
||||||
<ClInclude Include="Mesh.h" />
|
<ClInclude Include="Mesh.h" />
|
||||||
<ClInclude Include="Model.h" />
|
<ClInclude Include="Model.h" />
|
||||||
|
<ClInclude Include="PaintingMesh.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
|
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
|
||||||
|
|
|
@ -55,6 +55,9 @@
|
||||||
<ClCompile Include="Model.cpp">
|
<ClCompile Include="Model.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="PaintingMesh.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<QtMoc Include="RendererWidget.h">
|
<QtMoc Include="RendererWidget.h">
|
||||||
|
@ -80,6 +83,12 @@
|
||||||
<None Include="Shaders\final.frag">
|
<None Include="Shaders\final.frag">
|
||||||
<Filter>Resource Files\Shaders</Filter>
|
<Filter>Resource Files\Shaders</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="Shaders\painting.frag">
|
||||||
|
<Filter>Resource Files\Shaders</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="Shaders\painting.vert">
|
||||||
|
<Filter>Resource Files\Shaders</Filter>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Camera.h">
|
<ClInclude Include="Camera.h">
|
||||||
|
@ -91,5 +100,11 @@
|
||||||
<ClInclude Include="Model.h">
|
<ClInclude Include="Model.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="PaintingMesh.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Drawable.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
class Drawable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void draw() = 0;
|
||||||
|
};
|
||||||
|
|
|
@ -7,5 +7,7 @@
|
||||||
<file>Shaders/final.frag</file>
|
<file>Shaders/final.frag</file>
|
||||||
<file>Shaders/final.vert</file>
|
<file>Shaders/final.vert</file>
|
||||||
<file>container.jpg</file>
|
<file>container.jpg</file>
|
||||||
|
<file>Shaders/painting.frag</file>
|
||||||
|
<file>Shaders/painting.vert</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -1,69 +1,77 @@
|
||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
|
|
||||||
Mesh::Mesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model)
|
Mesh::Mesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model)
|
||||||
: glFunc(glFunc)
|
: glFunc(glFunc)
|
||||||
, shaderProgram(shaderProgram)
|
, shaderProgram(shaderProgram)
|
||||||
, VBO(QOpenGLBuffer::VertexBuffer)
|
, VBO(QOpenGLBuffer::VertexBuffer)
|
||||||
, EBO(QOpenGLBuffer::IndexBuffer)
|
, EBO(QOpenGLBuffer::IndexBuffer)
|
||||||
|
, model((float*)&model)
|
||||||
{
|
{
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
//for (int i = 0; i < 4; i++) {
|
||||||
for (int j = 0; j < 4; j++) {
|
// for (int j = 0; j < 4; j++) {
|
||||||
this->model(i, j) = model[i][j];
|
// this->model(i, j) = model[i][j];
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
void Mesh::Draw()
|
void Mesh::draw()
|
||||||
{
|
{
|
||||||
unsigned int diffuseNr = 1;
|
shaderProgram->bind();
|
||||||
unsigned int specularNr = 1;
|
|
||||||
unsigned int normalNr = 1;
|
|
||||||
unsigned int heightNr = 1;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < textures.size(); i++)
|
unsigned int diffuseNr = 1;
|
||||||
{
|
unsigned int specularNr = 1;
|
||||||
glFunc->glActiveTexture(GL_TEXTURE0 + i); // 在绑定之前激活相应的纹理单元
|
unsigned int normalNr = 1;
|
||||||
|
unsigned int heightNr = 1;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < textures.size(); i++)
|
||||||
|
{
|
||||||
|
glFunc->glActiveTexture(GL_TEXTURE0 + i); // 在绑定之前激活相应的纹理单元
|
||||||
|
|
||||||
|
|
||||||
textures[i]->texture.bind();
|
textures[i]->texture.bind();
|
||||||
//qDebug() << name + number;
|
//qDebug() << name + number;
|
||||||
shaderProgram->setUniformValue(textures[i]->type.toStdString().c_str(), i);
|
shaderProgram->setUniformValue(textures[i]->type.toStdString().c_str(), i);
|
||||||
}
|
}
|
||||||
// 绘制网格
|
// 绘制网格
|
||||||
|
|
||||||
QOpenGLVertexArrayObject::Binder bind(&VAO);
|
QOpenGLVertexArrayObject::Binder bind(&VAO);
|
||||||
shaderProgram->setUniformValue("model", model);
|
shaderProgram->setUniformValue("model", model);
|
||||||
glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
|
glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
|
||||||
|
|
||||||
|
shaderProgram->release();
|
||||||
}
|
}
|
||||||
void Mesh::setupMesh()
|
void Mesh::setupMesh()
|
||||||
{
|
{
|
||||||
|
shaderProgram->bind();
|
||||||
|
VAO.create();
|
||||||
|
VAO.bind();
|
||||||
|
|
||||||
VAO.create();
|
VBO.create();
|
||||||
VAO.bind();
|
EBO.create();
|
||||||
|
|
||||||
VBO.create();
|
VBO.bind();
|
||||||
EBO.create();
|
VBO.allocate(vertices.data(), vertices.size() * sizeof(Vertex));
|
||||||
|
|
||||||
VBO.bind();
|
EBO.bind();
|
||||||
VBO.allocate(vertices.data(), vertices.size() * sizeof(Vertex));
|
EBO.allocate(indices.data(), indices.size() * sizeof(unsigned int));
|
||||||
|
|
||||||
EBO.bind();
|
|
||||||
EBO.allocate(indices.data(), indices.size() * sizeof(unsigned int));
|
|
||||||
|
|
||||||
|
|
||||||
shaderProgram->enableAttributeArray(0);
|
|
||||||
shaderProgram->setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(Vertex));
|
|
||||||
|
|
||||||
shaderProgram->enableAttributeArray(1);
|
shaderProgram->enableAttributeArray(0);
|
||||||
shaderProgram->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, Normal), 3, sizeof(Vertex));
|
shaderProgram->setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(Vertex));
|
||||||
|
|
||||||
shaderProgram->enableAttributeArray(2);
|
shaderProgram->enableAttributeArray(1);
|
||||||
shaderProgram->setAttributeBuffer(2, GL_FLOAT, offsetof(Vertex, TexCoords), 2, sizeof(Vertex));
|
shaderProgram->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, Normal), 3, sizeof(Vertex));
|
||||||
|
|
||||||
shaderProgram->enableAttributeArray(1);
|
shaderProgram->enableAttributeArray(2);
|
||||||
shaderProgram->setAttributeBuffer(3, GL_FLOAT, offsetof(Vertex, Tangent), 3, sizeof(Vertex));
|
shaderProgram->setAttributeBuffer(2, GL_FLOAT, offsetof(Vertex, TexCoords), 2, sizeof(Vertex));
|
||||||
|
|
||||||
shaderProgram->enableAttributeArray(1);
|
shaderProgram->enableAttributeArray(3);
|
||||||
shaderProgram->setAttributeBuffer(4, GL_FLOAT, offsetof(Vertex, Bitangent), 3, sizeof(Vertex));
|
shaderProgram->setAttributeBuffer(3, GL_FLOAT, offsetof(Vertex, Tangent), 3, sizeof(Vertex));
|
||||||
VAO.release();
|
|
||||||
|
shaderProgram->enableAttributeArray(4);
|
||||||
|
shaderProgram->setAttributeBuffer(4, GL_FLOAT, offsetof(Vertex, Bitangent), 3, sizeof(Vertex));
|
||||||
|
|
||||||
|
VAO.release();
|
||||||
|
shaderProgram->release();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
#include "Drawable.h"
|
||||||
|
|
||||||
struct Vertex
|
struct Vertex
|
||||||
{
|
{
|
||||||
|
@ -35,7 +36,8 @@ struct Texture
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Mesh {
|
class Mesh : public Drawable
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/* 网格数据 */
|
/* 网格数据 */
|
||||||
QVector<Vertex> vertices; //顶点数据
|
QVector<Vertex> vertices; //顶点数据
|
||||||
|
@ -47,7 +49,7 @@ public:
|
||||||
|
|
||||||
/* 函数 */
|
/* 函数 */
|
||||||
Mesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model);
|
Mesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model);
|
||||||
void Draw();
|
void draw() override;
|
||||||
void setupMesh();
|
void setupMesh();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -4,189 +4,258 @@
|
||||||
#include <QOpenGLContext>
|
#include <QOpenGLContext>
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "PaintingMesh.h"
|
||||||
|
|
||||||
Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram)
|
Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram)
|
||||||
: context(context)
|
: context(context)
|
||||||
, shaderProgram(shaderProgram)
|
, shaderProgram(shaderProgram)
|
||||||
, directory(path)
|
, directory(path)
|
||||||
{
|
{
|
||||||
Assimp::Importer import;
|
Assimp::Importer import;
|
||||||
const aiScene* scene = import.ReadFile(directory.absolutePath().toUtf8(), aiProcess_Triangulate | aiProcess_FlipUVs);
|
const aiScene* scene = import.ReadFile(directory.absolutePath().toUtf8(), aiProcess_Triangulate | aiProcess_FlipUVs);
|
||||||
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||||
{
|
{
|
||||||
qDebug() << "ERROR::ASSIMP::" << import.GetErrorString() << endl;
|
qDebug() << "ERROR::ASSIMP::" << import.GetErrorString() << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qDebug() << directory.absolutePath() << "Loaded Successfully";
|
qDebug() << directory.absolutePath() << "Loaded Successfully";
|
||||||
qDebug() << "NumMeshes: " << scene->mNumMeshes;
|
qDebug() << "NumMeshes: " << scene->mNumMeshes;
|
||||||
qDebug() << "NumMaterials: " << scene->mNumMaterials;
|
qDebug() << "NumMaterials: " << scene->mNumMaterials;
|
||||||
qDebug() << "NumTextures: " << scene->mNumTextures;
|
qDebug() << "NumTextures: " << scene->mNumTextures;
|
||||||
directory.cdUp();
|
directory.cdUp();
|
||||||
processNode(scene->mRootNode, scene);
|
processNode(scene->mRootNode, scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram)
|
||||||
|
: context(context)
|
||||||
|
, shaderProgram(shaderProgram)
|
||||||
|
, paintingProgram(paintingProgram)
|
||||||
|
, directory(path)
|
||||||
|
{
|
||||||
|
Assimp::Importer import;
|
||||||
|
const aiScene* scene = import.ReadFile(directory.absolutePath().toUtf8(), aiProcess_Triangulate | aiProcess_FlipUVs);
|
||||||
|
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||||
|
{
|
||||||
|
qDebug() << "ERROR::ASSIMP::" << import.GetErrorString() << endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qDebug() << directory.absolutePath() << "Loaded Successfully";
|
||||||
|
qDebug() << "NumMeshes: " << scene->mNumMeshes;
|
||||||
|
qDebug() << "NumMaterials: " << scene->mNumMaterials;
|
||||||
|
qDebug() << "NumTextures: " << scene->mNumTextures;
|
||||||
|
directory.cdUp();
|
||||||
|
processNode(scene->mRootNode, scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
Model::~Model() //Ïú»Ù¶ÔÏó
|
Model::~Model() //Ïú»Ù¶ÔÏó
|
||||||
{
|
{
|
||||||
for (auto& it : textures_loaded) {
|
for (auto& it : textures_loaded) {
|
||||||
it->texture.destroy();
|
it->texture.destroy();
|
||||||
delete it;
|
delete it;
|
||||||
}
|
}
|
||||||
for (auto& it : meshes) {
|
for (auto& it : meshes) {
|
||||||
delete it;
|
delete it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::draw() {
|
void Model::draw() {
|
||||||
shaderProgram->bind();
|
//shaderProgram->bind();
|
||||||
for (Mesh* mesh : meshes) {
|
for (Drawable* mesh : meshes) {
|
||||||
mesh->Draw();
|
mesh->draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::destroy()
|
void Model::destroy()
|
||||||
{
|
{
|
||||||
context->doneCurrent();
|
context->doneCurrent();
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Model* Model::createModel(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram)
|
Model* Model::createModel(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram)
|
||||||
{
|
{
|
||||||
return new Model(path, context, shaderProgram);
|
return new Model(path, context, shaderProgram);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Model::processNode(aiNode* node, const aiScene* scene, aiMatrix4x4 mat4)
|
void Model::processNode(aiNode* node, const aiScene* scene, aiMatrix4x4 mat4)
|
||||||
{
|
{
|
||||||
|
|
||||||
// 处理节点所有的网格(如果有的话)
|
// 处理节点所有的网格(如果有的话)
|
||||||
for (unsigned int i = 0; i < node->mNumMeshes; i++)
|
for (unsigned int i = 0; i < node->mNumMeshes; i++)
|
||||||
{
|
{
|
||||||
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
|
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
|
||||||
meshes.push_back(processMesh(mesh, scene, mat4));
|
meshes.push_back(processMesh(mesh, scene, mat4));
|
||||||
|
|
||||||
}
|
}
|
||||||
// 接下来对它的子节点重复这一过程
|
// 接下来对它的子节点重复这一过程
|
||||||
for (unsigned int i = 0; i < node->mNumChildren; i++)
|
for (unsigned int i = 0; i < node->mNumChildren; i++)
|
||||||
{
|
{
|
||||||
processNode(node->mChildren[i], scene, mat4 * node->mChildren[i]->mTransformation);
|
processNode(node->mChildren[i], scene, mat4 * node->mChildren[i]->mTransformation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Mesh* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model)
|
Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model)
|
||||||
{
|
{
|
||||||
// 初始化网格
|
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
||||||
Mesh* m_mesh = new Mesh(QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Compatibility>(), shaderProgram, model);
|
|
||||||
// 遍历网格的每个顶点
|
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
|
|
||||||
{
|
|
||||||
Vertex vertex;
|
|
||||||
QVector3D vector; //将assimp的数据转化为QtOpenGL支持的数据
|
|
||||||
|
|
||||||
// 位置
|
aiString str;
|
||||||
vector.setX(mesh->mVertices[i].x);
|
material->GetTexture(aiTextureType_BASE_COLOR, 0, &str);
|
||||||
vector.setY(mesh->mVertices[i].y);
|
|
||||||
vector.setZ(mesh->mVertices[i].z);
|
|
||||||
vertex.Position = vector;
|
|
||||||
// 法向量
|
|
||||||
if (mesh->mNormals) {
|
|
||||||
vector.setX(mesh->mNormals[i].x);
|
|
||||||
vector.setY(mesh->mNormals[i].y);
|
|
||||||
vector.setZ(mesh->mNormals[i].z);
|
|
||||||
vertex.Normal = vector;
|
|
||||||
}
|
|
||||||
// 纹理坐标
|
|
||||||
if (mesh->mTextureCoords[0]) // does the mesh contain texture coordinates?
|
|
||||||
{
|
|
||||||
QVector2D vec;
|
|
||||||
//一个顶点最多可以包含8个不同的纹理坐标。因此我们假设我们不用
|
|
||||||
//使用一个顶点可以有多个纹理坐标的模型,所以我们总是取第一个集合(0)。
|
|
||||||
vec.setX(mesh->mTextureCoords[0][i].x);
|
|
||||||
vec.setY(mesh->mTextureCoords[0][i].y);
|
|
||||||
vertex.TexCoords = vec;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
vertex.TexCoords = QVector2D(0, 0);
|
|
||||||
}
|
|
||||||
if (mesh->mTangents) {
|
|
||||||
// tangent
|
|
||||||
vector.setX(mesh->mTangents[i].x);
|
|
||||||
vector.setY(mesh->mTangents[i].y);
|
|
||||||
vector.setZ(mesh->mTangents[i].z);
|
|
||||||
vertex.Tangent = vector;
|
|
||||||
}
|
|
||||||
if (mesh->mBitangents) {
|
|
||||||
vector.setX(mesh->mBitangents[i].x);
|
|
||||||
vector.setY(mesh->mBitangents[i].y);
|
|
||||||
vector.setZ(mesh->mBitangents[i].z);
|
|
||||||
vertex.Bitangent = vector;
|
|
||||||
}
|
|
||||||
// bitangent
|
|
||||||
m_mesh->vertices.push_back(vertex);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
|
if (paintingProgram != nullptr && std::strcmp(str.C_Str(), "17876391417123941155.jpg")==0)
|
||||||
{
|
{
|
||||||
aiFace face = mesh->mFaces[i];
|
qDebug() << str.C_Str();
|
||||||
// 将所有面的索引数据添加到索引数组中
|
// 初始化网格
|
||||||
for (unsigned int j = 0; j < face.mNumIndices; j++) {
|
PaintingMesh* m_mesh = new PaintingMesh(QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Compatibility>(), paintingProgram, model);
|
||||||
m_mesh->indices.push_back(face.mIndices[j]);
|
// 遍历网格的每个顶点
|
||||||
}
|
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||||
}
|
{
|
||||||
|
PaintingVertex vertex;
|
||||||
|
vertex.Position = QVector3D(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z);
|
||||||
|
// 法向量
|
||||||
|
if (mesh->mNormals)
|
||||||
|
vertex.Normal = QVector3D(mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z);
|
||||||
|
|
||||||
// 处理材质
|
// 纹理坐标
|
||||||
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
if (mesh->mTextureCoords[0])
|
||||||
|
vertex.TexCoords = QVector2D(mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y);
|
||||||
|
|
||||||
QVector<Texture*> diffuseMaps = loadMaterialTextures(material, aiTextureType_BASE_COLOR, "texture_basecolor");
|
if (mesh->mTangents)
|
||||||
for (auto& it : diffuseMaps)
|
vertex.Tangent = QVector3D(mesh->mTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z);
|
||||||
m_mesh->textures.push_back(it);
|
|
||||||
|
|
||||||
QVector<Texture*> metalnessMaps = loadMaterialTextures(material, aiTextureType_METALNESS, "texture_metallic_roughness");
|
if (mesh->mBitangents)
|
||||||
for (auto& it : metalnessMaps)
|
vertex.Bitangent = QVector3D(mesh->mBitangents[i].x, mesh->mBitangents[i].y, mesh->mBitangents[i].z);;
|
||||||
m_mesh->textures.push_back(it);
|
|
||||||
|
m_mesh->vertices.push_back(vertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
|
||||||
|
{
|
||||||
|
aiFace face = mesh->mFaces[i];
|
||||||
|
// 将所有面的索引数据添加到索引数组中
|
||||||
|
for (unsigned int j = 0; j < face.mNumIndices; j++) {
|
||||||
|
m_mesh->indices.push_back(face.mIndices[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_mesh->setupMesh();
|
||||||
|
return m_mesh;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 初始化网格
|
||||||
|
Mesh* m_mesh = new Mesh(QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Compatibility>(), shaderProgram, model);
|
||||||
|
// 遍历网格的每个顶点
|
||||||
|
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||||
|
{
|
||||||
|
Vertex vertex;
|
||||||
|
QVector3D vector; //将assimp的数据转化为QtOpenGL支持的数据
|
||||||
|
|
||||||
|
// 位置
|
||||||
|
vector.setX(mesh->mVertices[i].x);
|
||||||
|
vector.setY(mesh->mVertices[i].y);
|
||||||
|
vector.setZ(mesh->mVertices[i].z);
|
||||||
|
vertex.Position = vector;
|
||||||
|
// 法向量
|
||||||
|
if (mesh->mNormals) {
|
||||||
|
vector.setX(mesh->mNormals[i].x);
|
||||||
|
vector.setY(mesh->mNormals[i].y);
|
||||||
|
vector.setZ(mesh->mNormals[i].z);
|
||||||
|
vertex.Normal = vector;
|
||||||
|
}
|
||||||
|
// 纹理坐标
|
||||||
|
if (mesh->mTextureCoords[0]) // does the mesh contain texture coordinates?
|
||||||
|
{
|
||||||
|
QVector2D vec;
|
||||||
|
//一个顶点最多可以包含8个不同的纹理坐标。因此我们假设我们不用
|
||||||
|
//使用一个顶点可以有多个纹理坐标的模型,所以我们总是取第一个集合(0)。
|
||||||
|
vec.setX(mesh->mTextureCoords[0][i].x);
|
||||||
|
vec.setY(mesh->mTextureCoords[0][i].y);
|
||||||
|
vertex.TexCoords = vec;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vertex.TexCoords = QVector2D(0, 0);
|
||||||
|
}
|
||||||
|
if (mesh->mTangents) {
|
||||||
|
// tangent
|
||||||
|
vector.setX(mesh->mTangents[i].x);
|
||||||
|
vector.setY(mesh->mTangents[i].y);
|
||||||
|
vector.setZ(mesh->mTangents[i].z);
|
||||||
|
vertex.Tangent = vector;
|
||||||
|
}
|
||||||
|
if (mesh->mBitangents) {
|
||||||
|
vector.setX(mesh->mBitangents[i].x);
|
||||||
|
vector.setY(mesh->mBitangents[i].y);
|
||||||
|
vector.setZ(mesh->mBitangents[i].z);
|
||||||
|
vertex.Bitangent = vector;
|
||||||
|
}
|
||||||
|
// bitangent
|
||||||
|
m_mesh->vertices.push_back(vertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
|
||||||
|
{
|
||||||
|
aiFace face = mesh->mFaces[i];
|
||||||
|
// 将所有面的索引数据添加到索引数组中
|
||||||
|
for (unsigned int j = 0; j < face.mNumIndices; j++) {
|
||||||
|
m_mesh->indices.push_back(face.mIndices[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理材质
|
||||||
|
QVector<Texture*> diffuseMaps = loadMaterialTextures(material, aiTextureType_BASE_COLOR, "texture_basecolor");
|
||||||
|
for (auto& it : diffuseMaps)
|
||||||
|
m_mesh->textures.push_back(it);
|
||||||
|
|
||||||
|
QVector<Texture*> metalnessMaps = loadMaterialTextures(material, aiTextureType_METALNESS, "texture_metallic_roughness");
|
||||||
|
for (auto& it : metalnessMaps)
|
||||||
|
m_mesh->textures.push_back(it);
|
||||||
|
|
||||||
|
QVector<Texture*> normalMaps = loadMaterialTextures(material, aiTextureType_NORMALS, "texture_normal");
|
||||||
|
for (auto& it : normalMaps)
|
||||||
|
m_mesh->textures.push_back(it);
|
||||||
|
|
||||||
|
m_mesh->setupMesh();
|
||||||
|
return m_mesh;
|
||||||
|
}
|
||||||
|
|
||||||
QVector<Texture*> normalMaps = loadMaterialTextures(material, aiTextureType_NORMALS, "texture_normal");
|
|
||||||
for (auto& it : normalMaps)
|
|
||||||
m_mesh->textures.push_back(it);
|
|
||||||
|
|
||||||
m_mesh->setupMesh();
|
|
||||||
return m_mesh;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<Texture*> Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type, QString typeName)
|
QVector<Texture*> Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type, QString typeName)
|
||||||
{
|
{
|
||||||
QVector<Texture*> textures;
|
QVector<Texture*> textures;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < mat->GetTextureCount(type); i++)
|
for (unsigned int i = 0; i < mat->GetTextureCount(type); i++)
|
||||||
{
|
{
|
||||||
//qDebug() << typeName;
|
//qDebug() << typeName;
|
||||||
aiString str;
|
aiString str;
|
||||||
mat->GetTexture(type, i, &str);
|
mat->GetTexture(type, i, &str);
|
||||||
|
|
||||||
// 检查纹理是否在之前加载过,如果是,则继续到下一个迭代:跳过加载新纹理
|
// 检查纹理是否在之前加载过,如果是,则继续到下一个迭代:跳过加载新纹理
|
||||||
bool skip = false;
|
bool skip = false;
|
||||||
for (unsigned int j = 0; j < textures_loaded.size(); j++)
|
for (unsigned int j = 0; j < textures_loaded.size(); j++)
|
||||||
{
|
{
|
||||||
if (std::strcmp(textures_loaded[j]->path.toStdString().c_str(), str.C_Str()) == 0)
|
if (std::strcmp(textures_loaded[j]->path.toStdString().c_str(), str.C_Str()) == 0)
|
||||||
{
|
{
|
||||||
textures.push_back(textures_loaded[j]);
|
textures.push_back(textures_loaded[j]);
|
||||||
skip = true; //【优化】 带有相同filepath的纹理已经加载,继续到下一个
|
skip = true; //【优化】 带有相同filepath的纹理已经加载,继续到下一个
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!skip)
|
if (!skip)
|
||||||
{ // 如果材质还没有加载,加载它
|
{ // 如果材质还没有加载,加载它
|
||||||
Texture* texture = new Texture;
|
Texture* texture = new Texture;
|
||||||
QImage data(directory.filePath(str.C_Str()));
|
QImage data(directory.filePath(str.C_Str()));
|
||||||
if (!data.isNull()) {
|
if (!data.isNull()) {
|
||||||
texture->texture.setData(data);
|
texture->texture.setData(data);
|
||||||
texture->type = typeName;
|
texture->type = typeName;
|
||||||
texture->path = str.C_Str();
|
texture->path = str.C_Str();
|
||||||
textures.push_back(texture);
|
textures.push_back(texture);
|
||||||
textures_loaded.push_back(texture); // store it as texture loaded for entire model, to ensure we won't unnecesery load duplicate textures.
|
textures_loaded.push_back(texture); // store it as texture loaded for entire model, to ensure we won't unnecesery load duplicate textures.
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
qDebug() << "未能成功加载纹理:" << directory.filePath(str.C_Str());
|
qDebug() << "未能成功加载纹理:" << directory.filePath(str.C_Str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return textures;
|
return textures;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,36 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
|
#include "Drawable.h"
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
class Model
|
class Model
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void draw();
|
void draw();
|
||||||
void destroy();
|
void destroy();
|
||||||
static Model* createModel(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram);
|
static Model* createModel(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram);
|
||||||
|
Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram);
|
||||||
private:
|
private:
|
||||||
Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram);
|
Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram);
|
||||||
~Model();
|
|
||||||
QOpenGLContext* context; //opengl函数入口
|
|
||||||
QOpenGLShaderProgram* shaderProgram; //着色器程序
|
|
||||||
|
|
||||||
/* 模型数据 */
|
~Model();
|
||||||
QVector<Texture*>textures_loaded; //纹理
|
QOpenGLContext* context; //opengl函数入口
|
||||||
QVector<Mesh*> meshes; //网格
|
QOpenGLShaderProgram* shaderProgram = nullptr;
|
||||||
QDir directory; //模型所在路径
|
QOpenGLShaderProgram* paintingProgram = nullptr; //彩绘着色器程序
|
||||||
|
/* 模型数据 */
|
||||||
|
QVector<Texture*> textures_loaded; //纹理
|
||||||
|
QVector<Drawable*> meshes; //网格
|
||||||
|
QDir directory; //模型所在路径
|
||||||
|
|
||||||
//递归遍历结点
|
//递归遍历结点
|
||||||
void processNode(aiNode* node, const aiScene* scene, aiMatrix4x4 mat4 = aiMatrix4x4());
|
void processNode(aiNode* node, const aiScene* scene, aiMatrix4x4 mat4 = aiMatrix4x4());
|
||||||
|
|
||||||
//加载网格
|
//加载网格
|
||||||
Mesh* processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model);
|
Drawable* processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model);
|
||||||
|
|
||||||
//加载材质纹理
|
//加载材质纹理
|
||||||
QVector<Texture*> loadMaterialTextures(aiMaterial* mat, aiTextureType type, QString typeName);
|
QVector<Texture*> loadMaterialTextures(aiMaterial* mat, aiTextureType type, QString typeName);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
#include "PaintingMesh.h"
|
||||||
|
|
||||||
|
PaintingMesh::PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model)
|
||||||
|
: glFunc(glFunc)
|
||||||
|
, shaderProgram(shaderProgram)
|
||||||
|
, VBO(QOpenGLBuffer::VertexBuffer)
|
||||||
|
, EBO(QOpenGLBuffer::IndexBuffer)
|
||||||
|
, model((float*)&model)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void PaintingMesh::draw()
|
||||||
|
{
|
||||||
|
|
||||||
|
shaderProgram->bind();
|
||||||
|
QOpenGLVertexArrayObject::Binder bind(&VAO);
|
||||||
|
shaderProgram->setUniformValue("model", model);
|
||||||
|
glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
|
||||||
|
shaderProgram->release();
|
||||||
|
}
|
||||||
|
void PaintingMesh::setupMesh()
|
||||||
|
{
|
||||||
|
shaderProgram->bind();
|
||||||
|
VAO.create();
|
||||||
|
VAO.bind();
|
||||||
|
|
||||||
|
VBO.create();
|
||||||
|
EBO.create();
|
||||||
|
|
||||||
|
VBO.bind();
|
||||||
|
VBO.allocate(vertices.data(), vertices.size() * sizeof(PaintingVertex));
|
||||||
|
|
||||||
|
EBO.bind();
|
||||||
|
EBO.allocate(indices.data(), indices.size() * sizeof(unsigned int));
|
||||||
|
|
||||||
|
|
||||||
|
shaderProgram->enableAttributeArray(0);
|
||||||
|
shaderProgram->setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(PaintingVertex));
|
||||||
|
|
||||||
|
shaderProgram->enableAttributeArray(1);
|
||||||
|
shaderProgram->setAttributeBuffer(1, GL_FLOAT, offsetof(PaintingVertex, Normal), 3, sizeof(PaintingVertex));
|
||||||
|
|
||||||
|
shaderProgram->enableAttributeArray(2);
|
||||||
|
shaderProgram->setAttributeBuffer(2, GL_FLOAT, offsetof(PaintingVertex, TexCoords), 2, sizeof(PaintingVertex));
|
||||||
|
|
||||||
|
shaderProgram->enableAttributeArray(1);
|
||||||
|
shaderProgram->setAttributeBuffer(3, GL_FLOAT, offsetof(PaintingVertex, Tangent), 3, sizeof(PaintingVertex));
|
||||||
|
|
||||||
|
shaderProgram->enableAttributeArray(1);
|
||||||
|
shaderProgram->setAttributeBuffer(4, GL_FLOAT, offsetof(PaintingVertex, Bitangent), 3, sizeof(PaintingVertex));
|
||||||
|
|
||||||
|
|
||||||
|
VAO.release();
|
||||||
|
|
||||||
|
shaderProgram->release();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QOpenGLFunctions_4_5_Compatibility>
|
||||||
|
#include <QString>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QVector2D>
|
||||||
|
#include <QVector3D>
|
||||||
|
#include <QOpenGLShaderProgram>
|
||||||
|
#include <QOpenGLBuffer>
|
||||||
|
#include <QOpenGLVertexArrayObject>
|
||||||
|
#include <QOpenGLTexture>
|
||||||
|
#include <QOpenGLWidget>
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include <assimp/postprocess.h>
|
||||||
|
#include "Drawable.h"
|
||||||
|
|
||||||
|
struct PaintingVertex
|
||||||
|
{
|
||||||
|
QVector3D Position;
|
||||||
|
QVector3D Normal;
|
||||||
|
QVector2D TexCoords;
|
||||||
|
QVector3D Tangent;
|
||||||
|
QVector3D Bitangent;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PaintingMesh : public Drawable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* 网格数据 */
|
||||||
|
QVector<PaintingVertex> vertices; //顶点数据
|
||||||
|
QVector<unsigned int> indices; //索引数组
|
||||||
|
QMatrix4x4 model; //模型矩阵
|
||||||
|
QOpenGLFunctions_4_5_Compatibility* glFunc; //opengl函数入口
|
||||||
|
QOpenGLShaderProgram* shaderProgram; //着色器程序
|
||||||
|
|
||||||
|
/* 函数 */
|
||||||
|
PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model);
|
||||||
|
void draw() override;
|
||||||
|
void setupMesh();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* 渲染数据 */
|
||||||
|
QOpenGLVertexArrayObject VAO;
|
||||||
|
QOpenGLBuffer VBO, EBO;
|
||||||
|
|
||||||
|
};
|
|
@ -15,12 +15,27 @@ RendererWidget::RendererWidget(QWidget* parent)
|
||||||
|
|
||||||
RendererWidget::~RendererWidget()
|
RendererWidget::~RendererWidget()
|
||||||
{
|
{
|
||||||
if (modelProgramPtr == nullptr)
|
if (modelProgramPtr != nullptr)
|
||||||
return;
|
{
|
||||||
makeCurrent();
|
makeCurrent();
|
||||||
delete modelProgramPtr;
|
delete modelProgramPtr;
|
||||||
modelProgramPtr = nullptr;
|
modelProgramPtr = nullptr;
|
||||||
doneCurrent();
|
doneCurrent();
|
||||||
|
}
|
||||||
|
if (paintingProgramPtr != nullptr)
|
||||||
|
{
|
||||||
|
makeCurrent();
|
||||||
|
delete paintingProgramPtr;
|
||||||
|
paintingProgramPtr = nullptr;
|
||||||
|
doneCurrent();
|
||||||
|
}
|
||||||
|
if (finalProgramPtr != nullptr)
|
||||||
|
{
|
||||||
|
makeCurrent();
|
||||||
|
delete finalProgramPtr;
|
||||||
|
finalProgramPtr = nullptr;
|
||||||
|
doneCurrent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,6 +54,14 @@ void RendererWidget::initializeGL()
|
||||||
if (!modelProgramPtr->link())
|
if (!modelProgramPtr->link())
|
||||||
qDebug() << "ERROR:" << modelProgramPtr->log();
|
qDebug() << "ERROR:" << modelProgramPtr->log();
|
||||||
|
|
||||||
|
paintingProgramPtr = new QOpenGLShaderProgram;
|
||||||
|
if (!paintingProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/painting.vert"))
|
||||||
|
qDebug() << "ERROR:" << paintingProgramPtr->log();
|
||||||
|
if (!paintingProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/painting.frag"))
|
||||||
|
qDebug() << "ERROR:" << paintingProgramPtr->log();
|
||||||
|
if (!paintingProgramPtr->link())
|
||||||
|
qDebug() << "ERROR:" << paintingProgramPtr->log();
|
||||||
|
|
||||||
finalProgramPtr = new QOpenGLShaderProgram;
|
finalProgramPtr = new QOpenGLShaderProgram;
|
||||||
if (!finalProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/final.vert"))
|
if (!finalProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/final.vert"))
|
||||||
qDebug() << "ERROR:" << finalProgramPtr->log();
|
qDebug() << "ERROR:" << finalProgramPtr->log();
|
||||||
|
@ -54,7 +77,7 @@ void RendererWidget::initializeGL()
|
||||||
finalProgramPtr->setUniformValue("gMetallicRoughness", 3);
|
finalProgramPtr->setUniformValue("gMetallicRoughness", 3);
|
||||||
finalProgramPtr->release();
|
finalProgramPtr->release();
|
||||||
|
|
||||||
model = Model::createModel("Models/Sponza/Sponza.gltf", context(), modelProgramPtr);
|
model = new Model("Models/Sponza/Sponza.gltf", context(), modelProgramPtr, paintingProgramPtr);
|
||||||
|
|
||||||
quadVAO.create();
|
quadVAO.create();
|
||||||
QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO);
|
QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO);
|
||||||
|
@ -87,15 +110,20 @@ QVector3D lightPositions[] = { QVector3D(0,0,0), QVector3D(100,100,100) ,QVector
|
||||||
QVector3D lightColors[] = { QVector3D(150000,150000,130000), QVector3D(0,0,0) ,QVector3D(0,0,0) ,QVector3D(0,0,0) };
|
QVector3D lightColors[] = { QVector3D(150000,150000,130000), QVector3D(0,0,0) ,QVector3D(0,0,0) ,QVector3D(0,0,0) };
|
||||||
void RendererWidget::paintGL()
|
void RendererWidget::paintGL()
|
||||||
{
|
{
|
||||||
fboPtr->bind();
|
if (fboPtr->bind())
|
||||||
{
|
{
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
QMatrix4x4 view = camera.GetViewMatrix();
|
||||||
modelProgramPtr->bind();
|
modelProgramPtr->bind();
|
||||||
modelProgramPtr->setUniformValue("view", camera.GetViewMatrix());
|
modelProgramPtr->setUniformValue("view", view);
|
||||||
model->draw();
|
|
||||||
modelProgramPtr->release();
|
modelProgramPtr->release();
|
||||||
|
paintingProgramPtr->bind();
|
||||||
|
paintingProgramPtr->setUniformValue("view", view);
|
||||||
|
paintingProgramPtr->release();
|
||||||
|
model->draw();
|
||||||
|
fboPtr->release();
|
||||||
}
|
}
|
||||||
fboPtr->release();
|
|
||||||
|
|
||||||
//QOpenGLFramebufferObject::blitFramebuffer(nullptr, QRect(0, 0, 2*width(), 2*height()), fboPtr, QRect(0, 0, 1156, 756));
|
//QOpenGLFramebufferObject::blitFramebuffer(nullptr, QRect(0, 0, 2*width(), 2*height()), fboPtr, QRect(0, 0, 1156, 756));
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
@ -133,15 +161,19 @@ void RendererWidget::resizeGL(int width, int height)
|
||||||
fboPtr->addColorAttachment(devicePixelRatio() * width, devicePixelRatio() * height, GL_RG);
|
fboPtr->addColorAttachment(devicePixelRatio() * width, devicePixelRatio() * height, GL_RG);
|
||||||
GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
|
GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
|
||||||
glDrawBuffers(4, attachments);
|
glDrawBuffers(4, attachments);
|
||||||
fboPtr->bind();
|
if (fboPtr->bind())
|
||||||
{
|
{
|
||||||
modelProgramPtr->bind();
|
|
||||||
QMatrix4x4 projection;
|
QMatrix4x4 projection;
|
||||||
projection.perspective(camera.Zoom, (float)width / (float)height, 10.f, 10000.0f);
|
projection.perspective(camera.Zoom, (float)width / (float)height, 10.f, 10000.0f);
|
||||||
|
modelProgramPtr->bind();
|
||||||
modelProgramPtr->setUniformValue("projection", projection);
|
modelProgramPtr->setUniformValue("projection", projection);
|
||||||
modelProgramPtr->release();
|
modelProgramPtr->release();
|
||||||
|
paintingProgramPtr->bind();
|
||||||
|
paintingProgramPtr->setUniformValue("projection", projection);
|
||||||
|
paintingProgramPtr->release();
|
||||||
|
fboPtr->release();
|
||||||
}
|
}
|
||||||
fboPtr->release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererWidget::timerEvent(QTimerEvent* event)
|
void RendererWidget::timerEvent(QTimerEvent* event)
|
||||||
|
|
|
@ -32,6 +32,7 @@ private:
|
||||||
clock_t lastFrame;
|
clock_t lastFrame;
|
||||||
float deltaTime;
|
float deltaTime;
|
||||||
QOpenGLShaderProgram* modelProgramPtr = nullptr;
|
QOpenGLShaderProgram* modelProgramPtr = nullptr;
|
||||||
|
QOpenGLShaderProgram* paintingProgramPtr = nullptr;
|
||||||
QOpenGLShaderProgram* finalProgramPtr = nullptr;
|
QOpenGLShaderProgram* finalProgramPtr = nullptr;
|
||||||
QOpenGLFramebufferObject* fboPtr = nullptr;
|
QOpenGLFramebufferObject* fboPtr = nullptr;
|
||||||
QOpenGLBuffer quadVBO;
|
QOpenGLBuffer quadVBO;
|
||||||
|
|
|
@ -108,5 +108,4 @@ void main()
|
||||||
color = pow(color, vec3(1.0/2.2));
|
color = pow(color, vec3(1.0/2.2));
|
||||||
|
|
||||||
FragColor = vec4(color, 1.0);
|
FragColor = vec4(color, 1.0);
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout (location = 0) out vec4 gBaseColor;
|
||||||
|
layout (location = 1) out vec3 gNormal;
|
||||||
|
layout (location = 2) out vec3 gPosition;
|
||||||
|
layout (location = 3) out vec2 gMetallicRoughness;
|
||||||
|
|
||||||
|
in vec2 TexCoords;
|
||||||
|
in vec3 WorldPos;
|
||||||
|
in vec3 Normal;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gBaseColor = vec4(TexCoords,1,1);
|
||||||
|
gPosition = WorldPos;
|
||||||
|
gNormal = Normal;
|
||||||
|
gMetallicRoughness = vec2(0,0);
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#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 vec3 WorldPos;
|
||||||
|
out vec3 Normal;
|
||||||
|
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
TexCoords = aTexCoords;
|
||||||
|
WorldPos = vec3(model * vec4(aPos, 1.0));
|
||||||
|
Normal = mat3(model) * aNormal;
|
||||||
|
|
||||||
|
gl_Position = projection * view * vec4(WorldPos, 1.0);
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue