Fix textures
parent
81063eaaaf
commit
29f7e06701
|
@ -1,13 +1,23 @@
|
||||||
#version 110
|
#version 110
|
||||||
uniform vec3 eyePosition;
|
|
||||||
uniform sampler2D environmentIrradianceMapId[6];
|
uniform sampler2D environmentIrradianceMapId[6];
|
||||||
uniform sampler2D environmentSpecularMapId[6];
|
uniform sampler2D environmentSpecularMapId[6];
|
||||||
|
uniform sampler2D textureId;
|
||||||
|
uniform int textureEnabled;
|
||||||
|
uniform sampler2D normalMapId;
|
||||||
|
uniform int normalMapEnabled;
|
||||||
|
uniform sampler2D metalnessRoughnessAoMapId;
|
||||||
|
uniform int metalnessMapEnabled;
|
||||||
|
uniform int roughnessMapEnabled;
|
||||||
|
uniform int aoMapEnabled;
|
||||||
|
uniform vec3 eyePosition;
|
||||||
varying vec3 pointPosition;
|
varying vec3 pointPosition;
|
||||||
varying vec3 pointNormal;
|
varying vec3 pointNormal;
|
||||||
varying vec3 pointColor;
|
varying vec3 pointColor;
|
||||||
|
varying vec2 pointTexCoord;
|
||||||
varying float pointAlpha;
|
varying float pointAlpha;
|
||||||
varying float pointMetalness;
|
varying float pointMetalness;
|
||||||
varying float pointRoughness;
|
varying float pointRoughness;
|
||||||
|
varying mat3 pointTBN;
|
||||||
|
|
||||||
const float PI = 3.1415926;
|
const float PI = 3.1415926;
|
||||||
|
|
||||||
|
@ -45,9 +55,34 @@ vec4 texturesAsCube(in sampler2D maps[6], in vec3 direction)
|
||||||
vec2 st;
|
vec2 st;
|
||||||
cubemap(direction, texId, st);
|
cubemap(direction, texId, st);
|
||||||
vec4 color = vec4(0);
|
vec4 color = vec4(0);
|
||||||
for (int i = 0; i < 6; ++i) {
|
{
|
||||||
vec4 side = texture2D(maps[i], st);
|
vec4 side = texture2D(maps[0], st);
|
||||||
float select = step(float(i) - 0.5, texId) * step(texId, float(i) + 0.5);
|
float select = step(0.0 - 0.5, texId) * step(texId, 0.0 + 0.5);
|
||||||
|
color = mix(color, side, select);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
vec4 side = texture2D(maps[1], st);
|
||||||
|
float select = step(1.0 - 0.5, texId) * step(texId, 1.0 + 0.5);
|
||||||
|
color = mix(color, side, select);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
vec4 side = texture2D(maps[2], st);
|
||||||
|
float select = step(2.0 - 0.5, texId) * step(texId, 2.0 + 0.5);
|
||||||
|
color = mix(color, side, select);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
vec4 side = texture2D(maps[3], st);
|
||||||
|
float select = step(3.0 - 0.5, texId) * step(texId, 3.0 + 0.5);
|
||||||
|
color = mix(color, side, select);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
vec4 side = texture2D(maps[4], st);
|
||||||
|
float select = step(4.0 - 0.5, texId) * step(texId, 4.0 + 0.5);
|
||||||
|
color = mix(color, side, select);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
vec4 side = texture2D(maps[5], st);
|
||||||
|
float select = step(5.0 - 0.5, texId) * step(texId, 5.0 + 0.5);
|
||||||
color = mix(color, side, select);
|
color = mix(color, side, select);
|
||||||
}
|
}
|
||||||
return color;
|
return color;
|
||||||
|
@ -55,23 +90,48 @@ vec4 texturesAsCube(in sampler2D maps[6], in vec3 direction)
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec3 n = pointNormal;
|
vec3 color = pointColor;
|
||||||
|
float alpha = pointAlpha;
|
||||||
|
if (1 == textureEnabled) {
|
||||||
|
vec4 textColor = texture2D(textureId, pointTexCoord);
|
||||||
|
color = textColor.rgb;
|
||||||
|
alpha = textColor.a;
|
||||||
|
}
|
||||||
|
vec3 normal = pointNormal;
|
||||||
|
if (1 == normalMapEnabled) {
|
||||||
|
normal = texture2D(normalMapId, pointTexCoord).rgb;
|
||||||
|
normal = pointTBN * normalize(normal * 2.0 - 1.0);
|
||||||
|
}
|
||||||
|
float metalness = pointMetalness;
|
||||||
|
if (1 == metalnessMapEnabled) {
|
||||||
|
metalness = texture2D(metalnessRoughnessAoMapId, pointTexCoord).b;
|
||||||
|
}
|
||||||
|
float roughness = pointRoughness;
|
||||||
|
if (1 == roughnessMapEnabled) {
|
||||||
|
roughness = texture2D(metalnessRoughnessAoMapId, pointTexCoord).g;
|
||||||
|
}
|
||||||
|
float ambientOcclusion = 1.0;
|
||||||
|
if (1 == aoMapEnabled) {
|
||||||
|
ambientOcclusion = texture2D(metalnessRoughnessAoMapId, pointTexCoord).r;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 n = normal;
|
||||||
vec3 v = normalize(eyePosition - pointPosition);
|
vec3 v = normalize(eyePosition - pointPosition);
|
||||||
vec3 r = reflect(-v, n);
|
vec3 r = reflect(-v, n);
|
||||||
|
|
||||||
float NoV = abs(dot(n, v)) + 1e-5;
|
float NoV = abs(dot(n, v)) + 1e-5;
|
||||||
|
|
||||||
vec3 irradiance = texturesAsCube(environmentIrradianceMapId, r).rgb;
|
vec3 irradiance = texturesAsCube(environmentIrradianceMapId, r).rgb;
|
||||||
vec3 diffuse = irradiance * (1.0 - pointMetalness) * pointColor;
|
vec3 diffuse = irradiance * (1.0 - metalness) * pointColor;
|
||||||
|
|
||||||
vec3 f0 = mix(vec3(0.04), pointColor, pointMetalness);
|
vec3 f0 = mix(vec3(0.04), pointColor, metalness);
|
||||||
vec3 fresnelFactor = fresnelSchlickRoughness(NoV, f0, pointRoughness);
|
vec3 fresnelFactor = fresnelSchlickRoughness(NoV, f0, roughness);
|
||||||
vec3 specular = fresnelFactor * texturesAsCube(environmentSpecularMapId, r).rgb;
|
vec3 specular = fresnelFactor * texturesAsCube(environmentSpecularMapId, r).rgb;
|
||||||
|
|
||||||
vec3 color = diffuse + specular;
|
color = (diffuse + specular) * ambientOcclusion;
|
||||||
|
|
||||||
color = color / (color + vec3(1.0));
|
color = color / (color + vec3(1.0));
|
||||||
color = pow(color, vec3(1.0/2.2));
|
color = pow(color, vec3(1.0/2.2));
|
||||||
|
|
||||||
gl_FragColor = vec4(color, pointAlpha);
|
gl_FragColor = vec4(color, alpha);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,24 +8,43 @@ attribute float roughness;
|
||||||
attribute vec3 tangent;
|
attribute vec3 tangent;
|
||||||
attribute float alpha;
|
attribute float alpha;
|
||||||
uniform mat4 modelMatrix;
|
uniform mat4 modelMatrix;
|
||||||
|
uniform mat3 normalMatrix;
|
||||||
uniform mat4 viewMatrix;
|
uniform mat4 viewMatrix;
|
||||||
uniform mat4 projectionMatrix;
|
uniform mat4 projectionMatrix;
|
||||||
uniform vec3 eyePosition;
|
uniform int normalMapEnabled;
|
||||||
varying vec3 pointPosition;
|
varying vec3 pointPosition;
|
||||||
varying vec3 pointNormal;
|
varying vec3 pointNormal;
|
||||||
varying vec3 pointColor;
|
varying vec3 pointColor;
|
||||||
|
varying vec2 pointTexCoord;
|
||||||
varying float pointAlpha;
|
varying float pointAlpha;
|
||||||
varying float pointMetalness;
|
varying float pointMetalness;
|
||||||
varying float pointRoughness;
|
varying float pointRoughness;
|
||||||
|
varying mat3 pointTBN;
|
||||||
|
|
||||||
|
mat3 transpose(mat3 m)
|
||||||
|
{
|
||||||
|
return mat3(m[0][0], m[1][0], m[2][0],
|
||||||
|
m[0][1], m[1][1], m[2][1],
|
||||||
|
m[0][2], m[1][2], m[2][2]);
|
||||||
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
pointPosition = (modelMatrix * vertex).xyz;
|
pointPosition = (modelMatrix * vertex).xyz;
|
||||||
pointNormal = normalize((modelMatrix * vec4(normal, 1.0)).xyz);
|
pointNormal = normalize((modelMatrix * vec4(normal, 1.0)).xyz);
|
||||||
pointColor = color;
|
pointColor = color;
|
||||||
|
pointTexCoord = texCoord;
|
||||||
pointAlpha = alpha;
|
pointAlpha = alpha;
|
||||||
pointMetalness = metalness;
|
pointMetalness = metalness;
|
||||||
pointRoughness = roughness;
|
pointRoughness = roughness;
|
||||||
|
|
||||||
gl_Position = projectionMatrix * viewMatrix * vec4(pointPosition, 1.0);
|
gl_Position = projectionMatrix * viewMatrix * vec4(pointPosition, 1.0);
|
||||||
|
|
||||||
|
if (1 == normalMapEnabled) {
|
||||||
|
vec3 T = normalize(normalMatrix * tangent);
|
||||||
|
vec3 N = normalize(normalMatrix * normal);
|
||||||
|
T = normalize(T - dot(T, N) * N);
|
||||||
|
vec3 B = cross(N, T);
|
||||||
|
pointTBN = mat3(T, B, N);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
#version 330
|
#version 330
|
||||||
uniform vec3 eyePosition;
|
|
||||||
uniform samplerCube environmentIrradianceMapId;
|
uniform samplerCube environmentIrradianceMapId;
|
||||||
uniform samplerCube environmentSpecularMapId;
|
uniform samplerCube environmentSpecularMapId;
|
||||||
|
uniform sampler2D textureId;
|
||||||
|
uniform int textureEnabled;
|
||||||
|
uniform sampler2D normalMapId;
|
||||||
|
uniform int normalMapEnabled;
|
||||||
|
uniform sampler2D metalnessRoughnessAoMapId;
|
||||||
|
uniform int metalnessMapEnabled;
|
||||||
|
uniform int roughnessMapEnabled;
|
||||||
|
uniform int aoMapEnabled;
|
||||||
|
uniform vec3 eyePosition;
|
||||||
in vec3 pointPosition;
|
in vec3 pointPosition;
|
||||||
in vec3 pointNormal;
|
in vec3 pointNormal;
|
||||||
in vec3 pointColor;
|
in vec3 pointColor;
|
||||||
|
in vec2 pointTexCoord;
|
||||||
in float pointAlpha;
|
in float pointAlpha;
|
||||||
in float pointMetalness;
|
in float pointMetalness;
|
||||||
in float pointRoughness;
|
in float pointRoughness;
|
||||||
|
in mat3 pointTBN;
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
const float PI = 3.1415926;
|
const float PI = 3.1415926;
|
||||||
|
@ -19,23 +29,48 @@ vec3 fresnelSchlickRoughness(float NoV, vec3 f0, float roughness)
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec3 n = pointNormal;
|
vec3 color = pointColor;
|
||||||
|
float alpha = pointAlpha;
|
||||||
|
if (1 == textureEnabled) {
|
||||||
|
vec4 textColor = texture(textureId, pointTexCoord);
|
||||||
|
color = textColor.rgb;
|
||||||
|
alpha = textColor.a;
|
||||||
|
}
|
||||||
|
vec3 normal = pointNormal;
|
||||||
|
if (1 == normalMapEnabled) {
|
||||||
|
normal = texture(normalMapId, pointTexCoord).rgb;
|
||||||
|
normal = pointTBN * normalize(normal * 2.0 - 1.0);
|
||||||
|
}
|
||||||
|
float metalness = pointMetalness;
|
||||||
|
if (1 == metalnessMapEnabled) {
|
||||||
|
metalness = texture(metalnessRoughnessAoMapId, pointTexCoord).b;
|
||||||
|
}
|
||||||
|
float roughness = pointRoughness;
|
||||||
|
if (1 == roughnessMapEnabled) {
|
||||||
|
roughness = texture(metalnessRoughnessAoMapId, pointTexCoord).g;
|
||||||
|
}
|
||||||
|
float ambientOcclusion = 1.0;
|
||||||
|
if (1 == aoMapEnabled) {
|
||||||
|
ambientOcclusion = texture(metalnessRoughnessAoMapId, pointTexCoord).r;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 n = normal;
|
||||||
vec3 v = normalize(eyePosition - pointPosition);
|
vec3 v = normalize(eyePosition - pointPosition);
|
||||||
vec3 r = reflect(-v, n);
|
vec3 r = reflect(-v, n);
|
||||||
|
|
||||||
float NoV = abs(dot(n, v)) + 1e-5;
|
float NoV = abs(dot(n, v)) + 1e-5;
|
||||||
|
|
||||||
vec3 irradiance = texture(environmentIrradianceMapId, r).rgb;
|
vec3 irradiance = texture(environmentIrradianceMapId, r).rgb;
|
||||||
vec3 diffuse = irradiance * (1.0 - pointMetalness) * pointColor;
|
vec3 diffuse = irradiance * (1.0 - metalness) * pointColor;
|
||||||
|
|
||||||
vec3 f0 = mix(vec3(0.04), pointColor, pointMetalness);
|
vec3 f0 = mix(vec3(0.04), pointColor, metalness);
|
||||||
vec3 fresnelFactor = fresnelSchlickRoughness(NoV, f0, pointRoughness);
|
vec3 fresnelFactor = fresnelSchlickRoughness(NoV, f0, roughness);
|
||||||
vec3 specular = fresnelFactor * texture(environmentSpecularMapId, r, 0.0).rgb;
|
vec3 specular = fresnelFactor * texture(environmentSpecularMapId, r, 0.0).rgb;
|
||||||
|
|
||||||
vec3 color = diffuse + specular;
|
color = (diffuse + specular) * ambientOcclusion;
|
||||||
|
|
||||||
color = color / (color + vec3(1.0));
|
color = color / (color + vec3(1.0));
|
||||||
color = pow(color, vec3(1.0/2.2));
|
color = pow(color, vec3(1.0/2.2));
|
||||||
|
|
||||||
fragColor = vec4(color, pointAlpha);
|
fragColor = vec4(color, alpha);
|
||||||
}
|
}
|
|
@ -8,24 +8,43 @@ layout(location = 5) in float roughness;
|
||||||
layout(location = 6) in vec3 tangent;
|
layout(location = 6) in vec3 tangent;
|
||||||
layout(location = 7) in float alpha;
|
layout(location = 7) in float alpha;
|
||||||
uniform mat4 modelMatrix;
|
uniform mat4 modelMatrix;
|
||||||
|
uniform mat3 normalMatrix;
|
||||||
uniform mat4 viewMatrix;
|
uniform mat4 viewMatrix;
|
||||||
uniform mat4 projectionMatrix;
|
uniform mat4 projectionMatrix;
|
||||||
uniform vec3 eyePosition;
|
uniform int normalMapEnabled;
|
||||||
out vec3 pointPosition;
|
out vec3 pointPosition;
|
||||||
out vec3 pointNormal;
|
out vec3 pointNormal;
|
||||||
out vec3 pointColor;
|
out vec3 pointColor;
|
||||||
|
out vec2 pointTexCoord;
|
||||||
out float pointAlpha;
|
out float pointAlpha;
|
||||||
out float pointMetalness;
|
out float pointMetalness;
|
||||||
out float pointRoughness;
|
out float pointRoughness;
|
||||||
|
out mat3 pointTBN;
|
||||||
|
|
||||||
|
mat3 transpose(mat3 m)
|
||||||
|
{
|
||||||
|
return mat3(m[0][0], m[1][0], m[2][0],
|
||||||
|
m[0][1], m[1][1], m[2][1],
|
||||||
|
m[0][2], m[1][2], m[2][2]);
|
||||||
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
pointPosition = (modelMatrix * vertex).xyz;
|
pointPosition = (modelMatrix * vertex).xyz;
|
||||||
pointNormal = normalize((modelMatrix * vec4(normal, 1.0)).xyz);
|
pointNormal = normalize((modelMatrix * vec4(normal, 1.0)).xyz);
|
||||||
pointColor = color;
|
pointColor = color;
|
||||||
|
pointTexCoord = texCoord;
|
||||||
pointAlpha = alpha;
|
pointAlpha = alpha;
|
||||||
pointMetalness = metalness;
|
pointMetalness = metalness;
|
||||||
pointRoughness = roughness;
|
pointRoughness = roughness;
|
||||||
|
|
||||||
gl_Position = projectionMatrix * viewMatrix * vec4(pointPosition, 1.0);
|
gl_Position = projectionMatrix * viewMatrix * vec4(pointPosition, 1.0);
|
||||||
|
|
||||||
|
if (1 == normalMapEnabled) {
|
||||||
|
vec3 T = normalize(normalMatrix * tangent);
|
||||||
|
vec3 N = normalize(normalMatrix * normal);
|
||||||
|
T = normalize(T - dot(T, N) * N);
|
||||||
|
vec3 B = cross(N, T);
|
||||||
|
pointTBN = mat3(T, B, N);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -80,7 +80,6 @@ signals:
|
||||||
void turnaroundChanged();
|
void turnaroundChanged();
|
||||||
void editModeChanged();
|
void editModeChanged();
|
||||||
void resultTextureChanged();
|
void resultTextureChanged();
|
||||||
void resultColorTextureChanged();
|
|
||||||
void postProcessedResultChanged();
|
void postProcessedResultChanged();
|
||||||
void partSubdivStateChanged(dust3d::Uuid partId);
|
void partSubdivStateChanged(dust3d::Uuid partId);
|
||||||
void partXmirrorStateChanged(dust3d::Uuid partId);
|
void partXmirrorStateChanged(dust3d::Uuid partId);
|
||||||
|
|
|
@ -251,7 +251,6 @@ DocumentWindow::DocumentWindow()
|
||||||
m_modelRenderWidget->setMoveAndZoomByWindow(false);
|
m_modelRenderWidget->setMoveAndZoomByWindow(false);
|
||||||
m_modelRenderWidget->move(0, 0);
|
m_modelRenderWidget->move(0, 0);
|
||||||
m_modelRenderWidget->setAttribute(Qt::WA_TransparentForMouseEvents);
|
m_modelRenderWidget->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
m_modelRenderWidget->enableEnvironmentLight();
|
|
||||||
m_modelRenderWidget->toggleWireframe();
|
m_modelRenderWidget->toggleWireframe();
|
||||||
m_modelRenderWidget->disableCullFace();
|
m_modelRenderWidget->disableCullFace();
|
||||||
m_modelRenderWidget->setEyePosition(QVector3D(0.0, 0.0, -4.0));
|
m_modelRenderWidget->setEyePosition(QVector3D(0.0, 0.0, -4.0));
|
||||||
|
@ -726,10 +725,6 @@ DocumentWindow::DocumentWindow()
|
||||||
resultTextureMesh->removeColor();
|
resultTextureMesh->removeColor();
|
||||||
m_modelRenderWidget->updateMesh(resultTextureMesh);
|
m_modelRenderWidget->updateMesh(resultTextureMesh);
|
||||||
});
|
});
|
||||||
connect(m_document, &Document::resultColorTextureChanged, [=]() {
|
|
||||||
if (nullptr != m_document->textureImage)
|
|
||||||
m_modelRenderWidget->updateColorTexture(new QImage(*m_document->textureImage));
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_document, &Document::resultMeshChanged, [=]() {
|
connect(m_document, &Document::resultMeshChanged, [=]() {
|
||||||
auto resultMesh = m_document->takeResultMesh();
|
auto resultMesh = m_document->takeResultMesh();
|
||||||
|
|
|
@ -25,7 +25,7 @@ int main(int argc, char *argv[])
|
||||||
//freopen("dust3d.log", "w", stdout);
|
//freopen("dust3d.log", "w", stdout);
|
||||||
//setvbuf(stdout, 0, _IONBF, 0);
|
//setvbuf(stdout, 0, _IONBF, 0);
|
||||||
|
|
||||||
DocumentWindow *firstWindow = DocumentWindow::createDocumentWindow();
|
DocumentWindow::createDocumentWindow();
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,6 @@ MaterialEditWidget::MaterialEditWidget(const Document *document, QWidget *parent
|
||||||
m_previewWidget->setMinimumSize(128, 128);
|
m_previewWidget->setMinimumSize(128, 128);
|
||||||
m_previewWidget->resize(512, 512);
|
m_previewWidget->resize(512, 512);
|
||||||
m_previewWidget->move(-128, -128);
|
m_previewWidget->move(-128, -128);
|
||||||
m_previewWidget->enableEnvironmentLight();
|
|
||||||
m_previewWidget->setNotGraphics(true);
|
m_previewWidget->setNotGraphics(true);
|
||||||
|
|
||||||
QFont nameFont;
|
QFont nameFont;
|
||||||
|
|
|
@ -13,7 +13,6 @@ MaterialWidget::MaterialWidget(const Document *document, dust3d::Uuid materialId
|
||||||
m_previewWidget->setFixedSize(Theme::materialPreviewImageSize, Theme::materialPreviewImageSize);
|
m_previewWidget->setFixedSize(Theme::materialPreviewImageSize, Theme::materialPreviewImageSize);
|
||||||
m_previewWidget->enableMove(false);
|
m_previewWidget->enableMove(false);
|
||||||
m_previewWidget->enableZoom(false);
|
m_previewWidget->enableZoom(false);
|
||||||
m_previewWidget->enableEnvironmentLight();
|
|
||||||
|
|
||||||
m_nameLabel = new QLabel;
|
m_nameLabel = new QLabel;
|
||||||
m_nameLabel->setAlignment(Qt::AlignCenter);
|
m_nameLabel->setAlignment(Qt::AlignCenter);
|
||||||
|
|
|
@ -26,8 +26,8 @@ ModelMesh::ModelMesh(const ModelMesh &mesh) :
|
||||||
if (nullptr != mesh.m_normalMapImage) {
|
if (nullptr != mesh.m_normalMapImage) {
|
||||||
this->m_normalMapImage = new QImage(*mesh.m_normalMapImage);
|
this->m_normalMapImage = new QImage(*mesh.m_normalMapImage);
|
||||||
}
|
}
|
||||||
if (nullptr != mesh.m_metalnessRoughnessAmbientOcclusionImage) {
|
if (nullptr != mesh.m_metalnessRoughnessAmbientOcclusionMapImage) {
|
||||||
this->m_metalnessRoughnessAmbientOcclusionImage = new QImage(*mesh.m_metalnessRoughnessAmbientOcclusionImage);
|
this->m_metalnessRoughnessAmbientOcclusionMapImage = new QImage(*mesh.m_metalnessRoughnessAmbientOcclusionMapImage);
|
||||||
this->m_hasMetalnessInImage = mesh.m_hasMetalnessInImage;
|
this->m_hasMetalnessInImage = mesh.m_hasMetalnessInImage;
|
||||||
this->m_hasRoughnessInImage = mesh.m_hasRoughnessInImage;
|
this->m_hasRoughnessInImage = mesh.m_hasRoughnessInImage;
|
||||||
this->m_hasAmbientOcclusionInImage = mesh.m_hasAmbientOcclusionInImage;
|
this->m_hasAmbientOcclusionInImage = mesh.m_hasAmbientOcclusionInImage;
|
||||||
|
@ -46,8 +46,8 @@ void ModelMesh::removeColor()
|
||||||
delete this->m_normalMapImage;
|
delete this->m_normalMapImage;
|
||||||
this->m_normalMapImage = nullptr;
|
this->m_normalMapImage = nullptr;
|
||||||
|
|
||||||
delete this->m_metalnessRoughnessAmbientOcclusionImage;
|
delete this->m_metalnessRoughnessAmbientOcclusionMapImage;
|
||||||
this->m_metalnessRoughnessAmbientOcclusionImage = nullptr;
|
this->m_metalnessRoughnessAmbientOcclusionMapImage = nullptr;
|
||||||
|
|
||||||
this->m_hasMetalnessInImage = false;
|
this->m_hasMetalnessInImage = false;
|
||||||
this->m_hasRoughnessInImage = false;
|
this->m_hasRoughnessInImage = false;
|
||||||
|
@ -185,7 +185,7 @@ ModelMesh::~ModelMesh()
|
||||||
m_triangleVertexCount = 0;
|
m_triangleVertexCount = 0;
|
||||||
delete m_textureImage;
|
delete m_textureImage;
|
||||||
delete m_normalMapImage;
|
delete m_normalMapImage;
|
||||||
delete m_metalnessRoughnessAmbientOcclusionImage;
|
delete m_metalnessRoughnessAmbientOcclusionMapImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<dust3d::Vector3> &ModelMesh::vertices()
|
const std::vector<dust3d::Vector3> &ModelMesh::vertices()
|
||||||
|
@ -223,6 +223,13 @@ const QImage *ModelMesh::textureImage()
|
||||||
return m_textureImage;
|
return m_textureImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QImage *ModelMesh::takeTextureImage()
|
||||||
|
{
|
||||||
|
auto image = m_textureImage;
|
||||||
|
m_textureImage = nullptr;
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
void ModelMesh::setNormalMapImage(QImage *normalMapImage)
|
void ModelMesh::setNormalMapImage(QImage *normalMapImage)
|
||||||
{
|
{
|
||||||
m_normalMapImage = normalMapImage;
|
m_normalMapImage = normalMapImage;
|
||||||
|
@ -233,14 +240,28 @@ const QImage *ModelMesh::normalMapImage()
|
||||||
return m_normalMapImage;
|
return m_normalMapImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QImage *ModelMesh::metalnessRoughnessAmbientOcclusionImage()
|
QImage *ModelMesh::takeNormalMapImage()
|
||||||
{
|
{
|
||||||
return m_metalnessRoughnessAmbientOcclusionImage;
|
auto image = m_normalMapImage;
|
||||||
|
m_normalMapImage = nullptr;
|
||||||
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelMesh::setMetalnessRoughnessAmbientOcclusionImage(QImage *image)
|
const QImage *ModelMesh::metalnessRoughnessAmbientOcclusionMapImage()
|
||||||
{
|
{
|
||||||
m_metalnessRoughnessAmbientOcclusionImage = image;
|
return m_metalnessRoughnessAmbientOcclusionMapImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage *ModelMesh::takeMetalnessRoughnessAmbientOcclusionMapImage()
|
||||||
|
{
|
||||||
|
auto image = m_metalnessRoughnessAmbientOcclusionMapImage;
|
||||||
|
m_metalnessRoughnessAmbientOcclusionMapImage = nullptr;
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelMesh::setMetalnessRoughnessAmbientOcclusionMapImage(QImage *image)
|
||||||
|
{
|
||||||
|
m_metalnessRoughnessAmbientOcclusionMapImage = image;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModelMesh::hasMetalnessInImage()
|
bool ModelMesh::hasMetalnessInImage()
|
||||||
|
|
|
@ -25,19 +25,18 @@ public:
|
||||||
~ModelMesh();
|
~ModelMesh();
|
||||||
ModelOpenGLVertex *triangleVertices();
|
ModelOpenGLVertex *triangleVertices();
|
||||||
int triangleVertexCount();
|
int triangleVertexCount();
|
||||||
ModelOpenGLVertex *edgeVertices();
|
|
||||||
int edgeVertexCount();
|
|
||||||
ModelOpenGLVertex *toolVertices();
|
|
||||||
int toolVertexCount();
|
|
||||||
const std::vector<dust3d::Vector3> &vertices();
|
const std::vector<dust3d::Vector3> &vertices();
|
||||||
const std::vector<std::vector<size_t>> &faces();
|
const std::vector<std::vector<size_t>> &faces();
|
||||||
const std::vector<dust3d::Vector3> &triangulatedVertices();
|
const std::vector<dust3d::Vector3> &triangulatedVertices();
|
||||||
void setTextureImage(QImage *textureImage);
|
void setTextureImage(QImage *textureImage);
|
||||||
const QImage *textureImage();
|
const QImage *textureImage();
|
||||||
|
QImage *takeTextureImage();
|
||||||
void setNormalMapImage(QImage *normalMapImage);
|
void setNormalMapImage(QImage *normalMapImage);
|
||||||
const QImage *normalMapImage();
|
const QImage *normalMapImage();
|
||||||
const QImage *metalnessRoughnessAmbientOcclusionImage();
|
QImage *takeNormalMapImage();
|
||||||
void setMetalnessRoughnessAmbientOcclusionImage(QImage *image);
|
const QImage *metalnessRoughnessAmbientOcclusionMapImage();
|
||||||
|
QImage *takeMetalnessRoughnessAmbientOcclusionMapImage();
|
||||||
|
void setMetalnessRoughnessAmbientOcclusionMapImage(QImage *image);
|
||||||
bool hasMetalnessInImage();
|
bool hasMetalnessInImage();
|
||||||
void setHasMetalnessInImage(bool hasInImage);
|
void setHasMetalnessInImage(bool hasInImage);
|
||||||
bool hasRoughnessInImage();
|
bool hasRoughnessInImage();
|
||||||
|
@ -60,7 +59,7 @@ private:
|
||||||
std::vector<dust3d::Vector3> m_triangulatedVertices;
|
std::vector<dust3d::Vector3> m_triangulatedVertices;
|
||||||
QImage *m_textureImage = nullptr;
|
QImage *m_textureImage = nullptr;
|
||||||
QImage *m_normalMapImage = nullptr;
|
QImage *m_normalMapImage = nullptr;
|
||||||
QImage *m_metalnessRoughnessAmbientOcclusionImage = nullptr;
|
QImage *m_metalnessRoughnessAmbientOcclusionMapImage = nullptr;
|
||||||
bool m_hasMetalnessInImage = false;
|
bool m_hasMetalnessInImage = false;
|
||||||
bool m_hasRoughnessInImage = false;
|
bool m_hasRoughnessInImage = false;
|
||||||
bool m_hasAmbientOcclusionInImage = false;
|
bool m_hasAmbientOcclusionInImage = false;
|
||||||
|
|
|
@ -120,15 +120,18 @@ QImage ModelOffscreenRender::toImage(const QSize &size)
|
||||||
auto program = std::make_unique<ModelOpenGLProgram>();
|
auto program = std::make_unique<ModelOpenGLProgram>();
|
||||||
program->load(m_context->format().profile() == QSurfaceFormat::CoreProfile);
|
program->load(m_context->format().profile() == QSurfaceFormat::CoreProfile);
|
||||||
program->bind();
|
program->bind();
|
||||||
program->bindEnvironment();
|
program->bindMaps();
|
||||||
|
|
||||||
program->setUniformValue(program->getUniformLocationByName("eyePosition"), m_eyePosition);
|
program->setUniformValue(program->getUniformLocationByName("eyePosition"), m_eyePosition);
|
||||||
program->setUniformValue(program->getUniformLocationByName("projectionMatrix"), projection);
|
program->setUniformValue(program->getUniformLocationByName("projectionMatrix"), projection);
|
||||||
program->setUniformValue(program->getUniformLocationByName("modelMatrix"), world);
|
program->setUniformValue(program->getUniformLocationByName("modelMatrix"), world);
|
||||||
|
program->setUniformValue(program->getUniformLocationByName("normalMatrix"), world.normalMatrix());
|
||||||
program->setUniformValue(program->getUniformLocationByName("viewMatrix"), camera);
|
program->setUniformValue(program->getUniformLocationByName("viewMatrix"), camera);
|
||||||
|
|
||||||
object->draw();
|
object->draw();
|
||||||
|
|
||||||
|
program->releaseMaps();
|
||||||
|
|
||||||
program->release();
|
program->release();
|
||||||
|
|
||||||
f->glFlush();
|
f->glFlush();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <QOpenGLFunctions>
|
#include <QOpenGLFunctions>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QMutexLocker>
|
||||||
#include <dust3d/base/debug.h>
|
#include <dust3d/base/debug.h>
|
||||||
#include "model_opengl_program.h"
|
#include "model_opengl_program.h"
|
||||||
#include "dds_file.h"
|
#include "dds_file.h"
|
||||||
|
@ -29,6 +30,42 @@ bool ModelOpenGLProgram::isCoreProfile() const
|
||||||
return m_isCoreProfile;
|
return m_isCoreProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelOpenGLProgram::updateTextureImage(std::unique_ptr<QImage> image)
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&m_imageMutex);
|
||||||
|
m_textureImage = std::move(image);
|
||||||
|
m_imageIsDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelOpenGLProgram::updateNormalMapImage(std::unique_ptr<QImage> image)
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&m_imageMutex);
|
||||||
|
m_normalMapImage = std::move(image);
|
||||||
|
m_imageIsDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelOpenGLProgram::updateMetalnessRoughnessAmbientOcclusionMapImage(std::unique_ptr<QImage> image,
|
||||||
|
bool hasMetalnessMap,
|
||||||
|
bool hasRoughnessMap,
|
||||||
|
bool hasAmbientOcclusionMap)
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&m_imageMutex);
|
||||||
|
m_metalnessRoughnessAmbientOcclusionMapImage = std::move(image);
|
||||||
|
m_hasMetalnessMap = hasMetalnessMap;
|
||||||
|
m_hasRoughnessMap = hasRoughnessMap;
|
||||||
|
m_hasAmbientOcclusionMap = hasAmbientOcclusionMap;
|
||||||
|
m_imageIsDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelOpenGLProgram::activeAndBindTexture(int location, QOpenGLTexture *texture)
|
||||||
|
{
|
||||||
|
if (0 == texture->textureId()) {
|
||||||
|
dust3dDebug << "Expected texture with a bound id";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
texture->bind(location);
|
||||||
|
}
|
||||||
|
|
||||||
void ModelOpenGLProgram::load(bool isCoreProfile)
|
void ModelOpenGLProgram::load(bool isCoreProfile)
|
||||||
{
|
{
|
||||||
if (m_isLoaded)
|
if (m_isLoaded)
|
||||||
|
@ -54,8 +91,11 @@ void ModelOpenGLProgram::load(bool isCoreProfile)
|
||||||
m_isLoaded = true;
|
m_isLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelOpenGLProgram::bindEnvironment()
|
void ModelOpenGLProgram::bindMaps()
|
||||||
{
|
{
|
||||||
|
int bindLocation = 1;
|
||||||
|
|
||||||
|
// Bind environment maps
|
||||||
if (m_isCoreProfile) {
|
if (m_isCoreProfile) {
|
||||||
if (!m_environmentIrradianceMap) {
|
if (!m_environmentIrradianceMap) {
|
||||||
DdsFileReader irradianceFile(":/resources/cedar_bridge_irradiance.dds");
|
DdsFileReader irradianceFile(":/resources/cedar_bridge_irradiance.dds");
|
||||||
|
@ -66,11 +106,13 @@ void ModelOpenGLProgram::bindEnvironment()
|
||||||
m_environmentSpecularMap.reset(irradianceFile.createOpenGLTexture());
|
m_environmentSpecularMap.reset(irradianceFile.createOpenGLTexture());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_environmentIrradianceMap->bind(0);
|
bindLocation++;
|
||||||
setUniformValue(getUniformLocationByName("environmentIrradianceMapId"), 0);
|
activeAndBindTexture(bindLocation, m_environmentIrradianceMap.get());
|
||||||
|
setUniformValue(getUniformLocationByName("environmentIrradianceMapId"), bindLocation);
|
||||||
|
|
||||||
m_environmentSpecularMap->bind(1);
|
bindLocation++;
|
||||||
setUniformValue(getUniformLocationByName("environmentSpecularMapId"), 1);
|
activeAndBindTexture(bindLocation, m_environmentSpecularMap.get());
|
||||||
|
setUniformValue(getUniformLocationByName("environmentSpecularMapId"), bindLocation);
|
||||||
} else {
|
} else {
|
||||||
if (!m_environmentIrradianceMaps) {
|
if (!m_environmentIrradianceMaps) {
|
||||||
DdsFileReader irradianceFile(":/resources/cedar_bridge_irradiance.dds");
|
DdsFileReader irradianceFile(":/resources/cedar_bridge_irradiance.dds");
|
||||||
|
@ -81,19 +123,104 @@ void ModelOpenGLProgram::bindEnvironment()
|
||||||
m_environmentSpecularMaps = std::move(irradianceFile.createOpenGLTextures());
|
m_environmentSpecularMaps = std::move(irradianceFile.createOpenGLTextures());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t bindPosition = 0;
|
auto oldBindLocationStart = bindLocation;
|
||||||
|
|
||||||
bindPosition = 0;
|
|
||||||
for (size_t i = 0; i < m_environmentIrradianceMaps->size(); ++i)
|
for (size_t i = 0; i < m_environmentIrradianceMaps->size(); ++i)
|
||||||
m_environmentIrradianceMaps->at(i)->bind(bindPosition++);
|
activeAndBindTexture(bindLocation++, m_environmentIrradianceMaps->at(i).get());
|
||||||
for (size_t i = 0; i < m_environmentSpecularMaps->size(); ++i)
|
for (size_t i = 0; i < m_environmentSpecularMaps->size(); ++i)
|
||||||
m_environmentSpecularMaps->at(i)->bind(bindPosition++);
|
activeAndBindTexture(bindLocation++, m_environmentSpecularMaps->at(i).get());
|
||||||
|
|
||||||
|
bindLocation = oldBindLocationStart;
|
||||||
|
|
||||||
bindPosition = 0;
|
|
||||||
for (size_t i = 0; i < m_environmentIrradianceMaps->size(); ++i)
|
for (size_t i = 0; i < m_environmentIrradianceMaps->size(); ++i)
|
||||||
setUniformValue(getUniformLocationByName("environmentIrradianceMapId[" + std::to_string(i) + "]"), (int)(bindPosition++));
|
setUniformValue(getUniformLocationByName("environmentIrradianceMapId[" + std::to_string(i) + "]"), bindLocation++);
|
||||||
for (size_t i = 0; i < m_environmentSpecularMaps->size(); ++i)
|
for (size_t i = 0; i < m_environmentSpecularMaps->size(); ++i)
|
||||||
setUniformValue(getUniformLocationByName("environmentSpecularMapId[" + std::to_string(i) + "]"), (int)(bindPosition++));
|
setUniformValue(getUniformLocationByName("environmentSpecularMapId[" + std::to_string(i) + "]"), bindLocation++);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind texture, normal map, and other maps
|
||||||
|
if (m_imageIsDirty) {
|
||||||
|
QMutexLocker lock(&m_imageMutex);
|
||||||
|
if (m_imageIsDirty) {
|
||||||
|
m_imageIsDirty = false;
|
||||||
|
if (m_texture) {
|
||||||
|
m_texture->destroy();
|
||||||
|
m_texture.reset();
|
||||||
|
}
|
||||||
|
if (m_textureImage) {
|
||||||
|
m_texture = std::make_unique<QOpenGLTexture>(*m_textureImage);
|
||||||
|
}
|
||||||
|
if (m_normalMap) {
|
||||||
|
m_normalMap->destroy();
|
||||||
|
m_normalMap.reset();
|
||||||
|
}
|
||||||
|
if (m_normalMapImage) {
|
||||||
|
m_normalMap = std::make_unique<QOpenGLTexture>(*m_normalMapImage);
|
||||||
|
}
|
||||||
|
if (m_metalnessRoughnessAmbientOcclusionMap) {
|
||||||
|
m_metalnessRoughnessAmbientOcclusionMap->destroy();
|
||||||
|
m_metalnessRoughnessAmbientOcclusionMap.reset();
|
||||||
|
}
|
||||||
|
if (m_metalnessRoughnessAmbientOcclusionMapImage) {
|
||||||
|
m_metalnessRoughnessAmbientOcclusionMap = std::make_unique<QOpenGLTexture>(*m_metalnessRoughnessAmbientOcclusionMapImage);
|
||||||
|
}
|
||||||
|
m_metalnessMapEnabled = m_hasMetalnessMap;
|
||||||
|
m_roughnessMapEnabled = m_hasRoughnessMap;
|
||||||
|
m_ambientOcclusionMapEnabled = m_hasAmbientOcclusionMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bindLocation++;
|
||||||
|
if (m_texture) {
|
||||||
|
activeAndBindTexture(bindLocation, m_texture.get());
|
||||||
|
setUniformValue(getUniformLocationByName("textureId"), bindLocation);
|
||||||
|
setUniformValue(getUniformLocationByName("textureEnabled"), (int)1);
|
||||||
|
} else {
|
||||||
|
setUniformValue(getUniformLocationByName("textureId"), (int)0);
|
||||||
|
setUniformValue(getUniformLocationByName("textureEnabled"), (int)0);
|
||||||
|
}
|
||||||
|
bindLocation++;
|
||||||
|
if (m_normalMap) {
|
||||||
|
activeAndBindTexture(bindLocation, m_normalMap.get());
|
||||||
|
setUniformValue(getUniformLocationByName("normalMapId"), bindLocation);
|
||||||
|
setUniformValue(getUniformLocationByName("normalMapEnabled"), (int)1);
|
||||||
|
} else {
|
||||||
|
setUniformValue(getUniformLocationByName("normalMapId"), (int)0);
|
||||||
|
setUniformValue(getUniformLocationByName("normalMapEnabled"), (int)0);
|
||||||
|
}
|
||||||
|
bindLocation++;
|
||||||
|
if (m_metalnessRoughnessAmbientOcclusionMap) {
|
||||||
|
activeAndBindTexture(bindLocation, m_metalnessRoughnessAmbientOcclusionMap.get());
|
||||||
|
setUniformValue(getUniformLocationByName("metalnessRoughnessAoMapId"), bindLocation);
|
||||||
|
setUniformValue(getUniformLocationByName("metalnessMapEnabled"), (int)m_metalnessMapEnabled);
|
||||||
|
setUniformValue(getUniformLocationByName("roughnessMapEnabled"), (int)m_roughnessMapEnabled);
|
||||||
|
setUniformValue(getUniformLocationByName("aoMapEnabled"), (int)m_ambientOcclusionMapEnabled);
|
||||||
|
} else {
|
||||||
|
setUniformValue(getUniformLocationByName("metalnessRoughnessAoMapId"), (int)0);
|
||||||
|
setUniformValue(getUniformLocationByName("metalnessMapEnabled"), (int)0);
|
||||||
|
setUniformValue(getUniformLocationByName("roughnessMapEnabled"), (int)0);
|
||||||
|
setUniformValue(getUniformLocationByName("aoMapEnabled"), (int)0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelOpenGLProgram::releaseMaps()
|
||||||
|
{
|
||||||
|
if (m_texture)
|
||||||
|
m_texture->release();
|
||||||
|
if (m_normalMap)
|
||||||
|
m_normalMap->release();
|
||||||
|
if (m_metalnessRoughnessAmbientOcclusionMap)
|
||||||
|
m_metalnessRoughnessAmbientOcclusionMap->release();
|
||||||
|
if (m_environmentIrradianceMap)
|
||||||
|
m_environmentIrradianceMap->release();
|
||||||
|
if (m_environmentSpecularMap)
|
||||||
|
m_environmentSpecularMap->release();
|
||||||
|
if (m_environmentIrradianceMaps) {
|
||||||
|
for (size_t i = 0; i < m_environmentIrradianceMaps->size(); ++i)
|
||||||
|
m_environmentIrradianceMaps->at(i)->release();
|
||||||
|
}
|
||||||
|
if (m_environmentSpecularMaps) {
|
||||||
|
for (size_t i = 0; i < m_environmentSpecularMaps->size(); ++i)
|
||||||
|
m_environmentSpecularMaps->at(i)->release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QOpenGLShaderProgram>
|
#include <QOpenGLShaderProgram>
|
||||||
#include <QOpenGLShader>
|
#include <QOpenGLShader>
|
||||||
#include <QOpenGLTexture>
|
#include <QOpenGLTexture>
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
class ModelOpenGLProgram: public QOpenGLShaderProgram
|
class ModelOpenGLProgram: public QOpenGLShaderProgram
|
||||||
{
|
{
|
||||||
|
@ -12,10 +13,18 @@ public:
|
||||||
void load(bool isCoreProfile=false);
|
void load(bool isCoreProfile=false);
|
||||||
int getUniformLocationByName(const std::string &name);
|
int getUniformLocationByName(const std::string &name);
|
||||||
bool isCoreProfile() const;
|
bool isCoreProfile() const;
|
||||||
void bindEnvironment();
|
void bindMaps();
|
||||||
|
void releaseMaps();
|
||||||
|
void updateTextureImage(std::unique_ptr<QImage> image);
|
||||||
|
void updateNormalMapImage(std::unique_ptr<QImage> image);
|
||||||
|
void updateMetalnessRoughnessAmbientOcclusionMapImage(std::unique_ptr<QImage> image,
|
||||||
|
bool hasMetalnessMap = false,
|
||||||
|
bool hasRoughnessMap = false,
|
||||||
|
bool hasAmbientOcclusionMap = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addShaderFromResource(QOpenGLShader::ShaderType type, const char *resourceName);
|
void addShaderFromResource(QOpenGLShader::ShaderType type, const char *resourceName);
|
||||||
|
void activeAndBindTexture(int location, QOpenGLTexture *texture);
|
||||||
|
|
||||||
bool m_isLoaded = false;
|
bool m_isLoaded = false;
|
||||||
bool m_isCoreProfile = false;
|
bool m_isCoreProfile = false;
|
||||||
|
@ -25,6 +34,20 @@ private:
|
||||||
std::unique_ptr<QOpenGLTexture> m_environmentSpecularMap;
|
std::unique_ptr<QOpenGLTexture> m_environmentSpecularMap;
|
||||||
std::unique_ptr<std::vector<std::unique_ptr<QOpenGLTexture>>> m_environmentIrradianceMaps;
|
std::unique_ptr<std::vector<std::unique_ptr<QOpenGLTexture>>> m_environmentIrradianceMaps;
|
||||||
std::unique_ptr<std::vector<std::unique_ptr<QOpenGLTexture>>> m_environmentSpecularMaps;
|
std::unique_ptr<std::vector<std::unique_ptr<QOpenGLTexture>>> m_environmentSpecularMaps;
|
||||||
|
std::unique_ptr<QImage> m_textureImage;
|
||||||
|
std::unique_ptr<QImage> m_normalMapImage;
|
||||||
|
std::unique_ptr<QImage> m_metalnessRoughnessAmbientOcclusionMapImage;
|
||||||
|
std::unique_ptr<QOpenGLTexture> m_texture;
|
||||||
|
std::unique_ptr<QOpenGLTexture> m_normalMap;
|
||||||
|
std::unique_ptr<QOpenGLTexture> m_metalnessRoughnessAmbientOcclusionMap;
|
||||||
|
bool m_hasMetalnessMap = false;
|
||||||
|
bool m_hasRoughnessMap = false;
|
||||||
|
bool m_hasAmbientOcclusionMap = false;
|
||||||
|
QMutex m_imageMutex;
|
||||||
|
bool m_imageIsDirty = false;
|
||||||
|
bool m_metalnessMapEnabled = false;
|
||||||
|
bool m_roughnessMapEnabled = false;
|
||||||
|
bool m_ambientOcclusionMapEnabled = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -174,16 +174,6 @@ bool ModelWidget::isWireframeVisible()
|
||||||
return m_isWireframeVisible;
|
return m_isWireframeVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelWidget::enableEnvironmentLight()
|
|
||||||
{
|
|
||||||
m_isEnvironmentLightEnabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ModelWidget::isEnvironmentLightEnabled()
|
|
||||||
{
|
|
||||||
return m_isEnvironmentLightEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModelWidget::toggleRotation()
|
void ModelWidget::toggleRotation()
|
||||||
{
|
{
|
||||||
if (nullptr != m_rotationTimer) {
|
if (nullptr != m_rotationTimer) {
|
||||||
|
@ -371,9 +361,19 @@ void ModelWidget::setMousePickRadius(float radius)
|
||||||
|
|
||||||
void ModelWidget::updateMesh(ModelMesh *mesh)
|
void ModelWidget::updateMesh(ModelMesh *mesh)
|
||||||
{
|
{
|
||||||
|
if (!m_modelOpenGLProgram)
|
||||||
|
m_modelOpenGLProgram = std::make_unique<ModelOpenGLProgram>();
|
||||||
|
m_modelOpenGLProgram->updateTextureImage(std::unique_ptr<QImage>(nullptr != mesh ? mesh->takeTextureImage() : nullptr));
|
||||||
|
m_modelOpenGLProgram->updateNormalMapImage(std::unique_ptr<QImage>(nullptr != mesh ? mesh->takeNormalMapImage() : nullptr));
|
||||||
|
m_modelOpenGLProgram->updateMetalnessRoughnessAmbientOcclusionMapImage(std::unique_ptr<QImage>(nullptr != mesh ? mesh->takeMetalnessRoughnessAmbientOcclusionMapImage() : nullptr),
|
||||||
|
mesh && mesh->hasMetalnessInImage(),
|
||||||
|
mesh && mesh->hasRoughnessInImage(),
|
||||||
|
mesh && mesh->hasAmbientOcclusionInImage());
|
||||||
|
|
||||||
if (!m_modelOpenGLObject)
|
if (!m_modelOpenGLObject)
|
||||||
m_modelOpenGLObject = std::make_unique<ModelOpenGLObject>();
|
m_modelOpenGLObject = std::make_unique<ModelOpenGLObject>();
|
||||||
m_modelOpenGLObject->update(std::unique_ptr<ModelMesh>(mesh));
|
m_modelOpenGLObject->update(std::unique_ptr<ModelMesh>(mesh));
|
||||||
|
|
||||||
emit renderParametersChanged();
|
emit renderParametersChanged();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
@ -387,11 +387,6 @@ void ModelWidget::updateWireframeMesh(MonochromeMesh *mesh)
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelWidget::updateColorTexture(QImage *colorTextureImage)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
int ModelWidget::widthInPixels()
|
int ModelWidget::widthInPixels()
|
||||||
{
|
{
|
||||||
return m_widthInPixels;
|
return m_widthInPixels;
|
||||||
|
@ -511,19 +506,20 @@ void ModelWidget::paintGL()
|
||||||
m_monochromeOpenGLProgram->load(format().profile() == QSurfaceFormat::CoreProfile);
|
m_monochromeOpenGLProgram->load(format().profile() == QSurfaceFormat::CoreProfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drawModel();
|
drawModel();
|
||||||
if (m_isWireframeVisible)
|
if (m_isWireframeVisible) {
|
||||||
drawWireframe();
|
drawWireframe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelWidget::drawWireframe()
|
void ModelWidget::drawWireframe()
|
||||||
{
|
{
|
||||||
m_monochromeOpenGLProgram->bind();
|
m_monochromeOpenGLProgram->bind();
|
||||||
|
|
||||||
m_monochromeOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("projectionMatrix"), m_projection);
|
m_monochromeOpenGLProgram->setUniformValue(m_monochromeOpenGLProgram->getUniformLocationByName("projectionMatrix"), m_projection);
|
||||||
m_monochromeOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("modelMatrix"), m_world);
|
m_monochromeOpenGLProgram->setUniformValue(m_monochromeOpenGLProgram->getUniformLocationByName("modelMatrix"), m_world);
|
||||||
m_monochromeOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("viewMatrix"), m_camera);
|
m_monochromeOpenGLProgram->setUniformValue(m_monochromeOpenGLProgram->getUniformLocationByName("viewMatrix"), m_camera);
|
||||||
|
|
||||||
if (m_wireframeOpenGLObject)
|
if (m_wireframeOpenGLObject)
|
||||||
m_wireframeOpenGLObject->draw();
|
m_wireframeOpenGLObject->draw();
|
||||||
|
@ -538,12 +534,15 @@ void ModelWidget::drawModel()
|
||||||
m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("eyePosition"), m_eyePosition);
|
m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("eyePosition"), m_eyePosition);
|
||||||
m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("projectionMatrix"), m_projection);
|
m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("projectionMatrix"), m_projection);
|
||||||
m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("modelMatrix"), m_world);
|
m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("modelMatrix"), m_world);
|
||||||
|
m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("normalMatrix"), m_world.normalMatrix());
|
||||||
m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("viewMatrix"), m_camera);
|
m_modelOpenGLProgram->setUniformValue(m_modelOpenGLProgram->getUniformLocationByName("viewMatrix"), m_camera);
|
||||||
|
|
||||||
m_modelOpenGLProgram->bindEnvironment();
|
m_modelOpenGLProgram->bindMaps();
|
||||||
|
|
||||||
if (m_modelOpenGLObject)
|
if (m_modelOpenGLObject)
|
||||||
m_modelOpenGLObject->draw();
|
m_modelOpenGLObject->draw();
|
||||||
|
|
||||||
|
m_modelOpenGLProgram->releaseMaps();
|
||||||
|
|
||||||
m_modelOpenGLProgram->release();
|
m_modelOpenGLProgram->release();
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,12 +36,9 @@ public:
|
||||||
~ModelWidget();
|
~ModelWidget();
|
||||||
void updateMesh(ModelMesh *mesh);
|
void updateMesh(ModelMesh *mesh);
|
||||||
void updateWireframeMesh(MonochromeMesh *mesh);
|
void updateWireframeMesh(MonochromeMesh *mesh);
|
||||||
void updateColorTexture(QImage *colorTextureImage);
|
|
||||||
void toggleWireframe();
|
void toggleWireframe();
|
||||||
bool isWireframeVisible();
|
bool isWireframeVisible();
|
||||||
void toggleRotation();
|
void toggleRotation();
|
||||||
void enableEnvironmentLight();
|
|
||||||
bool isEnvironmentLightEnabled();
|
|
||||||
void enableMove(bool enabled);
|
void enableMove(bool enabled);
|
||||||
void enableZoom(bool enabled);
|
void enableZoom(bool enabled);
|
||||||
void enableMousePicking(bool enabled);
|
void enableMousePicking(bool enabled);
|
||||||
|
@ -113,7 +110,6 @@ private:
|
||||||
bool m_moveAndZoomByWindow = true;
|
bool m_moveAndZoomByWindow = true;
|
||||||
bool m_enableCullFace = true;
|
bool m_enableCullFace = true;
|
||||||
bool m_notGraphics = false;
|
bool m_notGraphics = false;
|
||||||
bool m_isEnvironmentLightEnabled = false;
|
|
||||||
bool m_isWireframeVisible = false;
|
bool m_isWireframeVisible = false;
|
||||||
std::pair<QVector3D, QVector3D> screenPositionToMouseRay(const QPoint &screenPosition);
|
std::pair<QVector3D, QVector3D> screenPositionToMouseRay(const QPoint &screenPosition);
|
||||||
void updateProjectionMatrix();
|
void updateProjectionMatrix();
|
||||||
|
|
|
@ -13,6 +13,45 @@ MonochromeMesh::MonochromeMesh(MonochromeMesh &&mesh)
|
||||||
|
|
||||||
MonochromeMesh::MonochromeMesh(const dust3d::Object &object)
|
MonochromeMesh::MonochromeMesh(const dust3d::Object &object)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
auto buildSection = [](const dust3d::Vector3 &origin,
|
||||||
|
const dust3d::Vector3 &faceNormal,
|
||||||
|
const dust3d::Vector3 &tagent,
|
||||||
|
double radius)
|
||||||
|
{
|
||||||
|
auto upDirection = dust3d::Vector3::crossProduct(tagent, faceNormal);
|
||||||
|
return std::vector<dust3d::Vector3> {
|
||||||
|
origin + tagent * radius,
|
||||||
|
origin - upDirection * radius,
|
||||||
|
origin - tagent * radius,
|
||||||
|
origin + upDirection * radius
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
auto calculateTagent = [](const dust3d::Vector3 &direction) {
|
||||||
|
const std::vector<dust3d::Vector3> axisList = {
|
||||||
|
dust3d::Vector3 {1, 0, 0},
|
||||||
|
dust3d::Vector3 {0, 1, 0},
|
||||||
|
dust3d::Vector3 {0, 0, 1},
|
||||||
|
};
|
||||||
|
float maxDot = -1;
|
||||||
|
size_t nearAxisIndex = 0;
|
||||||
|
bool reversed = false;
|
||||||
|
for (size_t i = 0; i < axisList.size(); ++i) {
|
||||||
|
const auto axis = axisList[i];
|
||||||
|
auto dot = dust3d::Vector3::dotProduct(axis, direction);
|
||||||
|
auto positiveDot = std::abs(dot);
|
||||||
|
if (positiveDot >= maxDot) {
|
||||||
|
reversed = dot < 0;
|
||||||
|
maxDot = positiveDot;
|
||||||
|
nearAxisIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const auto& choosenAxis = axisList[(nearAxisIndex + 1) % 3];
|
||||||
|
auto startDirection = dust3d::Vector3::crossProduct(direction, choosenAxis).normalized();
|
||||||
|
return reversed ? -startDirection : startDirection;
|
||||||
|
};
|
||||||
|
*/
|
||||||
std::set<std::pair<size_t, size_t>> halfEdges;
|
std::set<std::pair<size_t, size_t>> halfEdges;
|
||||||
for (const auto &face: object.triangleAndQuads) {
|
for (const auto &face: object.triangleAndQuads) {
|
||||||
if (3 == face.size()) {
|
if (3 == face.size()) {
|
||||||
|
@ -33,6 +72,7 @@ MonochromeMesh::MonochromeMesh(const dust3d::Object &object)
|
||||||
halfEdges.insert({face[3], face[0]});
|
halfEdges.insert({face[3], face[0]});
|
||||||
halfEdges.insert({face[0], face[3]});
|
halfEdges.insert({face[0], face[3]});
|
||||||
}
|
}
|
||||||
|
//m_triangleVertices.reserve(halfEdges.size() * 24);
|
||||||
m_lineVertices.reserve(halfEdges.size() * 2);
|
m_lineVertices.reserve(halfEdges.size() * 2);
|
||||||
for (const auto &halfEdge: halfEdges) {
|
for (const auto &halfEdge: halfEdges) {
|
||||||
// For two halfedges shared one edge, only output one line
|
// For two halfedges shared one edge, only output one line
|
||||||
|
@ -40,8 +80,60 @@ MonochromeMesh::MonochromeMesh(const dust3d::Object &object)
|
||||||
continue;
|
continue;
|
||||||
const auto &from = object.vertices[halfEdge.first];
|
const auto &from = object.vertices[halfEdge.first];
|
||||||
const auto &to = object.vertices[halfEdge.second];
|
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 {
|
||||||
m_lineVertices.emplace_back(MonochromeOpenGLVertex {(GLfloat)to.x(), (GLfloat)to.y(), (GLfloat)to.z()});
|
(GLfloat)from.x(),
|
||||||
|
(GLfloat)from.y(),
|
||||||
|
(GLfloat)from.z()
|
||||||
|
});
|
||||||
|
m_lineVertices.emplace_back(MonochromeOpenGLVertex {
|
||||||
|
(GLfloat)to.x(),
|
||||||
|
(GLfloat)to.y(),
|
||||||
|
(GLfloat)to.z()
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
auto direction = to - from;
|
||||||
|
auto sectionNormal = direction.normalized();
|
||||||
|
auto sectionTagent = calculateTagent(sectionNormal);
|
||||||
|
auto sectionTo = buildSection(to, sectionNormal, sectionTagent, 0.002);
|
||||||
|
auto sectionFrom = sectionTo;
|
||||||
|
for (auto &it: sectionFrom)
|
||||||
|
it = it - direction;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sectionTo.size(); ++i) {
|
||||||
|
size_t j = (i + 1) % sectionTo.size();
|
||||||
|
m_triangleVertices.emplace_back(MonochromeOpenGLVertex {
|
||||||
|
(GLfloat)sectionTo[i].x(),
|
||||||
|
(GLfloat)sectionTo[i].y(),
|
||||||
|
(GLfloat)sectionTo[i].z()
|
||||||
|
});
|
||||||
|
m_triangleVertices.emplace_back(MonochromeOpenGLVertex {
|
||||||
|
(GLfloat)sectionFrom[i].x(),
|
||||||
|
(GLfloat)sectionFrom[i].y(),
|
||||||
|
(GLfloat)sectionFrom[i].z()
|
||||||
|
});
|
||||||
|
m_triangleVertices.emplace_back(MonochromeOpenGLVertex {
|
||||||
|
(GLfloat)sectionTo[j].x(),
|
||||||
|
(GLfloat)sectionTo[j].y(),
|
||||||
|
(GLfloat)sectionTo[j].z()
|
||||||
|
});
|
||||||
|
|
||||||
|
m_triangleVertices.emplace_back(MonochromeOpenGLVertex {
|
||||||
|
(GLfloat)sectionFrom[i].x(),
|
||||||
|
(GLfloat)sectionFrom[i].y(),
|
||||||
|
(GLfloat)sectionFrom[i].z()
|
||||||
|
});
|
||||||
|
m_triangleVertices.emplace_back(MonochromeOpenGLVertex {
|
||||||
|
(GLfloat)sectionFrom[j].x(),
|
||||||
|
(GLfloat)sectionFrom[j].y(),
|
||||||
|
(GLfloat)sectionFrom[j].z()
|
||||||
|
});
|
||||||
|
m_triangleVertices.emplace_back(MonochromeOpenGLVertex {
|
||||||
|
(GLfloat)sectionTo[j].x(),
|
||||||
|
(GLfloat)sectionTo[j].y(),
|
||||||
|
(GLfloat)sectionTo[j].z()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef DUST3D_APPLICATION_MONOCHROME_OPENGL_PROGRAM_H_
|
#ifndef DUST3D_APPLICATION_MONOCHROME_OPENGL_PROGRAM_H_
|
||||||
#define DUST3D_APPLICATION_MONOCHROME_OPENGL_PROGRAM_H_
|
#define DUST3D_APPLICATION_MONOCHROME_OPENGL_PROGRAM_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <QOpenGLShaderProgram>
|
#include <QOpenGLShaderProgram>
|
||||||
#include <QOpenGLShader>
|
#include <QOpenGLShader>
|
||||||
|
|
||||||
|
|
|
@ -652,7 +652,7 @@ void TextureGenerator::generate()
|
||||||
if (nullptr != m_resultTextureNormalImage)
|
if (nullptr != m_resultTextureNormalImage)
|
||||||
m_resultMesh->setNormalMapImage(new QImage(*m_resultTextureNormalImage));
|
m_resultMesh->setNormalMapImage(new QImage(*m_resultTextureNormalImage));
|
||||||
if (hasMetalnessMap || hasRoughnessMap || hasAmbientOcclusionMap) {
|
if (hasMetalnessMap || hasRoughnessMap || hasAmbientOcclusionMap) {
|
||||||
m_resultMesh->setMetalnessRoughnessAmbientOcclusionImage(combineMetalnessRoughnessAmbientOcclusionImages(
|
m_resultMesh->setMetalnessRoughnessAmbientOcclusionMapImage(combineMetalnessRoughnessAmbientOcclusionImages(
|
||||||
m_resultTextureMetalnessImage,
|
m_resultTextureMetalnessImage,
|
||||||
m_resultTextureRoughnessImage,
|
m_resultTextureRoughnessImage,
|
||||||
m_resultTextureAmbientOcclusionImage));
|
m_resultTextureAmbientOcclusionImage));
|
||||||
|
|
Loading…
Reference in New Issue