8.17会议存档
parent
b37e5a0ee7
commit
1476da4cf8
|
@ -89,6 +89,7 @@
|
||||||
<ClCompile Include="Camera.cpp" />
|
<ClCompile Include="Camera.cpp" />
|
||||||
<ClCompile Include="Mesh.cpp" />
|
<ClCompile Include="Mesh.cpp" />
|
||||||
<ClCompile Include="Model.cpp" />
|
<ClCompile Include="Model.cpp" />
|
||||||
|
<ClCompile Include="PaintingHelper.cpp" />
|
||||||
<ClCompile Include="PaintingMesh.cpp" />
|
<ClCompile Include="PaintingMesh.cpp" />
|
||||||
<ClCompile Include="RendererWidget.cpp" />
|
<ClCompile Include="RendererWidget.cpp" />
|
||||||
<QtRcc Include="MainWindow.qrc" />
|
<QtRcc Include="MainWindow.qrc" />
|
||||||
|
@ -117,6 +118,7 @@
|
||||||
<ClInclude Include="Drawable.h" />
|
<ClInclude Include="Drawable.h" />
|
||||||
<ClInclude Include="Mesh.h" />
|
<ClInclude Include="Mesh.h" />
|
||||||
<ClInclude Include="Model.h" />
|
<ClInclude Include="Model.h" />
|
||||||
|
<ClInclude Include="PaintingHelper.h" />
|
||||||
<ClInclude Include="PaintingMesh.h" />
|
<ClInclude Include="PaintingMesh.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
|
|
@ -61,6 +61,9 @@
|
||||||
<ClCompile Include="BvhTree.cpp">
|
<ClCompile Include="BvhTree.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="PaintingHelper.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<QtMoc Include="RendererWidget.h">
|
<QtMoc Include="RendererWidget.h">
|
||||||
|
@ -115,5 +118,8 @@
|
||||||
<ClInclude Include="BvhTree.h">
|
<ClInclude Include="BvhTree.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="PaintingHelper.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -14,11 +14,12 @@ Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shader
|
||||||
, shaderProgram(shaderProgram)
|
, shaderProgram(shaderProgram)
|
||||||
, directory(path)
|
, directory(path)
|
||||||
{
|
{
|
||||||
Assimp::Importer import;
|
|
||||||
const aiScene* scene = import.ReadFile(directory.absolutePath().toUtf8(), aiProcess_Triangulate | aiProcess_FlipUVs);
|
Assimp::Importer importer;
|
||||||
|
const aiScene* scene = importer.ReadFile(directory.absolutePath().toUtf8(), aiProcess_Triangulate | aiProcess_FlipUVs);
|
||||||
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||||
{
|
{
|
||||||
qDebug() << "ERROR::ASSIMP::" << import.GetErrorString() << endl;
|
qDebug() << "ERROR::ASSIMP::" << importer.GetErrorString() << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qDebug() << directory.absolutePath() << "Loaded Successfully";
|
qDebug() << directory.absolutePath() << "Loaded Successfully";
|
||||||
|
@ -29,18 +30,19 @@ Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shader
|
||||||
processNode(scene->mRootNode, scene);
|
processNode(scene->mRootNode, scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram)
|
Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram, PaintingHelper* paintingHelper)
|
||||||
: context(context)
|
: context(context)
|
||||||
, glFunc(context->versionFunctions<QOpenGLFunctions_4_5_Compatibility>())
|
, glFunc(context->versionFunctions<QOpenGLFunctions_4_5_Compatibility>())
|
||||||
, shaderProgram(shaderProgram)
|
, shaderProgram(shaderProgram)
|
||||||
, paintingProgram(paintingProgram)
|
, paintingProgram(paintingProgram)
|
||||||
|
, paintingHelper(paintingHelper)
|
||||||
, directory(path)
|
, directory(path)
|
||||||
{
|
{
|
||||||
Assimp::Importer import;
|
Assimp::Importer importer;
|
||||||
const aiScene* scene = import.ReadFile(directory.absolutePath().toUtf8(), aiProcess_Triangulate | aiProcess_FlipUVs);
|
const aiScene* scene = importer.ReadFile(directory.absolutePath().toUtf8(), aiProcess_Triangulate | aiProcess_FlipUVs);
|
||||||
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||||
{
|
{
|
||||||
qDebug() << "ERROR::ASSIMP::" << import.GetErrorString() << endl;
|
qDebug() << "ERROR::ASSIMP::" << importer.GetErrorString() << endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qDebug() << directory.absolutePath() << "Loaded Successfully";
|
qDebug() << directory.absolutePath() << "Loaded Successfully";
|
||||||
|
@ -139,21 +141,39 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BvhTree bvhTree;
|
||||||
|
std::vector<QVector4D> initBound;
|
||||||
|
for (int i = 0; i < 30000; i++)
|
||||||
|
{
|
||||||
|
float x = (float)rand() / RAND_MAX * 2 - 1;
|
||||||
|
float y = (float)rand() / RAND_MAX * 2 - 1;
|
||||||
|
float z = 0.01 + x;//(float)rand() / RAND_MAX * (0.1) + x;
|
||||||
|
float w = 0.01 + y;//(float)rand() / RAND_MAX * (0.1) + y;
|
||||||
|
initBound.push_back(QVector4D(x, y, z, w));
|
||||||
|
}
|
||||||
|
/* initBound.push_back(QVector4D(-0.8, -0.8, -0.7, -0.7));
|
||||||
|
initBound.push_back(QVector4D(-0.8, 0.7, -0.7, 0.8));
|
||||||
|
initBound.push_back(QVector4D(0.7, -0.8, 0.8, -0.7));
|
||||||
|
initBound.push_back(QVector4D(0.7, 0.7, 0.8, 0.8));*/
|
||||||
|
bvhTree.buildBvhTree(initBound.data(), initBound.size());
|
||||||
|
std::vector<GLuint> children;
|
||||||
|
std::vector<QVector4D> bounds;
|
||||||
|
bvhTree.getBvhArray(children, bounds);
|
||||||
|
|
||||||
GLuint bvhChildren[] = { 7/*rootBVH长度*/,0/*与显存对齐*/,
|
std::vector<GLuint> bvhChildren = {
|
||||||
//root
|
//root
|
||||||
1,2,
|
1,2,
|
||||||
3,4, 5,6,
|
3,4, 5,6,
|
||||||
7,0, 7,30. / 360 * 65536 + 1 * 65536 /*右儿子用来表示旋转角度和层数*/, 8,0, 7,0,
|
7,0, 7,GLuint(30. / 360 * 65536 + 1 * 65536) /*右儿子用来表示旋转角度和zIndex*/, 8,0, 7,0,
|
||||||
//elememt0
|
//elememt0
|
||||||
1,2,
|
1,2,
|
||||||
5 + 28/*contour索引,由于contour不定长,这里需要给到contour在elementIndex中位置*/,5 + 12/*style索引,在elementData中位置*/, 3,4,
|
5 + 0/*contour索引*/,5 + 12/*style索引,在elementData中位置*/, 3,4,
|
||||||
5 + 36,5 + 12, 5 + 32,5 + 12,
|
5 + 2,5 + 12, 5 + 1,5 + 12,
|
||||||
//elememt1
|
//elememt1
|
||||||
1 + 0/*line索引,element中第几条*/,1 + 25
|
1 + 0/*line索引,element中第几条*/,1 + 25
|
||||||
|
|
||||||
};
|
};
|
||||||
QVector4D bvhBound[] = {
|
std::vector<QVector4D> bvhBounds = {
|
||||||
//root
|
//root
|
||||||
QVector4D(-1,-1,1,1),
|
QVector4D(-1,-1,1,1),
|
||||||
QVector4D(-0.9,-0.9,-0.1,0.9), QVector4D(0.1, -0.9,0.9,0.9),
|
QVector4D(-0.9,-0.9,-0.1,0.9), QVector4D(0.1, -0.9,0.9,0.9),
|
||||||
|
@ -165,56 +185,22 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
||||||
//elememt1
|
//elememt1
|
||||||
QVector4D(-1,0,1,1),
|
QVector4D(-1,0,1,1),
|
||||||
};
|
};
|
||||||
|
std::vector<GLuint> elementOffset = {
|
||||||
BvhTree bvhTree;
|
|
||||||
std::vector<QVector4D> initBound;
|
|
||||||
for (int i = 0; i < 2000; i++)
|
|
||||||
{
|
|
||||||
float x = (float)rand() / RAND_MAX * 2 - 1;
|
|
||||||
float y = (float)rand() / RAND_MAX * 2 - 1;
|
|
||||||
float z = 0.1+x;//(float)rand() / RAND_MAX * (0.1) + x;
|
|
||||||
float w = 0.1+y;//(float)rand() / RAND_MAX * (0.1) + y;
|
|
||||||
initBound.push_back(QVector4D(x,y,z,w));
|
|
||||||
}
|
|
||||||
/* initBound.push_back(QVector4D(-0.8, -0.8, -0.7, -0.7));
|
|
||||||
initBound.push_back(QVector4D(-0.8, 0.7, -0.7, 0.8));
|
|
||||||
initBound.push_back(QVector4D(0.7, -0.8, 0.8, -0.7));
|
|
||||||
initBound.push_back(QVector4D(0.7, 0.7, 0.8, 0.8));*/
|
|
||||||
bvhTree.buildBvhTree(initBound.data(), initBound.size());
|
|
||||||
std::vector<GLuint> children;
|
|
||||||
std::vector<QVector4D> bounds;
|
|
||||||
bvhTree.getBvhArray(children, bounds);
|
|
||||||
qDebug() << children;
|
|
||||||
qDebug() << bounds;
|
|
||||||
|
|
||||||
glFunc->glGenBuffers(1, &m_mesh->bvhSSBO);
|
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->bvhSSBO);
|
|
||||||
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, children.size()*sizeof(GLuint), children.data(), GL_DYNAMIC_DRAW);
|
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
|
||||||
|
|
||||||
glFunc->glGenBuffers(1, &m_mesh->bvhBoundSSBO);
|
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->bvhBoundSSBO);
|
|
||||||
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, bounds.size()*sizeof(QVector4D), bounds.data(), GL_DYNAMIC_DRAW);
|
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
|
||||||
|
|
||||||
GLuint elementOffset[] = {
|
|
||||||
//element0
|
//element0
|
||||||
7, //elementBvhRoot
|
7, //elementBvhRoot
|
||||||
5, //elementBvhLength
|
5, //elementBvhLength
|
||||||
0, //pointsOffset
|
0, //pointsOffset
|
||||||
0, //linesOffset
|
0, //linesOffset
|
||||||
|
28, //contoursOffset
|
||||||
//element1
|
//element1
|
||||||
12, //elementBvhRoot
|
12, //elementBvhRoot
|
||||||
1, //elementBvhLength
|
1, //elementBvhLength
|
||||||
19, //pointsOffset
|
19, //pointsOffset
|
||||||
40, //linesOffset
|
40, //linesOffset
|
||||||
|
44 //contoursOffset
|
||||||
};
|
};
|
||||||
glFunc->glGenBuffers(1, &m_mesh->elementOffsetSSBO);
|
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->elementOffsetSSBO);
|
|
||||||
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(elementOffset), elementOffset, GL_DYNAMIC_DRAW);
|
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
|
||||||
|
|
||||||
GLuint elementIndex[] = {
|
std::vector<GLuint> elementIndex = {
|
||||||
//element0
|
//element0
|
||||||
//lines, 全部当作三阶贝塞尔, 每条线四个点索引
|
//lines, 全部当作三阶贝塞尔, 每条线四个点索引
|
||||||
4,2,2,0,
|
4,2,2,0,
|
||||||
|
@ -224,22 +210,16 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
||||||
4,4,5,5,
|
4,4,5,5,
|
||||||
1,1,3,3,
|
1,1,3,3,
|
||||||
3,3,5,5,
|
3,3,5,5,
|
||||||
//contours, 第一个元素指明轮廓段数,后面为lines索引
|
//contours, 每个轮廓三个线索引
|
||||||
3, 0,1,2,
|
0,1,2,
|
||||||
3, 2,3,4,
|
2,3,4,
|
||||||
3, 3,5,6,
|
3,5,6,
|
||||||
|
|
||||||
//element2
|
//element2
|
||||||
//lines
|
//lines
|
||||||
0,1,2
|
0,1,2
|
||||||
};
|
};
|
||||||
glFunc->glGenBuffers(1, &m_mesh->elementIndexSSBO);
|
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->elementIndexSSBO);
|
|
||||||
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(elementIndex), elementIndex, GL_DYNAMIC_DRAW);
|
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
|
||||||
|
|
||||||
|
std::vector<GLfloat> elementData = {
|
||||||
GLfloat elementData[] = {
|
|
||||||
//element0
|
//element0
|
||||||
//points
|
//points
|
||||||
-1,0.5, -1,-0.5, 0,1, 0,-1, 1,0.5, 1,-0.5,
|
-1,0.5, -1,-0.5, 0,1, 0,-1, 1,0.5, 1,-0.5,
|
||||||
|
@ -266,11 +246,11 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
||||||
//strokeFillColorMetallicRoughness
|
//strokeFillColorMetallicRoughness
|
||||||
0,1,0, 0,0.8
|
0,1,0, 0,0.8
|
||||||
};
|
};
|
||||||
glFunc->glGenBuffers(1, &m_mesh->elementDataSSBO);
|
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->elementDataSSBO);
|
|
||||||
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(elementData), elementData, GL_DYNAMIC_DRAW);
|
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
|
||||||
|
|
||||||
|
//m_mesh->paintingIndex = paintingHelper->addPainting(bounds.size(), std::vector<GLuint>(children.begin()+2, children.end()), bounds,
|
||||||
|
// elementOffset, elementIndex, elementData);
|
||||||
|
m_mesh->paintingIndex = paintingHelper->addPainting(7, bvhChildren, bvhBounds,
|
||||||
|
elementOffset, elementIndex, elementData);
|
||||||
|
|
||||||
m_mesh->setupMesh();
|
m_mesh->setupMesh();
|
||||||
return m_mesh;
|
return m_mesh;
|
||||||
|
@ -358,6 +338,7 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
||||||
|
|
||||||
QVector<Texture*> Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type, QString typeName)
|
QVector<Texture*> Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type, QString typeName)
|
||||||
{
|
{
|
||||||
|
|
||||||
QVector<Texture*> textures;
|
QVector<Texture*> textures;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < mat->GetTextureCount(type); i++)
|
for (unsigned int i = 0; i < mat->GetTextureCount(type); i++)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
#include "Drawable.h"
|
#include "Drawable.h"
|
||||||
|
#include "PaintingHelper.h"
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
class Model
|
class Model
|
||||||
|
@ -10,7 +11,7 @@ public:
|
||||||
void draw();
|
void draw();
|
||||||
void destroy();
|
void destroy();
|
||||||
static Model* createModel(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram);
|
static Model* createModel(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram);
|
||||||
Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram);
|
Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram, PaintingHelper* paintingHelper);
|
||||||
private:
|
private:
|
||||||
Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram);
|
Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram);
|
||||||
|
|
||||||
|
@ -19,6 +20,8 @@ private:
|
||||||
QOpenGLFunctions_4_5_Compatibility* glFunc;
|
QOpenGLFunctions_4_5_Compatibility* glFunc;
|
||||||
QOpenGLShaderProgram* shaderProgram = nullptr;
|
QOpenGLShaderProgram* shaderProgram = nullptr;
|
||||||
QOpenGLShaderProgram* paintingProgram = nullptr; //彩绘着色器程序
|
QOpenGLShaderProgram* paintingProgram = nullptr; //彩绘着色器程序
|
||||||
|
PaintingHelper* paintingHelper = nullptr;
|
||||||
|
|
||||||
/* 模型数据 */
|
/* 模型数据 */
|
||||||
QVector<Texture*> textures_loaded; //纹理
|
QVector<Texture*> textures_loaded; //纹理
|
||||||
QVector<Drawable*> meshes; //网格
|
QVector<Drawable*> meshes; //网格
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
#include "PaintingHelper.h"
|
||||||
|
|
||||||
|
|
||||||
|
PaintingHelper::PaintingHelper(QOpenGLFunctions_4_5_Compatibility* glFunc) :glFunc(glFunc)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int PaintingHelper::addPainting(GLuint paintingBvhLength, std::vector<GLuint> bvhChildren, std::vector<QVector4D> bvhBound, std::vector<GLuint> elementOffset, std::vector<GLuint> elementIndex, std::vector<GLfloat> elementData)
|
||||||
|
{
|
||||||
|
this->paintingOffsets.push_back(0);//paintingBvhRoot
|
||||||
|
this->paintingOffsets.push_back(paintingBvhLength);
|
||||||
|
|
||||||
|
this->bvhChildren.insert(this->bvhChildren.end(), bvhChildren.begin(), bvhChildren.end());
|
||||||
|
this->bvhBound.insert(this->bvhBound.end(), bvhBound.begin(), bvhBound.end());
|
||||||
|
this->elementOffset.insert(this->elementOffset.end(), elementOffset.begin(), elementOffset.end());
|
||||||
|
this->elementIndex.insert(this->elementIndex.end(), elementIndex.begin(), elementIndex.end());
|
||||||
|
this->elementData.insert(this->elementData.end(), elementData.begin(), elementData.end());
|
||||||
|
|
||||||
|
return ++paintingCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaintingHelper::allocateBuffers()
|
||||||
|
{
|
||||||
|
glFunc->glGenBuffers(1, &paintingOffsetsSSBO);
|
||||||
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, paintingOffsetsSSBO);
|
||||||
|
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, paintingOffsets.size() * sizeof(GLuint), paintingOffsets.data(), GL_DYNAMIC_DRAW);
|
||||||
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
|
|
||||||
|
glFunc->glGenBuffers(1, &bvhSSBO);
|
||||||
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, bvhSSBO);
|
||||||
|
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, bvhChildren.size() * sizeof(GLuint), bvhChildren.data(), GL_DYNAMIC_DRAW);
|
||||||
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
|
|
||||||
|
glFunc->glGenBuffers(1, &bvhBoundSSBO);
|
||||||
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, bvhBoundSSBO);
|
||||||
|
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, bvhBound.size() * sizeof(QVector4D), bvhBound.data(), GL_DYNAMIC_DRAW);
|
||||||
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
|
|
||||||
|
|
||||||
|
glFunc->glGenBuffers(1, &elementOffsetSSBO);
|
||||||
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, elementOffsetSSBO);
|
||||||
|
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, elementOffset.size() * sizeof(GLuint), elementOffset.data(), GL_DYNAMIC_DRAW);
|
||||||
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
|
|
||||||
|
|
||||||
|
glFunc->glGenBuffers(1, &elementIndexSSBO);
|
||||||
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, elementIndexSSBO);
|
||||||
|
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, elementIndex.size() * sizeof(GLuint), elementIndex.data(), GL_DYNAMIC_DRAW);
|
||||||
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
|
|
||||||
|
glFunc->glGenBuffers(1, &elementDataSSBO);
|
||||||
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, elementDataSSBO);
|
||||||
|
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, elementData.size() * sizeof(GLfloat), elementData.data(), GL_DYNAMIC_DRAW);
|
||||||
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaintingHelper::bindPaintingBuffers()
|
||||||
|
{
|
||||||
|
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, paintingOffsetsSSBO);
|
||||||
|
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, bvhSSBO);
|
||||||
|
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, bvhBoundSSBO);
|
||||||
|
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, elementOffsetSSBO);
|
||||||
|
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, elementIndexSSBO);
|
||||||
|
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, elementDataSSBO);
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QVector4D>
|
||||||
|
#include <QOpenGLFunctions_4_5_Compatibility>
|
||||||
|
#include "BvhTree.h"
|
||||||
|
|
||||||
|
class PaintingHelper
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
QOpenGLFunctions_4_5_Compatibility* glFunc;
|
||||||
|
GLuint paintingOffsetsSSBO, bvhSSBO, bvhBoundSSBO, elementOffsetSSBO, elementIndexSSBO, elementDataSSBO;
|
||||||
|
std::vector<GLuint> paintingOffsets;
|
||||||
|
std::vector<GLuint> bvhChildren;
|
||||||
|
std::vector<QVector4D> bvhBound;
|
||||||
|
std::vector<GLuint> elementOffset;
|
||||||
|
std::vector<GLuint> elementIndex;
|
||||||
|
std::vector<GLfloat> elementData;
|
||||||
|
int paintingCount = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PaintingHelper(QOpenGLFunctions_4_5_Compatibility* glFunc);
|
||||||
|
int addPainting(GLuint paintingBvhLength, std::vector<GLuint> bvhChildren, std::vector<QVector4D> bvhBound,
|
||||||
|
std::vector<GLuint> elementOffset, std::vector<GLuint> elementIndex, std::vector<GLfloat> elementData);
|
||||||
|
void allocateBuffers();
|
||||||
|
void bindPaintingBuffers();
|
||||||
|
};
|
||||||
|
|
|
@ -14,13 +14,6 @@ void PaintingMesh::draw()
|
||||||
shaderProgram->bind();
|
shaderProgram->bind();
|
||||||
QOpenGLVertexArrayObject::Binder bind(&VAO);
|
QOpenGLVertexArrayObject::Binder bind(&VAO);
|
||||||
shaderProgram->setUniformValue("model", model);
|
shaderProgram->setUniformValue("model", model);
|
||||||
|
|
||||||
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, bvhSSBO);
|
|
||||||
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, bvhBoundSSBO);
|
|
||||||
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, elementOffsetSSBO);
|
|
||||||
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, elementIndexSSBO);
|
|
||||||
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, elementDataSSBO);
|
|
||||||
|
|
||||||
glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
|
glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
shaderProgram->release();
|
shaderProgram->release();
|
||||||
|
|
|
@ -33,9 +33,7 @@ public:
|
||||||
QMatrix4x4 model; //模型矩阵
|
QMatrix4x4 model; //模型矩阵
|
||||||
QOpenGLFunctions_4_5_Compatibility* glFunc; //opengl函数入口
|
QOpenGLFunctions_4_5_Compatibility* glFunc; //opengl函数入口
|
||||||
QOpenGLShaderProgram* shaderProgram; //着色器程序
|
QOpenGLShaderProgram* shaderProgram; //着色器程序
|
||||||
|
GLuint paintingIndex;
|
||||||
GLuint bvhSSBO, bvhBoundSSBO, elementOffsetSSBO, elementIndexSSBO, elementDataSSBO;
|
|
||||||
|
|
||||||
/* 函数 */
|
/* 函数 */
|
||||||
PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model);
|
PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model);
|
||||||
void draw() override;
|
void draw() override;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
|
|
||||||
|
|
||||||
RendererWidget::RendererWidget(QWidget* parent)
|
RendererWidget::RendererWidget(QWidget* parent)
|
||||||
: QOpenGLWidget(parent), camera(QVector3D(0.0f, 100.0f, 0.0f))
|
: QOpenGLWidget(parent), camera(QVector3D(0.0f, 100.0f, 0.0f))
|
||||||
{
|
{
|
||||||
|
@ -84,10 +85,20 @@ void RendererWidget::initializeGL()
|
||||||
finalProgramPtr->setUniformValue("gNormal", 1);
|
finalProgramPtr->setUniformValue("gNormal", 1);
|
||||||
finalProgramPtr->setUniformValue("gPosition", 2);
|
finalProgramPtr->setUniformValue("gPosition", 2);
|
||||||
finalProgramPtr->setUniformValue("gMetallicRoughness", 3);
|
finalProgramPtr->setUniformValue("gMetallicRoughness", 3);
|
||||||
finalProgramPtr->setUniformValue("gPainting", 4);
|
|
||||||
finalProgramPtr->release();
|
finalProgramPtr->release();
|
||||||
|
|
||||||
model = new Model("Models/Sponza/Sponza.gltf", context(), modelProgramPtr, paintingProgramPtr);
|
|
||||||
|
|
||||||
|
paintingHelper = new PaintingHelper(QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Compatibility>());
|
||||||
|
|
||||||
|
model = new Model("Models/Sponza/Sponza.gltf", context(), modelProgramPtr, paintingProgramPtr, paintingHelper);
|
||||||
|
|
||||||
|
|
||||||
|
paintingHelper->allocateBuffers();
|
||||||
|
paintingCompProgramPtr->bind();
|
||||||
|
paintingHelper->bindPaintingBuffers();
|
||||||
|
paintingCompProgramPtr->release();
|
||||||
|
|
||||||
|
|
||||||
quadVAO.create();
|
quadVAO.create();
|
||||||
QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO);
|
QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO);
|
||||||
|
@ -143,9 +154,12 @@ void RendererWidget::paintGL()
|
||||||
glActiveTexture(GL_TEXTURE4);
|
glActiveTexture(GL_TEXTURE4);
|
||||||
glBindTexture(GL_TEXTURE_2D, gbuffers[4]);
|
glBindTexture(GL_TEXTURE_2D, gbuffers[4]);
|
||||||
glBindImageTexture(0, gbuffers[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
|
glBindImageTexture(0, gbuffers[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
|
||||||
glBindImageTexture(1, gbuffers[3], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG16);
|
glBindImageTexture(1, gbuffers[3], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG8);
|
||||||
glBindImageTexture(2, gbuffers[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
|
glBindImageTexture(2, gbuffers[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R16UI);
|
||||||
|
glBindImageTexture(3, gbuffers[5], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG16F);
|
||||||
|
|
||||||
glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
|
glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
|
||||||
|
//glDispatchCompute(1,1, 1);
|
||||||
|
|
||||||
|
|
||||||
//QOpenGLFramebufferObject::blitFramebuffer(nullptr, QRect(0, 0, 2*width(), 2*height()), fboPtr, QRect(0, 0, 1156, 756));
|
//QOpenGLFramebufferObject::blitFramebuffer(nullptr, QRect(0, 0, 2*width(), 2*height()), fboPtr, QRect(0, 0, 1156, 756));
|
||||||
|
@ -167,8 +181,6 @@ void RendererWidget::paintGL()
|
||||||
glBindTexture(GL_TEXTURE_2D, gbuffers[2]);
|
glBindTexture(GL_TEXTURE_2D, gbuffers[2]);
|
||||||
glActiveTexture(GL_TEXTURE3);
|
glActiveTexture(GL_TEXTURE3);
|
||||||
glBindTexture(GL_TEXTURE_2D, gbuffers[3]);
|
glBindTexture(GL_TEXTURE_2D, gbuffers[3]);
|
||||||
glActiveTexture(GL_TEXTURE4);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, gbuffers[4]);
|
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
finalProgramPtr->release();
|
finalProgramPtr->release();
|
||||||
}
|
}
|
||||||
|
@ -185,13 +197,48 @@ void RendererWidget::resizeGL(int width, int height)
|
||||||
fboPtr = new QOpenGLFramebufferObject(frameWidth, frameHeight, QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D);
|
fboPtr = new QOpenGLFramebufferObject(frameWidth, frameHeight, QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D);
|
||||||
if (fboPtr->bind())
|
if (fboPtr->bind())
|
||||||
{
|
{
|
||||||
|
/*fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RGB16F);
|
||||||
fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RGB16F);
|
fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RGB16F);
|
||||||
fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RGB16F);
|
fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RG8);
|
||||||
fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RG16);
|
fboPtr->addColorAttachment(frameWidth, frameHeight, GL_R16F);
|
||||||
fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RGBA32F);
|
fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RG16F);*/
|
||||||
GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4 };
|
|
||||||
glDrawBuffers(5, attachments);
|
gbuffers[0] = fboPtr->texture();
|
||||||
gbuffers = fboPtr->textures();
|
|
||||||
|
glGenTextures(5, gbuffers+1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gbuffers[1]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gbuffers[1], 0);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gbuffers[2]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gbuffers[2], 0);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gbuffers[3]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, frameWidth, frameHeight, 0, GL_RG, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gbuffers[3], 0);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gbuffers[4]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, frameWidth, frameHeight, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, gbuffers[4], 0);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gbuffers[5]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16F, frameWidth, frameHeight, 0, GL_RG, GL_FLOAT, NULL);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, GL_TEXTURE_2D, gbuffers[5], 0);
|
||||||
|
|
||||||
|
GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5 };
|
||||||
|
glDrawBuffers(6, attachments);
|
||||||
|
//gbuffers = fboPtr->textures();
|
||||||
|
|
||||||
fboPtr->release();
|
fboPtr->release();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
|
#include "PaintingHelper.h"
|
||||||
|
|
||||||
class RendererWidget : public QOpenGLWidget, protected QOpenGLFunctions_4_5_Compatibility
|
class RendererWidget : public QOpenGLWidget, protected QOpenGLFunctions_4_5_Compatibility
|
||||||
{
|
{
|
||||||
|
@ -39,9 +40,10 @@ private:
|
||||||
QOpenGLShaderProgram* paintingCompProgramPtr = nullptr;
|
QOpenGLShaderProgram* paintingCompProgramPtr = nullptr;
|
||||||
QOpenGLShaderProgram* finalProgramPtr = nullptr;
|
QOpenGLShaderProgram* finalProgramPtr = nullptr;
|
||||||
QOpenGLFramebufferObject* fboPtr = nullptr;
|
QOpenGLFramebufferObject* fboPtr = nullptr;
|
||||||
QVector<GLuint> gbuffers;
|
GLuint gbuffers[6];
|
||||||
QOpenGLBuffer quadVBO;
|
QOpenGLBuffer quadVBO;
|
||||||
QOpenGLVertexArrayObject quadVAO;
|
QOpenGLVertexArrayObject quadVAO;
|
||||||
Model* model;
|
Model* model;
|
||||||
|
PaintingHelper* paintingHelper;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ uniform sampler2D gBaseColor;
|
||||||
uniform sampler2D gNormal;
|
uniform sampler2D gNormal;
|
||||||
uniform sampler2D gPosition;
|
uniform sampler2D gPosition;
|
||||||
uniform sampler2D gMetallicRoughness;
|
uniform sampler2D gMetallicRoughness;
|
||||||
uniform sampler2D gPainting;
|
|
||||||
// lights
|
// lights
|
||||||
uniform vec3 lightPositions[4];
|
uniform vec3 lightPositions[4];
|
||||||
uniform vec3 lightColors[4];
|
uniform vec3 lightColors[4];
|
||||||
|
|
|
@ -9,7 +9,7 @@ layout (location = 0) out vec4 gBaseColor;
|
||||||
layout (location = 1) out vec3 gNormal;
|
layout (location = 1) out vec3 gNormal;
|
||||||
layout (location = 2) out vec3 gPosition;
|
layout (location = 2) out vec3 gPosition;
|
||||||
layout (location = 3) out vec2 gMetallicRoughness;
|
layout (location = 3) out vec2 gMetallicRoughness;
|
||||||
layout(location = 4) out vec3 gPainting;
|
layout (location = 4) out uint gPaintingIndex;
|
||||||
|
|
||||||
in vec2 TexCoords;
|
in vec2 TexCoords;
|
||||||
in vec3 WorldPos;
|
in vec3 WorldPos;
|
||||||
|
@ -43,6 +43,6 @@ void main()
|
||||||
gPosition = WorldPos;
|
gPosition = WorldPos;
|
||||||
gNormal = getNormalFromMap();
|
gNormal = getNormalFromMap();
|
||||||
gMetallicRoughness = texture(texture_metallic_roughness, TexCoords).bg;
|
gMetallicRoughness = texture(texture_metallic_roughness, TexCoords).bg;
|
||||||
gPainting = vec3(0);
|
gPaintingIndex = 0;
|
||||||
|
|
||||||
}
|
}
|
|
@ -3,43 +3,50 @@
|
||||||
layout (local_size_x = 8, local_size_y = 8) in;
|
layout (local_size_x = 8, local_size_y = 8) in;
|
||||||
|
|
||||||
layout(rgba8, binding = 0) uniform image2D gBaseColor;
|
layout(rgba8, binding = 0) uniform image2D gBaseColor;
|
||||||
layout(rg16, binding = 1) uniform image2D gMetallicRoughness;
|
layout(rg8, binding = 1) uniform image2D gMetallicRoughness;
|
||||||
layout(rgba32f, binding = 2) uniform image2D gPainting;
|
layout(r16ui, binding = 2) uniform uimage2D gPaintingIndex;
|
||||||
|
layout(rg16f, binding = 3) uniform image2D gPaintingTexCoord;
|
||||||
|
|
||||||
|
layout(std430, binding = 1) buffer paintingOffsetBuffer
|
||||||
|
{
|
||||||
layout(std430, binding = 1) buffer bvhBuffer
|
/**********************
|
||||||
|
** @x paintingBvhRoot
|
||||||
|
** @y paintingBvhLength
|
||||||
|
**********************/
|
||||||
|
uvec2 paintingOffsets[];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std430, binding = 2) buffer bvhBuffer
|
||||||
{
|
{
|
||||||
uint bvhLength;
|
|
||||||
uvec2 bvhChildren[];
|
uvec2 bvhChildren[];
|
||||||
};
|
};
|
||||||
layout(std430, binding = 2) buffer bvhBoundBuffer
|
layout(std430, binding = 3) buffer bvhBoundBuffer
|
||||||
{
|
{
|
||||||
vec4 bvhBound[];
|
vec4 bvhBound[];
|
||||||
};
|
};
|
||||||
layout(std430, binding = 3) buffer elementOffsetBuffer
|
layout(std430, binding = 4) buffer elementOffsetBuffer
|
||||||
{
|
{
|
||||||
/**********************
|
/**********************
|
||||||
** @x elementBvhRoot
|
** @[0] elementBvhRoot
|
||||||
** @y elementBvhLength
|
** @[1] elementBvhLength
|
||||||
** @z pointsOffset
|
** @[2] pointsOffset
|
||||||
** @w linesOffset
|
** @[3] linesOffset
|
||||||
|
** @[4] contoursOffset
|
||||||
**********************/
|
**********************/
|
||||||
uvec4 elementOffset[];
|
uint elementOffset[][5];
|
||||||
};
|
};
|
||||||
layout(std430, binding = 4) buffer elementIndexBuffer
|
layout(std430, binding = 5) buffer elementIndexBuffer
|
||||||
{
|
{
|
||||||
uint elementIndexs[]; //线和面
|
uint elementIndexs[]; //线和面
|
||||||
};
|
};
|
||||||
layout(std430, binding = 5) buffer elementDataBuffer
|
layout(std430, binding = 6) buffer elementDataBuffer
|
||||||
{
|
{
|
||||||
float elementData[]; //点和Style
|
float elementData[]; //点和Style
|
||||||
};
|
};
|
||||||
|
|
||||||
const float PI = 3.14159265358979;
|
const float PI = 3.14159265358979;
|
||||||
|
|
||||||
|
|
||||||
const uint STACK_SIZE = 30;
|
const uint STACK_SIZE = 16;
|
||||||
|
|
||||||
struct Stack
|
struct Stack
|
||||||
{
|
{
|
||||||
|
@ -79,21 +86,287 @@ struct Stack
|
||||||
} stack, elementStack;
|
} stack, elementStack;
|
||||||
|
|
||||||
|
|
||||||
|
// Modified from http://tog.acm.org/resources/GraphicsGems/gems/Roots3And4.c
|
||||||
|
// Credits to Doublefresh for hinting there
|
||||||
|
int solve_quadric(vec2 coeffs, inout vec2 roots)
|
||||||
|
{
|
||||||
|
|
||||||
|
// normal form: x^2 + px + q = 0
|
||||||
|
float p = coeffs[1] / 2.;
|
||||||
|
float q = coeffs[0];
|
||||||
|
|
||||||
|
float D = p * p - q;
|
||||||
|
|
||||||
|
if (D < 0.)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
roots[0] = -sqrt(D) - p;
|
||||||
|
roots[1] = sqrt(D) - p;
|
||||||
|
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// From Trisomie21
|
||||||
|
// But instead of his cancellation fix i'm using a newton iteration
|
||||||
|
int solve_cubic(vec3 coeffs, inout vec3 r)
|
||||||
|
{
|
||||||
|
|
||||||
|
float a = coeffs[2];
|
||||||
|
float b = coeffs[1];
|
||||||
|
float c = coeffs[0];
|
||||||
|
|
||||||
|
float p = b - a * a / 3.0;
|
||||||
|
float q = a * (2.0 * a * a - 9.0 * b) / 27.0 + c;
|
||||||
|
float p3 = p * p * p;
|
||||||
|
float d = q * q + 4.0 * p3 / 27.0;
|
||||||
|
float offset = -a / 3.0;
|
||||||
|
if (d >= 0.0)
|
||||||
|
{ // Single solution
|
||||||
|
float z = sqrt(d);
|
||||||
|
float u = (-q + z) / 2.0;
|
||||||
|
float v = (-q - z) / 2.0;
|
||||||
|
u = sign(u) * pow(abs(u), 1.0 / 3.0);
|
||||||
|
v = sign(v) * pow(abs(v), 1.0 / 3.0);
|
||||||
|
r[0] = offset + u + v;
|
||||||
|
|
||||||
|
// Single newton iteration to account for cancellation
|
||||||
|
float f = ((r[0] + a) * r[0] + b) * r[0] + c;
|
||||||
|
float f1 = (3. * r[0] + 2. * a) * r[0] + b;
|
||||||
|
|
||||||
|
r[0] -= f / f1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
float u = sqrt(-p / 3.0);
|
||||||
|
float v = acos(-sqrt(-27.0 / p3) * q / 2.0) / 3.0;
|
||||||
|
float m = cos(v), n = sin(v) * 1.732050808;
|
||||||
|
|
||||||
|
// Single newton iteration to account for cancellation
|
||||||
|
//(once for every root)
|
||||||
|
r[0] = offset + u * (m + m);
|
||||||
|
r[1] = offset - u * (n + m);
|
||||||
|
r[2] = offset + u * (n - m);
|
||||||
|
|
||||||
|
vec3 f = ((r + a) * r + b) * r + c;
|
||||||
|
vec3 f1 = (3. * r + 2. * a) * r + b;
|
||||||
|
|
||||||
|
r -= f / f1;
|
||||||
|
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int segment_int_test(vec2 uv, vec2 p0, vec2 p1)
|
||||||
|
{
|
||||||
|
p0 -= uv;
|
||||||
|
p1 -= uv;
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (p0.y * p1.y < 0.)
|
||||||
|
{
|
||||||
|
vec2 nor = p0 - p1;
|
||||||
|
nor = vec2(nor.y, -nor.x);
|
||||||
|
|
||||||
|
float sgn;
|
||||||
|
|
||||||
|
if (p0.y > p1.y)
|
||||||
|
{
|
||||||
|
sgn = 1.;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sgn = -1.;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dot(nor, p0) * sgn < 0.)
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cubic_bezier_int_test(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3)
|
||||||
|
{
|
||||||
|
|
||||||
|
float cu = (-p0.y + 3. * p1.y - 3. * p2.y + p3.y);
|
||||||
|
float qu = (3. * p0.y - 6. * p1.y + 3. * p2.y);
|
||||||
|
float li = (-3. * p0.y + 3. * p1.y);
|
||||||
|
float co = p0.y - uv.y;
|
||||||
|
|
||||||
|
vec3 roots = vec3(1e38);
|
||||||
|
int n_roots;
|
||||||
|
|
||||||
|
int n_ints = 0;
|
||||||
|
|
||||||
|
if (uv.x < min(min(p0.x, p1.x), min(p2.x, p3.x)))
|
||||||
|
{
|
||||||
|
if (uv.y >= min(p0.y, p3.y) && uv.y <= max(p0.y, p3.y))
|
||||||
|
{
|
||||||
|
n_ints = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
if (abs(cu) < .0001)
|
||||||
|
{
|
||||||
|
n_roots = solve_quadric(vec2(co / qu, li / qu), roots.xy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
n_roots = solve_cubic(vec3(co / cu, li / cu, qu / cu), roots);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < n_roots; i++)
|
||||||
|
{
|
||||||
|
if (roots[i] >= 0. && roots[i] <= 1.)
|
||||||
|
{
|
||||||
|
float x_pos = -p0.x + 3. * p1.x - 3. * p2.x + p3.x;
|
||||||
|
x_pos = x_pos * roots[i] + 3. * p0.x - 6. * p1.x + 3. * p2.x;
|
||||||
|
x_pos = x_pos * roots[i] + -3. * p0.x + 3. * p1.x;
|
||||||
|
x_pos = x_pos * roots[i] + p0.x;
|
||||||
|
|
||||||
|
if (x_pos > uv.x)
|
||||||
|
{
|
||||||
|
n_ints++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return n_ints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 drawElement(uint elementIndex, vec2 localUV, inout vec3 debugBVH = vec3(0))
|
||||||
|
{
|
||||||
|
vec4 elementColor = vec4(0);
|
||||||
|
|
||||||
|
uint currentOffset[5] = elementOffset[elementIndex];
|
||||||
|
uint elementBvhRoot = currentOffset[0];
|
||||||
|
uint elementBvhLength = currentOffset[1];
|
||||||
|
uint pointsOffset = currentOffset[2];
|
||||||
|
uint linesOffset = currentOffset[3];
|
||||||
|
uint contoursOffset = currentOffset[4];
|
||||||
|
|
||||||
|
elementStack.top = 0;
|
||||||
|
uint elementBvhIndex = 0;
|
||||||
|
while (elementBvhIndex < elementBvhLength || !elementStack.empty())
|
||||||
|
{
|
||||||
|
|
||||||
|
while (elementBvhIndex < elementBvhLength)
|
||||||
|
{
|
||||||
|
vec4 bound = bvhBound[elementBvhRoot + elementBvhIndex];
|
||||||
|
uint leftChild = bvhChildren[elementBvhRoot + elementBvhIndex].x;
|
||||||
|
|
||||||
|
if (all(lessThan(bound.xy, localUV)) && all(lessThan(localUV, bound.zw)))
|
||||||
|
{
|
||||||
|
if (leftChild >= elementBvhLength)
|
||||||
|
{
|
||||||
|
debugBVH.g += 0.5;
|
||||||
|
|
||||||
|
uint styleIndex = bvhChildren[elementBvhRoot + elementBvhIndex].y - elementBvhLength;
|
||||||
|
// for(int i = 0; i<200;i++)
|
||||||
|
if (elementData[styleIndex] == 0.) //Ãæ
|
||||||
|
{
|
||||||
|
uint contourIndex = leftChild - elementBvhLength;
|
||||||
|
|
||||||
|
uint num_its = 0;
|
||||||
|
|
||||||
|
uint contourIterator = contoursOffset + contourIndex*3;
|
||||||
|
if(elementIndexs[contourIterator]==elementIndexs[contourIterator+1])
|
||||||
|
contourIterator++;
|
||||||
|
for (;contourIterator < contoursOffset + contourIndex*3 + 3; contourIterator++)
|
||||||
|
{
|
||||||
|
uint lineIndex = elementIndexs[contourIterator];
|
||||||
|
uint p0Index = elementIndexs[linesOffset + 4 * lineIndex];
|
||||||
|
uint p1Index = elementIndexs[linesOffset + 4 * lineIndex + 1];
|
||||||
|
uint p2Index = elementIndexs[linesOffset + 4 * lineIndex + 2];
|
||||||
|
uint p3Index = elementIndexs[linesOffset + 4 * lineIndex + 3];
|
||||||
|
|
||||||
|
vec2 p0 = vec2(elementData[pointsOffset + 2 * p0Index],
|
||||||
|
elementData[pointsOffset + 2 * p0Index + 1]);
|
||||||
|
vec2 p1 = vec2(elementData[pointsOffset + 2 * p1Index],
|
||||||
|
elementData[pointsOffset + 2 * p1Index + 1]);
|
||||||
|
vec2 p2 = vec2(elementData[pointsOffset + 2 * p2Index],
|
||||||
|
elementData[pointsOffset + 2 * p2Index + 1]);
|
||||||
|
vec2 p3 = vec2(elementData[pointsOffset + 2 * p3Index],
|
||||||
|
elementData[pointsOffset + 2 * p3Index + 1]);
|
||||||
|
|
||||||
|
if (p0 == p1 && p2 == p3)
|
||||||
|
{
|
||||||
|
num_its += segment_int_test(localUV, p0, p3);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
num_its += cubic_bezier_int_test(localUV, p0, p1, p2, p3);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_its % 2 == 1)
|
||||||
|
{
|
||||||
|
elementColor = vec4(1);
|
||||||
|
//debugHit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (elementData[styleIndex] == 1) //Ïß
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
elementBvhIndex = elementBvhLength;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// debugBVH.b += 0.2;
|
||||||
|
elementStack.push(elementBvhIndex);
|
||||||
|
elementBvhIndex = leftChild;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
elementBvhIndex = elementBvhLength;
|
||||||
|
}
|
||||||
|
if (!elementStack.empty())
|
||||||
|
{
|
||||||
|
elementStack.getTop(elementBvhIndex);
|
||||||
|
elementStack.pop();
|
||||||
|
elementBvhIndex = bvhChildren[elementBvhRoot + elementBvhIndex].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return elementColor.xyz;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
//ivec2 pixelLocation = ivec2(((gl_LocalInvocationID.xy)*imageSize(gPaintingIndex)/gl_WorkGroupSize.xy + gl_WorkGroupID.xy).xy);
|
||||||
ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy);
|
ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy);
|
||||||
if(imageLoad(gPainting, pixelLocation).r==0)
|
uint paintingIndex = imageLoad(gPaintingIndex, pixelLocation).r;
|
||||||
|
if(paintingIndex==0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
imageStore(gMetallicRoughness, pixelLocation, vec4(0 /*金属度*/, 0.8 /*粗糙度*/, 0, 1));
|
imageStore(gMetallicRoughness, pixelLocation, vec4(0 /*金属度*/, 0.8 /*粗糙度*/, 0, 1));
|
||||||
|
|
||||||
vec2 uv = imageLoad(gPainting, pixelLocation).gb;
|
vec2 uv = imageLoad(gPaintingTexCoord, pixelLocation).rg;
|
||||||
|
|
||||||
vec3 debugBVH = vec3(0);
|
vec3 debugBVH = vec3(0);
|
||||||
bool debugHit = false;
|
bool debugHit = false;
|
||||||
stack.top = 0;
|
stack.top = 0;
|
||||||
uint index = 0, visitTime = 0;
|
uint index = 0, visitTime = 0;
|
||||||
|
uint bvhLength = paintingOffsets[paintingIndex-1].y;
|
||||||
while (index < bvhLength || !stack.empty())
|
while (index < bvhLength || !stack.empty())
|
||||||
{
|
{
|
||||||
while (index < bvhLength)
|
while (index < bvhLength)
|
||||||
|
@ -115,10 +388,10 @@ void main()
|
||||||
if (zIndex == 1)
|
if (zIndex == 1)
|
||||||
debugBVH = vec3(1, 0, 1);
|
debugBVH = vec3(1, 0, 1);
|
||||||
uint elementIndex = leftChild - bvhLength;
|
uint elementIndex = leftChild - bvhLength;
|
||||||
debugBVH.bg += 0.5 * (localUV + vec2(1));
|
debugBVH.bg += 0.5 * (localUV + vec2(1));
|
||||||
// debugBVH = vec3(0);
|
|
||||||
|
|
||||||
//debugHit = drawElement(leftChild - bvhLength, localUV, debugBVH) == vec3(1);
|
debugBVH = vec3(0);
|
||||||
|
debugHit = drawElement(leftChild - bvhLength, localUV, debugBVH) == vec3(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +399,7 @@ void main()
|
||||||
}
|
}
|
||||||
else if (all(lessThan(bound.xy, uv)) && all(lessThan(uv, bound.zw)))
|
else if (all(lessThan(bound.xy, uv)) && all(lessThan(uv, bound.zw)))
|
||||||
{
|
{
|
||||||
debugBVH.r += 0.2;
|
debugBVH.r += 0.02;
|
||||||
stack.push(index);
|
stack.push(index);
|
||||||
index = leftChild;
|
index = leftChild;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,29 @@ layout(location = 0) out vec4 gBaseColor;
|
||||||
layout(location = 1) out vec3 gNormal;
|
layout(location = 1) out vec3 gNormal;
|
||||||
layout(location = 2) out vec3 gPosition;
|
layout(location = 2) out vec3 gPosition;
|
||||||
layout(location = 3) out vec2 gMetallicRoughness;
|
layout(location = 3) out vec2 gMetallicRoughness;
|
||||||
layout(location = 4) out vec3 gPainting;
|
layout(location = 4) out uint gPaintingIndex;
|
||||||
|
layout(location = 5) out vec2 gPaintingTexCoord;
|
||||||
|
|
||||||
in vec2 TexCoords;
|
in vec2 TexCoords;
|
||||||
in vec3 WorldPos;
|
in vec3 WorldPos;
|
||||||
in vec3 Normal;
|
in vec3 Normal;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
|
||||||
|
gBaseColor = vec4( vec3(1),1 );
|
||||||
|
// mainImage(gBaseColor, vec2(1.,1.)-TexCoords);
|
||||||
|
gPosition = WorldPos;
|
||||||
|
gNormal = normalize(Normal);
|
||||||
|
// gMetallicRoughness = vec2(1, 46./255);
|
||||||
|
gMetallicRoughness = vec2(0);
|
||||||
|
gPaintingIndex = 1;
|
||||||
|
gPaintingTexCoord = vec2(1., 1.) - TexCoords * 2;
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
layout(std430, binding = 1) buffer bvhBuffer
|
layout(std430, binding = 1) buffer bvhBuffer
|
||||||
{
|
{
|
||||||
uint bvhLength;
|
uint bvhLength;
|
||||||
|
@ -628,104 +645,3 @@ vec3 drawElement(uint elementIndex, vec2 localUV, inout vec3 debugBVH = vec3(0))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
|
|
||||||
gBaseColor = vec4( vec3(1,0,0),1 );
|
|
||||||
// mainImage(gBaseColor, vec2(1.,1.)-TexCoords);
|
|
||||||
gPosition = WorldPos;
|
|
||||||
gNormal = normalize(Normal);
|
|
||||||
// gMetallicRoughness = vec2(1, 46./255);
|
|
||||||
gMetallicRoughness = vec2(0 /*½ðÊô¶È*/, 0.8 /*´Ö²Ú¶È*/);
|
|
||||||
gPainting = vec3(1, vec2(1., 1.) - TexCoords * 2);
|
|
||||||
return;
|
|
||||||
// gBaseColor = vec4(TexCoords,1,1);
|
|
||||||
// gBaseColor = vec4(240./255, 220./255,157./255,1);
|
|
||||||
// gBaseColor = vec4(bvh[0].bound==vec4(0,0,1,1));
|
|
||||||
|
|
||||||
//vec2 uv = vec2(1., 1.) - TexCoords * 2;
|
|
||||||
vec2 uv = vec2(0., -0.7) ;
|
|
||||||
vec3 debugBVH = vec3(0);
|
|
||||||
bool debugHit = false;
|
|
||||||
stack.top = 0;
|
|
||||||
uint index = 0, visitTime = 0;
|
|
||||||
while (index < bvhLength || !stack.empty())
|
|
||||||
{
|
|
||||||
while (index < bvhLength)
|
|
||||||
{
|
|
||||||
visitTime++;
|
|
||||||
vec4 bound = bvhBound[index];
|
|
||||||
uint leftChild = bvhChildren[index].x;
|
|
||||||
if (leftChild >= bvhLength)
|
|
||||||
{
|
|
||||||
uint zIndex = bvhChildren[index].y / 65535;
|
|
||||||
float angle = (bvhChildren[index].y / 65535. - zIndex) * 2 * PI;
|
|
||||||
|
|
||||||
mat2 rotation = {{cos(angle), -sin(angle)}, {sin(angle), cos(angle)}};
|
|
||||||
vec2 localUV = uv - (bound.xy + bound.zw) / 2;
|
|
||||||
localUV = rotation * localUV;
|
|
||||||
localUV /= (bound.zw - bound.xy) / 2;
|
|
||||||
if (all(lessThan(vec2(-1), localUV)) && all(lessThan(localUV, vec2(1))))
|
|
||||||
{
|
|
||||||
if (zIndex == 1)
|
|
||||||
debugBVH = vec3(1, 0, 1);
|
|
||||||
uint elementIndex = leftChild - bvhLength;
|
|
||||||
debugBVH.bg += 0.5 * (localUV + vec2(1));
|
|
||||||
// debugBVH = vec3(0);
|
|
||||||
|
|
||||||
//debugHit = drawElement(leftChild - bvhLength, localUV, debugBVH) == vec3(1);
|
|
||||||
|
|
||||||
|
|
||||||
// mainImage(debugBVH,localUV);
|
|
||||||
|
|
||||||
// for(uint i=elementOffset[elementIndex][1];i<elementOffset[elementIndex][2];i+=7)
|
|
||||||
// {
|
|
||||||
// if(tri_test(localUV, vec2(elementData[i],elementData[i+1]),
|
|
||||||
// vec2(elementData[i+2],elementData[i+3]), vec2(elementData[i+4],elementData[i+5]), true))
|
|
||||||
// {
|
|
||||||
// if(elementData[i+6]==0)
|
|
||||||
// {
|
|
||||||
// debugHit=true;
|
|
||||||
// }
|
|
||||||
// else if(elementData[i+6]==1)
|
|
||||||
// {
|
|
||||||
// if(-bezier_sd(localUV, vec2(elementData[i],elementData[i+1]),
|
|
||||||
// vec2(elementData[i+2],elementData[i+3]), vec2(elementData[i+4],elementData[i+5]))>0)
|
|
||||||
// debugHit=true;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// if(bezier_sd(localUV, vec2(elementData[i],elementData[i+1]),
|
|
||||||
// vec2(elementData[i+2],elementData[i+3]), vec2(elementData[i+4],elementData[i+5]))>0)
|
|
||||||
// debugHit=true;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
index = bvhLength;
|
|
||||||
}
|
|
||||||
else if (all(lessThan(bound.xy, uv)) && all(lessThan(uv, bound.zw)))
|
|
||||||
{
|
|
||||||
debugBVH.r += 0.2;
|
|
||||||
stack.push(index);
|
|
||||||
index = leftChild;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
index = bvhLength;
|
|
||||||
}
|
|
||||||
if (!stack.empty())
|
|
||||||
{
|
|
||||||
stack.getTop(index);
|
|
||||||
stack.pop();
|
|
||||||
index = bvhChildren[index].y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debugHit)
|
|
||||||
gBaseColor = vec4(vec3(1, 1, 0), 1);
|
|
||||||
else
|
|
||||||
gBaseColor = vec4(vec3(int(visitTime)-9), 1);
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue