OpenSceneGraph/examples/osgdepthpeeling/Utility.cpp

153 lines
3.9 KiB
C++

/*
Steffen Frey
Fachpraktikum Graphik-Programmierung 2007
Institut fuer Visualisierung und Interaktive Systeme
Universitaet Stuttgart
*/
#include "Utility.h"
#include <assert.h>
#include <iostream>
#include <stdio.h>
#include <osg/Geometry>
#include <osg/Geode>
#include <osgDB/FileUtils>
#include <osgDB/fstream>
bool Utility::readFile(const char* fName, std::string& s)
{
std::string foundFile = osgDB::findDataFile(fName);
if (foundFile.empty()) return false;
osgDB::ifstream is;//(fName);
is.open(foundFile.c_str());
if (is.fail())
{
std::cerr << "Could not open " << fName << " for reading.\n";
return false;
}
char ch = is.get();
while (!is.eof())
{
s += ch;
ch = is.get();
}
is.close();
return true;
}
std::string Utility::toString(double d)
{
std::stringstream ostr;
ostr << d;
return ostr.str();
}
osg::Program* Utility::createProgram(std::string vs, std::string fs)
{
//setup shader
std::string vertSource;
if(!readFile((char*)vs.c_str(), vertSource))
{
printf("shader source not found\n");
return 0;
}
std::string fragSource;
if(!readFile((char*)fs.c_str(), fragSource))
{
printf("shader source not found\n");
return 0;
}
osg::Program* program = new osg::Program;
program->addShader( new osg::Shader( osg::Shader::VERTEX, vertSource.c_str() ) );
program->addShader( new osg::Shader( osg::Shader::FRAGMENT, fragSource.c_str() ) );
return program;
}
double Utility::getNoise(unsigned x, unsigned y, unsigned random)
{
int n = x + y * 57 + random * 131;
n = (n<<13) ^ n;
double noise = (1.0f - ( (n * (n * n * 15731 + 789221) +
1376312589)&0x7fffffff)* 0.000000000931322574615478515625f);
return noise;
}
double Utility::smoothNoise(unsigned width, unsigned height, unsigned x, unsigned y, unsigned char* noise)
{
assert(noise);
if(x==0 || x > width -2
|| y==0 || y > height -2)
return noise[x + y*width];
double corners = (noise[x-1 + (y-1) *width]
+noise[x+1 + (y-1)*width]
+noise[x-1 + (y+1) * width]
+noise[x+1 + (y+1) * width]) / 16.0;
double sides = (noise[x-1 + y*width]
+noise[x+1 + y*width]
+noise[x + (y-1)*width]
+noise[x + (y+1)*width]) / 8.0;
double center = noise[x + y*width] / 4.0;
return corners + sides + center;
}
osg::Texture2D* Utility::newColorTexture2D(unsigned width, unsigned height, unsigned accuracy)
{
osg::Texture2D* texture2D = new osg::Texture2D;
texture2D->setTextureSize(width, height);
if(accuracy == 32)
{
texture2D->setInternalFormat(GL_RGBA32F_ARB);
texture2D->setSourceFormat(GL_RGBA);
}
else if(accuracy == 8)
{
texture2D->setInternalFormat(GL_RGBA);
}
texture2D->setSourceType(GL_FLOAT);
texture2D->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
texture2D->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
return texture2D;
}
osg::Geode* Utility::getCanvasQuad(unsigned width, unsigned height, double depth)
{
osg::Vec3Array* vertices = new osg::Vec3Array;
osg::Vec2Array* texCoords = new osg::Vec2Array;
vertices->push_back(osg::Vec3(0,0,depth));
texCoords->push_back(osg::Vec2(0,0));
vertices->push_back(osg::Vec3(width,0,depth));
texCoords->push_back(osg::Vec2(1,0));
vertices->push_back(osg::Vec3(0,height,depth));
texCoords->push_back(osg::Vec2(0,1));
vertices->push_back(osg::Vec3(width,height,depth));
texCoords->push_back(osg::Vec2(1,1));
osg::Geometry* quad = new osg::Geometry;
quad->setVertexArray(vertices);
quad->setTexCoordArray(1,texCoords);
quad->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,0,vertices->size()));
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
quad->setColorArray(colors, osg::Array::BIND_OVERALL);
osg::Geode* geode = new osg::Geode();
geode->addDrawable(quad);
return geode;
}