From 7c278ce5d649f25374d0c321a568e06c998b2273 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 6 Mar 2012 10:29:47 +0000 Subject: [PATCH] From Christian Buchner, "The attached openscenegraph example is much simpler than osgshaders.cpp and demonstrates the use of GLSL vertex and fragment shaders with a simple animation callback. I found the osgshaders.cpp too complex to serve as a starting point for GLSL programming" --- examples/CMakeLists.txt | 1 + examples/osgsimpleshaders/CMakeLists.txt | 3 + .../osgsimpleshaders/osgsimpleshaders.cpp | 141 ++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 examples/osgsimpleshaders/CMakeLists.txt create mode 100644 examples/osgsimpleshaders/osgsimpleshaders.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 95b13ca69..e3dbfbaaf 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -102,6 +102,7 @@ IF(DYNAMIC_OPENSCENEGRAPH) ADD_SUBDIRECTORY(osgshadow) ADD_SUBDIRECTORY(osgshape) ADD_SUBDIRECTORY(osgsharedarray) + ADD_SUBDIRECTORY(osgsimpleshaders) ADD_SUBDIRECTORY(osgsimplifier) ADD_SUBDIRECTORY(osgsimulation) ADD_SUBDIRECTORY(osgsidebyside) diff --git a/examples/osgsimpleshaders/CMakeLists.txt b/examples/osgsimpleshaders/CMakeLists.txt new file mode 100644 index 000000000..7b944c156 --- /dev/null +++ b/examples/osgsimpleshaders/CMakeLists.txt @@ -0,0 +1,3 @@ +SET(TARGET_SRC osgsimpleshaders.cpp ) + +SETUP_EXAMPLE(osgsimpleshaders) diff --git a/examples/osgsimpleshaders/osgsimpleshaders.cpp b/examples/osgsimpleshaders/osgsimpleshaders.cpp new file mode 100644 index 000000000..37f226146 --- /dev/null +++ b/examples/osgsimpleshaders/osgsimpleshaders.cpp @@ -0,0 +1,141 @@ +/* OpenSceneGraph example, osgminimalglsl. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +/* file: examples/osgminimalglsl.cpp + * + * A minimal demo of the OpenGL Shading Language shaders using core OSG. + * + * blocky shader taken from osgshaders sample (Author: Mike Weiblein) +*/ + +#include + +#include +#include +#include + +#include +#include +#include + +using namespace osg; + +/////////////////////////////////////////////////////////////////////////// +// in-line GLSL source code + +static const char *blockyVertSource = { + "// blocky.vert - an GLSL vertex shader with animation\n" + "// the App updates uniforms \"slowly\" (eg once per frame) for animation.\n" + "uniform float Sine;\n" + "const vec3 LightPosition = vec3(0.0, 0.0, 4.0);\n" + "const float BlockScale = 0.30;\n" + "// varyings are written by vert shader, interpolated, and read by frag shader.\n" + "varying float LightIntensity;\n" + "varying vec2 BlockPosition;\n" + "void main(void)\n" + "{\n" + " // per-vertex diffuse lighting\n" + " vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;\n" + " vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal);\n" + " vec3 lightVec = normalize(LightPosition - vec3 (ecPosition));\n" + " LightIntensity = max(dot(lightVec, tnorm), 0.0);\n" + " // blocks will be determined by fragment's position on the XZ plane.\n" + " BlockPosition = gl_Vertex.xz / BlockScale;\n" + " // scale the geometry based on an animation variable.\n" + " vec4 vertex = gl_Vertex;\n" + " vertex.w = 1.0 + 0.4 * (Sine + 1.0);\n" + " gl_Position = gl_ModelViewProjectionMatrix * vertex;\n" + "}\n" +}; + +static const char *blockyFragSource = { + "// blocky.frag - an GLSL fragment shader with animation\n" + "// the App updates uniforms \"slowly\" (eg once per frame) for animation.\n" + "uniform float Sine;\n" + "const vec3 Color1 = vec3(1.0, 1.0, 1.0);\n" + "const vec3 Color2 = vec3(0.0, 0.0, 0.0);\n" + "// varyings are written by vert shader, interpolated, and read by frag shader.\n" + "varying vec2 BlockPosition;\n" + "varying float LightIntensity;\n" + "void main(void)\n" + "{\n" + " vec3 color;\n" + " float ss, tt, w, h;\n" + " ss = BlockPosition.x;\n" + " tt = BlockPosition.y;\n" + " if (fract(tt * 0.5) > 0.5)\n" + " ss += 0.5;\n" + " ss = fract(ss);\n" + " tt = fract(tt);\n" + " // animate the proportion of block to mortar\n" + " float blockFract = (Sine + 1.1) * 0.4;\n" + " w = step(ss, blockFract);\n" + " h = step(tt, blockFract);\n" + " color = mix(Color2, Color1, w * h) * LightIntensity;\n" + " gl_FragColor = vec4 (color, 1.0);\n" + "}\n" +}; + +/////////////////////////////////////////////////////////////////////////// +// callback for animating various Uniforms (currently only the SIN uniform) + +class AnimateCallback: public osg::Uniform::Callback +{ + public: + enum Operation { SIN }; + AnimateCallback(Operation op) : _operation(op) {} + virtual void operator() ( osg::Uniform* uniform, osg::NodeVisitor* nv ) + { + float angle = 2.0 * nv->getFrameStamp()->getSimulationTime(); + float sine = sinf( angle ); // -1 -> 1 + switch(_operation) { + case SIN : uniform->set( sine ); break; + } + } + private: + Operation _operation; +}; + +int main(int, char **) +{ + // construct the viewer. + osgViewer::Viewer viewer; + + // use a geode with a Box ShapeDrawable + osg::Geode* basicModel = new osg::Geode(); + basicModel->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.0f,0.0f,0.0f),1.0f))); + + // create the "blocky" shader, a simple animation test + osg::StateSet *ss = basicModel->getOrCreateStateSet(); + osg::Program* program = new osg::Program; + program->setName( "blocky" ); + program->addShader( new osg::Shader( osg::Shader::VERTEX, blockyVertSource ) ); + program->addShader( new osg::Shader( osg::Shader::FRAGMENT, blockyFragSource ) ); + ss->setAttributeAndModes(program, osg::StateAttribute::ON); + + // attach some animated Uniform variable to the state set + osg::Uniform* SineUniform = new osg::Uniform( "Sine", 0.0f ); + ss->addUniform( SineUniform ); + SineUniform->setUpdateCallback(new AnimateCallback(AnimateCallback::SIN)); + + // run the osg::Viewer using our model + viewer.setSceneData( basicModel ); + return viewer.run(); +} + +/*EOF*/