光线追踪

#include <osgViewer/Viewer>
#include <osgDB/WriteFile>
const int GRID_WIDTH = 1024;
const int GRID_HEIGHT = 800;
#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgViewerd.lib")
#pragma comment(lib, "osgDBd.lib")
class CRay
{
public:
	CRay(osg::Vec3 orgin, osg::Vec3 direction)
		:_orgin(orgin)
		,_direction(direction)
	{
		
	}

	osg::Vec3 GetOrgin()
	{
		return _orgin;
	}
	
	void SetOrgin(osg::Vec3 orgin)
	{
		_orgin = orgin;
	}

	osg::Vec3 GetDirection()
	{
		return _direction;
	}
	
	void SetDirection(osg::Vec3 dir)
	{
		_direction = dir;
	}

	osg::Vec3 GetPoint(float t)
	{
		return _orgin + _direction * t;
	}

private:
	osg::Vec3 _orgin;
	osg::Vec3 _direction;
	float     _t;
};

class CIntersectResult
{
public:
	CIntersectResult()
		:_isHit(false)
	{
			
	}
	static CIntersectResult NoHit()
	{
		return CIntersectResult();
	}
public:
	bool        _isHit;
	float       _distance;
	osg::Vec3   _position;
	osg::Vec3   _normal;
};

class CGeometry
{
public:
	CGeometry()
	{

	}
	virtual CIntersectResult IsIntersect(CRay ray) = 0;
};


class CSphere : public CGeometry
{
public:
	CSphere()
		:CGeometry()
	{

	}
	CSphere(osg::Vec3 center, double radius)
		:CGeometry()
		,_center(center)
		,_radius(radius)
	{

	}
	CSphere(CSphere & s)
	{
		_center = s.GetCenter();
		_radius = s.GetRadius();
	}

	void SetCenter(osg::Vec3 & center)
	{
		_center = center;	
	}
	void SetRadius(float radius)
	{
		_radius = radius;
	}

	osg::Vec3 GetCenter()
	{
		return _center;	
	}

	float GetRadius()
	{
		return _radius;	
	}

	osg::Vec3 GetNormal(osg::Vec3 p)
	{
		return p - _center;
	}

	virtual CIntersectResult IsIntersect(CRay ray)
	{
		CIntersectResult result = CIntersectResult::NoHit();
		osg::Vec3 v = ray.GetOrgin() - _center;
		float a0 = v * v - _radius * _radius;
		float dir_dot_v = ray.GetDirection() * v;

		if (dir_dot_v < 0)
		{
			float discr = dir_dot_v * dir_dot_v - a0;
			if (discr >= 0)
			{
				result._isHit = true;
				result._distance = -dir_dot_v - std::sqrt(discr);
				result._position = ray.GetPoint(result._distance);
				result._normal = result._position - _center;
				result._normal.normalize();
			}
		}
		return result;
	}

private:
	osg::Vec3 _center;
	float     _radius;
};

class CPerspectiveCamera
{
public:
	CPerspectiveCamera()
	{
		
	}
	~CPerspectiveCamera()
	{

	}
	CPerspectiveCamera(const osg::Vec3 & eye, const osg::Vec3 & front, const osg::Vec3 & refUp, float fov)
	{
		_eye = eye;
		_front = front;
		_refUp = refUp;
		_fov = fov;
		_right = _front ^ _refUp;
		_up = _right ^ _front;
		_fovScale = std::tan(fov * osg::PI * 0.5 / 180.0) * 2.0;
	}
	CRay GenerateRay(float x, float y)
	{
		osg::Vec3 r = _right * ((x - 0.5f) * _fovScale);
		osg::Vec3 u = _up * ((y - 0.5f) * _fovScale);
		osg::Vec3 temp = _front + r + u;
		temp.normalize();
		return CRay(_eye, temp);
	}
private:
	osg::Vec3 _eye;
	osg::Vec3 _front;
	osg::Vec3 _refUp;
	float     _fov;
	osg::Vec3 _right;
	osg::Vec3 _up;
	float     _fovScale;
};

osg::ref_ptr<osg::Image> CreateImage()
{
	osg::ref_ptr<osg::Image> image = new osg::Image;
	image->allocateImage(1024, 800, 1, GL_RGBA, GL_UNSIGNED_BYTE);
	unsigned char * data = image->data();
	CPerspectiveCamera camera(osg::Vec3(0.0, 10.0, 10), osg::Vec3(0.0, 0.0, -1.0), osg::Vec3(0.0, 1.0, 0.0), 90);
	float depth = 7.0;
	float maxDepth = 18.0;
	CSphere sphere(osg::Vec3(0.0, 10, -10.0), 10.0);
	float dx = 1.0f/GRID_WIDTH;
	float dy = 1.0f/GRID_HEIGHT;
	float dDepth = 255.0f/maxDepth;
	int i = 0;
	for (int y = 0; y < GRID_HEIGHT; ++y)
	{
		float sy = 1 - dy * y;
		for (int x = 0; x < GRID_WIDTH; ++x)
		{
			float sx = dx * x;
			CRay ray(camera.GenerateRay(sx, sy));
			CIntersectResult result = sphere.IsIntersect(ray);
			if (result._isHit)
			{
				float t = std::min(result._distance * dDepth, 255.0f);
				int depth = (int)(255 - t);
				data[i] = depth;
				data[i+1] = depth;
				data[i+2] = depth;
				data[i+3] = 255;
			}
			i += 4;
		}
	}
	return image.get();
}

int main()
{
	osg::ref_ptr<osg::Image> image = CreateImage();
	osgDB::writeImageFile(*image.get(), "H:/1.png");
	return 0;
}

 

 

posted @ 2014-05-20 20:50  20118281131  阅读(826)  评论(1编辑  收藏  举报