Created
July 21, 2013 00:49
-
-
Save bkmeneguello/6047028 to your computer and use it in GitHub Desktop.
OpenSceneGraph Shader 4.00
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <osg/ArgumentParser> | |
#include <osg/Array> | |
#include <osg/Camera> | |
#include <osg/Drawable> | |
#include <osg/Geode> | |
#include <osg/Geometry> | |
#include <osg/Group> | |
#include <osg/Light> | |
#include <osg/Matrixd> | |
#include <osg/MixinVector> | |
#include <osg/Node> | |
#include <osg/NodeVisitor> | |
#include <osg/Object> | |
#include <osg/PrimitiveSet> | |
#include <osg/Program> | |
#include <osg/Shader> | |
#include <osg/StateAttribute> | |
#include <osg/StateSet> | |
#include <osg/Transform> | |
#include <osg/Uniform> | |
#include <osg/Vec3f> | |
#include <osg/Vec4f> | |
#include <osg/View> | |
#include <osgDB/ReadFile> | |
#include <osgGA/OrbitManipulator> | |
#include <osgGA/StateSetManipulator> | |
#include <osgViewer/View> | |
#include <osgViewer/Viewer> | |
#include <osgViewer/ViewerEventHandlers> | |
struct ModelViewMatrixCallback: public osg::Uniform::Callback { | |
ModelViewMatrixCallback(osg::Camera* camera) : | |
_camera(camera) { | |
} | |
virtual void operator()(osg::Uniform* uniform, osg::NodeVisitor* nv) { | |
osg::Matrixd viewMatrix = _camera->getViewMatrix(); | |
osg::Matrixd modelMatrix = osg::computeLocalToWorld(nv->getNodePath()); | |
uniform->set(modelMatrix * viewMatrix); | |
} | |
osg::Camera* _camera; | |
}; | |
struct NormalMatrixCallback: public osg::Uniform::Callback { | |
NormalMatrixCallback(osg::Camera* camera) : | |
_camera(camera) { | |
} | |
virtual void operator()(osg::Uniform* uniform, osg::NodeVisitor* nv) { | |
osg::Matrixd viewMatrix = _camera->getViewMatrix(); | |
osg::Matrixd modelMatrix = osg::computeLocalToWorld(nv->getNodePath()); | |
osg::Matrixd modelViewMatrix = modelMatrix * viewMatrix; | |
modelViewMatrix.setTrans(0.0, 0.0, 0.0); | |
osg::Matrixd inverse; | |
inverse.invert(modelViewMatrix); | |
osg::Matrix3 normalMatrix( | |
inverse(0,0), inverse(1,0), inverse(2,0), | |
inverse(0,1), inverse(1,1), inverse(2,1), | |
inverse(0,2), inverse(1,2), inverse(2,2)); | |
uniform->set(normalMatrix); | |
} | |
osg::Camera* _camera; | |
}; | |
struct ModelViewProjectionMatrixCallback: public osg::Uniform::Callback { | |
ModelViewProjectionMatrixCallback(osg::Camera* camera) : | |
_camera(camera) { | |
} | |
virtual void operator()(osg::Uniform* uniform, osg::NodeVisitor* nv) { | |
osg::Matrixd viewMatrix = _camera->getViewMatrix(); | |
osg::Matrixd modelMatrix = osg::computeLocalToWorld(nv->getNodePath()); | |
osg::Matrixd modelViewProjectionMatrix = modelMatrix * viewMatrix * _camera->getProjectionMatrix(); | |
uniform->set(modelViewProjectionMatrix); | |
} | |
osg::Camera* _camera; | |
}; | |
int main(int argc, char** argv) { | |
osg::ArgumentParser arguments(&argc, argv); | |
osgViewer::Viewer* viewer = new osgViewer::Viewer(arguments); | |
osg::Camera* camera = viewer->getCamera(); | |
viewer->setCameraManipulator(new osgGA::OrbitManipulator()); | |
osgGA::StateSetManipulator* stateSet = new osgGA::StateSetManipulator(camera->getOrCreateStateSet()); | |
viewer->addEventHandler(stateSet); | |
viewer->addEventHandler(new osgViewer::StatsHandler); | |
viewer->addEventHandler(new osgViewer::WindowSizeHandler); | |
osg::Group* root = new osg::Group(); | |
osg::Vec3Array& vertex = *(new osg::Vec3Array(4)); | |
osg::Vec3Array& normal = *(new osg::Vec3Array(1)); | |
osg::Vec4Array& color = *(new osg::Vec4Array(4)); | |
vertex.setName("Vertex"); | |
vertex[0].set(0,0,0); | |
vertex[1].set(1,0,0); | |
vertex[2].set(1,0,1); | |
vertex[3].set(0,0,1); | |
normal.setName("Normal"); | |
normal[0].set(0,-1,0); | |
color.setName("Color"); | |
color[0].set(1,0,0,1); | |
color[1].set(0,1,0,1); | |
color[2].set(0,0,1,1); | |
color[3].set(1,0,1,1); | |
osg::Geometry *geom = new osg::Geometry; | |
geom->setUseDisplayList(false); | |
geom->setVertexAttribArray(0, &vertex); | |
geom->setVertexAttribNormalize(0, false); | |
geom->setVertexAttribBinding(0, osg::Geometry::BIND_PER_VERTEX); | |
geom->setVertexAttribArray(1, &normal); | |
geom->setVertexAttribNormalize(1, true); | |
geom->setVertexAttribBinding(1, osg::Geometry::BIND_OVERALL); | |
geom->setVertexAttribArray(2, &color); | |
geom->setVertexAttribNormalize(2, false); | |
geom->setVertexAttribBinding(2, osg::Geometry::BIND_PER_VERTEX); | |
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); | |
osg::Program* program = new osg::Program; | |
program->setName("shader"); | |
program->addShader(osgDB::readShaderFile(osg::Shader::VERTEX, "test.vert")); | |
program->addShader(osgDB::readShaderFile(osg::Shader::FRAGMENT, "test.frag")); | |
osg::Geode* geode = new osg::Geode; | |
geode->addDrawable(geom); | |
osg::StateSet* state = geode->getOrCreateStateSet(); | |
state->setAttributeAndModes(program, osg::StateAttribute::ON); | |
osg::Uniform* modelViewMatrix = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "ModelViewMatrix"); | |
modelViewMatrix->setUpdateCallback(new ModelViewMatrixCallback(camera)); | |
state->addUniform(modelViewMatrix); | |
osg::Uniform* normalMatrix = new osg::Uniform(osg::Uniform::FLOAT_MAT3, "NormalMatrix"); | |
normalMatrix->setUpdateCallback(new NormalMatrixCallback(camera)); | |
state->addUniform(normalMatrix); | |
state->addUniform(new osg::Uniform("ProjectionMatrix", camera->getProjectionMatrix())); | |
osg::Uniform* modelViewProjectionMatrix = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "ModelViewProjectionMatrix"); | |
modelViewProjectionMatrix->setUpdateCallback(new ModelViewProjectionMatrixCallback(camera)); | |
state->addUniform(modelViewProjectionMatrix); | |
state->addUniform(new osg::Uniform("LightPosition", viewer->getLight()->getPosition())); | |
state->addUniform(new osg::Uniform("DiffuseColor", osg::Vec3f(1, 1, 0))); | |
state->addUniform(new osg::Uniform("LightIntensity", osg::Vec3f(.5, .5, 0))); | |
root->addChild(geode); | |
viewer->setSceneData(root); | |
while(!viewer->done()) { | |
viewer->frame(); | |
} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 400 | |
in vec3 EyeLightIntensity; | |
layout(location = 0) out vec4 FragColor; | |
void main(void) { | |
FragColor = vec4(EyeLightIntensity, 1.0); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 400 | |
uniform mat4 ModelViewMatrix; | |
uniform mat3 NormalMatrix; | |
uniform mat4 ProjectionMatrix; | |
uniform mat4 ModelViewProjectionMatrix; | |
uniform vec4 LightPosition; // Light position in eye coords. | |
uniform vec3 DiffuseColor; // Diffuse reflectivity | |
uniform vec3 LightIntensity; // Light source intensity | |
layout(location = 0) in vec4 Vertex; | |
layout(location = 1) in vec3 Normal; | |
layout(location = 2) in vec4 Color; | |
out vec3 EyeLightIntensity; | |
void main(void) { | |
// Convert normal and position to eye coords | |
vec3 tnorm = normalize(NormalMatrix * Normal); | |
vec4 eyeCoords = ModelViewMatrix * Vertex; | |
vec3 s = normalize(vec3(LightPosition - eyeCoords)); | |
// The diffuse shading equation | |
EyeLightIntensity = LightIntensity * DiffuseColor * max(dot(s, tnorm), 0); | |
//LightIntensity = vec3(1,0,1) * vec3(1,1,1) * max(dot(s, tnorm), 0); | |
//LightIntensity = Color * max(dot(s, tnorm), 0); | |
// Convert position to clip coordinates and pass along | |
gl_Position = ModelViewProjectionMatrix * Vertex; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment