Skip to content

Commit

Permalink
Fix #3534
Browse files Browse the repository at this point in the history
  • Loading branch information
StasJ committed Feb 28, 2024
1 parent c8eaec5 commit 6ac7b3e
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 34 deletions.
13 changes: 13 additions & 0 deletions apps/vaporgui/ParticleEventRouter.cpp
Expand Up @@ -8,6 +8,14 @@ using namespace VAPoR;

static RenderEventRouterRegistrar<ParticleEventRouter> registrar(ParticleEventRouter::GetClassType());

struct PParticleRadiusVariableSelector : public PVariableSelector {
PParticleRadiusVariableSelector()
: PVariableSelector(ParticleParams::RenderRadiusVariableTag, "Particle Radius Scalar") {
AddNullOption();
ShowParticleVars();
}
};

ParticleEventRouter::ParticleEventRouter(QWidget *parent, ControlExec *ce) : RenderEventRouterGUI(ce, BarbParams::GetClassType())
{
// clang-format off
Expand All @@ -18,6 +26,7 @@ ParticleEventRouter::ParticleEventRouter(QWidget *parent, ControlExec *ce) : Ren
(new PXFieldVariableSelector)->ShowParticleVars(),
(new PYFieldVariableSelector)->ShowParticleVars(),
(new PZFieldVariableSelector)->ShowParticleVars(),
(new PParticleRadiusVariableSelector()),
}),
new PSection("Data Fidelity", {
(new PIntegerInput(ParticleParams::StrideTag, "Stride"))->SetRange(1, 1000)
Expand All @@ -28,6 +37,10 @@ ParticleEventRouter::ParticleEventRouter(QWidget *parent, ControlExec *ce) : Ren
new PTFEditor,
new PSection("Particles", {
(new PDoubleSliderEdit(ParticleParams::RenderRadiusScalarTag, "Radius"))->SetRange(0.5, 25)->AllowUserRange(true)->EnableDynamicUpdate()->EnableBasedOnParam(ParticleParams::RenderLegacyTag, false),
(new PParticleRadiusVariableSelector()),
// (new PShowIf(ParticleParams::RenderRadiusVariableTag))->Not()->Equals("")->Then({
// (new PDoubleSliderEdit(ParticleParams::RenderRadiusVariableStrengthTag, "Radius Variable Strength"))->SetRange(0.001, 1)->AllowUserRange(true)->EnableDynamicUpdate()
// }),
new PCheckbox(ParticleParams::ShowDirectionTag, "Show direction"),
(new PDoubleSliderEdit(ParticleParams::DirectionScaleTag, "Length scale"))->SetRange(0.0001, 10)->AllowUserRange(true)->EnableDynamicUpdate()->EnableBasedOnParam(ParticleParams::ShowDirectionTag),
(new PXFieldVariableSelector)->ShowParticleVars()->EnableBasedOnParam(ParticleParams::ShowDirectionTag),
Expand Down
2 changes: 2 additions & 0 deletions include/vapor/ParamsBase.h
Expand Up @@ -28,6 +28,8 @@
#include <vapor/MyBase.h>
#include <vapor/XmlNode.h>

#define PARAMS_IMPL_TAG(class, tag) const std::string class::tag = #tag;

namespace VAPoR {

//
Expand Down
2 changes: 2 additions & 0 deletions include/vapor/ParticleParams.h
Expand Up @@ -36,6 +36,8 @@ class PARAMS_API ParticleParams : public RenderParams {

//! Scale the rendered particle size
static const std::string RenderRadiusScalarTag;
static const std::string RenderRadiusVariableTag;
static const std::string RenderRadiusVariableStrengthTag;

static const std::string RenderRadiusBaseTag;
static const std::string RenderLegacyTag;
Expand Down
1 change: 1 addition & 0 deletions include/vapor/ParticleRenderer.h
Expand Up @@ -64,6 +64,7 @@ class RENDER_API ParticleRenderer : public Renderer {
float directionScale;
size_t stride;
string varName;
string radiusVarName;
std::vector<std::string> fieldVars;
} _cacheParams;

Expand Down
3 changes: 3 additions & 0 deletions lib/params/ParticleParams.cpp
Expand Up @@ -13,6 +13,8 @@ const std::string ParticleParams::ShowDirectionTag = "ShowDirectionTag";
const std::string ParticleParams::DirectionScaleTag = "DirectionScaleTag";
const std::string ParticleParams::StrideTag = "StrideTag";
const std::string ParticleParams::RenderRadiusScalarTag = "RenderRadiusScalarTag";
PARAMS_IMPL_TAG(ParticleParams, RenderRadiusVariableTag);
PARAMS_IMPL_TAG(ParticleParams, RenderRadiusVariableStrengthTag);
const std::string ParticleParams::LightingEnabledTag = "LightingEnabledTag";
const std::string ParticleParams::RenderRadiusBaseTag = "RenderRadiusBaseTag";
const std::string ParticleParams::RenderLegacyTag = "RenderLegacyTag";
Expand Down Expand Up @@ -47,6 +49,7 @@ void ParticleParams::_init()
SetValueDouble(DirectionScaleTag, "", 1);
SetValueLong(StrideTag, "", 1);
SetValueDouble(RenderRadiusScalarTag, "", 8.);
SetValueDouble(RenderRadiusVariableStrengthTag, "", 1.);
SetValueDouble(RenderRadiusBaseTag, "", -1);
SetValueLong(RenderLegacyTag, "", false);
SetValueLong(LightingEnabledTag, "", true);
Expand Down
87 changes: 62 additions & 25 deletions lib/render/ParticleRenderer.cpp
Expand Up @@ -159,26 +159,38 @@ int ParticleRenderer::_initializeGL() {
return 0;
}

static void SetupParticlePointGL(const int VAO, const int VBO) {
static void SetupParticlePointGL(const int VAO, const int VBO, const bool dynamicSize) {
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), NULL);
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (void *)sizeof(glm::vec3));
int elSize = sizeof(glm::vec4);
if (dynamicSize) elSize += sizeof(float);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, elSize, NULL);
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, elSize, (void *)sizeof(glm::vec3));
if (dynamicSize)
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, elSize, (void *)sizeof(glm::vec4));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
if (dynamicSize)
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}

static void SetupParticleDirectionGL(const int VAO, const int VBO) {
static void SetupParticleDirectionGL(const int VAO, const int VBO, const bool dynamicSize) {
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float)*7, NULL);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float)*7, (void *)sizeof(glm::vec3));
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(float)*7, (void *)(2*sizeof(glm::vec3)));
int elSize = sizeof(float)*7;
if (dynamicSize) elSize += sizeof(float);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, elSize, NULL);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, elSize, (void *)sizeof(glm::vec3));
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, elSize, (void *)(2*sizeof(glm::vec3)));
if (dynamicSize)
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, elSize, (void *)(sizeof(float)*7));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
if (dynamicSize)
glEnableVertexAttribArray(3);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
Expand All @@ -198,6 +210,7 @@ bool ParticleRenderer::_particleCacheIsDirty() const {
if (_cacheParams.stride != p->GetValueLong( ParticleParams::StrideTag, 1)) return true;
if (_cacheParams.varName != p->GetVariableName() ) return true;
if (_cacheParams.fieldVars != p->GetFieldVariableNames() ) return true;
if (_cacheParams.radiusVarName != p->GetValueString( ParticleParams::RenderRadiusVariableTag, "")) return true;
if (_cacheParams.direction != (bool)p->GetValueLong( ParticleParams::ShowDirectionTag, false)) return true;
if (_cacheParams.directionScale != p->GetValueDouble( ParticleParams::DirectionScaleTag, false)) return true;

Expand All @@ -220,6 +233,7 @@ void ParticleRenderer::_resetParticleCache() {
_cacheParams.stride = p->GetValueLong(ParticleParams::StrideTag, 1);
_cacheParams.varName = p->GetVariableName();
_cacheParams.fieldVars = p->GetFieldVariableNames();
_cacheParams.radiusVarName = p->GetValueString( ParticleParams::RenderRadiusVariableTag, "");
}

bool ParticleRenderer::_colormapCacheIsDirty() const {
Expand Down Expand Up @@ -264,12 +278,16 @@ int ParticleRenderer::_renderParticlesHelper()
}
float radius = radiusBase * rp->GetValueDouble(ParticleParams::RenderRadiusScalarTag, 1.);

ShaderProgram *shader = nullptr;

string shaderKey;
if (_cacheParams.direction)
shader = _glManager->shaderManager->GetShader("ParticleDirection");
shaderKey = "ParticleDirection";
else
shader = _glManager->shaderManager->GetShader("ParticlePoint");
shaderKey = "ParticlePoint";

if (!_cacheParams.radiusVarName.empty())
shaderKey += ":DYNAMIC_RADIUS";

ShaderProgram *shader = _glManager->shaderManager->GetShader(shaderKey);
if (!shader) return -1;

double m[16];
Expand All @@ -284,6 +302,7 @@ int ParticleRenderer::_renderParticlesHelper()
shader->SetUniform("MV", _glManager->matrixManager->GetModelViewMatrix());
shader->SetUniform("aspect", _glManager->matrixManager->GetProjectionAspectRatio());
shader->SetUniform("radius", radius);
// shader->SetUniform("radiusVarStrength", (float)rp->GetValueDouble(ParticleParams::RenderRadiusVariableStrengthTag, 1.));
shader->SetUniform("dirScale", (float)rp->GetValueDouble(ParticleParams::DirectionScaleTag, 1.));
shader->SetUniform("lightingEnabled", (bool)rp->GetValueLong(ParticleParams::LightingEnabledTag, true));
shader->SetUniform("scales", _getScales());
Expand Down Expand Up @@ -367,33 +386,42 @@ int ParticleRenderer::_getGrids(Grid*& grid, std::vector<Grid*>& vecGrids) const
}
}

if (!_cacheParams.radiusVarName.empty()) {
vecGrids.push_back(_dataMgr->GetVariable(_cacheParams.ts, _cacheParams.radiusVarName, _cacheParams.rLevel, _cacheParams.cLevel, _cacheParams.boxMin, _cacheParams.boxMax, true));
}

return 0;
}

template<typename T> static void UploadDataBuffer(T buffer) {
glBufferData(GL_ARRAY_BUFFER, sizeof(T) * buffer.size(), buffer.data(), GL_STATIC_DRAW);
}

void ParticleRenderer::_generateTextureData(const Grid* grid, const std::vector<Grid*>& vecGrids) {
bool showDir = _cacheParams.direction;
bool dynamicSize = !_cacheParams.radiusVarName.empty();
size_t stride = max(1L, (long)_cacheParams.stride);
float dirScale = _cacheParams.directionScale;
auto node = grid->ConstNodeBegin(_cacheParams.boxMin, _cacheParams.boxMax);
auto nodeEnd = grid->ConstNodeEnd();
CoordType coordsBuf;
vector<Grid::ConstIterator> dirs;

if (showDir) for (auto g : vecGrids) dirs.push_back(g->cbegin(_cacheParams.boxMin, _cacheParams.boxMax));

struct PointDataT {vec3 pos; float val;};
vector<PointDataT> pointData;
if (showDir) for (int i = 0; i < 3; i++) dirs.push_back(vecGrids[i]->cbegin(_cacheParams.boxMin, _cacheParams.boxMax));
if (dynamicSize) dirs.push_back(vecGrids[vecGrids.size()-1]);

struct DirectionDataT {vec3 pos; vec3 norm; float val;};
vector<DirectionDataT> directionData;
struct PointDataT {vec3 pos; float val;}; vector<PointDataT> pointData;
struct DirectionDataT {vec3 pos; vec3 norm; float val;}; vector<DirectionDataT> directionData;
struct PointDynSizeDataT {vec3 pos; float val; float radius;}; vector<PointDynSizeDataT> pointDynSizeData;
struct DirectionDynSizeDataT {vec3 pos; vec3 norm; float val; float radius;}; vector<DirectionDynSizeDataT> directionDynSizeData;

_particlesCount = grid->GetCoordDimensions(1)[0] / stride;

if (showDir) {
SetupParticleDirectionGL(_VAO, _VBO);
SetupParticleDirectionGL(_VAO, _VBO, dynamicSize);
directionData.reserve(_particlesCount);
} else {
SetupParticlePointGL(_VAO, _VBO);
SetupParticlePointGL(_VAO, _VBO, dynamicSize);
pointData.reserve(_particlesCount);
}
assert(glIsVertexArray(_VAO) == GL_TRUE);
Expand All @@ -408,9 +436,15 @@ void ParticleRenderer::_generateTextureData(const Grid* grid, const std::vector<

if (showDir){
const glm::vec3 norm(*(dirs[0]), *(dirs[1]), *(dirs[2]));
directionData.push_back({p, norm, value});
if (dynamicSize)
directionDynSizeData.push_back({p, norm, value, *(dirs[dirs.size()-1])});
else
directionData.push_back({p, norm, value});
} else {
pointData.push_back({p, value});
if (dynamicSize)
pointDynSizeData.push_back({p, value, *(dirs[dirs.size()-1])});
else
pointData.push_back({p, value});
}
}
step:
Expand All @@ -420,10 +454,13 @@ void ParticleRenderer::_generateTextureData(const Grid* grid, const std::vector<

glBindVertexArray(_VAO);
glBindBuffer(GL_ARRAY_BUFFER, _VBO);
if (showDir)
glBufferData(GL_ARRAY_BUFFER, sizeof(DirectionDataT) * directionData.size(), directionData.data(), GL_STATIC_DRAW);
else
glBufferData(GL_ARRAY_BUFFER, sizeof(PointDataT) * pointData.size(), pointData.data(), GL_STATIC_DRAW);
if (dynamicSize) {
if (showDir) UploadDataBuffer(directionDynSizeData);
else UploadDataBuffer(pointDynSizeData);
} else {
if (showDir) UploadDataBuffer(directionData);
else UploadDataBuffer(pointData);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
}

Expand Down
21 changes: 16 additions & 5 deletions share/shaders/ParticleDirection.geom
Expand Up @@ -24,18 +24,23 @@ out float fValue;
out vec3 fNormal;


#ifdef DYNAMIC_RADIUS
in float gRadius[];
#endif


uniform mat4 P;
uniform mat4 MV;
uniform vec3 scales;
uniform float radius = 0.05;
uniform float dirScale = 0.05;

void EmitWorld(const vec3 v);
void CylinderVert(const vec3 v, const vec3 d, const float value);
void CylinderVert(const vec3 v, const vec3 d, const float value, const float radius);


void main()
{
{gs
//fValue = gValue[0];
//EmitWorld(gl_in[0].gl_Position.xyz);
//EmitWorld(gl_in[0].gl_Position.xyz + gNorm[0] * dirScale);
Expand All @@ -61,6 +66,12 @@ void main()
XH = normalize(cross(N, up));
YH = normalize(cross(XH, N));

#ifdef DYNAMIC_RADIUS
float finalRadius = radius * gRadius[0];
#else
float finalRadius = radius;
#endif

vec2 fade = CalculateFade();

//fNormal = vec3(1,0,0); fValue = 1; EmitWorld(gl_in[0].gl_Position.xyz); EmitWorld(gl_in[1].gl_Position.xyz); EndPrimitive(); return;
Expand All @@ -70,8 +81,8 @@ void main()
vec3 D;
D = XH*cos(t) + YH*sin(t);

CylinderVert(V[0], D, gValue[0]);
CylinderVert(V[1], D, gValue[0]);
CylinderVert(V[0], D, gValue[0], finalRadius);
CylinderVert(V[1], D, gValue[0], finalRadius);
}
EndPrimitive();
}
Expand All @@ -84,7 +95,7 @@ void EmitWorld(const vec3 v)
}


void CylinderVert(const vec3 v, const vec3 d, const float value)
void CylinderVert(const vec3 v, const vec3 d, const float value, const float radius)
{
fNormal = d;
fValue = value;
Expand Down
9 changes: 9 additions & 0 deletions share/shaders/ParticleDirection.vert
Expand Up @@ -7,8 +7,17 @@ layout (location = 2) in float vValue;
out vec3 gNorm;
out float gValue;

#ifdef DYNAMIC_RADIUS
layout (location = 3) in float vRadius;
out float gRadius;
#endif

void main() {
gValue = vValue;
gNorm = vNorm;
gl_Position = vec4(vPos, 1.0f);

#ifdef DYNAMIC_RADIUS
gRadius = vRadius;
#endif
}
19 changes: 15 additions & 4 deletions share/shaders/ParticlePoint.geom
Expand Up @@ -13,6 +13,11 @@ out float fValue;
out vec2 fC;


#ifdef DYNAMIC_RADIUS
in float gRadius[];
#endif


uniform mat4 P;
uniform mat4 MV;
uniform vec3 cameraPos;
Expand All @@ -36,11 +41,17 @@ void main()
xh /= scales;
yh /= scales;

#ifdef DYNAMIC_RADIUS
float finalRadius = radius * gRadius[0];
#else
float finalRadius = radius;
#endif

// Billboard
fC = vec2(-1.0, -1.0); EmitWorld(o + radius * (-xh + -yh));
fC = vec2( 1.0, -1.0); EmitWorld(o + radius * ( xh + -yh));
fC = vec2(-1.0, 1.0); EmitWorld(o + radius * (-xh + yh));
fC = vec2( 1.0, 1.0); EmitWorld(o + radius * ( xh + yh));
fC = vec2(-1.0, -1.0); EmitWorld(o + finalRadius * (-xh + -yh));
fC = vec2( 1.0, -1.0); EmitWorld(o + finalRadius * ( xh + -yh));
fC = vec2(-1.0, 1.0); EmitWorld(o + finalRadius * (-xh + yh));
fC = vec2( 1.0, 1.0); EmitWorld(o + finalRadius * ( xh + yh));
EndPrimitive();
}

Expand Down
9 changes: 9 additions & 0 deletions share/shaders/ParticlePoint.vert
Expand Up @@ -5,7 +5,16 @@ layout (location = 1) in float vValue;

out float gValue;

#ifdef DYNAMIC_RADIUS
layout (location = 2) in float vRadius;
out float gRadius;
#endif

void main() {
gValue = vValue;
gl_Position = vec4(vPos, 1.0f);

#ifdef DYNAMIC_RADIUS
gRadius = vRadius;
#endif
}

0 comments on commit 6ac7b3e

Please sign in to comment.