Use GL_LINES to show wireframe

master
Jeremy HU 2022-09-24 01:54:49 +10:00
parent d512ec0f7e
commit 61869d89dd
36 changed files with 579 additions and 182 deletions

View File

@ -155,17 +155,24 @@ HEADERS += sources/mesh_generator.h
SOURCES += sources/mesh_generator.cc SOURCES += sources/mesh_generator.cc
HEADERS += sources/mesh_result_post_processor.h HEADERS += sources/mesh_result_post_processor.h
SOURCES += sources/mesh_result_post_processor.cc SOURCES += sources/mesh_result_post_processor.cc
HEADERS += sources/model.h HEADERS += sources/model_mesh.h
SOURCES += sources/model.cc SOURCES += sources/model_mesh.cc
HEADERS += sources/model_offscreen_render.h HEADERS += sources/model_offscreen_render.h
SOURCES += sources/model_offscreen_render.cc SOURCES += sources/model_offscreen_render.cc
HEADERS += sources/model_opengl_program.h HEADERS += sources/model_opengl_program.h
SOURCES += sources/model_opengl_program.cc SOURCES += sources/model_opengl_program.cc
HEADERS += sources/model_opengl_object.h HEADERS += sources/model_opengl_object.h
SOURCES += sources/model_opengl_object.cc SOURCES += sources/model_opengl_object.cc
HEADERS += sources/model_shader_vertex.h HEADERS += sources/model_opengl_vertex.h
HEADERS += sources/model_widget.h HEADERS += sources/model_widget.h
SOURCES += sources/model_widget.cc SOURCES += sources/model_widget.cc
HEADERS += sources/monochrome_mesh.h
SOURCES += sources/monochrome_mesh.cc
HEADERS += sources/monochrome_opengl_program.h
SOURCES += sources/monochrome_opengl_program.cc
HEADERS += sources/monochrome_opengl_object.h
SOURCES += sources/monochrome_opengl_object.cc
HEADERS += sources/monochrome_opengl_vertex.h
HEADERS += sources/part_preview_images_generator.h HEADERS += sources/part_preview_images_generator.h
SOURCES += sources/part_preview_images_generator.cc SOURCES += sources/part_preview_images_generator.cc
HEADERS += sources/part_tree_widget.h HEADERS += sources/part_tree_widget.h

View File

@ -8,6 +8,10 @@
<file>shaders/model.frag</file> <file>shaders/model.frag</file>
<file>shaders/model_core.vert</file> <file>shaders/model_core.vert</file>
<file>shaders/model_core.frag</file> <file>shaders/model_core.frag</file>
<file>shaders/monochrome.vert</file>
<file>shaders/monochrome.frag</file>
<file>shaders/monochrome_core.vert</file>
<file>shaders/monochrome_core.frag</file>
<file>resources/cedar_bridge_irradiance.dds</file> <file>resources/cedar_bridge_irradiance.dds</file>
<file>resources/cedar_bridge_specular.dds</file> <file>resources/cedar_bridge_specular.dds</file>
<file>resources/dust3d-vertical.png</file> <file>resources/dust3d-vertical.png</file>

View File

@ -0,0 +1,9 @@
#version 110
varying vec3 pointPosition;
varying vec3 pointColor;
varying float pointAlpha;
void main()
{
gl_FragColor = vec4(pointColor, pointAlpha);
}

View File

@ -0,0 +1,19 @@
#version 110
attribute vec4 vertex;
attribute vec3 color;
attribute float alpha;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
varying vec3 pointPosition;
varying vec3 pointColor;
varying float pointAlpha;
void main()
{
pointPosition = (modelMatrix * vertex).xyz;
pointColor = color;
pointAlpha = alpha;
gl_Position = projectionMatrix * viewMatrix * vec4(pointPosition, 1.0);
}

View File

@ -0,0 +1,8 @@
#version 330
in vec3 pointColor;
in float pointAlpha;
out vec4 fragColor;
void main()
{
fragColor = vec4(pointColor, pointAlpha);
}

View File

@ -0,0 +1,19 @@
#version 330
layout(location = 0) in vec4 vertex;
layout(location = 1) in vec3 color;
layout(location = 2) in float alpha;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
out vec3 pointPosition;
out vec3 pointColor;
out float pointAlpha;
void main()
{
pointPosition = (modelMatrix * vertex).xyz;
pointColor = color;
pointAlpha = alpha;
gl_Position = projectionMatrix * viewMatrix * vec4(pointPosition, 1.0);
}

View File

@ -729,30 +729,38 @@ void Document::fromSnapshot(const dust3d::Snapshot &snapshot)
emit uncheckAll(); emit uncheckAll();
} }
Model *Document::takeResultMesh() ModelMesh *Document::takeResultMesh()
{ {
if (nullptr == m_resultMesh) if (nullptr == m_resultMesh)
return nullptr; return nullptr;
Model *resultMesh = new Model(*m_resultMesh); ModelMesh *resultMesh = new ModelMesh(*m_resultMesh);
return resultMesh; return resultMesh;
} }
MonochromeMesh *Document::takeWireframeMesh()
{
if (nullptr == m_wireframeMesh)
return nullptr;
return new MonochromeMesh(*m_wireframeMesh);
}
bool Document::isMeshGenerationSucceed() bool Document::isMeshGenerationSucceed()
{ {
return m_isMeshGenerationSucceed; return m_isMeshGenerationSucceed;
} }
Model *Document::takeResultTextureMesh() ModelMesh *Document::takeResultTextureMesh()
{ {
if (nullptr == m_resultTextureMesh) if (nullptr == m_resultTextureMesh)
return nullptr; return nullptr;
Model *resultTextureMesh = new Model(*m_resultTextureMesh); ModelMesh *resultTextureMesh = new ModelMesh(*m_resultTextureMesh);
return resultTextureMesh; return resultTextureMesh;
} }
void Document::meshReady() void Document::meshReady()
{ {
Model *resultMesh = m_meshGenerator->takeResultMesh(); ModelMesh *resultMesh = m_meshGenerator->takeResultMesh();
m_wireframeMesh.reset(m_meshGenerator->takeWireframeMesh());
dust3d::Object *object = m_meshGenerator->takeObject(); dust3d::Object *object = m_meshGenerator->takeObject();
bool isSuccessful = m_meshGenerator->isSuccessful(); bool isSuccessful = m_meshGenerator->isSuccessful();
@ -772,7 +780,7 @@ void Document::meshReady()
for (auto &partId: m_meshGenerator->generatedPreviewPartIds()) { for (auto &partId: m_meshGenerator->generatedPreviewPartIds()) {
auto part = partMap.find(partId); auto part = partMap.find(partId);
if (part != partMap.end()) { if (part != partMap.end()) {
Model *resultPartPreviewMesh = m_meshGenerator->takePartPreviewMesh(partId); ModelMesh *resultPartPreviewMesh = m_meshGenerator->takePartPreviewMesh(partId);
part->second.updatePreviewMesh(resultPartPreviewMesh); part->second.updatePreviewMesh(resultPartPreviewMesh);
partPreviewsChanged = true; partPreviewsChanged = true;
} }
@ -1591,7 +1599,7 @@ void Document::materialPreviewsReady()
for (const auto &materialId: m_materialPreviewsGenerator->generatedPreviewMaterialIds()) { for (const auto &materialId: m_materialPreviewsGenerator->generatedPreviewMaterialIds()) {
auto material = materialMap.find(materialId); auto material = materialMap.find(materialId);
if (material != materialMap.end()) { if (material != materialMap.end()) {
Model *resultPartPreviewMesh = m_materialPreviewsGenerator->takePreview(materialId); ModelMesh *resultPartPreviewMesh = m_materialPreviewsGenerator->takePreview(materialId);
material->second.updatePreviewMesh(resultPartPreviewMesh); material->second.updatePreviewMesh(resultPartPreviewMesh);
emit materialPreviewChanged(materialId); emit materialPreviewChanged(materialId);
} }

View File

@ -14,7 +14,8 @@
#include <dust3d/base/snapshot.h> #include <dust3d/base/snapshot.h>
#include <dust3d/base/texture_type.h> #include <dust3d/base/texture_type.h>
#include <dust3d/base/combine_mode.h> #include <dust3d/base/combine_mode.h>
#include "model.h" #include "model_mesh.h"
#include "monochrome_mesh.h"
#include "theme.h" #include "theme.h"
#include "skeleton_document.h" #include "skeleton_document.h"
#include "material_layer.h" #include "material_layer.h"
@ -44,20 +45,20 @@ public:
QString name; QString name;
bool dirty = true; bool dirty = true;
std::vector<MaterialLayer> layers; std::vector<MaterialLayer> layers;
void updatePreviewMesh(Model *previewMesh) void updatePreviewMesh(ModelMesh *previewMesh)
{ {
delete m_previewMesh; delete m_previewMesh;
m_previewMesh = previewMesh; m_previewMesh = previewMesh;
} }
Model *takePreviewMesh() const ModelMesh *takePreviewMesh() const
{ {
if (nullptr == m_previewMesh) if (nullptr == m_previewMesh)
return nullptr; return nullptr;
return new Model(*m_previewMesh); return new ModelMesh(*m_previewMesh);
} }
private: private:
Q_DISABLE_COPY(Material); Q_DISABLE_COPY(Material);
Model *m_previewMesh = nullptr; ModelMesh *m_previewMesh = nullptr;
}; };
enum class DocumentToSnapshotFor enum class DocumentToSnapshotFor
@ -133,8 +134,8 @@ public: // need initialize
QImage *textureAmbientOcclusionImage = nullptr; QImage *textureAmbientOcclusionImage = nullptr;
QByteArray *textureAmbientOcclusionImageByteArray = nullptr; QByteArray *textureAmbientOcclusionImageByteArray = nullptr;
bool weldEnabled = true; bool weldEnabled = true;
float brushMetalness = Model::m_defaultMetalness; float brushMetalness = ModelMesh::m_defaultMetalness;
float brushRoughness = Model::m_defaultRoughness; float brushRoughness = ModelMesh::m_defaultRoughness;
public: public:
Document(); Document();
~Document(); ~Document();
@ -160,11 +161,12 @@ public:
}; };
void addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSource source=SnapshotSource::Paste); void addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSource source=SnapshotSource::Paste);
const Material *findMaterial(dust3d::Uuid materialId) const; const Material *findMaterial(dust3d::Uuid materialId) const;
Model *takeResultMesh(); ModelMesh *takeResultMesh();
Model *takePaintedMesh(); MonochromeMesh *takeWireframeMesh();
ModelMesh *takePaintedMesh();
bool isMeshGenerationSucceed(); bool isMeshGenerationSucceed();
Model *takeResultTextureMesh(); ModelMesh *takeResultTextureMesh();
Model *takeResultRigWeightMesh(); ModelMesh *takeResultRigWeightMesh();
void updateTurnaround(const QImage &image); void updateTurnaround(const QImage &image);
void clearTurnaround(); void clearTurnaround();
void updateTextureImage(QImage *image); void updateTextureImage(QImage *image);
@ -239,7 +241,8 @@ private:
bool m_isResultMeshObsolete = false; bool m_isResultMeshObsolete = false;
MeshGenerator *m_meshGenerator = nullptr; MeshGenerator *m_meshGenerator = nullptr;
Model *m_resultMesh = nullptr; ModelMesh *m_resultMesh = nullptr;
std::unique_ptr<MonochromeMesh> m_wireframeMesh;
bool m_isMeshGenerationSucceed = true; bool m_isMeshGenerationSucceed = true;
int m_batchChangeRefCount = 0; int m_batchChangeRefCount = 0;
dust3d::Object *m_currentObject = nullptr; dust3d::Object *m_currentObject = nullptr;
@ -248,7 +251,7 @@ private:
bool m_isPostProcessResultObsolete = false; bool m_isPostProcessResultObsolete = false;
MeshResultPostProcessor *m_postProcessor = nullptr; MeshResultPostProcessor *m_postProcessor = nullptr;
dust3d::Object *m_postProcessedObject = new dust3d::Object; dust3d::Object *m_postProcessedObject = new dust3d::Object;
Model *m_resultTextureMesh = nullptr; ModelMesh *m_resultTextureMesh = nullptr;
unsigned long long m_textureImageUpdateVersion = 0; unsigned long long m_textureImageUpdateVersion = 0;
bool m_smoothNormal = false; bool m_smoothNormal = false;
MaterialPreviewsGenerator *m_materialPreviewsGenerator = nullptr; MaterialPreviewsGenerator *m_materialPreviewsGenerator = nullptr;

