Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions Demos/Shaders/Line_Pulse_Thickness.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// FRAGMENT SHADER
// Creates a pulsing intensity effect that simulates line thickness variation

// Use GLSL 1.20 (OpenGL 2.1)
#version 120

uniform float osg_FrameTime; // From OSG
varying float vertexLocation; // From vertex shader (alternates 0/1 for line endpoints)

const float pulseSpeed = 2.0; // Speed of pulsing (higher = faster)
const float minIntensity = 0.4; // Minimum brightness (0-1)
const float maxIntensity = 1.0; // Maximum brightness (0-1)

void main(void)
{
vec4 baseColor = gl_Color;

// Create smooth pulsing wave using sine
float pulse = sin(osg_FrameTime * pulseSpeed) * 0.5 + 0.5; // 0 to 1

// Scale pulse between min and max intensity
float intensity = mix(minIntensity, maxIntensity, pulse);

// Apply intensity to color and alpha for a "glowing" pulse effect
vec4 finalColor = baseColor * intensity;
finalColor.a = baseColor.a * intensity; // Also pulse the alpha

gl_FragColor = finalColor;
}
31 changes: 31 additions & 0 deletions Demos/Shaders/Line_Pulse_Traveling.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// FRAGMENT SHADER
// Draws a pulse that travels from the start of the trajectory to the end

// Use GLSL 1.20 (OpenGL 2.1)
#version 120

uniform float osg_FrameTime; // From OSG
uniform float of_NumVertices; // Total vertex count, set by CurveArtist
varying float vertexRawID; // Raw vertex index from vertex shader

const float pulseDuration = 2.0; // Seconds for one full pass along the line
const float pulseWidth = 0.05; // Width of pulse as fraction of total line length

void main(void)
{
vec4 color = gl_Color;
vec4 colorInv = vec4(1.0 - gl_Color.rgb, 1.0);

// Normalize vertex index to [0, 1] over the full line
float linePos = vertexRawID / max(of_NumVertices - 1.0, 1.0);

// Pulse center travels from 0 (start) to 1 (end) over pulseDuration seconds
float pulseCenter = fract(osg_FrameTime / pulseDuration);

// Create a smooth 0-1-0 bump centered at the pulse location
float y1 = smoothstep(pulseCenter - pulseWidth, pulseCenter, linePos);
float y2 = smoothstep(pulseCenter, pulseCenter + pulseWidth, linePos);
float pulseVal = y1 - y2;

gl_FragColor = mix(color, colorInv, pulseVal);
}
2 changes: 2 additions & 0 deletions include/OpenFrames/CurveArtist.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ namespace OpenFrames
void setColor(float r, float g, float b);
void setWidth(float width);
void setPattern(GLint factor, GLushort pattern);
bool setShader(const std::string &fname);

/** Data was cleared from or added to the trajectory. Inherited
from TrajectoryArtist */
Expand All @@ -88,6 +89,7 @@ namespace OpenFrames
osg::ref_ptr<osg::LineWidth> _lineWidth;
osg::ref_ptr<osg::LineStipple> _linePattern;
osg::ref_ptr<osg::Vec4Array> _lineColors;
osg::ref_ptr<osg::Shader> _fragShader; // Line fragment shader

mutable bool _dataValid; // If trajectory supports required data
mutable bool _dataZero; // If we are just drawing at the origin
Expand Down
11 changes: 11 additions & 0 deletions include/OpenFrames/OF_Interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -1768,6 +1768,17 @@ OF_EXPORT void OF_FCN(ofcurveartist_setwidth)(float *width);
*/
OF_EXPORT void OF_FCN(ofcurveartist_setpattern)(int *factor, unsigned short *pattern);

/*
* \brief Set GLSL fragment shader used to draw the curve, overriding any existing shader.
*
* If an empty string is provided, the shader is reset to default.
*
* This applies to the current active CurveArtist.
*
* \param fname File containing the shader source.
*/
OF_EXPORT void OF_FCN(ofcurveartist_setshader)(OF_CHARARG(fname));

