Use GL_LINES to show wireframe
parent
d512ec0f7e
commit
61869d89dd
|
@ -155,17 +155,24 @@ HEADERS += sources/mesh_generator.h
|
|||
SOURCES += sources/mesh_generator.cc
|
||||
HEADERS += sources/mesh_result_post_processor.h
|
||||
SOURCES += sources/mesh_result_post_processor.cc
|
||||
HEADERS += sources/model.h
|
||||
SOURCES += sources/model.cc
|
||||
HEADERS += sources/model_mesh.h
|
||||
SOURCES += sources/model_mesh.cc
|
||||
HEADERS += sources/model_offscreen_render.h
|
||||
SOURCES += sources/model_offscreen_render.cc
|
||||
HEADERS += sources/model_opengl_program.h
|
||||
SOURCES += sources/model_opengl_program.cc
|
||||
HEADERS += sources/model_opengl_object.h
|
||||
SOURCES += sources/model_opengl_object.cc
|
||||
HEADERS += sources/model_shader_vertex.h
|
||||
HEADERS += sources/model_opengl_vertex.h
|
||||
HEADERS += sources/model_widget.h
|
||||
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
|
||||
SOURCES += sources/part_preview_images_generator.cc
|
||||
HEADERS += sources/part_tree_widget.h
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
<file>shaders/model.frag</file>
|
||||
<file>shaders/model_core.vert</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_specular.dds</file>
|
||||
<file>resources/dust3d-vertical.png</file>
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
#version 110
|
||||
varying vec3 pointPosition;
|
||||
varying vec3 pointColor;
|
||||
varying float pointAlpha;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(pointColor, pointAlpha);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#version 330
|
||||
in vec3 pointColor;
|
||||
in float pointAlpha;
|
||||
out vec4 fragColor;
|
||||
void main()
|
||||
{
|
||||
fragColor = vec4(pointColor, pointAlpha);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -729,30 +729,38 @@ void Document::fromSnapshot(const dust3d::Snapshot &snapshot)
|
|||
emit uncheckAll();
|
||||
}
|
||||
|
||||
Model *Document::takeResultMesh()
|
||||
ModelMesh *Document::takeResultMesh()
|
||||
{
|
||||
if (nullptr == m_resultMesh)
|
||||
return nullptr;
|
||||
Model *resultMesh = new Model(*m_resultMesh);
|
||||
ModelMesh *resultMesh = new ModelMesh(*m_resultMesh);
|
||||
return resultMesh;
|
||||
}
|
||||
|
||||
MonochromeMesh *Document::takeWireframeMesh()
|
||||
{
|
||||
if (nullptr == m_wireframeMesh)
|
||||
return nullptr;
|
||||
return new MonochromeMesh(*m_wireframeMesh);
|
||||
}
|
||||
|
||||
bool Document::isMeshGenerationSucceed()
|
||||
{
|
||||
return m_isMeshGenerationSucceed;
|
||||
}
|
||||
|
||||
Model *Document::takeResultTextureMesh()
|
||||
ModelMesh *Document::takeResultTextureMesh()
|
||||
{
|
||||
if (nullptr == m_resultTextureMesh)
|
||||
return nullptr;
|
||||
Model *resultTextureMesh = new Model(*m_resultTextureMesh);
|
||||
ModelMesh *resultTextureMesh = new ModelMesh(*m_resultTextureMesh);
|
||||
return resultTextureMesh;
|
||||
}
|
||||
|
||||
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();
|
||||
bool isSuccessful = m_meshGenerator->isSuccessful();
|
||||
|
||||
|
@ -772,7 +780,7 @@ void Document::meshReady()
|
|||
for (auto &partId: m_meshGenerator->generatedPreviewPartIds()) {
|
||||
auto part = partMap.find(partId);
|
||||
if (part != partMap.end()) {
|
||||
Model *resultPartPreviewMesh = m_meshGenerator->takePartPreviewMesh(partId);
|
||||
ModelMesh *resultPartPreviewMesh = m_meshGenerator->takePartPreviewMesh(partId);
|
||||
part->second.updatePreviewMesh(resultPartPreviewMesh);
|
||||
partPreviewsChanged = true;
|
||||
}
|
||||
|
@ -1591,7 +1599,7 @@ void Document::materialPreviewsReady()
|
|||
for (const auto &materialId: m_materialPreviewsGenerator->generatedPreviewMaterialIds()) {
|
||||
auto material = materialMap.find(materialId);
|
||||
if (material != materialMap.end()) {
|
||||
Model *resultPartPreviewMesh = m_materialPreviewsGenerator->takePreview(materialId);
|
||||
ModelMesh *resultPartPreviewMesh = m_materialPreviewsGenerator->takePreview(materialId);
|
||||
material->second.updatePreviewMesh(resultPartPreviewMesh);
|
||||
emit materialPreviewChanged(materialId);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
#include <dust3d/base/snapshot.h>
|
||||
#include <dust3d/base/texture_type.h>
|
||||
#include <dust3d/base/combine_mode.h>
|
||||
#include "model.h"
|
||||
#include "model_mesh.h"
|
||||
#include "monochrome_mesh.h"
|
||||
#include "theme.h"
|
||||
#include "skeleton_document.h"
|
||||
#include "material_layer.h"
|
||||
|
@ -44,20 +45,20 @@ public:
|
|||
QString name;
|
||||
bool dirty = true;
|
||||
std::vector<MaterialLayer> layers;
|
||||
void updatePreviewMesh(Model *previewMesh)
|
||||
void updatePreviewMesh(ModelMesh *previewMesh)
|
||||
{
|
||||
delete m_previewMesh;
|
||||
m_previewMesh = previewMesh;
|
||||
}
|
||||
Model *takePreviewMesh() const
|
||||
ModelMesh *takePreviewMesh() const
|
||||
{
|
||||
if (nullptr == m_previewMesh)
|
||||
return nullptr;
|
||||
return new Model(*m_previewMesh);
|
||||
return new ModelMesh(*m_previewMesh);
|
||||
}
|
||||
private:
|
||||
Q_DISABLE_COPY(Material);
|
||||
Model *m_previewMesh = nullptr;
|
||||
ModelMesh *m_previewMesh = nullptr;
|
||||
};
|
||||
|
||||
enum class DocumentToSnapshotFor
|
||||
|
@ -133,8 +134,8 @@ public: // need initialize
|
|||
QImage *textureAmbientOcclusionImage = nullptr;
|
||||
QByteArray *textureAmbientOcclusionImageByteArray = nullptr;
|
||||
bool weldEnabled = true;
|
||||
float brushMetalness = Model::m_defaultMetalness;
|
||||
float brushRoughness = Model::m_defaultRoughness;
|
||||
float brushMetalness = ModelMesh::m_defaultMetalness;
|
||||
float brushRoughness = ModelMesh::m_defaultRoughness;
|
||||
public:
|
||||
Document();
|
||||
~Document();
|
||||
|
@ -160,11 +161,12 @@ public:
|
|||
};
|
||||
void addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSource source=SnapshotSource::Paste);
|
||||
const Material *findMaterial(dust3d::Uuid materialId) const;
|
||||
Model *takeResultMesh();
|
||||
Model *takePaintedMesh();
|
||||
ModelMesh *takeResultMesh();
|
||||
MonochromeMesh *takeWireframeMesh();
|
||||
ModelMesh *takePaintedMesh();
|
||||
bool isMeshGenerationSucceed();
|
||||
Model *takeResultTextureMesh();
|
||||
Model *takeResultRigWeightMesh();
|
||||
ModelMesh *takeResultTextureMesh();
|
||||
ModelMesh *takeResultRigWeightMesh();
|
||||
void updateTurnaround(const QImage &image);
|
||||
void clearTurnaround();
|
||||
void updateTextureImage(QImage *image);
|
||||
|
@ -239,7 +241,8 @@ private:
|
|||
|
||||
bool m_isResultMeshObsolete = false;
|
||||
MeshGenerator *m_meshGenerator = nullptr;
|
||||
Model *m_resultMesh = nullptr;
|
||||
ModelMesh *m_resultMesh = nullptr;
|
||||
std::unique_ptr<MonochromeMesh> m_wireframeMesh;
|
||||
bool m_isMeshGenerationSucceed = true;
|
||||
int m_batchChangeRefCount = 0;
|
||||
dust3d::Object *m_currentObject = nullptr;
|
||||
|
@ -248,7 +251,7 @@ private:
|
|||
bool m_isPostProcessResultObsolete = false;
|
||||
MeshResultPostProcessor *m_postProcessor = nullptr;
|
||||
dust3d::Object *m_postProcessedObject = new dust3d::Object;
|
||||
Model *m_resultTextureMesh = nullptr;
|
||||
ModelMesh *m_resultTextureMesh = nullptr;
|
||||
unsigned long long m_textureImageUpdateVersion = 0;
|
||||
bool m_smoothNormal = false;
|
||||
MaterialPreviewsGenerator *m_materialPreviewsGenerator = nullptr;
|
||||
|
|
|
@ -423,7 +423,7 @@ DocumentWindow::DocumentWindow()
|
|||
m_toggleColorAction = new QAction(tr("Toggle Color"), this);
|
||||
connect(m_toggleColorAction, &QAction::triggered, [&]() {
|
||||
m_modelRemoveColor = !m_modelRemoveColor;
|
||||
Model *mesh = nullptr;
|
||||
ModelMesh *mesh = nullptr;
|
||||
if (m_document->isMeshGenerating() ||
|
||||
m_document->isPostProcessing() ||
|
||||
m_document->isTextureGenerating()) {
|
||||
|
@ -738,6 +738,7 @@ DocumentWindow::DocumentWindow()
|
|||
if (m_modelRemoveColor && resultMesh)
|
||||
resultMesh->removeColor();
|
||||
m_modelRenderWidget->updateMesh(resultMesh);
|
||||
m_modelRenderWidget->updateWireframeMesh(m_document->takeWireframeMesh());
|
||||
});
|
||||
|
||||
connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::cursorChanged, [=]() {
|
||||
|
@ -1027,7 +1028,7 @@ void DocumentWindow::openPathAs(const QString &path, const QString &asName)
|
|||
QByteArray fileData = file.readAll();
|
||||
|
||||
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];
|
||||
qDebug() << "[" << i << "]item.name:" << item.name << "item.type:" << item.type;
|
||||
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];
|
||||
if (item.type == "model") {
|
||||
std::vector<std::uint8_t> data;
|
||||
|
@ -1124,7 +1125,7 @@ void DocumentWindow::exportObjResult()
|
|||
void DocumentWindow::exportObjToFilename(const QString &filename)
|
||||
{
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
Model *resultMesh = m_document->takeResultMesh();
|
||||
ModelMesh *resultMesh = m_document->takeResultMesh();
|
||||
if (nullptr != resultMesh) {
|
||||
resultMesh->exportAsObj(filename);
|
||||
delete resultMesh;
|
||||
|
@ -1534,13 +1535,13 @@ void DocumentWindow::updateRecentFileActions()
|
|||
{
|
||||
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]));
|
||||
m_recentFileActions[i]->setText(text);
|
||||
m_recentFileActions[i]->setData(files[i]);
|
||||
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_recentFileSeparatorAction->setVisible(files.size() > 0);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <QtCore/qbuffer.h>
|
||||
#include "glb_file.h"
|
||||
#include "version.h"
|
||||
#include "model.h"
|
||||
#include "model_mesh.h"
|
||||
|
||||
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);
|
||||
int textureIndex = 0;
|
||||
m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["baseColorTexture"]["index"] = textureIndex++;
|
||||
m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["metallicFactor"] = Model::m_defaultMetalness;
|
||||
m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["roughnessFactor"] = Model::m_defaultRoughness;
|
||||
m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["metallicFactor"] = ModelMesh::m_defaultMetalness;
|
||||
m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["roughnessFactor"] = ModelMesh::m_defaultRoughness;
|
||||
if (object.alphaEnabled)
|
||||
m_json["materials"][primitiveIndex]["alphaMode"] = "BLEND";
|
||||
if (normalImage) {
|
||||
|
|
|
@ -31,9 +31,9 @@ const std::set<dust3d::Uuid> &MaterialPreviewsGenerator::generatedPreviewMateria
|
|||
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;
|
||||
return resultMesh;
|
||||
}
|
||||
|
@ -102,9 +102,9 @@ void MaterialPreviewsGenerator::generate()
|
|||
}
|
||||
}
|
||||
textureGenerator->generate();
|
||||
Model *texturedResultMesh = textureGenerator->takeResultMesh();
|
||||
ModelMesh *texturedResultMesh = textureGenerator->takeResultMesh();
|
||||
if (nullptr != texturedResultMesh) {
|
||||
m_previews[material.first] = new Model(*texturedResultMesh);
|
||||
m_previews[material.first] = new ModelMesh(*texturedResultMesh);
|
||||
m_generatedMaterialIds.insert(material.first);
|
||||
delete texturedResultMesh;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <QObject>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "model.h"
|
||||
#include "model_mesh.h"
|
||||
#include "material_layer.h"
|
||||
|
||||
class MaterialPreviewsGenerator : public QObject
|
||||
|
@ -15,7 +15,7 @@ public:
|
|||
~MaterialPreviewsGenerator();
|
||||
void addMaterial(dust3d::Uuid materialId, const std::vector<MaterialLayer> &layers);
|
||||
const std::set<dust3d::Uuid> &generatedPreviewMaterialIds();
|
||||
Model *takePreview(dust3d::Uuid materialId);
|
||||
ModelMesh *takePreview(dust3d::Uuid materialId);
|
||||
void generate();
|
||||
signals:
|
||||
void finished();
|
||||
|
@ -23,7 +23,7 @@ public slots:
|
|||
void process();
|
||||
private:
|
||||
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;
|
||||
};
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ void MaterialWidget::updatePreview(dust3d::Uuid materialId)
|
|||
qDebug() << "Material not found:" << m_materialId;
|
||||
return;
|
||||
}
|
||||
Model *previewMesh = material->takePreviewMesh();
|
||||
ModelMesh *previewMesh = material->takePreviewMesh();
|
||||
m_previewWidget->updateMesh(previewMesh);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,9 @@ MeshGenerator::~MeshGenerator()
|
|||
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;
|
||||
return resultMesh;
|
||||
}
|
||||
|
@ -31,6 +31,11 @@ QImage *MeshGenerator::takePartPreviewImage(const dust3d::Uuid &partId)
|
|||
return image;
|
||||
}
|
||||
|
||||
MonochromeMesh *MeshGenerator::takeWireframeMesh()
|
||||
{
|
||||
return m_wireframeMesh.release();
|
||||
}
|
||||
|
||||
void MeshGenerator::process()
|
||||
{
|
||||
QElapsedTimer countTimeConsumed;
|
||||
|
@ -39,7 +44,7 @@ void MeshGenerator::process()
|
|||
generate();
|
||||
|
||||
if (nullptr != m_object)
|
||||
m_resultMesh = new Model(*m_object);
|
||||
m_resultMesh = new ModelMesh(*m_object);
|
||||
|
||||
for (const auto &partId: m_generatedPreviewImagePartIds) {
|
||||
auto it = m_generatedPartPreviews.find(partId);
|
||||
|
@ -51,7 +56,7 @@ void MeshGenerator::process()
|
|||
auto it = m_generatedPartPreviews.find(partId);
|
||||
if (it == m_generatedPartPreviews.end())
|
||||
continue;
|
||||
m_partPreviewMeshes[partId] = new Model(it->second.vertices,
|
||||
m_partPreviewMeshes[partId] = new ModelMesh(it->second.vertices,
|
||||
it->second.triangles,
|
||||
it->second.vertexNormals,
|
||||
it->second.color,
|
||||
|
@ -59,14 +64,17 @@ void MeshGenerator::process()
|
|||
it->second.roughness);
|
||||
}
|
||||
|
||||
if (nullptr != m_object)
|
||||
m_wireframeMesh = std::make_unique<MonochromeMesh>(*m_object);
|
||||
|
||||
qDebug() << "The mesh generation took" << countTimeConsumed.elapsed() << "milliseconds";
|
||||
|
||||
emit finished();
|
||||
}
|
||||
|
||||
Model *MeshGenerator::takeResultMesh()
|
||||
ModelMesh *MeshGenerator::takeResultMesh()
|
||||
{
|
||||
Model *resultMesh = m_resultMesh;
|
||||
ModelMesh *resultMesh = m_resultMesh;
|
||||
m_resultMesh = nullptr;
|
||||
return resultMesh;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
#ifndef DUST3D_APPLICATION_MESH_GENERATOR_H_
|
||||
#define DUST3D_APPLICATION_MESH_GENERATOR_H_
|
||||
|
||||
#include <memory>
|
||||
#include <QObject>
|
||||
#include <QImage>
|
||||
#include <dust3d/mesh/mesh_generator.h>
|
||||
#include "model.h"
|
||||
#include "model_mesh.h"
|
||||
#include "monochrome_mesh.h"
|
||||
|
||||
class MeshGenerator : public QObject, public dust3d::MeshGenerator
|
||||
{
|
||||
|
@ -12,17 +14,19 @@ class MeshGenerator : public QObject, public dust3d::MeshGenerator
|
|||
public:
|
||||
MeshGenerator(dust3d::Snapshot *snapshot);
|
||||
~MeshGenerator();
|
||||
Model *takeResultMesh();
|
||||
Model *takePartPreviewMesh(const dust3d::Uuid &partId);
|
||||
ModelMesh *takeResultMesh();
|
||||
ModelMesh *takePartPreviewMesh(const dust3d::Uuid &partId);
|
||||
QImage *takePartPreviewImage(const dust3d::Uuid &partId);
|
||||
MonochromeMesh *takeWireframeMesh();
|
||||
public slots:
|
||||
void process();
|
||||
signals:
|
||||
void finished();
|
||||
private:
|
||||
Model *m_resultMesh = nullptr;
|
||||
std::map<dust3d::Uuid, Model *> m_partPreviewMeshes;
|
||||
ModelMesh *m_resultMesh = nullptr;
|
||||
std::map<dust3d::Uuid, ModelMesh *> m_partPreviewMeshes;
|
||||
std::map<dust3d::Uuid, QImage *> m_partPreviewImages;
|
||||
std::unique_ptr<MonochromeMesh> m_wireframeMesh;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
#include <QTextStream>
|
||||
#include <QFile>
|
||||
#include <cmath>
|
||||
#include "model.h"
|
||||
#include "model_mesh.h"
|
||||
#include "version.h"
|
||||
|
||||
float Model::m_defaultMetalness = 0.0;
|
||||
float Model::m_defaultRoughness = 1.0;
|
||||
float ModelMesh::m_defaultMetalness = 0.0;
|
||||
float ModelMesh::m_defaultRoughness = 1.0;
|
||||
|
||||
Model::Model(const Model &mesh) :
|
||||
ModelMesh::ModelMesh(const ModelMesh &mesh) :
|
||||
m_triangleVertices(nullptr),
|
||||
m_triangleVertexCount(0),
|
||||
m_edgeVertices(nullptr),
|
||||
|
@ -17,21 +17,21 @@ Model::Model(const Model &mesh) :
|
|||
{
|
||||
if (nullptr != mesh.m_triangleVertices &&
|
||||
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;
|
||||
for (int i = 0; i < mesh.m_triangleVertexCount; i++)
|
||||
this->m_triangleVertices[i] = mesh.m_triangleVertices[i];
|
||||
}
|
||||
if (nullptr != mesh.m_edgeVertices &&
|
||||
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;
|
||||
for (int i = 0; i < mesh.m_edgeVertexCount; i++)
|
||||
this->m_edgeVertices[i] = mesh.m_edgeVertices[i];
|
||||
}
|
||||
if (nullptr != mesh.m_toolVertices &&
|
||||
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;
|
||||
for (int i = 0; i < mesh.m_toolVertexCount; i++)
|
||||
this->m_toolVertices[i] = mesh.m_toolVertices[i];
|
||||
|
@ -54,7 +54,7 @@ Model::Model(const Model &mesh) :
|
|||
this->m_meshId = mesh.meshId();
|
||||
}
|
||||
|
||||
void Model::removeColor()
|
||||
void ModelMesh::removeColor()
|
||||
{
|
||||
delete this->m_textureImage;
|
||||
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_triangleVertexCount(vertexNum),
|
||||
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 dust3d::Color &color,
|
||||
float metalness,
|
||||
float roughness)
|
||||
{
|
||||
m_triangleVertexCount = (int)triangles.size() * 3;
|
||||
m_triangleVertices = new ModelShaderVertex[m_triangleVertexCount];
|
||||
m_triangleVertices = new ModelOpenGLVertex[m_triangleVertexCount];
|
||||
int destIndex = 0;
|
||||
for (size_t i = 0; i < triangles.size(); ++i) {
|
||||
for (auto j = 0; j < 3; j++) {
|
||||
int vertexIndex = (int)triangles[i][j];
|
||||
const dust3d::Vector3 *srcVert = &vertices[vertexIndex];
|
||||
const dust3d::Vector3 *srcNormal = &(triangleVertexNormals)[i][j];
|
||||
ModelShaderVertex *dest = &m_triangleVertices[destIndex];
|
||||
ModelOpenGLVertex *dest = &m_triangleVertices[destIndex];
|
||||
dest->colorR = color.r();
|
||||
dest->colorG = color.g();
|
||||
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_triangleVertexCount(0),
|
||||
m_edgeVertices(nullptr),
|
||||
|
@ -141,7 +141,7 @@ Model::Model(dust3d::Object &object) :
|
|||
}
|
||||
|
||||
m_triangleVertexCount = (int)object.triangles.size() * 3;
|
||||
m_triangleVertices = new ModelShaderVertex[m_triangleVertexCount];
|
||||
m_triangleVertices = new ModelOpenGLVertex[m_triangleVertexCount];
|
||||
int destIndex = 0;
|
||||
const auto triangleVertexNormals = object.triangleVertexNormals();
|
||||
const auto triangleVertexUvs = object.triangleVertexUvs();
|
||||
|
@ -163,7 +163,7 @@ Model::Model(dust3d::Object &object) :
|
|||
const dust3d::Vector3 *srcTangent = &defaultTangent;
|
||||
if (triangleTangents)
|
||||
srcTangent = &(*triangleTangents)[i];
|
||||
ModelShaderVertex *dest = &m_triangleVertices[destIndex];
|
||||
ModelOpenGLVertex *dest = &m_triangleVertices[destIndex];
|
||||
dest->colorR = triangleColor->r();
|
||||
dest->colorG = triangleColor->g();
|
||||
dest->colorB = triangleColor->b();
|
||||
|
@ -196,7 +196,7 @@ Model::Model(dust3d::Object &object) :
|
|||
edgeCount += face.size();
|
||||
}
|
||||
m_edgeVertexCount = (int)edgeCount * 2;
|
||||
m_edgeVertices = new ModelShaderVertex[m_edgeVertexCount];
|
||||
m_edgeVertices = new ModelOpenGLVertex[m_edgeVertexCount];
|
||||
size_t edgeVertexIndex = 0;
|
||||
for (size_t faceIndex = 0; faceIndex < object.triangleAndQuads.size(); ++faceIndex) {
|
||||
const auto &face = object.triangleAndQuads[faceIndex];
|
||||
|
@ -204,8 +204,8 @@ Model::Model(dust3d::Object &object) :
|
|||
for (size_t x = 0; x < 2; ++x) {
|
||||
size_t sourceIndex = face[(i + x) % face.size()];
|
||||
const dust3d::Vector3 *srcVert = &object.vertices[sourceIndex];
|
||||
ModelShaderVertex *dest = &m_edgeVertices[edgeVertexIndex];
|
||||
memset(dest, 0, sizeof(ModelShaderVertex));
|
||||
ModelOpenGLVertex *dest = &m_edgeVertices[edgeVertexIndex];
|
||||
memset(dest, 0, sizeof(ModelOpenGLVertex));
|
||||
dest->colorR = 0.0;
|
||||
dest->colorG = 0.0;
|
||||
dest->colorB = 0.0;
|
||||
|
@ -221,7 +221,7 @@ Model::Model(dust3d::Object &object) :
|
|||
}
|
||||
}
|
||||
|
||||
Model::Model() :
|
||||
ModelMesh::ModelMesh() :
|
||||
m_triangleVertices(nullptr),
|
||||
m_triangleVertexCount(0),
|
||||
m_edgeVertices(nullptr),
|
||||
|
@ -230,7 +230,7 @@ Model::Model() :
|
|||
{
|
||||
}
|
||||
|
||||
Model::~Model()
|
||||
ModelMesh::~ModelMesh()
|
||||
{
|
||||
delete[] m_triangleVertices;
|
||||
m_triangleVertexCount = 0;
|
||||
|
@ -243,112 +243,112 @@ Model::~Model()
|
|||
delete m_metalnessRoughnessAmbientOcclusionImage;
|
||||
}
|
||||
|
||||
const std::vector<dust3d::Vector3> &Model::vertices()
|
||||
const std::vector<dust3d::Vector3> &ModelMesh::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;
|
||||
}
|
||||
|
||||
const std::vector<dust3d::Vector3> &Model::triangulatedVertices()
|
||||
const std::vector<dust3d::Vector3> &ModelMesh::triangulatedVertices()
|
||||
{
|
||||
return m_triangulatedVertices;
|
||||
}
|
||||
|
||||
ModelShaderVertex *Model::triangleVertices()
|
||||
ModelOpenGLVertex *ModelMesh::triangleVertices()
|
||||
{
|
||||
return m_triangleVertices;
|
||||
}
|
||||
|
||||
int Model::triangleVertexCount()
|
||||
int ModelMesh::triangleVertexCount()
|
||||
{
|
||||
return m_triangleVertexCount;
|
||||
}
|
||||
|
||||
ModelShaderVertex *Model::edgeVertices()
|
||||
ModelOpenGLVertex *ModelMesh::edgeVertices()
|
||||
{
|
||||
return m_edgeVertices;
|
||||
}
|
||||
|
||||
int Model::edgeVertexCount()
|
||||
int ModelMesh::edgeVertexCount()
|
||||
{
|
||||
return m_edgeVertexCount;
|
||||
}
|
||||
|
||||
ModelShaderVertex *Model::toolVertices()
|
||||
ModelOpenGLVertex *ModelMesh::toolVertices()
|
||||
{
|
||||
return m_toolVertices;
|
||||
}
|
||||
|
||||
int Model::toolVertexCount()
|
||||
int ModelMesh::toolVertexCount()
|
||||
{
|
||||
return m_toolVertexCount;
|
||||
}
|
||||
|
||||
void Model::setTextureImage(QImage *textureImage)
|
||||
void ModelMesh::setTextureImage(QImage *textureImage)
|
||||
{
|
||||
m_textureImage = textureImage;
|
||||
}
|
||||
|
||||
const QImage *Model::textureImage()
|
||||
const QImage *ModelMesh::textureImage()
|
||||
{
|
||||
return m_textureImage;
|
||||
}
|
||||
|
||||
void Model::setNormalMapImage(QImage *normalMapImage)
|
||||
void ModelMesh::setNormalMapImage(QImage *normalMapImage)
|
||||
{
|
||||
m_normalMapImage = normalMapImage;
|
||||
}
|
||||
|
||||
const QImage *Model::normalMapImage()
|
||||
const QImage *ModelMesh::normalMapImage()
|
||||
{
|
||||
return m_normalMapImage;
|
||||
}
|
||||
|
||||
const QImage *Model::metalnessRoughnessAmbientOcclusionImage()
|
||||
const QImage *ModelMesh::metalnessRoughnessAmbientOcclusionImage()
|
||||
{
|
||||
return m_metalnessRoughnessAmbientOcclusionImage;
|
||||
}
|
||||
|
||||
void Model::setMetalnessRoughnessAmbientOcclusionImage(QImage *image)
|
||||
void ModelMesh::setMetalnessRoughnessAmbientOcclusionImage(QImage *image)
|
||||
{
|
||||
m_metalnessRoughnessAmbientOcclusionImage = image;
|
||||
}
|
||||
|
||||
bool Model::hasMetalnessInImage()
|
||||
bool ModelMesh::hasMetalnessInImage()
|
||||
{
|
||||
return m_hasMetalnessInImage;
|
||||
}
|
||||
|
||||
void Model::setHasMetalnessInImage(bool hasInImage)
|
||||
void ModelMesh::setHasMetalnessInImage(bool hasInImage)
|
||||
{
|
||||
m_hasMetalnessInImage = hasInImage;
|
||||
}
|
||||
|
||||
bool Model::hasRoughnessInImage()
|
||||
bool ModelMesh::hasRoughnessInImage()
|
||||
{
|
||||
return m_hasRoughnessInImage;
|
||||
}
|
||||
|
||||
void Model::setHasRoughnessInImage(bool hasInImage)
|
||||
void ModelMesh::setHasRoughnessInImage(bool hasInImage)
|
||||
{
|
||||
m_hasRoughnessInImage = hasInImage;
|
||||
}
|
||||
|
||||
bool Model::hasAmbientOcclusionInImage()
|
||||
bool ModelMesh::hasAmbientOcclusionInImage()
|
||||
{
|
||||
return m_hasAmbientOcclusionInImage;
|
||||
}
|
||||
|
||||
void Model::setHasAmbientOcclusionInImage(bool hasInImage)
|
||||
void ModelMesh::setHasAmbientOcclusionInImage(bool hasInImage)
|
||||
{
|
||||
m_hasAmbientOcclusionInImage = hasInImage;
|
||||
}
|
||||
|
||||
void Model::exportAsObj(QTextStream *textStream)
|
||||
void ModelMesh::exportAsObj(QTextStream *textStream)
|
||||
{
|
||||
auto &stream = *textStream;
|
||||
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);
|
||||
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;
|
||||
m_toolVertices = nullptr;
|
||||
|
@ -384,7 +384,7 @@ void Model::updateTool(ModelShaderVertex *toolVertices, int vertexNum)
|
|||
m_toolVertexCount = vertexNum;
|
||||
}
|
||||
|
||||
void Model::updateEdges(ModelShaderVertex *edgeVertices, int edgeVertexCount)
|
||||
void ModelMesh::updateEdges(ModelOpenGLVertex *edgeVertices, int edgeVertexCount)
|
||||
{
|
||||
delete[] m_edgeVertices;
|
||||
m_edgeVertices = nullptr;
|
||||
|
@ -394,7 +394,7 @@ void Model::updateEdges(ModelShaderVertex *edgeVertices, int edgeVertexCount)
|
|||
m_edgeVertexCount = edgeVertexCount;
|
||||
}
|
||||
|
||||
void Model::updateTriangleVertices(ModelShaderVertex *triangleVertices, int triangleVertexCount)
|
||||
void ModelMesh::updateTriangleVertices(ModelOpenGLVertex *triangleVertices, int triangleVertexCount)
|
||||
{
|
||||
delete[] m_triangleVertices;
|
||||
m_triangleVertices = 0;
|
||||
|
@ -404,12 +404,12 @@ void Model::updateTriangleVertices(ModelShaderVertex *triangleVertices, int tria
|
|||
m_triangleVertexCount = triangleVertexCount;
|
||||
}
|
||||
|
||||
quint64 Model::meshId() const
|
||||
quint64 ModelMesh::meshId() const
|
||||
{
|
||||
return m_meshId;
|
||||
}
|
||||
|
||||
void Model::setMeshId(quint64 id)
|
||||
void ModelMesh::setMeshId(quint64 id)
|
||||
{
|
||||
m_meshId = id;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef DUST3D_APPLICATION_MODEL_H_
|
||||
#define DUST3D_APPLICATION_MODEL_H_
|
||||
#ifndef DUST3D_APPLICATION_MODEL_MESH_H_
|
||||
#define DUST3D_APPLICATION_MODEL_MESH_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <vector>
|
||||
|
@ -8,26 +8,26 @@
|
|||
#include <dust3d/base/vector3.h>
|
||||
#include <dust3d/base/color.h>
|
||||
#include <dust3d/base/object.h>
|
||||
#include "model_shader_vertex.h"
|
||||
#include "model_opengl_vertex.h"
|
||||
|
||||
class Model
|
||||
class ModelMesh
|
||||
{
|
||||
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 dust3d::Color &color=dust3d::Color::createWhite(),
|
||||
float metalness=0.0,
|
||||
float roughness=0.0);
|
||||
Model(dust3d::Object &object);
|
||||
Model(ModelShaderVertex *triangleVertices, int vertexNum, ModelShaderVertex *edgeVertices=nullptr, int edgeVertexCount=0);
|
||||
Model(const Model &mesh);
|
||||
Model();
|
||||
~Model();
|
||||
ModelShaderVertex *triangleVertices();
|
||||
ModelMesh(dust3d::Object &object);
|
||||
ModelMesh(ModelOpenGLVertex *triangleVertices, int vertexNum, ModelOpenGLVertex *edgeVertices=nullptr, int edgeVertexCount=0);
|
||||
ModelMesh(const ModelMesh &mesh);
|
||||
ModelMesh();
|
||||
~ModelMesh();
|
||||
ModelOpenGLVertex *triangleVertices();
|
||||
int triangleVertexCount();
|
||||
ModelShaderVertex *edgeVertices();
|
||||
ModelOpenGLVertex *edgeVertices();
|
||||
int edgeVertexCount();
|
||||
ModelShaderVertex *toolVertices();
|
||||
ModelOpenGLVertex *toolVertices();
|
||||
int toolVertexCount();
|
||||
const std::vector<dust3d::Vector3> &vertices();
|
||||
const std::vector<std::vector<size_t>> &faces();
|
||||
|
@ -48,18 +48,18 @@ public:
|
|||
static float m_defaultRoughness;
|
||||
void exportAsObj(const QString &filename);
|
||||
void exportAsObj(QTextStream *textStream);
|
||||
void updateTool(ModelShaderVertex *toolVertices, int vertexNum);
|
||||
void updateEdges(ModelShaderVertex *edgeVertices, int edgeVertexCount);
|
||||
void updateTriangleVertices(ModelShaderVertex *triangleVertices, int triangleVertexCount);
|
||||
void updateTool(ModelOpenGLVertex *toolVertices, int vertexNum);
|
||||
void updateEdges(ModelOpenGLVertex *edgeVertices, int edgeVertexCount);
|
||||
void updateTriangleVertices(ModelOpenGLVertex *triangleVertices, int triangleVertexCount);
|
||||
quint64 meshId() const;
|
||||
void setMeshId(quint64 id);
|
||||
void removeColor();
|
||||
private:
|
||||
ModelShaderVertex *m_triangleVertices = nullptr;
|
||||
ModelOpenGLVertex *m_triangleVertices = nullptr;
|
||||
int m_triangleVertexCount = 0;
|
||||
ModelShaderVertex *m_edgeVertices = nullptr;
|
||||
ModelOpenGLVertex *m_edgeVertices = nullptr;
|
||||
int m_edgeVertexCount = 0;
|
||||
ModelShaderVertex *m_toolVertices = nullptr;
|
||||
ModelOpenGLVertex *m_toolVertices = nullptr;
|
||||
int m_toolVertexCount = 0;
|
||||
std::vector<dust3d::Vector3> m_vertices;
|
||||
std::vector<std::vector<size_t>> m_faces;
|
|
@ -40,7 +40,7 @@ void ModelOffscreenRender::setRenderThread(QThread *thread)
|
|||
// TODO
|
||||
}
|
||||
|
||||
void ModelOffscreenRender::updateMesh(Model *mesh)
|
||||
void ModelOffscreenRender::updateMesh(ModelMesh *mesh)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <QOffscreenSurface>
|
||||
#include <QSurfaceFormat>
|
||||
#include <QVector3D>
|
||||
#include "model.h"
|
||||
#include "model_mesh.h"
|
||||
|
||||
class ModelOffscreenRender: public QOffscreenSurface
|
||||
{
|
||||
|
@ -17,7 +17,7 @@ public:
|
|||
void setEyePosition(const QVector3D &eyePosition);
|
||||
void setMoveToPosition(const QVector3D &moveToPosition);
|
||||
void setRenderThread(QThread *thread);
|
||||
void updateMesh(Model *mesh);
|
||||
void updateMesh(ModelMesh *mesh);
|
||||
QImage toImage(const QSize &size);
|
||||
};
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <QOpenGLContext>
|
||||
#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);
|
||||
m_mesh = std::move(mesh);
|
||||
|
@ -22,7 +22,7 @@ void ModelOpenGLObject::draw()
|
|||
|
||||
void ModelOpenGLObject::copyMeshToOpenGL()
|
||||
{
|
||||
std::unique_ptr<Model> mesh;
|
||||
std::unique_ptr<ModelMesh> mesh;
|
||||
bool meshChanged = false;
|
||||
if (m_meshIsDirty) {
|
||||
QMutexLocker lock(&m_meshMutex);
|
||||
|
@ -41,7 +41,7 @@ void ModelOpenGLObject::copyMeshToOpenGL()
|
|||
m_buffer.destroy();
|
||||
m_buffer.create();
|
||||
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();
|
||||
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
||||
f->glEnableVertexAttribArray(0);
|
||||
|
@ -52,14 +52,14 @@ void ModelOpenGLObject::copyMeshToOpenGL()
|
|||
f->glEnableVertexAttribArray(5);
|
||||
f->glEnableVertexAttribArray(6);
|
||||
f->glEnableVertexAttribArray(7);
|
||||
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ModelShaderVertex), 0);
|
||||
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(ModelShaderVertex), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ModelShaderVertex), reinterpret_cast<void *>(6 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(ModelShaderVertex), reinterpret_cast<void *>(9 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(ModelShaderVertex), reinterpret_cast<void *>(11 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(ModelShaderVertex), reinterpret_cast<void *>(12 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ModelShaderVertex), reinterpret_cast<void *>(13 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(ModelShaderVertex), reinterpret_cast<void *>(16 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), 0);
|
||||
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(ModelOpenGLVertex), reinterpret_cast<void *>(6 * 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(ModelOpenGLVertex), reinterpret_cast<void *>(11 * 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(ModelOpenGLVertex), reinterpret_cast<void *>(13 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void *>(16 * sizeof(GLfloat)));
|
||||
m_buffer.release();
|
||||
}
|
||||
}
|
|
@ -5,18 +5,18 @@
|
|||
#include <QMutex>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
#include <QOpenGLBuffer>
|
||||
#include "model.h"
|
||||
#include "model_mesh.h"
|
||||
|
||||
class ModelOpenGLObject
|
||||
{
|
||||
public:
|
||||
void update(std::unique_ptr<Model> mesh);
|
||||
void update(std::unique_ptr<ModelMesh> mesh);
|
||||
void draw();
|
||||
private:
|
||||
void copyMeshToOpenGL();
|
||||
QOpenGLVertexArrayObject m_vertexArrayObject;
|
||||
QOpenGLBuffer m_buffer;
|
||||
std::unique_ptr<Model> m_mesh;
|
||||
std::unique_ptr<ModelMesh> m_mesh;
|
||||
bool m_meshIsDirty = false;
|
||||
QMutex m_meshMutex;
|
||||
int m_meshTriangleVertexCount = 0;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef DUST3D_APPLICATION_MODEL_SHADER_VERTEX_H_
|
||||
#define DUST3D_APPLICATION_MODEL_SHADER_VERTEX_H_
|
||||
#ifndef DUST3D_APPLICATION_MODEL_OPENGL_VERTEX_H_
|
||||
#define DUST3D_APPLICATION_MODEL_OPENGL_VERTEX_H_
|
||||
|
||||
#include <QOpenGLFunctions>
|
||||
|
||||
|
@ -24,7 +24,7 @@ typedef struct
|
|||
GLfloat tangentY;
|
||||
GLfloat tangentZ;
|
||||
GLfloat alpha = 1.0;
|
||||
} ModelShaderVertex;
|
||||
} ModelOpenGLVertex;
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
|
@ -115,11 +115,11 @@ void ModelWidget::setZRotation(int angle)
|
|||
|
||||
void ModelWidget::cleanup()
|
||||
{
|
||||
if (!m_openGLProgram)
|
||||
if (!m_modelOpenGLProgram)
|
||||
return;
|
||||
makeCurrent();
|
||||
m_openGLObject.reset();
|
||||
m_openGLProgram.reset();
|
||||
m_modelOpenGLObject.reset();
|
||||
m_modelOpenGLProgram.reset();
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
|
@ -163,13 +163,13 @@ std::pair<QVector3D, QVector3D> ModelWidget::screenPositionToMouseRay(const QPoi
|
|||
|
||||
void ModelWidget::toggleWireframe()
|
||||
{
|
||||
// TODO
|
||||
m_isWireframeVisible = !m_isWireframeVisible;
|
||||
update();
|
||||
}
|
||||
|
||||
bool ModelWidget::isWireframeVisible()
|
||||
{
|
||||
// TODO
|
||||
return false;
|
||||
return m_isWireframeVisible;
|
||||
}
|
||||
|
||||
void ModelWidget::enableEnvironmentLight()
|
||||
|
@ -367,11 +367,20 @@ void ModelWidget::setMousePickRadius(float radius)
|
|||
update();
|
||||
}
|
||||
|
||||
void ModelWidget::updateMesh(Model *mesh)
|
||||
void ModelWidget::updateMesh(ModelMesh *mesh)
|
||||
{
|
||||
if (!m_openGLObject)
|
||||
m_openGLObject = std::make_unique<ModelOpenGLObject>();
|
||||
m_openGLObject->update(std::unique_ptr<Model>(mesh));
|
||||
if (!m_modelOpenGLObject)
|
||||
m_modelOpenGLObject = std::make_unique<ModelOpenGLObject>();
|
||||
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();
|
||||
update();
|
||||
}
|
||||
|
@ -481,20 +490,48 @@ void ModelWidget::paintGL()
|
|||
m_camera.setToIdentity();
|
||||
m_camera.translate(m_eyePosition.x(), m_eyePosition.y(), m_eyePosition.z());
|
||||
|
||||
if (!m_openGLProgram) {
|
||||
m_openGLProgram = std::make_unique<ModelOpenGLProgram>();
|
||||
m_openGLProgram->load(format().profile() == QSurfaceFormat::CoreProfile);
|
||||
if (!m_modelOpenGLProgram) {
|
||||
m_modelOpenGLProgram = std::make_unique<ModelOpenGLProgram>();
|
||||
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);
|
||||
m_openGLProgram->setUniformValue(m_openGLProgram->getUniformLocationByName("projectionMatrix"), m_projection);
|
||||
m_openGLProgram->setUniformValue(m_openGLProgram->getUniformLocationByName("modelMatrix"), m_world);
|
||||
m_openGLProgram->setUniformValue(m_openGLProgram->getUniformLocationByName("viewMatrix"), m_camera);
|
||||
drawModel();
|
||||
if (m_isWireframeVisible)
|
||||
drawWireframe();
|
||||
}
|
||||
|
||||
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_openGLProgram->isCoreProfile()) {
|
||||
if (m_modelOpenGLProgram->isCoreProfile()) {
|
||||
if (!m_environmentIrradianceMap) {
|
||||
DdsFileReader irradianceFile(":/resources/cedar_bridge_irradiance.dds");
|
||||
m_environmentIrradianceMap.reset(irradianceFile.createOpenGLTexture());
|
||||
|
@ -505,10 +542,10 @@ void ModelWidget::paintGL()
|
|||
}
|
||||
|
||||
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_openGLProgram->setUniformValue(m_openGLProgram->getUniformLocationByName("environmentSpecularMapId"), 1);
|
||||
m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("environmentSpecularMapId"), 1);
|
||||
} else {
|
||||
if (!m_environmentIrradianceMaps) {
|
||||
DdsFileReader irradianceFile(":/resources/cedar_bridge_irradiance.dds");
|
||||
|
@ -529,14 +566,14 @@ void ModelWidget::paintGL()
|
|||
|
||||
bindPosition = 0;
|
||||
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)
|
||||
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)
|
||||
m_openGLObject->draw();
|
||||
if (m_modelOpenGLObject)
|
||||
m_modelOpenGLObject->draw();
|
||||
|
||||
m_openGLProgram->release();
|
||||
m_modelOpenGLProgram->release();
|
||||
}
|
||||
|
|
|
@ -10,9 +10,12 @@
|
|||
#include <QVector2D>
|
||||
#include <QTimer>
|
||||
#include <QString>
|
||||
#include "model.h"
|
||||
#include "model_mesh.h"
|
||||
#include "model_opengl_program.h"
|
||||
#include "model_opengl_object.h"
|
||||
#include "monochrome_mesh.h"
|
||||
#include "monochrome_opengl_program.h"
|
||||
#include "monochrome_opengl_object.h"
|
||||
|
||||
class ModelWidget : public QOpenGLWidget
|
||||
{
|
||||
|
@ -31,7 +34,8 @@ signals:
|
|||
public:
|
||||
ModelWidget(QWidget *parent = 0);
|
||||
~ModelWidget();
|
||||
void updateMesh(Model *mesh);
|
||||
void updateMesh(ModelMesh *mesh);
|
||||
void updateWireframeMesh(MonochromeMesh *mesh);
|
||||
void updateColorTexture(QImage *colorTextureImage);
|
||||
void toggleWireframe();
|
||||
bool isWireframeVisible();
|
||||
|
@ -82,8 +86,10 @@ private:
|
|||
int m_yRot = m_defaultYRotation;
|
||||
int m_zRot = m_defaultZRotation;
|
||||
int m_directionOnMoveStart = 0;
|
||||
std::unique_ptr<ModelOpenGLProgram> m_openGLProgram;
|
||||
std::unique_ptr<ModelOpenGLObject> m_openGLObject;
|
||||
std::unique_ptr<ModelOpenGLProgram> m_modelOpenGLProgram;
|
||||
std::unique_ptr<ModelOpenGLObject> m_modelOpenGLObject;
|
||||
std::unique_ptr<MonochromeOpenGLProgram> m_monochromeOpenGLProgram;
|
||||
std::unique_ptr<MonochromeOpenGLObject> m_wireframeOpenGLObject;
|
||||
bool m_moveStarted = false;
|
||||
bool m_moveEnabled = true;
|
||||
bool m_zoomEnabled = true;
|
||||
|
@ -108,6 +114,7 @@ private:
|
|||
bool m_enableCullFace = true;
|
||||
bool m_notGraphics = false;
|
||||
bool m_isEnvironmentLightEnabled = false;
|
||||
bool m_isWireframeVisible = false;
|
||||
std::unique_ptr<QOpenGLTexture> m_environmentIrradianceMap;
|
||||
std::unique_ptr<QOpenGLTexture> m_environmentSpecularMap;
|
||||
std::unique_ptr<std::vector<std::unique_ptr<QOpenGLTexture>>> m_environmentIrradianceMaps;
|
||||
|
@ -116,6 +123,8 @@ private:
|
|||
std::pair<QVector3D, QVector3D> screenPositionToMouseRay(const QPoint &screenPosition);
|
||||
void updateProjectionMatrix();
|
||||
void normalizeAngle(int &angle);
|
||||
void drawModel();
|
||||
void drawWireframe();
|
||||
public:
|
||||
static int m_defaultXRotation;
|
||||
static int m_defaultYRotation;
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -2,7 +2,7 @@
|
|||
#include "part_preview_images_generator.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}});
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ public:
|
|||
|
||||
struct PreviewInput
|
||||
{
|
||||
Model *mesh = nullptr;
|
||||
ModelMesh *mesh = nullptr;
|
||||
bool isCutFace = false;
|
||||
};
|
||||
|
||||
|
@ -32,7 +32,7 @@ public:
|
|||
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();
|
||||
std::map<dust3d::Uuid, QImage> *takePartImages();
|
||||
signals:
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include <dust3d/base/part_base.h>
|
||||
#include <dust3d/base/combine_mode.h>
|
||||
#include "theme.h"
|
||||
#include "model.h"
|
||||
#include "model_mesh.h"
|
||||
#include "debug.h"
|
||||
|
||||
class SkeletonNode
|
||||
|
@ -388,21 +388,21 @@ public:
|
|||
smooth = other.smooth;
|
||||
hollowThickness = other.hollowThickness;
|
||||
}
|
||||
void updatePreviewMesh(Model *previewMesh)
|
||||
void updatePreviewMesh(ModelMesh *previewMesh)
|
||||
{
|
||||
delete m_previewMesh;
|
||||
m_previewMesh = previewMesh;
|
||||
isPreviewMeshObsolete = true;
|
||||
}
|
||||
Model *takePreviewMesh() const
|
||||
ModelMesh *takePreviewMesh() const
|
||||
{
|
||||
if (nullptr == m_previewMesh)
|
||||
return nullptr;
|
||||
return new Model(*m_previewMesh);
|
||||
return new ModelMesh(*m_previewMesh);
|
||||
}
|
||||
private:
|
||||
Q_DISABLE_COPY(SkeletonPart);
|
||||
Model *m_previewMesh = nullptr;
|
||||
ModelMesh *m_previewMesh = nullptr;
|
||||
};
|
||||
|
||||
enum class SkeletonDocumentEditMode
|
||||
|
|
|
@ -73,9 +73,9 @@ dust3d::Object *TextureGenerator::takeObject()
|
|||
return object;
|
||||
}
|
||||
|
||||
Model *TextureGenerator::takeResultMesh()
|
||||
ModelMesh *TextureGenerator::takeResultMesh()
|
||||
{
|
||||
Model *resultMesh = m_resultMesh;
|
||||
ModelMesh *resultMesh = m_resultMesh;
|
||||
m_resultMesh = nullptr;
|
||||
return resultMesh;
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ bool TextureGenerator::hasTransparencySettings()
|
|||
|
||||
void TextureGenerator::generate()
|
||||
{
|
||||
m_resultMesh = new Model(*m_object);
|
||||
m_resultMesh = new ModelMesh(*m_object);
|
||||
|
||||
if (nullptr == m_object->triangleVertexUvs())
|
||||
return;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <QPixmap>
|
||||
#include <dust3d/base/object.h>
|
||||
#include <dust3d/base/snapshot.h>
|
||||
#include "model.h"
|
||||
#include "model_mesh.h"
|
||||
|
||||
class TextureGenerator : public QObject
|
||||
{
|
||||
|
@ -22,7 +22,7 @@ public:
|
|||
QImage *takeResultTextureMetalnessImage();
|
||||
QImage *takeResultTextureAmbientOcclusionImage();
|
||||
dust3d::Object *takeObject();
|
||||
Model *takeResultMesh();
|
||||
ModelMesh *takeResultMesh();
|
||||
bool hasTransparencySettings();
|
||||
void addPartColorMap(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_resultTextureMetalnessImage = 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_partNormalTextureMap;
|
||||
std::map<dust3d::Uuid, std::pair<QImage, float>> m_partMetalnessTextureMap;
|
||||
|
|
Loading…
Reference in New Issue