View File

@ -423,7 +423,7 @@ DocumentWindow::DocumentWindow()
m_toggleColorAction = new QAction(tr("Toggle Color"), this); m_toggleColorAction = new QAction(tr("Toggle Color"), this);
connect(m_toggleColorAction, &QAction::triggered, [&]() { connect(m_toggleColorAction, &QAction::triggered, [&]() {
m_modelRemoveColor = !m_modelRemoveColor; m_modelRemoveColor = !m_modelRemoveColor;
Model *mesh = nullptr; ModelMesh *mesh = nullptr;
if (m_document->isMeshGenerating() || if (m_document->isMeshGenerating() ||
m_document->isPostProcessing() || m_document->isPostProcessing() ||
m_document->isTextureGenerating()) { m_document->isTextureGenerating()) {
@ -738,6 +738,7 @@ DocumentWindow::DocumentWindow()
if (m_modelRemoveColor && resultMesh) if (m_modelRemoveColor && resultMesh)
resultMesh->removeColor(); resultMesh->removeColor();
m_modelRenderWidget->updateMesh(resultMesh); m_modelRenderWidget->updateMesh(resultMesh);
m_modelRenderWidget->updateWireframeMesh(m_document->takeWireframeMesh());
}); });
connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::cursorChanged, [=]() { connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::cursorChanged, [=]() {
@ -1027,7 +1028,7 @@ void DocumentWindow::openPathAs(const QString &path, const QString &asName)
QByteArray fileData = file.readAll(); QByteArray fileData = file.readAll();
dust3d::Ds3FileReader ds3Reader((const std::uint8_t *)fileData.data(), fileData.size()); dust3d::Ds3FileReader ds3Reader((const std::uint8_t *)fileData.data(), fileData.size());
for (int i = 0; i < ds3Reader.items().size(); ++i) { for (int i = 0; i < (int)ds3Reader.items().size(); ++i) {
const dust3d::Ds3ReaderItem &item = ds3Reader.items()[i]; const dust3d::Ds3ReaderItem &item = ds3Reader.items()[i];
qDebug() << "[" << i << "]item.name:" << item.name << "item.type:" << item.type; qDebug() << "[" << i << "]item.name:" << item.name << "item.type:" << item.type;
if (item.type == "asset") { if (item.type == "asset") {
@ -1045,7 +1046,7 @@ void DocumentWindow::openPathAs(const QString &path, const QString &asName)
} }
} }
for (int i = 0; i < ds3Reader.items().size(); ++i) { for (int i = 0; i < (int)ds3Reader.items().size(); ++i) {
const dust3d::Ds3ReaderItem &item = ds3Reader.items()[i]; const dust3d::Ds3ReaderItem &item = ds3Reader.items()[i];
if (item.type == "model") { if (item.type == "model") {
std::vector<std::uint8_t> data; std::vector<std::uint8_t> data;
@ -1124,7 +1125,7 @@ void DocumentWindow::exportObjResult()
void DocumentWindow::exportObjToFilename(const QString &filename) void DocumentWindow::exportObjToFilename(const QString &filename)
{ {
QApplication::setOverrideCursor(Qt::WaitCursor); QApplication::setOverrideCursor(Qt::WaitCursor);
Model *resultMesh = m_document->takeResultMesh(); ModelMesh *resultMesh = m_document->takeResultMesh();
if (nullptr != resultMesh) { if (nullptr != resultMesh) {
resultMesh->exportAsObj(filename); resultMesh->exportAsObj(filename);
delete resultMesh; delete resultMesh;
@ -1534,13 +1535,13 @@ void DocumentWindow::updateRecentFileActions()
{ {
QStringList files = Preferences::instance().recentFileList(); QStringList files = Preferences::instance().recentFileList();
for (int i = 0; i < files.size() && i < m_recentFileActions.size(); ++i) { for (int i = 0; i < (int)files.size() && i < (int)m_recentFileActions.size(); ++i) {
QString text = tr("&%1 %2").arg(i + 1).arg(strippedName(files[i])); QString text = tr("&%1 %2").arg(i + 1).arg(strippedName(files[i]));
m_recentFileActions[i]->setText(text); m_recentFileActions[i]->setText(text);
m_recentFileActions[i]->setData(files[i]); m_recentFileActions[i]->setData(files[i]);
m_recentFileActions[i]->setVisible(true); m_recentFileActions[i]->setVisible(true);
} }
for (int j = files.size(); j < m_recentFileActions.size(); ++j) for (int j = files.size(); j < (int)m_recentFileActions.size(); ++j)
m_recentFileActions[j]->setVisible(false); m_recentFileActions[j]->setVisible(false);
m_recentFileSeparatorAction->setVisible(files.size() > 0); m_recentFileSeparatorAction->setVisible(files.size() > 0);

View File

@ -7,7 +7,7 @@
#include <QtCore/qbuffer.h> #include <QtCore/qbuffer.h>
#include "glb_file.h" #include "glb_file.h"
#include "version.h" #include "version.h"
#include "model.h" #include "model_mesh.h"
bool GlbFileWriter::m_enableComment = false; bool GlbFileWriter::m_enableComment = false;
@ -79,8 +79,8 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
m_json["meshes"][0]["primitives"][primitiveIndex]["attributes"]["TEXCOORD_0"] = bufferViewIndex + (++attributeIndex); m_json["meshes"][0]["primitives"][primitiveIndex]["attributes"]["TEXCOORD_0"] = bufferViewIndex + (++attributeIndex);
int textureIndex = 0; int textureIndex = 0;
m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["baseColorTexture"]["index"] = textureIndex++; m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["baseColorTexture"]["index"] = textureIndex++;
m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["metallicFactor"] = Model::m_defaultMetalness; m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["metallicFactor"] = ModelMesh::m_defaultMetalness;
m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["roughnessFactor"] = Model::m_defaultRoughness; m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["roughnessFactor"] = ModelMesh::m_defaultRoughness;
if (object.alphaEnabled) if (object.alphaEnabled)
m_json["materials"][primitiveIndex]["alphaMode"] = "BLEND"; m_json["materials"][primitiveIndex]["alphaMode"] = "BLEND";
if (normalImage) { if (normalImage) {

View File

@ -31,9 +31,9 @@ const std::set<dust3d::Uuid> &MaterialPreviewsGenerator::generatedPreviewMateria
return m_generatedMaterialIds; return m_generatedMaterialIds;
} }
Model *MaterialPreviewsGenerator::takePreview(dust3d::Uuid materialId) ModelMesh *MaterialPreviewsGenerator::takePreview(dust3d::Uuid materialId)
{ {
Model *resultMesh = m_previews[materialId]; ModelMesh *resultMesh = m_previews[materialId];
m_previews[materialId] = nullptr; m_previews[materialId] = nullptr;
return resultMesh; return resultMesh;
} }
@ -102,9 +102,9 @@ void MaterialPreviewsGenerator::generate()
} }
} }
textureGenerator->generate(); textureGenerator->generate();
Model *texturedResultMesh = textureGenerator->takeResultMesh(); ModelMesh *texturedResultMesh = textureGenerator->takeResultMesh();
if (nullptr != texturedResultMesh) { if (nullptr != texturedResultMesh) {
m_previews[material.first] = new Model(*texturedResultMesh); m_previews[material.first] = new ModelMesh(*texturedResultMesh);
m_generatedMaterialIds.insert(material.first); m_generatedMaterialIds.insert(material.first);
delete texturedResultMesh; delete texturedResultMesh;
} }

View File

@ -4,7 +4,7 @@
#include <QObject> #include <QObject>
#include <map> #include <map>
#include <vector> #include <vector>
#include "model.h" #include "model_mesh.h"
#include "material_layer.h" #include "material_layer.h"
class MaterialPreviewsGenerator : public QObject class MaterialPreviewsGenerator : public QObject
@ -15,7 +15,7 @@ public:
~MaterialPreviewsGenerator(); ~MaterialPreviewsGenerator();
void addMaterial(dust3d::Uuid materialId, const std::vector<MaterialLayer> &layers); void addMaterial(dust3d::Uuid materialId, const std::vector<MaterialLayer> &layers);
const std::set<dust3d::Uuid> &generatedPreviewMaterialIds(); const std::set<dust3d::Uuid> &generatedPreviewMaterialIds();
Model *takePreview(dust3d::Uuid materialId); ModelMesh *takePreview(dust3d::Uuid materialId);
void generate(); void generate();
signals: signals:
void finished(); void finished();
@ -23,7 +23,7 @@ public slots:
void process(); void process();
private: private:
std::vector<std::pair<dust3d::Uuid, std::vector<MaterialLayer>>> m_materials; std::vector<std::pair<dust3d::Uuid, std::vector<MaterialLayer>>> m_materials;
std::map<dust3d::Uuid, Model *> m_previews; std::map<dust3d::Uuid, ModelMesh *> m_previews;
std::set<dust3d::Uuid> m_generatedMaterialIds; std::set<dust3d::Uuid> m_generatedMaterialIds;
}; };

View File

@ -63,7 +63,7 @@ void MaterialWidget::updatePreview(dust3d::Uuid materialId)
qDebug() << "Material not found:" << m_materialId; qDebug() << "Material not found:" << m_materialId;
return; return;
} }
Model *previewMesh = material->takePreviewMesh(); ModelMesh *previewMesh = material->takePreviewMesh();
m_previewWidget->updateMesh(previewMesh); m_previewWidget->updateMesh(previewMesh);
} }

View File

@ -17,9 +17,9 @@ MeshGenerator::~MeshGenerator()
delete m_resultMesh; delete m_resultMesh;
} }
Model *MeshGenerator::takePartPreviewMesh(const dust3d::Uuid &partId) ModelMesh *MeshGenerator::takePartPreviewMesh(const dust3d::Uuid &partId)
{ {
Model *resultMesh = m_partPreviewMeshes[partId]; ModelMesh *resultMesh = m_partPreviewMeshes[partId];
m_partPreviewMeshes[partId] = nullptr; m_partPreviewMeshes[partId] = nullptr;
return resultMesh; return resultMesh;
} }
@ -31,6 +31,11 @@ QImage *MeshGenerator::takePartPreviewImage(const dust3d::Uuid &partId)
return image; return image;
} }
MonochromeMesh *MeshGenerator::takeWireframeMesh()
{
return m_wireframeMesh.release();
}
void MeshGenerator::process() void MeshGenerator::process()
{ {
QElapsedTimer countTimeConsumed; QElapsedTimer countTimeConsumed;
@ -39,7 +44,7 @@ void MeshGenerator::process()
generate(); generate();
if (nullptr != m_object) if (nullptr != m_object)
m_resultMesh = new Model(*m_object); m_resultMesh = new ModelMesh(*m_object);
for (const auto &partId: m_generatedPreviewImagePartIds) { for (const auto &partId: m_generatedPreviewImagePartIds) {
auto it = m_generatedPartPreviews.find(partId); auto it = m_generatedPartPreviews.find(partId);
@ -51,22 +56,25 @@ void MeshGenerator::process()
auto it = m_generatedPartPreviews.find(partId); auto it = m_generatedPartPreviews.find(partId);
if (it == m_generatedPartPreviews.end()) if (it == m_generatedPartPreviews.end())
continue; continue;
m_partPreviewMeshes[partId] = new Model(it->second.vertices, m_partPreviewMeshes[partId] = new ModelMesh(it->second.vertices,
it->second.triangles, it->second.triangles,
it->second.vertexNormals, it->second.vertexNormals,
it->second.color, it->second.color,
it->second.metalness, it->second.metalness,
it->second.roughness); it->second.roughness);
} }
if (nullptr != m_object)
m_wireframeMesh = std::make_unique<MonochromeMesh>(*m_object);
qDebug() << "The mesh generation took" << countTimeConsumed.elapsed() << "milliseconds"; qDebug() << "The mesh generation took" << countTimeConsumed.elapsed() << "milliseconds";
emit finished(); emit finished();
} }
Model *MeshGenerator::takeResultMesh() ModelMesh *MeshGenerator::takeResultMesh()
{ {
Model *resultMesh = m_resultMesh; ModelMesh *resultMesh = m_resultMesh;
m_resultMesh = nullptr; m_resultMesh = nullptr;
return resultMesh; return resultMesh;
} }

View File

@ -1,10 +1,12 @@
#ifndef DUST3D_APPLICATION_MESH_GENERATOR_H_ #ifndef DUST3D_APPLICATION_MESH_GENERATOR_H_
#define DUST3D_APPLICATION_MESH_GENERATOR_H_ #define DUST3D_APPLICATION_MESH_GENERATOR_H_
#include <memory>
#include <QObject> #include <QObject>
#include <QImage> #include <QImage>
#include <dust3d/mesh/mesh_generator.h> #include <dust3d/mesh/mesh_generator.h>
#include "model.h" #include "model_mesh.h"
#include "monochrome_mesh.h"
class MeshGenerator : public QObject, public dust3d::MeshGenerator class MeshGenerator : public QObject, public dust3d::MeshGenerator
{ {
@ -12,17 +14,19 @@ class MeshGenerator : public QObject, public dust3d::MeshGenerator
public: public:
MeshGenerator(dust3d::Snapshot *snapshot); MeshGenerator(dust3d::Snapshot *snapshot);
~MeshGenerator(); ~MeshGenerator();
Model *takeResultMesh(); ModelMesh *takeResultMesh();
Model *takePartPreviewMesh(const dust3d::Uuid &partId); ModelMesh *takePartPreviewMesh(const dust3d::Uuid &partId);
QImage *takePartPreviewImage(const dust3d::Uuid &partId); QImage *takePartPreviewImage(const dust3d::Uuid &partId);
MonochromeMesh *takeWireframeMesh();
public slots: public slots:
void process(); void process();
signals: signals:
void finished(); void finished();
private: private:
Model *m_resultMesh = nullptr; ModelMesh *m_resultMesh = nullptr;
std::map<dust3d::Uuid, Model *> m_partPreviewMeshes; std::map<dust3d::Uuid, ModelMesh *> m_partPreviewMeshes;
std::map<dust3d::Uuid, QImage *> m_partPreviewImages; std::map<dust3d::Uuid, QImage *> m_partPreviewImages;
std::unique_ptr<MonochromeMesh> m_wireframeMesh;
}; };
#endif #endif

View File

@ -2,13 +2,13 @@
#include <QTextStream> #include <QTextStream>
#include <QFile> #include <QFile>
#include <cmath> #include <cmath>
#include "model.h" #include "model_mesh.h"
#include "version.h" #include "version.h"
float Model::m_defaultMetalness = 0.0; float ModelMesh::m_defaultMetalness = 0.0;
float Model::m_defaultRoughness = 1.0; float ModelMesh::m_defaultRoughness = 1.0;
Model::Model(const Model &mesh) : ModelMesh::ModelMesh(const ModelMesh &mesh) :
m_triangleVertices(nullptr), m_triangleVertices(nullptr),
m_triangleVertexCount(0), m_triangleVertexCount(0),
m_edgeVertices(nullptr), m_edgeVertices(nullptr),
@ -17,21 +17,21 @@ Model::Model(const Model &mesh) :
{ {
if (nullptr != mesh.m_triangleVertices && if (nullptr != mesh.m_triangleVertices &&
mesh.m_triangleVertexCount > 0) { mesh.m_triangleVertexCount > 0) {
this->m_triangleVertices = new ModelShaderVertex[mesh.m_triangleVertexCount]; this->m_triangleVertices = new ModelOpenGLVertex[mesh.m_triangleVertexCount];
this->m_triangleVertexCount = mesh.m_triangleVertexCount; this->m_triangleVertexCount = mesh.m_triangleVertexCount;
for (int i = 0; i < mesh.m_triangleVertexCount; i++) for (int i = 0; i < mesh.m_triangleVertexCount; i++)
this->m_triangleVertices[i] = mesh.m_triangleVertices[i]; this->m_triangleVertices[i] = mesh.m_triangleVertices[i];
} }
if (nullptr != mesh.m_edgeVertices && if (nullptr != mesh.m_edgeVertices &&
mesh.m_edgeVertexCount > 0) { mesh.m_edgeVertexCount > 0) {
this->m_edgeVertices = new ModelShaderVertex[mesh.m_edgeVertexCount]; this->m_edgeVertices = new ModelOpenGLVertex[mesh.m_edgeVertexCount];
this->m_edgeVertexCount = mesh.m_edgeVertexCount; this->m_edgeVertexCount = mesh.m_edgeVertexCount;
for (int i = 0; i < mesh.m_edgeVertexCount; i++) for (int i = 0; i < mesh.m_edgeVertexCount; i++)
this->m_edgeVertices[i] = mesh.m_edgeVertices[i]; this->m_edgeVertices[i] = mesh.m_edgeVertices[i];
} }
if (nullptr != mesh.m_toolVertices && if (nullptr != mesh.m_toolVertices &&
mesh.m_toolVertexCount > 0) { mesh.m_toolVertexCount > 0) {
this->m_toolVertices = new ModelShaderVertex[mesh.m_toolVertexCount]; this->m_toolVertices = new ModelOpenGLVertex[mesh.m_toolVertexCount];
this->m_toolVertexCount = mesh.m_toolVertexCount; this->m_toolVertexCount = mesh.m_toolVertexCount;
for (int i = 0; i < mesh.m_toolVertexCount; i++) for (int i = 0; i < mesh.m_toolVertexCount; i++)
this->m_toolVertices[i] = mesh.m_toolVertices[i]; this->m_toolVertices[i] = mesh.m_toolVertices[i];
@ -54,7 +54,7 @@ Model::Model(const Model &mesh) :
this->m_meshId = mesh.meshId(); this->m_meshId = mesh.meshId();
} }
void Model::removeColor() void ModelMesh::removeColor()
{ {
delete this->m_textureImage; delete this->m_textureImage;
this->m_textureImage = nullptr; this->m_textureImage = nullptr;
@ -77,7 +77,7 @@ void Model::removeColor()
} }
} }
Model::Model(ModelShaderVertex *triangleVertices, int vertexNum, ModelShaderVertex *edgeVertices, int edgeVertexCount) : ModelMesh::ModelMesh(ModelOpenGLVertex *triangleVertices, int vertexNum, ModelOpenGLVertex *edgeVertices, int edgeVertexCount) :
m_triangleVertices(triangleVertices), m_triangleVertices(triangleVertices),
m_triangleVertexCount(vertexNum), m_triangleVertexCount(vertexNum),
m_edgeVertices(edgeVertices), m_edgeVertices(edgeVertices),
@ -86,21 +86,21 @@ Model::Model(ModelShaderVertex *triangleVertices, int vertexNum, ModelShaderVert
{ {
} }
Model::Model(const std::vector<dust3d::Vector3> &vertices, const std::vector<std::vector<size_t>> &triangles, ModelMesh::ModelMesh(const std::vector<dust3d::Vector3> &vertices, const std::vector<std::vector<size_t>> &triangles,
const std::vector<std::vector<dust3d::Vector3>> &triangleVertexNormals, const std::vector<std::vector<dust3d::Vector3>> &triangleVertexNormals,
const dust3d::Color &color, const dust3d::Color &color,
float metalness, float metalness,
float roughness) float roughness)
{ {
m_triangleVertexCount = (int)triangles.size() * 3; m_triangleVertexCount = (int)triangles.size() * 3;
m_triangleVertices = new ModelShaderVertex[m_triangleVertexCount]; m_triangleVertices = new ModelOpenGLVertex[m_triangleVertexCount];
int destIndex = 0; int destIndex = 0;
for (size_t i = 0; i < triangles.size(); ++i) { for (size_t i = 0; i < triangles.size(); ++i) {
for (auto j = 0; j < 3; j++) { for (auto j = 0; j < 3; j++) {
int vertexIndex = (int)triangles[i][j]; int vertexIndex = (int)triangles[i][j];
const dust3d::Vector3 *srcVert = &vertices[vertexIndex]; const dust3d::Vector3 *srcVert = &vertices[vertexIndex];
const dust3d::Vector3 *srcNormal = &(triangleVertexNormals)[i][j]; const dust3d::Vector3 *srcNormal = &(triangleVertexNormals)[i][j];
ModelShaderVertex *dest = &m_triangleVertices[destIndex]; ModelOpenGLVertex *dest = &m_triangleVertices[destIndex];
dest->colorR = color.r(); dest->colorR = color.r();
dest->colorG = color.g(); dest->colorG = color.g();
dest->colorB = color.b(); dest->colorB = color.b();
@ -123,7 +123,7 @@ Model::Model(const std::vector<dust3d::Vector3> &vertices, const std::vector<std
} }
} }
Model::Model(dust3d::Object &object) : ModelMesh::ModelMesh(dust3d::Object &object) :
m_triangleVertices(nullptr), m_triangleVertices(nullptr),
m_triangleVertexCount(0), m_triangleVertexCount(0),
m_edgeVertices(nullptr), m_edgeVertices(nullptr),
@ -141,7 +141,7 @@ Model::Model(dust3d::Object &object) :
} }
m_triangleVertexCount = (int)object.triangles.size() * 3; m_triangleVertexCount = (int)object.triangles.size() * 3;
m_triangleVertices = new ModelShaderVertex[m_triangleVertexCount]; m_triangleVertices = new ModelOpenGLVertex[m_triangleVertexCount];
int destIndex = 0; int destIndex = 0;
const auto triangleVertexNormals = object.triangleVertexNormals(); const auto triangleVertexNormals = object.triangleVertexNormals();
const auto triangleVertexUvs = object.triangleVertexUvs(); const auto triangleVertexUvs = object.triangleVertexUvs();
@ -163,7 +163,7 @@ Model::Model(dust3d::Object &object) :
const dust3d::Vector3 *srcTangent = &defaultTangent; const dust3d::Vector3 *srcTangent = &defaultTangent;
if (triangleTangents) if (triangleTangents)
srcTangent = &(*triangleTangents)[i]; srcTangent = &(*triangleTangents)[i];
ModelShaderVertex *dest = &m_triangleVertices[destIndex]; ModelOpenGLVertex *dest = &m_triangleVertices[destIndex];
dest->colorR = triangleColor->r(); dest->colorR = triangleColor->r();
dest->colorG = triangleColor->g(); dest->colorG = triangleColor->g();
dest->colorB = triangleColor->b(); dest->colorB = triangleColor->b();
@ -196,7 +196,7 @@ Model::Model(dust3d::Object &object) :
edgeCount += face.size(); edgeCount += face.size();
} }
m_edgeVertexCount = (int)edgeCount * 2; m_edgeVertexCount = (int)edgeCount * 2;
m_edgeVertices = new ModelShaderVertex[m_edgeVertexCount]; m_edgeVertices = new ModelOpenGLVertex[m_edgeVertexCount];
size_t edgeVertexIndex = 0; size_t edgeVertexIndex = 0;
for (size_t faceIndex = 0; faceIndex < object.triangleAndQuads.size(); ++faceIndex) { for (size_t faceIndex = 0; faceIndex < object.triangleAndQuads.size(); ++faceIndex) {
const auto &face = object.triangleAndQuads[faceIndex]; const auto &face = object.triangleAndQuads[faceIndex];
@ -204,8 +204,8 @@ Model::Model(dust3d::Object &object) :
for (size_t x = 0; x < 2; ++x) { for (size_t x = 0; x < 2; ++x) {
size_t sourceIndex = face[(i + x) % face.size()]; size_t sourceIndex = face[(i + x) % face.size()];
const dust3d::Vector3 *srcVert = &object.vertices[sourceIndex]; const dust3d::Vector3 *srcVert = &object.vertices[sourceIndex];
ModelShaderVertex *dest = &m_edgeVertices[edgeVertexIndex]; ModelOpenGLVertex *dest = &m_edgeVertices[edgeVertexIndex];
memset(dest, 0, sizeof(ModelShaderVertex)); memset(dest, 0, sizeof(ModelOpenGLVertex));
dest->colorR = 0.0; dest->colorR = 0.0;
dest->colorG = 0.0; dest->colorG = 0.0;
dest->colorB = 0.0; dest->colorB = 0.0;
@ -221,7 +221,7 @@ Model::Model(dust3d::Object &object) :
} }
} }
Model::Model() : ModelMesh::ModelMesh() :
m_triangleVertices(nullptr), m_triangleVertices(nullptr),
m_triangleVertexCount(0), m_triangleVertexCount(0),
m_edgeVertices(nullptr), m_edgeVertices(nullptr),
@ -230,7 +230,7 @@ Model::Model() :
{ {
} }
Model::~Model() ModelMesh::~ModelMesh()
{ {
delete[] m_triangleVertices; delete[] m_triangleVertices;
m_triangleVertexCount = 0; m_triangleVertexCount = 0;
@ -243,112 +243,112 @@ Model::~Model()
delete m_metalnessRoughnessAmbientOcclusionImage; delete m_metalnessRoughnessAmbientOcclusionImage;
} }
const std::vector<dust3d::Vector3> &Model::vertices() const std::vector<dust3d::Vector3> &ModelMesh::vertices()
{ {
return m_vertices; return m_vertices;
} }
const std::vector<std::vector<size_t>> &Model::faces() const std::vector<std::vector<size_t>> &ModelMesh::faces()
{ {
return m_faces; return m_faces;
} }
const std::vector<dust3d::Vector3> &Model::triangulatedVertices() const std::vector<dust3d::Vector3> &ModelMesh::triangulatedVertices()
{ {
return m_triangulatedVertices; return m_triangulatedVertices;
} }
ModelShaderVertex *Model::triangleVertices() ModelOpenGLVertex *ModelMesh::triangleVertices()
{ {
return m_triangleVertices; return m_triangleVertices;
} }
int Model::triangleVertexCount() int ModelMesh::triangleVertexCount()
{ {
return m_triangleVertexCount; return m_triangleVertexCount;
} }
ModelShaderVertex *Model::edgeVertices() ModelOpenGLVertex *ModelMesh::edgeVertices()
{ {
return m_edgeVertices; return m_edgeVertices;
} }
int Model::edgeVertexCount() int ModelMesh::edgeVertexCount()
{ {
return m_edgeVertexCount; return m_edgeVertexCount;
} }
ModelShaderVertex *Model::toolVertices() ModelOpenGLVertex *ModelMesh::toolVertices()
{ {
return m_toolVertices; return m_toolVertices;
} }
int Model::toolVertexCount() int ModelMesh::toolVertexCount()
{ {
return m_toolVertexCount; return m_toolVertexCount;
} }
void Model::setTextureImage(QImage *textureImage) void ModelMesh::setTextureImage(QImage *textureImage)
{ {
m_textureImage = textureImage; m_textureImage = textureImage;
} }
const QImage *Model::textureImage() const QImage *ModelMesh::textureImage()
{ {
return m_textureImage; return m_textureImage;
} }
void Model::setNormalMapImage(QImage *normalMapImage) void ModelMesh::setNormalMapImage(QImage *normalMapImage)
{ {
m_normalMapImage = normalMapImage; m_normalMapImage = normalMapImage;
} }
const QImage *Model::normalMapImage() const QImage *ModelMesh::normalMapImage()
{ {
return m_normalMapImage; return m_normalMapImage;
} }
const QImage *Model::metalnessRoughnessAmbientOcclusionImage() const QImage *ModelMesh::metalnessRoughnessAmbientOcclusionImage()
{ {
return m_metalnessRoughnessAmbientOcclusionImage; return m_metalnessRoughnessAmbientOcclusionImage;
} }
void Model::setMetalnessRoughnessAmbientOcclusionImage(QImage *image) void ModelMesh::setMetalnessRoughnessAmbientOcclusionImage(QImage *image)
{ {
m_metalnessRoughnessAmbientOcclusionImage = image; m_metalnessRoughnessAmbientOcclusionImage = image;
} }
bool Model::hasMetalnessInImage() bool ModelMesh::hasMetalnessInImage()
{ {
return m_hasMetalnessInImage; return m_hasMetalnessInImage;
} }
void Model::setHasMetalnessInImage(bool hasInImage) void ModelMesh::setHasMetalnessInImage(bool hasInImage)
{ {
m_hasMetalnessInImage = hasInImage; m_hasMetalnessInImage = hasInImage;
} }
bool Model::hasRoughnessInImage() bool ModelMesh::hasRoughnessInImage()
{ {
return m_hasRoughnessInImage; return m_hasRoughnessInImage;
} }
void Model::setHasRoughnessInImage(bool hasInImage) void ModelMesh::setHasRoughnessInImage(bool hasInImage)
{ {
m_hasRoughnessInImage = hasInImage; m_hasRoughnessInImage = hasInImage;
} }
bool Model::hasAmbientOcclusionInImage() bool ModelMesh::hasAmbientOcclusionInImage()
{ {
return m_hasAmbientOcclusionInImage; return m_hasAmbientOcclusionInImage;
} }
void Model::setHasAmbientOcclusionInImage(bool hasInImage) void ModelMesh::setHasAmbientOcclusionInImage(bool hasInImage)
{ {
m_hasAmbientOcclusionInImage = hasInImage; m_hasAmbientOcclusionInImage = hasInImage;
} }
void Model::exportAsObj(QTextStream *textStream) void ModelMesh::exportAsObj(QTextStream *textStream)
{ {
auto &stream = *textStream; auto &stream = *textStream;
stream << "# " << APP_NAME << " " << APP_HUMAN_VER << endl; stream << "# " << APP_NAME << " " << APP_HUMAN_VER << endl;
@ -365,7 +365,7 @@ void Model::exportAsObj(QTextStream *textStream)
} }
} }
void Model::exportAsObj(const QString &filename) void ModelMesh::exportAsObj(const QString &filename)
{ {
QFile file(filename); QFile file(filename);
if (file.open(QIODevice::WriteOnly)) { if (file.open(QIODevice::WriteOnly)) {
@ -374,7 +374,7 @@ void Model::exportAsObj(const QString &filename)
} }
} }
void Model::updateTool(ModelShaderVertex *toolVertices, int vertexNum) void ModelMesh::updateTool(ModelOpenGLVertex *toolVertices, int vertexNum)
{ {
delete[] m_toolVertices; delete[] m_toolVertices;
m_toolVertices = nullptr; m_toolVertices = nullptr;
@ -384,7 +384,7 @@ void Model::updateTool(ModelShaderVertex *toolVertices, int vertexNum)
m_toolVertexCount = vertexNum; m_toolVertexCount = vertexNum;
} }
void Model::updateEdges(ModelShaderVertex *edgeVertices, int edgeVertexCount) void ModelMesh::updateEdges(ModelOpenGLVertex *edgeVertices, int edgeVertexCount)
{ {
delete[] m_edgeVertices; delete[] m_edgeVertices;
m_edgeVertices = nullptr; m_edgeVertices = nullptr;
@ -394,7 +394,7 @@ void Model::updateEdges(ModelShaderVertex *edgeVertices, int edgeVertexCount)
m_edgeVertexCount = edgeVertexCount; m_edgeVertexCount = edgeVertexCount;
} }
void Model::updateTriangleVertices(ModelShaderVertex *triangleVertices, int triangleVertexCount) void ModelMesh::updateTriangleVertices(ModelOpenGLVertex *triangleVertices, int triangleVertexCount)
{ {
delete[] m_triangleVertices; delete[] m_triangleVertices;
m_triangleVertices = 0; m_triangleVertices = 0;
@ -404,12 +404,12 @@ void Model::updateTriangleVertices(ModelShaderVertex *triangleVertices, int tria
m_triangleVertexCount = triangleVertexCount; m_triangleVertexCount = triangleVertexCount;
} }
quint64 Model::meshId() const quint64 ModelMesh::meshId() const
{ {
return m_meshId; return m_meshId;
} }
void Model::setMeshId(quint64 id) void ModelMesh::setMeshId(quint64 id)
{ {
m_meshId = id; m_meshId = id;
} }

View File

@ -1,5 +1,5 @@
#ifndef DUST3D_APPLICATION_MODEL_H_ #ifndef DUST3D_APPLICATION_MODEL_MESH_H_
#define DUST3D_APPLICATION_MODEL_H_ #define DUST3D_APPLICATION_MODEL_MESH_H_
#include <QObject> #include <QObject>
#include <vector> #include <vector>
@ -8,26 +8,26 @@
#include <dust3d/base/vector3.h> #include <dust3d/base/vector3.h>
#include <dust3d/base/color.h> #include <dust3d/base/color.h>
#include <dust3d/base/object.h> #include <dust3d/base/object.h>
#include "model_shader_vertex.h" #include "model_opengl_vertex.h"
class Model class ModelMesh
{ {
public: public:
Model(const std::vector<dust3d::Vector3> &vertices, const std::vector<std::vector<size_t>> &triangles, ModelMesh(const std::vector<dust3d::Vector3> &vertices, const std::vector<std::vector<size_t>> &triangles,
const std::vector<std::vector<dust3d::Vector3>> &triangleVertexNormals, const std::vector<std::vector<dust3d::Vector3>> &triangleVertexNormals,
const dust3d::Color &color=dust3d::Color::createWhite(), const dust3d::Color &color=dust3d::Color::createWhite(),
float metalness=0.0, float metalness=0.0,
float roughness=0.0); float roughness=0.0);
Model(dust3d::Object &object); ModelMesh(dust3d::Object &object);
Model(ModelShaderVertex *triangleVertices, int vertexNum, ModelShaderVertex *edgeVertices=nullptr, int edgeVertexCount=0); ModelMesh(ModelOpenGLVertex *triangleVertices, int vertexNum, ModelOpenGLVertex *edgeVertices=nullptr, int edgeVertexCount=0);
Model(const Model &mesh); ModelMesh(const ModelMesh &mesh);
Model(); ModelMesh();
~Model(); ~ModelMesh();
ModelShaderVertex *triangleVertices(); ModelOpenGLVertex *triangleVertices();
int triangleVertexCount(); int triangleVertexCount();
ModelShaderVertex *edgeVertices(); ModelOpenGLVertex *edgeVertices();
int edgeVertexCount(); int edgeVertexCount();
ModelShaderVertex *toolVertices(); ModelOpenGLVertex *toolVertices();
int toolVertexCount(); int toolVertexCount();
const std::vector<dust3d::Vector3> &vertices(); const std::vector<dust3d::Vector3> &vertices();
const std::vector<std::vector<size_t>> &faces(); const std::vector<std::vector<size_t>> &faces();
@ -48,18 +48,18 @@ public:
static float m_defaultRoughness; static float m_defaultRoughness;
void exportAsObj(const QString &filename); void exportAsObj(const QString &filename);
void exportAsObj(QTextStream *textStream); void exportAsObj(QTextStream *textStream);
void updateTool(ModelShaderVertex *toolVertices, int vertexNum); void updateTool(ModelOpenGLVertex *toolVertices, int vertexNum);
void updateEdges(ModelShaderVertex *edgeVertices, int edgeVertexCount); void updateEdges(ModelOpenGLVertex *edgeVertices, int edgeVertexCount);
void updateTriangleVertices(ModelShaderVertex *triangleVertices, int triangleVertexCount); void updateTriangleVertices(ModelOpenGLVertex *triangleVertices, int triangleVertexCount);
quint64 meshId() const; quint64 meshId() const;
void setMeshId(quint64 id); void setMeshId(quint64 id);
void removeColor(); void removeColor();
private: private:
ModelShaderVertex *m_triangleVertices = nullptr; ModelOpenGLVertex *m_triangleVertices = nullptr;
int m_triangleVertexCount = 0; int m_triangleVertexCount = 0;
ModelShaderVertex *m_edgeVertices = nullptr; ModelOpenGLVertex *m_edgeVertices = nullptr;
int m_edgeVertexCount = 0; int m_edgeVertexCount = 0;
ModelShaderVertex *m_toolVertices = nullptr; ModelOpenGLVertex *m_toolVertices = nullptr;
int m_toolVertexCount = 0; int m_toolVertexCount = 0;
std::vector<dust3d::Vector3> m_vertices; std::vector<dust3d::Vector3> m_vertices;
std::vector<std::vector<size_t>> m_faces; std::vector<std::vector<size_t>> m_faces;

View File

@ -40,7 +40,7 @@ void ModelOffscreenRender::setRenderThread(QThread *thread)
// TODO // TODO
} }
void ModelOffscreenRender::updateMesh(Model *mesh) void ModelOffscreenRender::updateMesh(ModelMesh *mesh)
{ {
// TODO // TODO
} }

View File

@ -4,7 +4,7 @@
#include <QOffscreenSurface> #include <QOffscreenSurface>
#include <QSurfaceFormat> #include <QSurfaceFormat>
#include <QVector3D> #include <QVector3D>
#include "model.h" #include "model_mesh.h"
class ModelOffscreenRender: public QOffscreenSurface class ModelOffscreenRender: public QOffscreenSurface
{ {
@ -17,7 +17,7 @@ public:
void setEyePosition(const QVector3D &eyePosition); void setEyePosition(const QVector3D &eyePosition);
void setMoveToPosition(const QVector3D &moveToPosition); void setMoveToPosition(const QVector3D &moveToPosition);
void setRenderThread(QThread *thread); void setRenderThread(QThread *thread);
void updateMesh(Model *mesh); void updateMesh(ModelMesh *mesh);
QImage toImage(const QSize &size); QImage toImage(const QSize &size);
}; };

View File

@ -3,7 +3,7 @@
#include <QOpenGLContext> #include <QOpenGLContext>
#include "model_opengl_object.h" #include "model_opengl_object.h"
void ModelOpenGLObject::update(std::unique_ptr<Model> mesh) void ModelOpenGLObject::update(std::unique_ptr<ModelMesh> mesh)
{ {
QMutexLocker lock(&m_meshMutex); QMutexLocker lock(&m_meshMutex);
m_mesh = std::move(mesh); m_mesh = std::move(mesh);
@ -22,7 +22,7 @@ void ModelOpenGLObject::draw()
void ModelOpenGLObject::copyMeshToOpenGL() void ModelOpenGLObject::copyMeshToOpenGL()
{ {
std::unique_ptr<Model> mesh; std::unique_ptr<ModelMesh> mesh;
bool meshChanged = false; bool meshChanged = false;
if (m_meshIsDirty) { if (m_meshIsDirty) {
QMutexLocker lock(&m_meshMutex); QMutexLocker lock(&m_meshMutex);
@ -41,7 +41,7 @@ void ModelOpenGLObject::copyMeshToOpenGL()
m_buffer.destroy(); m_buffer.destroy();
m_buffer.create(); m_buffer.create();
m_buffer.bind(); m_buffer.bind();
m_buffer.allocate(mesh->triangleVertices(), mesh->triangleVertexCount() * sizeof(ModelShaderVertex)); m_buffer.allocate(mesh->triangleVertices(), mesh->triangleVertexCount() * sizeof(ModelOpenGLVertex));
m_meshTriangleVertexCount = mesh->triangleVertexCount(); m_meshTriangleVertexCount = mesh->triangleVertexCount();
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glEnableVertexAttribArray(0); f->glEnableVertexAttribArray(0);
@ -52,14 +52,14 @@ void ModelOpenGLObject::copyMeshToOpenGL()
f->glEnableVertexAttribArray(5); f->glEnableVertexAttribArray(5);
f->glEnableVertexAttribArray(6); f->glEnableVertexAttribArray(6);
f->glEnableVertexAttribArray(7); f->glEnableVertexAttribArray(7);
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ModelShaderVertex), 0); f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), 0);
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(ModelShaderVertex), reinterpret_cast<void *>(3 * sizeof(GLfloat))); f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ModelShaderVertex), reinterpret_cast<void *>(6 * sizeof(GLfloat))); f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void *>(6 * sizeof(GLfloat)));
f->glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(ModelShaderVertex), reinterpret_cast<void *>(9 * sizeof(GLfloat))); f->glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void *>(9 * sizeof(GLfloat)));
f->glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(ModelShaderVertex), reinterpret_cast<void *>(11 * sizeof(GLfloat))); f->glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void *>(11 * sizeof(GLfloat)));
f->glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(ModelShaderVertex), reinterpret_cast<void *>(12 * sizeof(GLfloat))); f->glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void *>(12 * sizeof(GLfloat)));
f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ModelShaderVertex), reinterpret_cast<void *>(13 * sizeof(GLfloat))); f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void *>(13 * sizeof(GLfloat)));
f->glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(ModelShaderVertex), reinterpret_cast<void *>(16 * sizeof(GLfloat))); f->glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void *>(16 * sizeof(GLfloat)));
m_buffer.release(); m_buffer.release();
} }
} }

View File

@ -5,18 +5,18 @@
#include <QMutex> #include <QMutex>
#include <QOpenGLVertexArrayObject> #include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer> #include <QOpenGLBuffer>
#include "model.h" #include "model_mesh.h"
class ModelOpenGLObject class ModelOpenGLObject
{ {
public: public:
void update(std::unique_ptr<Model> mesh); void update(std::unique_ptr<ModelMesh> mesh);
void draw(); void draw();
private: private:
void copyMeshToOpenGL(); void copyMeshToOpenGL();
QOpenGLVertexArrayObject m_vertexArrayObject; QOpenGLVertexArrayObject m_vertexArrayObject;
QOpenGLBuffer m_buffer; QOpenGLBuffer m_buffer;
std::unique_ptr<Model> m_mesh; std::unique_ptr<ModelMesh> m_mesh;
bool m_meshIsDirty = false; bool m_meshIsDirty = false;
QMutex m_meshMutex; QMutex m_meshMutex;
int m_meshTriangleVertexCount = 0; int m_meshTriangleVertexCount = 0;

View File

@ -1,5 +1,5 @@
#ifndef DUST3D_APPLICATION_MODEL_SHADER_VERTEX_H_ #ifndef DUST3D_APPLICATION_MODEL_OPENGL_VERTEX_H_
#define DUST3D_APPLICATION_MODEL_SHADER_VERTEX_H_ #define DUST3D_APPLICATION_MODEL_OPENGL_VERTEX_H_
#include <QOpenGLFunctions> #include <QOpenGLFunctions>
@ -24,7 +24,7 @@ typedef struct
GLfloat tangentY; GLfloat tangentY;
GLfloat tangentZ; GLfloat tangentZ;
GLfloat alpha = 1.0; GLfloat alpha = 1.0;
} ModelShaderVertex; } ModelOpenGLVertex;
#pragma pack(pop) #pragma pack(pop)
#endif #endif

View File

@ -115,11 +115,11 @@ void ModelWidget::setZRotation(int angle)
void ModelWidget::cleanup() void ModelWidget::cleanup()
{ {
if (!m_openGLProgram) if (!m_modelOpenGLProgram)
return; return;
makeCurrent(); makeCurrent();
m_openGLObject.reset(); m_modelOpenGLObject.reset();
m_openGLProgram.reset(); m_modelOpenGLProgram.reset();
doneCurrent(); doneCurrent();
} }
@ -163,13 +163,13 @@ std::pair<QVector3D, QVector3D> ModelWidget::screenPositionToMouseRay(const QPoi
void ModelWidget::toggleWireframe() void ModelWidget::toggleWireframe()
{ {
// TODO m_isWireframeVisible = !m_isWireframeVisible;
update();
} }
bool ModelWidget::isWireframeVisible() bool ModelWidget::isWireframeVisible()
{ {
// TODO return m_isWireframeVisible;
return false;
} }
void ModelWidget::enableEnvironmentLight() void ModelWidget::enableEnvironmentLight()
@ -367,11 +367,20 @@ void ModelWidget::setMousePickRadius(float radius)
update(); update();
} }
void ModelWidget::updateMesh(Model *mesh) void ModelWidget::updateMesh(ModelMesh *mesh)
{ {
if (!m_openGLObject) if (!m_modelOpenGLObject)
m_openGLObject = std::make_unique<ModelOpenGLObject>(); m_modelOpenGLObject = std::make_unique<ModelOpenGLObject>();
m_openGLObject->update(std::unique_ptr<Model>(mesh)); m_modelOpenGLObject->update(std::unique_ptr<ModelMesh>(mesh));
emit renderParametersChanged();
update();
}
void ModelWidget::updateWireframeMesh(MonochromeMesh *mesh)
{
if (!m_wireframeOpenGLObject)
m_wireframeOpenGLObject = std::make_unique<MonochromeOpenGLObject>();
m_wireframeOpenGLObject->update(std::unique_ptr<MonochromeMesh>(mesh));
emit renderParametersChanged(); emit renderParametersChanged();
update(); update();
} }
@ -481,20 +490,48 @@ void ModelWidget::paintGL()
m_camera.setToIdentity(); m_camera.setToIdentity();
m_camera.translate(m_eyePosition.x(), m_eyePosition.y(), m_eyePosition.z()); m_camera.translate(m_eyePosition.x(), m_eyePosition.y(), m_eyePosition.z());
if (!m_openGLProgram) { if (!m_modelOpenGLProgram) {
m_openGLProgram = std::make_unique<ModelOpenGLProgram>(); m_modelOpenGLProgram = std::make_unique<ModelOpenGLProgram>();
m_openGLProgram->load(format().profile() == QSurfaceFormat::CoreProfile); m_modelOpenGLProgram->load(format().profile() == QSurfaceFormat::CoreProfile);
} }
m_openGLProgram->bind(); if (m_isWireframeVisible) {
if (!m_monochromeOpenGLProgram) {
m_monochromeOpenGLProgram = std::make_unique<MonochromeOpenGLProgram>();
m_monochromeOpenGLProgram->load(format().profile() == QSurfaceFormat::CoreProfile);
}
}
m_openGLProgram->setUniformValue(m_openGLProgram->getUniformLocationByName("eyePosition"), m_eyePosition); drawModel();
m_openGLProgram->setUniformValue(m_openGLProgram->getUniformLocationByName("projectionMatrix"), m_projection); if (m_isWireframeVisible)
m_openGLProgram->setUniformValue(m_openGLProgram->getUniformLocationByName("modelMatrix"), m_world); drawWireframe();
m_openGLProgram->setUniformValue(m_openGLProgram->getUniformLocationByName("viewMatrix"), m_camera); }
void ModelWidget::drawWireframe()
{
m_monochromeOpenGLProgram->bind();
m_monochromeOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("projectionMatrix"), m_projection);
m_monochromeOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("modelMatrix"), m_world);
m_monochromeOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("viewMatrix"), m_camera);
if (m_wireframeOpenGLObject)
m_wireframeOpenGLObject->draw();
m_monochromeOpenGLProgram->release();
}
void ModelWidget::drawModel()
{
m_modelOpenGLProgram->bind();
m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("eyePosition"), m_eyePosition);
m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("projectionMatrix"), m_projection);
m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("modelMatrix"), m_world);
m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("viewMatrix"), m_camera);
if (m_isEnvironmentLightEnabled) { if (m_isEnvironmentLightEnabled) {
if (m_openGLProgram->isCoreProfile()) { if (m_modelOpenGLProgram->isCoreProfile()) {
if (!m_environmentIrradianceMap) { if (!m_environmentIrradianceMap) {
DdsFileReader irradianceFile(":/resources/cedar_bridge_irradiance.dds"); DdsFileReader irradianceFile(":/resources/cedar_bridge_irradiance.dds");
m_environmentIrradianceMap.reset(irradianceFile.createOpenGLTexture()); m_environmentIrradianceMap.reset(irradianceFile.createOpenGLTexture());
@ -505,10 +542,10 @@ void ModelWidget::paintGL()
} }
m_environmentIrradianceMap->bind(0); m_environmentIrradianceMap->bind(0);
m_openGLProgram->setUniformValue(m_openGLProgram->getUniformLocationByName("environmentIrradianceMapId"), 0); m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("environmentIrradianceMapId"), 0);
m_environmentSpecularMap->bind(1); m_environmentSpecularMap->bind(1);
m_openGLProgram->setUniformValue(m_openGLProgram->getUniformLocationByName("environmentSpecularMapId"), 1); m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("environmentSpecularMapId"), 1);
} else { } else {
if (!m_environmentIrradianceMaps) { if (!m_environmentIrradianceMaps) {
DdsFileReader irradianceFile(":/resources/cedar_bridge_irradiance.dds"); DdsFileReader irradianceFile(":/resources/cedar_bridge_irradiance.dds");
@ -529,14 +566,14 @@ void ModelWidget::paintGL()
bindPosition = 0; bindPosition = 0;
for (size_t i = 0; i < m_environmentIrradianceMaps->size(); ++i) for (size_t i = 0; i < m_environmentIrradianceMaps->size(); ++i)
m_openGLProgram->setUniformValue(m_openGLProgram->getUniformLocationByName("environmentIrradianceMapId[" + std::to_string(i) + "]"), (int)(bindPosition++)); m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("environmentIrradianceMapId[" + std::to_string(i) + "]"), (int)(bindPosition++));
for (size_t i = 0; i < m_environmentSpecularMaps->size(); ++i) for (size_t i = 0; i < m_environmentSpecularMaps->size(); ++i)
m_openGLProgram->setUniformValue(m_openGLProgram->getUniformLocationByName("environmentSpecularMapId[" + std::to_string(i) + "]"), (int)(bindPosition++)); m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("environmentSpecularMapId[" + std::to_string(i) + "]"), (int)(bindPosition++));
} }
} }
if (m_openGLObject) if (m_modelOpenGLObject)
m_openGLObject->draw(); m_modelOpenGLObject->draw();
m_openGLProgram->release(); m_modelOpenGLProgram->release();
} }

