/*
*shadowmap示例,根据http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-16-shadow-mapping/教程用osg写的demo
*缪国凯
*MK(821486004@qq.com)
*/
#include "../Common/Common.h"
#include <osg/AlphaFunc>
#include <osg/Texture2D>
#include <osg/Shape>
#include <osg/ShapeDrawable>
#define AREA 10
#define SM_TEXTURE_WIDTH 4096
void loadShaders( osg::StateSet* ss, std::string filepath = "shader")
{
osg::Shader *fragShader=new osg::Shader(osg::Shader::FRAGMENT);
osg::Shader *vertShader=new osg::Shader(osg::Shader::VERTEX);
if(!fragShader->loadShaderSourceFromFile(filepath+".frag"))
{
printf("加载%s失败\n",(filepath+".frag").c_str());
};
printf("加载%s成功\n", (filepath + ".frag").c_str());
if(!vertShader->loadShaderSourceFromFile(filepath+".vert"))
{
printf("加载%s失败\n", (filepath + ".vert").c_str());
};
printf("加载%s成功\n", (filepath + ".vert").c_str());
osg::ref_ptr<osg::Program> program = new osg::Program;
program->addShader( vertShader);
program->addShader( fragShader);
if ( ss )
ss->setAttributeAndModes( program.get(), osg::StateAttribute::ON );
}
osg::Node* CreateModel(osg::Texture2D* tex, osg::Image *img, int width = 4.0, osg::Vec4 tmpColor = osg::Vec4(1.0, 1.0, 1.0, 1.0))
{
osg::Geometry *_geo = new osg::Geometry;
osg::Vec3Array * pCoords = new osg::Vec3Array;
osg::Vec3Array * pNormals = new osg::Vec3Array;
pNormals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
osg::Vec4Array * pColors = new osg::Vec4Array;
pColors->push_back(tmpColor);
_geo->setNormalArray(pNormals);
_geo->setNormalBinding(osg::Geometry::BIND_OVERALL);
_geo->setColorArray(pColors);
_geo->setColorBinding(osg::Geometry::BIND_OVERALL);
osg::ref_ptr<osg::Vec2Array> _coords = new osg::Vec2Array;
_geo->setTexCoordArray(0, _coords);
pCoords->push_back(osg::Vec3(-width/2, width/2, 0.0));
_coords->push_back(osg::Vec2(0.0, 0.0));
pCoords->push_back(osg::Vec3(width/2, width/2, 0.0));
_coords->push_back(osg::Vec2(1.0, 0.0));
pCoords->push_back(osg::Vec3(width/2, -width/2, 0.0));
_coords->push_back(osg::Vec2(1.0, 1.0));
pCoords->push_back(osg::Vec3(-width/2, -width/2, 0.0));
_coords->push_back(osg::Vec2(0.0, 1.0));
_geo->setVertexArray(pCoords);
_geo->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, pCoords->size()));
osg::Geode *_geo_LocalPlane = new osg::Geode;
_geo_LocalPlane->addDrawable(_geo);
{
osg::StateSet* stateset = _geo_LocalPlane->getOrCreateStateSet();
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED);
osg::ref_ptr<osg::BlendFunc> blendFunc = new osg::BlendFunc();
blendFunc->setSource(osg::BlendFunc::SRC_ALPHA);
blendFunc->setDestination(osg::BlendFunc::ONE_MINUS_SRC_ALPHA);
osg::AlphaFunc* alphaFunc = new osg::AlphaFunc;
alphaFunc->setFunction(osg::AlphaFunc::GEQUAL, 0.5f);
stateset->setAttributeAndModes(alphaFunc, osg::StateAttribute::ON);
if (NULL != tex && img == NULL)
{
stateset->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON);
}
else if (NULL != img)
{
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
texture->setImage(img);
texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST);
texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST);
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
}
}
return _geo_LocalPlane;
}
osg::Texture2D* CreateDepthTexture(int width, int height)
{
osg::Texture2D* _texture = new osg::Texture2D;
_texture->setTextureSize(width, height);
_texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
_texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
_texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
_texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
_texture->setInternalFormat(GL_DEPTH_COMPONENT);
_texture->setSourceFormat(GL_DEPTH_COMPONENT);
_texture->setSourceType(GL_FLOAT);
//tex->setShadowComparison(true);
_texture->setShadowTextureMode(osg::Texture2D::LUMINANCE);
return _texture;
}
osg::Image* CreateDepthImg(int width, int height)
{
osg::Image *depthImg = new osg::Image;
depthImg->allocateImage(width, height, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_FLOAT);
return depthImg;
}
osg::Camera* CreateShadowMapCamera(int x, int y, int w, int h, osg::Texture2D *_texture2D)
{
osg::ref_ptr<osg::Camera> _camera = new osg::Camera;
_camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
_camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
_camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
_camera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
_camera->setViewport(0,0,w, h);
_camera->setRenderOrder(osg::Camera::PRE_RENDER);
_camera->setProjectionMatrixAsOrtho(-AREA, AREA, -AREA, AREA, -AREA, 3*AREA);
osg::Vec3 tmpEyeps(0, 9, 15);
_camera->setViewMatrixAsLookAt(tmpEyeps, osg::Vec3(0, 0, 0), osg::Vec3(0, 1, 0));
_camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
_camera->attach(osg::Camera::DEPTH_BUFFER, _texture2D);
return _camera.release();
}
osg::Camera* initCamera(int x, int y, int w, int h)
{
osg::Camera * _camera = new osg::Camera;
_camera = new osg::Camera;
_camera->setName("CCTV");
_camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
_camera->setNearFarRatio(0.000001);
//_camera->setClearColor(osg::Vec4f(0.0,0.0,0.0,0.25));
_camera->setProjectionMatrixAsPerspective(30.0, (float)w/(float)h, 1,10000.0);
_camera->setViewport(x, y, w, h);
_camera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
return _camera;
}
osg::ref_ptr<osg::Camera> createTestHUD(int x, int y, int w, int h, osg::Texture2D *tex)
{
osg::ref_ptr<osg::Camera> hudCamera = new osg::Camera;
hudCamera->setProjectionMatrixAsOrtho2D(0, 1, 0, 1);
hudCamera->setViewMatrix(osg::Matrix::identity());
hudCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
hudCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
hudCamera->setClearColor(osg::Vec4(1.0, 1.0, 1.0, 1.0));
hudCamera->setRenderOrder(osg::Camera::POST_RENDER);
hudCamera->setAllowEventFocus(false);
hudCamera->setViewport(x, y, w, h);
hudCamera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
osg::ref_ptr<osg::Vec3Array> vc = new osg::Vec3Array;
vc->push_back(osg::Vec3d(0, 0, 0));
vc->push_back(osg::Vec3d(1, 0, 0));
vc->push_back(osg::Vec3d(1, 1, 0));
vc->push_back(osg::Vec3d(0, 1, 0));
geom->setVertexArray(vc.get());
osg::ref_ptr<osg::Vec2Array> vt = new osg::Vec2Array;
vt->push_back(osg::Vec2(0, 0));
vt->push_back(osg::Vec2(1, 0));
vt->push_back(osg::Vec2(1, 1));
vt->push_back(osg::Vec2(0, 1));
geom->setTexCoordArray(0, vt.get());
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
geode->addDrawable(geom.get());
hudCamera->addChild(geode.get());
osg::StateSet *stateset = geode->getOrCreateStateSet();
if (NULL != tex)
{
stateset->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON);
}
return hudCamera;
}
void main()
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
osg::ref_ptr<osg::Group> root = new osg::Group;
osg::Group * tmpGroup = new osg::Group;
osg::Node *roomNode = osgDB::readNodeFile("room.ive");
roomNode->getOrCreateStateSet()->setTextureAttributeAndModes(0,new osg::Texture2D(