diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj
index d89b5f2..b04115d 100644
--- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj
+++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj
@@ -88,6 +88,7 @@
+
@@ -103,13 +104,17 @@
+
+
+
+
diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters
index 8e6f9a5..2cc8f3c 100644
--- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters
+++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters
@@ -55,6 +55,9 @@
Source Files
+
+ Source Files
+
@@ -80,6 +83,12 @@
Resource Files\Shaders
+
+ Resource Files\Shaders
+
+
+ Resource Files\Shaders
+
@@ -91,5 +100,11 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
\ No newline at end of file
diff --git a/ArchitectureColoredPainting/Drawable.h b/ArchitectureColoredPainting/Drawable.h
new file mode 100644
index 0000000..0a4c784
--- /dev/null
+++ b/ArchitectureColoredPainting/Drawable.h
@@ -0,0 +1,7 @@
+#pragma once
+class Drawable
+{
+public:
+ virtual void draw() = 0;
+};
+
diff --git a/ArchitectureColoredPainting/MainWindow.qrc b/ArchitectureColoredPainting/MainWindow.qrc
index abee18a..c7f85b4 100644
--- a/ArchitectureColoredPainting/MainWindow.qrc
+++ b/ArchitectureColoredPainting/MainWindow.qrc
@@ -7,5 +7,7 @@
Shaders/final.frag
Shaders/final.vert
container.jpg
+ Shaders/painting.frag
+ Shaders/painting.vert
diff --git a/ArchitectureColoredPainting/Mesh.cpp b/ArchitectureColoredPainting/Mesh.cpp
index adb5fdc..39fc7d7 100644
--- a/ArchitectureColoredPainting/Mesh.cpp
+++ b/ArchitectureColoredPainting/Mesh.cpp
@@ -1,69 +1,77 @@
#include "Mesh.h"
Mesh::Mesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model)
- : glFunc(glFunc)
- , shaderProgram(shaderProgram)
- , VBO(QOpenGLBuffer::VertexBuffer)
- , EBO(QOpenGLBuffer::IndexBuffer)
+ : glFunc(glFunc)
+ , shaderProgram(shaderProgram)
+ , VBO(QOpenGLBuffer::VertexBuffer)
+ , EBO(QOpenGLBuffer::IndexBuffer)
+ , model((float*)&model)
{
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- this->model(i, j) = model[i][j];
- }
- }
+ //for (int i = 0; i < 4; i++) {
+ // for (int j = 0; j < 4; j++) {
+ // this->model(i, j) = model[i][j];
+ // }
+ //}
}
-void Mesh::Draw()
+void Mesh::draw()
{
- unsigned int diffuseNr = 1;
- unsigned int specularNr = 1;
- unsigned int normalNr = 1;
- unsigned int heightNr = 1;
+ shaderProgram->bind();
- for (unsigned int i = 0; i < textures.size(); i++)
- {
- glFunc->glActiveTexture(GL_TEXTURE0 + i); // 在绑定之前激活相应的纹理单元
-
-
- textures[i]->texture.bind();
- //qDebug() << name + number;
- shaderProgram->setUniformValue(textures[i]->type.toStdString().c_str(), i);
- }
- // 绘制网格
+ unsigned int diffuseNr = 1;
+ unsigned int specularNr = 1;
+ unsigned int normalNr = 1;
+ unsigned int heightNr = 1;
- QOpenGLVertexArrayObject::Binder bind(&VAO);
- shaderProgram->setUniformValue("model", model);
- glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
+ for (unsigned int i = 0; i < textures.size(); i++)
+ {
+ glFunc->glActiveTexture(GL_TEXTURE0 + i); // 在绑定之前激活相应的纹理单元
+
+
+ textures[i]->texture.bind();
+ //qDebug() << name + number;
+ shaderProgram->setUniformValue(textures[i]->type.toStdString().c_str(), i);
+ }
+ // 绘制网格
+
+ QOpenGLVertexArrayObject::Binder bind(&VAO);
+ shaderProgram->setUniformValue("model", model);
+ glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
+
+ shaderProgram->release();
}
void Mesh::setupMesh()
{
+ shaderProgram->bind();
+ VAO.create();
+ VAO.bind();
- VAO.create();
- VAO.bind();
+ VBO.create();
+ EBO.create();
- VBO.create();
- EBO.create();
+ VBO.bind();
+ VBO.allocate(vertices.data(), vertices.size() * sizeof(Vertex));
- VBO.bind();
- VBO.allocate(vertices.data(), vertices.size() * sizeof(Vertex));
-
- EBO.bind();
- 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->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, Normal), 3, sizeof(Vertex));
+ shaderProgram->enableAttributeArray(0);
+ shaderProgram->setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(Vertex));
- shaderProgram->enableAttributeArray(2);
- shaderProgram->setAttributeBuffer(2, GL_FLOAT, offsetof(Vertex, TexCoords), 2, sizeof(Vertex));
+ shaderProgram->enableAttributeArray(1);
+ shaderProgram->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, Normal), 3, sizeof(Vertex));
- shaderProgram->enableAttributeArray(1);
- shaderProgram->setAttributeBuffer(3, GL_FLOAT, offsetof(Vertex, Tangent), 3, sizeof(Vertex));
+ shaderProgram->enableAttributeArray(2);
+ shaderProgram->setAttributeBuffer(2, GL_FLOAT, offsetof(Vertex, TexCoords), 2, sizeof(Vertex));
- shaderProgram->enableAttributeArray(1);
- shaderProgram->setAttributeBuffer(4, GL_FLOAT, offsetof(Vertex, Bitangent), 3, sizeof(Vertex));
- VAO.release();
+ shaderProgram->enableAttributeArray(3);
+ shaderProgram->setAttributeBuffer(3, GL_FLOAT, offsetof(Vertex, Tangent), 3, sizeof(Vertex));
+
+ shaderProgram->enableAttributeArray(4);
+ shaderProgram->setAttributeBuffer(4, GL_FLOAT, offsetof(Vertex, Bitangent), 3, sizeof(Vertex));
+
+ VAO.release();
+ shaderProgram->release();
}
diff --git a/ArchitectureColoredPainting/Mesh.h b/ArchitectureColoredPainting/Mesh.h
index 5ecdddc..3103c50 100644
--- a/ArchitectureColoredPainting/Mesh.h
+++ b/ArchitectureColoredPainting/Mesh.h
@@ -12,6 +12,7 @@
#include
#include
#include
+#include "Drawable.h"
struct Vertex
{
@@ -35,7 +36,8 @@ struct Texture
}
};
-class Mesh {
+class Mesh : public Drawable
+{
public:
/* 网格数据 */
QVector vertices; //顶点数据
@@ -47,7 +49,7 @@ public:
/* 函数 */
Mesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model);
- void Draw();
+ void draw() override;
void setupMesh();
private:
diff --git a/ArchitectureColoredPainting/Model.cpp b/ArchitectureColoredPainting/Model.cpp
index a42945e..4e74aa9 100644
--- a/ArchitectureColoredPainting/Model.cpp
+++ b/ArchitectureColoredPainting/Model.cpp
@@ -4,189 +4,258 @@
#include
#include
#include
+#include "PaintingMesh.h"
Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram)
- : context(context)
- , shaderProgram(shaderProgram)
- , directory(path)
+ : context(context)
+ , shaderProgram(shaderProgram)
+ , 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);
+ 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(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() //销毁对象
{
- for (auto& it : textures_loaded) {
- it->texture.destroy();
- delete it;
- }
- for (auto& it : meshes) {
- delete it;
- }
+ for (auto& it : textures_loaded) {
+ it->texture.destroy();
+ delete it;
+ }
+ for (auto& it : meshes) {
+ delete it;
+ }
}
void Model::draw() {
- shaderProgram->bind();
- for (Mesh* mesh : meshes) {
- mesh->Draw();
- }
+ //shaderProgram->bind();
+ for (Drawable* mesh : meshes) {
+ mesh->draw();
+ }
}
void Model::destroy()
{
- context->doneCurrent();
- delete this;
+ context->doneCurrent();
+ delete this;
}
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)
{
- // 处理节点所有的网格(如果有的话)
- for (unsigned int i = 0; i < node->mNumMeshes; i++)
- {
- aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
- meshes.push_back(processMesh(mesh, scene, mat4));
+ // 处理节点所有的网格(如果有的话)
+ for (unsigned int i = 0; i < node->mNumMeshes; i++)
+ {
+ aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
+ meshes.push_back(processMesh(mesh, scene, mat4));
- }
- // 接下来对它的子节点重复这一过程
- for (unsigned int i = 0; i < node->mNumChildren; i++)
- {
- processNode(node->mChildren[i], scene, mat4 * node->mChildren[i]->mTransformation);
- }
+ }
+ // 接下来对它的子节点重复这一过程
+ for (unsigned int i = 0; i < node->mNumChildren; i++)
+ {
+ 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)
{
- // 初始化网格
- Mesh* m_mesh = new Mesh(QOpenGLContext::currentContext()->versionFunctions(), shaderProgram, model);
- // 遍历网格的每个顶点
- for (unsigned int i = 0; i < mesh->mNumVertices; i++)
- {
- Vertex vertex;
- QVector3D vector; //将assimp的数据转化为QtOpenGL支持的数据
+ aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
- // 位置
- 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);
- }
+ aiString str;
+ material->GetTexture(aiTextureType_BASE_COLOR, 0, &str);
- 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]);
- }
- }
+ if (paintingProgram != nullptr && std::strcmp(str.C_Str(), "17876391417123941155.jpg")==0)
+ {
+ qDebug() << str.C_Str();
+ // 初始化网格
+ PaintingMesh* m_mesh = new PaintingMesh(QOpenGLContext::currentContext()->versionFunctions(), paintingProgram, model);
+ // 遍历网格的每个顶点
+ 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 diffuseMaps = loadMaterialTextures(material, aiTextureType_BASE_COLOR, "texture_basecolor");
- for (auto& it : diffuseMaps)
- m_mesh->textures.push_back(it);
+ if (mesh->mTangents)
+ vertex.Tangent = QVector3D(mesh->mTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z);
- QVector metalnessMaps = loadMaterialTextures(material, aiTextureType_METALNESS, "texture_metallic_roughness");
- for (auto& it : metalnessMaps)
- m_mesh->textures.push_back(it);
+ if (mesh->mBitangents)
+ vertex.Bitangent = QVector3D(mesh->mBitangents[i].x, mesh->mBitangents[i].y, mesh->mBitangents[i].z);;
+
+ 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(), 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 diffuseMaps = loadMaterialTextures(material, aiTextureType_BASE_COLOR, "texture_basecolor");
+ for (auto& it : diffuseMaps)
+ m_mesh->textures.push_back(it);
+
+ QVector metalnessMaps = loadMaterialTextures(material, aiTextureType_METALNESS, "texture_metallic_roughness");
+ for (auto& it : metalnessMaps)
+ m_mesh->textures.push_back(it);
+
+ QVector normalMaps = loadMaterialTextures(material, aiTextureType_NORMALS, "texture_normal");
+ for (auto& it : normalMaps)
+ m_mesh->textures.push_back(it);
+
+ m_mesh->setupMesh();
+ return m_mesh;
+ }
- QVector normalMaps = loadMaterialTextures(material, aiTextureType_NORMALS, "texture_normal");
- for (auto& it : normalMaps)
- m_mesh->textures.push_back(it);
- m_mesh->setupMesh();
- return m_mesh;
}
QVector Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type, QString typeName)
{
- QVector textures;
+ QVector textures;
- for (unsigned int i = 0; i < mat->GetTextureCount(type); i++)
- {
- //qDebug() << typeName;
- aiString str;
- mat->GetTexture(type, i, &str);
+ for (unsigned int i = 0; i < mat->GetTextureCount(type); i++)
+ {
+ //qDebug() << typeName;
+ aiString str;
+ mat->GetTexture(type, i, &str);
- // 检查纹理是否在之前加载过,如果是,则继续到下一个迭代:跳过加载新纹理
- bool skip = false;
- for (unsigned int j = 0; j < textures_loaded.size(); j++)
- {
- if (std::strcmp(textures_loaded[j]->path.toStdString().c_str(), str.C_Str()) == 0)
- {
- textures.push_back(textures_loaded[j]);
- skip = true; //【优化】 带有相同filepath的纹理已经加载,继续到下一个
- break;
- }
- }
- if (!skip)
- { // 如果材质还没有加载,加载它
- Texture* texture = new Texture;
- QImage data(directory.filePath(str.C_Str()));
- if (!data.isNull()) {
- texture->texture.setData(data);
- texture->type = typeName;
- texture->path = str.C_Str();
- 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.
- }
- else {
- qDebug() << "未能成功加载纹理:" << directory.filePath(str.C_Str());
- }
- }
- }
- return textures;
+ // 检查纹理是否在之前加载过,如果是,则继续到下一个迭代:跳过加载新纹理
+ bool skip = false;
+ for (unsigned int j = 0; j < textures_loaded.size(); j++)
+ {
+ if (std::strcmp(textures_loaded[j]->path.toStdString().c_str(), str.C_Str()) == 0)
+ {
+ textures.push_back(textures_loaded[j]);
+ skip = true; //【优化】 带有相同filepath的纹理已经加载,继续到下一个
+ break;
+ }
+ }
+ if (!skip)
+ { // 如果材质还没有加载,加载它
+ Texture* texture = new Texture;
+ QImage data(directory.filePath(str.C_Str()));
+ if (!data.isNull()) {
+ texture->texture.setData(data);
+ texture->type = typeName;
+ texture->path = str.C_Str();
+ 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.
+ }
+ else {
+ qDebug() << "未能成功加载纹理:" << directory.filePath(str.C_Str());
+ }
+ }
+ }
+ return textures;
}
diff --git a/ArchitectureColoredPainting/Model.h b/ArchitectureColoredPainting/Model.h
index c60fd17..c414a06 100644
--- a/ArchitectureColoredPainting/Model.h
+++ b/ArchitectureColoredPainting/Model.h
@@ -1,34 +1,36 @@
#pragma once
#include "Mesh.h"
+#include "Drawable.h"
#include
class Model
{
public:
- void draw();
- void destroy();
- static Model* createModel(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram);
-
+ void draw();
+ void destroy();
+ static Model* createModel(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram);
+ Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram);
private:
- Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram);
- ~Model();
- QOpenGLContext* context; //opengl函数入口
- QOpenGLShaderProgram* shaderProgram; //着色器程序
+ Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram);
- /* 模型数据 */
- QVectortextures_loaded; //纹理
- QVector meshes; //网格
- QDir directory; //模型所在路径
+ ~Model();
+ QOpenGLContext* context; //opengl函数入口
+ QOpenGLShaderProgram* shaderProgram = nullptr;
+ QOpenGLShaderProgram* paintingProgram = nullptr; //彩绘着色器程序
+ /* 模型数据 */
+ QVector textures_loaded; //纹理
+ QVector 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 loadMaterialTextures(aiMaterial* mat, aiTextureType type, QString typeName);
+ //加载材质纹理
+ QVector loadMaterialTextures(aiMaterial* mat, aiTextureType type, QString typeName);
};
diff --git a/ArchitectureColoredPainting/PaintingMesh.cpp b/ArchitectureColoredPainting/PaintingMesh.cpp
new file mode 100644
index 0000000..763c928
--- /dev/null
+++ b/ArchitectureColoredPainting/PaintingMesh.cpp
@@ -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();
+
+}
diff --git a/ArchitectureColoredPainting/PaintingMesh.h b/ArchitectureColoredPainting/PaintingMesh.h
new file mode 100644
index 0000000..c2a44cd
--- /dev/null
+++ b/ArchitectureColoredPainting/PaintingMesh.h
@@ -0,0 +1,47 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "Drawable.h"
+
+struct PaintingVertex
+{
+ QVector3D Position;
+ QVector3D Normal;
+ QVector2D TexCoords;
+ QVector3D Tangent;
+ QVector3D Bitangent;
+};
+
+class PaintingMesh : public Drawable
+{
+public:
+ /* 网格数据 */
+ QVector vertices; //顶点数据
+ QVector 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;
+
+};
diff --git a/ArchitectureColoredPainting/RendererWidget.cpp b/ArchitectureColoredPainting/RendererWidget.cpp
index 0660128..918d9c0 100644
--- a/ArchitectureColoredPainting/RendererWidget.cpp
+++ b/ArchitectureColoredPainting/RendererWidget.cpp
@@ -15,12 +15,27 @@ RendererWidget::RendererWidget(QWidget* parent)
RendererWidget::~RendererWidget()
{
- if (modelProgramPtr == nullptr)
- return;
- makeCurrent();
- delete modelProgramPtr;
- modelProgramPtr = nullptr;
- doneCurrent();
+ if (modelProgramPtr != nullptr)
+ {
+ makeCurrent();
+ delete modelProgramPtr;
+ modelProgramPtr = nullptr;
+ 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())
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;
if (!finalProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/final.vert"))
qDebug() << "ERROR:" << finalProgramPtr->log();
@@ -54,7 +77,7 @@ void RendererWidget::initializeGL()
finalProgramPtr->setUniformValue("gMetallicRoughness", 3);
finalProgramPtr->release();
- model = Model::createModel("Models/Sponza/Sponza.gltf", context(), modelProgramPtr);
+ model = new Model("Models/Sponza/Sponza.gltf", context(), modelProgramPtr, paintingProgramPtr);
quadVAO.create();
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) };
void RendererWidget::paintGL()
{
- fboPtr->bind();
+ if (fboPtr->bind())
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ QMatrix4x4 view = camera.GetViewMatrix();
modelProgramPtr->bind();
- modelProgramPtr->setUniformValue("view", camera.GetViewMatrix());
- model->draw();
+ modelProgramPtr->setUniformValue("view", view);
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));
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);
GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
glDrawBuffers(4, attachments);
- fboPtr->bind();
+ if (fboPtr->bind())
{
- modelProgramPtr->bind();
QMatrix4x4 projection;
projection.perspective(camera.Zoom, (float)width / (float)height, 10.f, 10000.0f);
+ modelProgramPtr->bind();
modelProgramPtr->setUniformValue("projection", projection);
modelProgramPtr->release();
+ paintingProgramPtr->bind();
+ paintingProgramPtr->setUniformValue("projection", projection);
+ paintingProgramPtr->release();
+ fboPtr->release();
}
- fboPtr->release();
+
}
void RendererWidget::timerEvent(QTimerEvent* event)
diff --git a/ArchitectureColoredPainting/RendererWidget.h b/ArchitectureColoredPainting/RendererWidget.h
index ea254c8..ba6d4cc 100644
--- a/ArchitectureColoredPainting/RendererWidget.h
+++ b/ArchitectureColoredPainting/RendererWidget.h
@@ -32,6 +32,7 @@ private:
clock_t lastFrame;
float deltaTime;
QOpenGLShaderProgram* modelProgramPtr = nullptr;
+ QOpenGLShaderProgram* paintingProgramPtr = nullptr;
QOpenGLShaderProgram* finalProgramPtr = nullptr;
QOpenGLFramebufferObject* fboPtr = nullptr;
QOpenGLBuffer quadVBO;
diff --git a/ArchitectureColoredPainting/Shaders/final.frag b/ArchitectureColoredPainting/Shaders/final.frag
index 869800b..d2fd4b4 100644
--- a/ArchitectureColoredPainting/Shaders/final.frag
+++ b/ArchitectureColoredPainting/Shaders/final.frag
@@ -108,5 +108,4 @@ void main()
color = pow(color, vec3(1.0/2.2));
FragColor = vec4(color, 1.0);
-
}
\ No newline at end of file
diff --git a/ArchitectureColoredPainting/Shaders/painting.frag b/ArchitectureColoredPainting/Shaders/painting.frag
new file mode 100644
index 0000000..2ac91c6
--- /dev/null
+++ b/ArchitectureColoredPainting/Shaders/painting.frag
@@ -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);
+}
\ No newline at end of file
diff --git a/ArchitectureColoredPainting/Shaders/painting.vert b/ArchitectureColoredPainting/Shaders/painting.vert
new file mode 100644
index 0000000..8e2587b
--- /dev/null
+++ b/ArchitectureColoredPainting/Shaders/painting.vert
@@ -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);
+
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 53d85ce..81e3fb4 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,12 @@
閲囩敤pbr鏉愯川锛岀幇鍦ㄦ湁涓涓厜婧愬拰鎽勫儚鏈虹粦瀹氾紝瓒充互鍒嗚鲸鍑轰笉鍚屾潗璐ㄧ殑鏁堟灉
+鎶婁竴鍧楀竷鏇挎崲鎴愪簡锛堝緟瀹屾垚鐨勶級褰╃粯绠$嚎锛岃PaintingMesh绫讳互鍙妏ainting鐫鑹插櫒
+
TODO锛
- [x] 鏀圭敤寤惰繜娓叉煋
-- [ ] 鎸囧畾涓鍧楁潗璐ㄤ娇鐢ㄧ嫭绔嬬绾胯繘琛岀汗鐞嗛噰鏍
\ No newline at end of file
+- [x] 鎸囧畾涓鍧楁潗璐ㄤ娇鐢ㄧ嫭绔嬬绾胯繘琛岀汗鐞嗛噰鏍
+
+- [ ] 褰╃粯鐨勮〃绀恒佽鍙栥侀噰鏍...
\ No newline at end of file