/*****************************************************************
SegmentArtist Functions
A SegmentArtist is a type of TrajectoryArtist that allows arbitrary
Expand Down
43 changes: 43 additions & 0 deletions src/CurveArtist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
#include <OpenFrames/CurveArtist.hpp>
#include <OpenFrames/DoubleSingleUtils.hpp>
#include <osg/Geometry>
#include <osg/Shader>
#include <osg/Program>
#include <osgDB/FileUtils>
#include <osgDB/ReadFile>
#include <climits>

namespace OpenFrames
Expand Down Expand Up @@ -108,6 +112,10 @@ class CurveArtistUpdateCallback : public osg::Callback
_vertexLow->dirty();
}

// Keep of_NumVertices uniform in sync so traveling-pulse shaders know the line length
osg::Uniform* numVertsUniform = _ca->getOrCreateStateSet()->getUniform("of_NumVertices");
if(numVertsUniform) numVertsUniform->set((float)_drawArrays->getCount());

// Continue traversing as needed
return traverse(object, data);
}
Expand Down Expand Up @@ -205,6 +213,12 @@ CurveArtist::CurveArtist(const Trajectory *traj)
stateset->setAttribute(_lineWidth.get());
stateset->setAttributeAndModes(_linePattern.get());

// Initialize shader for custom line effects (optional, added to program on demand)
_fragShader = new osg::Shader(osg::Shader::FRAGMENT);

// Uniform holding total vertex count; used by traveling-pulse shaders
stateset->addUniform(new osg::Uniform("of_NumVertices", 0.0f));

// Initialize colors
// Currently we use one color for the whole trajectory, but this can be
// changed later for per-vertex colors
Expand Down Expand Up @@ -296,6 +310,35 @@ void CurveArtist::setPattern( GLint factor, GLushort pattern )
_linePattern->setPattern(pattern);
}

bool CurveArtist::setShader(const std::string &fname)
{
// Remove shader if empty filename
if(fname.length() == 0)
{
_program->removeShader(_fragShader);
return true;
}

// Load shader source from file using the non-deprecated osgDB API
osg::ref_ptr<osg::Shader> tmpShader = osgDB::readRefShaderFile(osg::Shader::FRAGMENT, fname);
if(!tmpShader.valid())
{
OSG_WARN << "OpenFrames::CurveArtist ERROR: Shader file \'" << fname << "\' not properly loaded!" << std::endl;
return false;
}
_fragShader->setShaderSource(tmpShader->getShaderSource());

// Re-attach shader to program if it was previously removed
bool attached = false;
for(unsigned int i = 0; i < _program->getNumShaders(); ++i)
{
if(_program->getShader(i) == _fragShader.get()) { attached = true; break; }
}
if(!attached) _program->addShader(_fragShader);

return true;
}

void CurveArtist::dataCleared(const Trajectory* traj)
{
verifyData();
Expand Down
13 changes: 13 additions & 0 deletions src/OF_Interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2549,6 +2549,19 @@ void OF_FCN(ofcurveartist_setpattern)(int *factor, unsigned short *pattern)
}
}

OF_EXPORT void OF_FCN(ofcurveartist_setshader)(OF_CHARARG(fname))
{
CurveArtist *artist = dynamic_cast<CurveArtist*>(_objs->_currArtist);
if (artist) {
// Convert given character string and length to a proper C string
std::string temp(OF_STRING(fname));
_objs->_intVal = !artist->setShader(temp);
}
else {
_objs->_intVal = -2;
}
}

/************************************************
SegmentArtist Functions
************************************************/
Expand Down
5 changes: 5 additions & 0 deletions src/OpenFrames.f90
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,11 @@ SUBROUTINE ofcurveartist_setpattern(factor, pattern)
INTEGER(2), INTENT(IN) :: pattern
END SUBROUTINE

SUBROUTINE ofcurveartist_setshader(fname)
!DEC$ ATTRIBUTES DLLIMPORT,C,REFERENCE :: ofcurveartist_setshader
CHARACTER(LEN=*), INTENT(IN) :: fname
END SUBROUTINE

! SegmentArtist functions

SUBROUTINE ofsegmentartist_create(name)
Expand Down
12 changes: 12 additions & 0 deletions src/TrajectoryArtist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ namespace OpenFrames
// Implement vertex shader for Rendering Relative to Eye using GPU
static const char *OFTA_VertSource = {
"#version 120\n"
"#extension GL_EXT_gpu_shader4 : enable\n" // Enables gl_VertexID
"uniform mat4 osg_ProjectionMatrix;\n"

// ModelView matrix with zero translation component
Expand All @@ -40,6 +41,13 @@ static const char *OFTA_VertSource = {
// High part comes in through gl_Vertex
"attribute vec4 of_VertexLow;\n"

// Vertex location along line (0 or 1 for alternating vertices)
// Used by custom shaders like Line_Pulse.frag
"varying float vertexLocation;\n"

// Raw vertex index, used with of_NumVertices uniform for full-line position
"varying float vertexRawID;\n"

"void main(void)\n"
"{\n"
// Low part of vertex - eye and associated numerical error
Expand All @@ -57,6 +65,10 @@ static const char *OFTA_VertSource = {
" gl_Position = osg_ProjectionMatrix*of_RTEModelViewMatrix*vec4(diffHigh+diffLow, 1.0);\n"
" gl_FrontColor = gl_Color;\n"
" gl_TexCoord[0] = gl_MultiTexCoord0;\n"

// Compute vertex location for line shaders (0 or 1 for alternating vertices)
" vertexLocation = mod(float(gl_VertexID), 2.0);\n"
" vertexRawID = float(gl_VertexID);\n"
"}\n"
};

Expand Down