View File

@ -10,9 +10,12 @@
#include <QVector2D> #include <QVector2D>
#include <QTimer> #include <QTimer>
#include <QString> #include <QString>
#include "model.h" #include "model_mesh.h"
#include "model_opengl_program.h" #include "model_opengl_program.h"
#include "model_opengl_object.h" #include "model_opengl_object.h"
#include "monochrome_mesh.h"
#include "monochrome_opengl_program.h"
#include "monochrome_opengl_object.h"
class ModelWidget : public QOpenGLWidget class ModelWidget : public QOpenGLWidget
{ {
@ -31,7 +34,8 @@ signals:
public: public:
ModelWidget(QWidget *parent = 0); ModelWidget(QWidget *parent = 0);
~ModelWidget(); ~ModelWidget();
void updateMesh(Model *mesh); void updateMesh(ModelMesh *mesh);
void updateWireframeMesh(MonochromeMesh *mesh);
void updateColorTexture(QImage *colorTextureImage); void updateColorTexture(QImage *colorTextureImage);
void toggleWireframe(); void toggleWireframe();
bool isWireframeVisible(); bool isWireframeVisible();
@ -82,8 +86,10 @@ private:
int m_yRot = m_defaultYRotation; int m_yRot = m_defaultYRotation;
int m_zRot = m_defaultZRotation; int m_zRot = m_defaultZRotation;
int m_directionOnMoveStart = 0; int m_directionOnMoveStart = 0;
std::unique_ptr<ModelOpenGLProgram> m_openGLProgram; std::unique_ptr<ModelOpenGLProgram> m_modelOpenGLProgram;
std::unique_ptr<ModelOpenGLObject> m_openGLObject; std::unique_ptr<ModelOpenGLObject> m_modelOpenGLObject;
std::unique_ptr<MonochromeOpenGLProgram> m_monochromeOpenGLProgram;
std::unique_ptr<MonochromeOpenGLObject> m_wireframeOpenGLObject;
bool m_moveStarted = false; bool m_moveStarted = false;
bool m_moveEnabled = true; bool m_moveEnabled = true;
bool m_zoomEnabled = true; bool m_zoomEnabled = true;
@ -108,6 +114,7 @@ private:
bool m_enableCullFace = true; bool m_enableCullFace = true;
bool m_notGraphics = false; bool m_notGraphics = false;
bool m_isEnvironmentLightEnabled = false; bool m_isEnvironmentLightEnabled = false;
bool m_isWireframeVisible = false;
std::unique_ptr<QOpenGLTexture> m_environmentIrradianceMap; std::unique_ptr<QOpenGLTexture> m_environmentIrradianceMap;
std::unique_ptr<QOpenGLTexture> m_environmentSpecularMap; std::unique_ptr<QOpenGLTexture> m_environmentSpecularMap;
std::unique_ptr<std::vector<std::unique_ptr<QOpenGLTexture>>> m_environmentIrradianceMaps; std::unique_ptr<std::vector<std::unique_ptr<QOpenGLTexture>>> m_environmentIrradianceMaps;
@ -116,6 +123,8 @@ private:
std::pair<QVector3D, QVector3D> screenPositionToMouseRay(const QPoint &screenPosition); std::pair<QVector3D, QVector3D> screenPositionToMouseRay(const QPoint &screenPosition);
void updateProjectionMatrix(); void updateProjectionMatrix();
void normalizeAngle(int &angle); void normalizeAngle(int &angle);
void drawModel();
void drawWireframe();
public: public:
static int m_defaultXRotation; static int m_defaultXRotation;
static int m_defaultYRotation; static int m_defaultYRotation;

View File

@ -0,0 +1,58 @@
#include <set>
#include "monochrome_mesh.h"
MonochromeMesh::MonochromeMesh(const MonochromeMesh &mesh)
{
m_lineVertices = mesh.m_lineVertices;
}
MonochromeMesh::MonochromeMesh(MonochromeMesh &&mesh)
{
m_lineVertices = std::move(mesh.m_lineVertices);
}
MonochromeMesh::MonochromeMesh(const dust3d::Object &object)
{
std::set<std::pair<size_t, size_t>> halfEdges;
for (const auto &face: object.triangleAndQuads) {
if (3 == face.size()) {
halfEdges.insert({face[0], face[1]});
halfEdges.insert({face[1], face[0]});
halfEdges.insert({face[1], face[2]});
halfEdges.insert({face[2], face[1]});
halfEdges.insert({face[2], face[0]});
halfEdges.insert({face[0], face[2]});
continue;
}
halfEdges.insert({face[0], face[1]});
halfEdges.insert({face[1], face[0]});
halfEdges.insert({face[1], face[2]});
halfEdges.insert({face[2], face[1]});
halfEdges.insert({face[2], face[3]});
halfEdges.insert({face[3], face[2]});
halfEdges.insert({face[3], face[0]});
halfEdges.insert({face[0], face[3]});
}
m_lineVertices.reserve(halfEdges.size() * 2);
for (const auto &halfEdge: halfEdges) {
// For two halfedges shared one edge, only output one line
if (halfEdge.first > halfEdge.second)
continue;
const auto &from = object.vertices[halfEdge.first];
const auto &to = object.vertices[halfEdge.second];
m_lineVertices.emplace_back(MonochromeOpenGLVertex {(GLfloat)from.x(), (GLfloat)from.y(), (GLfloat)from.z()});
m_lineVertices.emplace_back(MonochromeOpenGLVertex {(GLfloat)to.x(), (GLfloat)to.y(), (GLfloat)to.z()});
}
}
const MonochromeOpenGLVertex *MonochromeMesh::lineVertices()
{
if (m_lineVertices.empty())
return nullptr;
return &m_lineVertices[0];
}
int MonochromeMesh::lineVertexCount()
{
return (int)m_lineVertices.size();
}

View File

@ -0,0 +1,21 @@
#ifndef DUST3D_APPLICATION_MONOCHROME_MESH_H_
#define DUST3D_APPLICATION_MONOCHROME_MESH_H_
#include <memory>
#include <dust3d/base/object.h>
#include "monochrome_opengl_vertex.h"
class MonochromeMesh
{
public:
MonochromeMesh(const MonochromeMesh &mesh);
MonochromeMesh(MonochromeMesh &&mesh);
MonochromeMesh(const dust3d::Object &object);
const MonochromeOpenGLVertex *lineVertices();
int lineVertexCount();
private:
std::vector<MonochromeOpenGLVertex> m_lineVertices;
};
#endif

View File

@ -0,0 +1,55 @@
#include <dust3d/base/debug.h>
#include <QOpenGLFunctions>
#include <QOpenGLContext>
#include "monochrome_opengl_object.h"
void MonochromeOpenGLObject::update(std::unique_ptr<MonochromeMesh> mesh)
{
QMutexLocker lock(&m_meshMutex);
m_mesh = std::move(mesh);
m_meshIsDirty = true;
}
void MonochromeOpenGLObject::draw()
{
copyMeshToOpenGL();
if (0 == m_meshLineVertexCount)
return;
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
QOpenGLVertexArrayObject::Binder binder(&m_vertexArrayObject);
f->glDrawArrays(GL_LINES, 0, m_meshLineVertexCount);
}
void MonochromeOpenGLObject::copyMeshToOpenGL()
{
std::unique_ptr<MonochromeMesh> mesh;
bool meshChanged = false;
if (m_meshIsDirty) {
QMutexLocker lock(&m_meshMutex);
if (m_meshIsDirty) {
m_meshIsDirty = false;
meshChanged = true;
mesh = std::move(m_mesh);
}
}
if (!meshChanged)
return;
m_meshLineVertexCount = 0;
if (mesh) {
QOpenGLVertexArrayObject::Binder binder(&m_vertexArrayObject);
if (m_buffer.isCreated())
m_buffer.destroy();
m_buffer.create();
m_buffer.bind();
m_buffer.allocate(mesh->lineVertices(), mesh->lineVertexCount() * sizeof(MonochromeOpenGLVertex));
m_meshLineVertexCount = mesh->lineVertexCount();
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glEnableVertexAttribArray(0);
f->glEnableVertexAttribArray(1);
f->glEnableVertexAttribArray(2);
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), 0);
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
f->glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), reinterpret_cast<void *>(6 * sizeof(GLfloat)));
m_buffer.release();
}
}

View File

@ -0,0 +1,25 @@
#ifndef DUST3D_APPLICATION_MONOCHROME_OPENGL_OBJECT_H_
#define DUST3D_APPLICATION_MONOCHROME_OPENGL_OBJECT_H_
#include <memory>
#include <QMutex>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include "monochrome_mesh.h"
class MonochromeOpenGLObject
{
public:
void update(std::unique_ptr<MonochromeMesh> mesh);
void draw();
private:
void copyMeshToOpenGL();
QOpenGLVertexArrayObject m_vertexArrayObject;
QOpenGLBuffer m_buffer;
std::unique_ptr<MonochromeMesh> m_mesh;
bool m_meshIsDirty = false;
QMutex m_meshMutex;
int m_meshLineVertexCount = 0;
};
#endif

View File

@ -0,0 +1,60 @@
#include <QOpenGLFunctions>
#include <QFile>
#include <dust3d/base/debug.h>
#include "monochrome_opengl_program.h"
static const QString &loadShaderSource(const QString &name)
{
static std::map<QString, QString> s_shaderSources;
auto findShader = s_shaderSources.find(name);
if (findShader != s_shaderSources.end()) {
return findShader->second;
}
QFile file(name);
file.open(QFile::ReadOnly | QFile::Text);
QTextStream stream(&file);
auto insertResult = s_shaderSources.insert({name, stream.readAll()});
return insertResult.first->second;
}
void MonochromeOpenGLProgram::addShaderFromResource(QOpenGLShader::ShaderType type, const char *resourceName)
{
if (!addShaderFromSourceCode(type, loadShaderSource(resourceName)))
dust3dDebug << "Failed to addShaderFromResource, resource:" << resourceName << ", " << log().toStdString();
}
bool MonochromeOpenGLProgram::isCoreProfile() const
{
return m_isCoreProfile;
}
void MonochromeOpenGLProgram::load(bool isCoreProfile)
{
if (m_isLoaded)
return;
m_isCoreProfile = isCoreProfile;
if (m_isCoreProfile) {
addShaderFromResource(QOpenGLShader::Vertex, ":/shaders/monochrome_core.vert");
addShaderFromResource(QOpenGLShader::Fragment, ":/shaders/monochrome_core.frag");
} else {
addShaderFromResource(QOpenGLShader::Vertex, ":/shaders/monochrome.vert");
addShaderFromResource(QOpenGLShader::Fragment, ":/shaders/monochrome.frag");
}
bindAttributeLocation("vertex", 0);
bindAttributeLocation("color", 1);
bindAttributeLocation("alpha", 2);
link();
bind();
m_isLoaded = true;
}
int MonochromeOpenGLProgram::getUniformLocationByName(const std::string &name)
{
auto findLocation = m_uniformLocationMap.find(name);
if (findLocation != m_uniformLocationMap.end())
return findLocation->second;
int location = uniformLocation(name.c_str());
m_uniformLocationMap.insert({name, location});
return location;
}

View File

@ -0,0 +1,22 @@
#ifndef DUST3D_APPLICATION_MONOCHROME_OPENGL_PROGRAM_H_
#define DUST3D_APPLICATION_MONOCHROME_OPENGL_PROGRAM_H_
#include <QOpenGLShaderProgram>
#include <QOpenGLShader>
class MonochromeOpenGLProgram: public QOpenGLShaderProgram
{
public:
void load(bool isCoreProfile=false);
int getUniformLocationByName(const std::string &name);
bool isCoreProfile() const;
private:
void addShaderFromResource(QOpenGLShader::ShaderType type, const char *resourceName);
bool m_isLoaded = false;
bool m_isCoreProfile = false;
std::map<std::string, int> m_uniformLocationMap;
};
#endif

View File

@ -0,0 +1,20 @@
#ifndef DUST3D_APPLICATION_MONOCHROME_OPENGL_VERTEX_H_
#define DUST3D_APPLICATION_MONOCHROME_OPENGL_VERTEX_H_
#include <QOpenGLFunctions>
#pragma pack(push)
#pragma pack(1)
typedef struct
{
GLfloat posX;
GLfloat posY;
GLfloat posZ;
GLfloat colorR = 1.0;
GLfloat colorG = 1.0;
GLfloat colorB = 1.0;
GLfloat alpha = 1.0;
} MonochromeOpenGLVertex;
#pragma pack(pop)
#endif

View File

@ -2,7 +2,7 @@
#include "part_preview_images_generator.h" #include "part_preview_images_generator.h"
#include "theme.h" #include "theme.h"
void PartPreviewImagesGenerator::addPart(const dust3d::Uuid &partId, Model *previewMesh, bool isCutFace) void PartPreviewImagesGenerator::addPart(const dust3d::Uuid &partId, ModelMesh *previewMesh, bool isCutFace)
{ {
m_partPreviews.insert({partId, {previewMesh, isCutFace}}); m_partPreviews.insert({partId, {previewMesh, isCutFace}});
} }

View File

@ -18,7 +18,7 @@ public:
struct PreviewInput struct PreviewInput
{ {
Model *mesh = nullptr; ModelMesh *mesh = nullptr;
bool isCutFace = false; bool isCutFace = false;
}; };
@ -32,7 +32,7 @@ public:
delete m_offscreenRender; delete m_offscreenRender;
} }
void addPart(const dust3d::Uuid &partId, Model *previewMesh, bool isCutFace); void addPart(const dust3d::Uuid &partId, ModelMesh *previewMesh, bool isCutFace);
void generate(); void generate();
std::map<dust3d::Uuid, QImage> *takePartImages(); std::map<dust3d::Uuid, QImage> *takePartImages();
signals: signals:

View File

@ -15,7 +15,7 @@
#include <dust3d/base/part_base.h> #include <dust3d/base/part_base.h>
#include <dust3d/base/combine_mode.h> #include <dust3d/base/combine_mode.h>
#include "theme.h" #include "theme.h"
#include "model.h" #include "model_mesh.h"
#include "debug.h" #include "debug.h"
class SkeletonNode class SkeletonNode
@ -388,21 +388,21 @@ public:
smooth = other.smooth; smooth = other.smooth;
hollowThickness = other.hollowThickness; hollowThickness = other.hollowThickness;
} }
void updatePreviewMesh(Model *previewMesh) void updatePreviewMesh(ModelMesh *previewMesh)
{ {
delete m_previewMesh; delete m_previewMesh;
m_previewMesh = previewMesh; m_previewMesh = previewMesh;
isPreviewMeshObsolete = true; isPreviewMeshObsolete = true;
} }
Model *takePreviewMesh() const ModelMesh *takePreviewMesh() const
{ {
if (nullptr == m_previewMesh) if (nullptr == m_previewMesh)
return nullptr; return nullptr;
return new Model(*m_previewMesh); return new ModelMesh(*m_previewMesh);
} }
private: private:
Q_DISABLE_COPY(SkeletonPart); Q_DISABLE_COPY(SkeletonPart);
Model *m_previewMesh = nullptr; ModelMesh *m_previewMesh = nullptr;
}; };
enum class SkeletonDocumentEditMode enum class SkeletonDocumentEditMode

View File

@ -73,9 +73,9 @@ dust3d::Object *TextureGenerator::takeObject()
return object; return object;
} }
Model *TextureGenerator::takeResultMesh() ModelMesh *TextureGenerator::takeResultMesh()
{ {
Model *resultMesh = m_resultMesh; ModelMesh *resultMesh = m_resultMesh;
m_resultMesh = nullptr; m_resultMesh = nullptr;
return resultMesh; return resultMesh;
} }
@ -174,7 +174,7 @@ bool TextureGenerator::hasTransparencySettings()
void TextureGenerator::generate() void TextureGenerator::generate()
{ {
m_resultMesh = new Model(*m_object); m_resultMesh = new ModelMesh(*m_object);
if (nullptr == m_object->triangleVertexUvs()) if (nullptr == m_object->triangleVertexUvs())
return; return;

View File

@ -8,7 +8,7 @@
#include <QPixmap> #include <QPixmap>
#include <dust3d/base/object.h> #include <dust3d/base/object.h>
#include <dust3d/base/snapshot.h> #include <dust3d/base/snapshot.h>
#include "model.h" #include "model_mesh.h"
class TextureGenerator : public QObject class TextureGenerator : public QObject
{ {
@ -22,7 +22,7 @@ public:
QImage *takeResultTextureMetalnessImage(); QImage *takeResultTextureMetalnessImage();
QImage *takeResultTextureAmbientOcclusionImage(); QImage *takeResultTextureAmbientOcclusionImage();
dust3d::Object *takeObject(); dust3d::Object *takeObject();
Model *takeResultMesh(); ModelMesh *takeResultMesh();
bool hasTransparencySettings(); bool hasTransparencySettings();
void addPartColorMap(dust3d::Uuid partId, const QImage *image, float tileScale); void addPartColorMap(dust3d::Uuid partId, const QImage *image, float tileScale);
void addPartNormalMap(dust3d::Uuid partId, const QImage *image, float tileScale); void addPartNormalMap(dust3d::Uuid partId, const QImage *image, float tileScale);
@ -48,7 +48,7 @@ private:
QImage *m_resultTextureRoughnessImage = nullptr; QImage *m_resultTextureRoughnessImage = nullptr;
QImage *m_resultTextureMetalnessImage = nullptr; QImage *m_resultTextureMetalnessImage = nullptr;
QImage *m_resultTextureAmbientOcclusionImage = nullptr; QImage *m_resultTextureAmbientOcclusionImage = nullptr;
Model *m_resultMesh = nullptr; ModelMesh *m_resultMesh = nullptr;
std::map<dust3d::Uuid, std::pair<QImage, float>> m_partColorTextureMap; std::map<dust3d::Uuid, std::pair<QImage, float>> m_partColorTextureMap;
std::map<dust3d::Uuid, std::pair<QImage, float>> m_partNormalTextureMap; std::map<dust3d::Uuid, std::pair<QImage, float>> m_partNormalTextureMap;
std::map<dust3d::Uuid, std::pair<QImage, float>> m_partMetalnessTextureMap; std::map<dust3d::Uuid, std::pair<QImage, float>> m_partMetalnessTextureMap;