Hi I'm a Student and we have to write a Ray Tracer with hard coded Shaders.
I got some Problems with my Environment Shader. I put it on a Sphere.
Following things are there:
I got a working box funktion which calcs a box around the sphere.
I got a working Infinite Sphere Class which is used to get the right side of the hitten box. The ray must hit 2 Planes and I take the plane with the shorten distance of the hitpoint.
I got a working textured triangle class for texture things (sry no rectangle class). I'm making the hitten side of the box out of 2 Triangles. But i doesnt work!
The ray hits the Plane, but only at 20% the triangles. This is realy Strange. Maybe you can help me. It would be realy nice
Here is the Picture:
[IMG]
http://i44.tinypic.com/2r61icz.jpg[/IMG]Debog Code:
[code]Was in LEFT ((-1.91083,-0.569883,-7.11584) /t = 7.38994)!
Was in DOWN ((-0.0233016,-0.00694942,-0.0867739) /t = 0.0901164)!
Hitpoint: (-2.11247,-0.3,0.0539508) / ON DOWN PLANE
Box: Leftdown (-4,-0.3,-2) / UpRight (0,3.7,2)
ReflectedRay: (-2.08917,-0.293051,0.140725) + t * (-0.258572,-0.0771161,-0.962909) / Hitpoint: (-2.11247,-0.3,0.0539508)
TexturedSmoothTriangle one((-4,-0.3,-2),(0,-0.3,-2),(-4,-0.3,2), Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,599,0), Vec3f(799,599,0), Vec3f(0,0,0) ,(FlatShader*) 0x00000000)
TexturedSmoothTriangle two((0,-0.3,-2),(0,-0.3,2),(-4,-0.3,2), Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(799,599,0), Vec3f(799,0,0), Vec3f(0,0,0) ,(FlatShader*) 0x00000000)
Down: Env Shader error : the ray has not hitten one or two (the triangles of the env cube)
[/code]
Hier is the source Code:
[code]Vec3f
EnvShader::Shade(Ray& ray)
{
//Thank you for the phong shader
Vec3f N = ray.hit()->GetNormal(ray);
Vec3f reflectedDirection = ray.direction() - N*2*N.dot(ray.direction());
reflectedDirection.normalize();
//Vec3f leftDown = Vec3f(-10,-10,-10);
//Vec3f rightUp = Vec3f(10,10,10);
float oldt = 400020001;
int use = 0;
int maxX, maxY;
//cool even more code that can be used again.
Vec3f hitPoint = ray.origin()+ray.direction()*ray.t();
Ray reflectedRay(hitPoint, reflectedDirection);
//wow this class almost only use allready existent code
m_box = ray.hit()->CalcBounds();
//m_box = m_scene->GetSceneBox();
Vec3f leftDown = m_box.min();
Vec3f rightUp = m_box.max();
//Vec3f leftDown = Vec3f(-100,-100,-100);
//Vec3f rightUp = Vec3f(100,100,100);;
//ok the tnear and tfar stuff is complicated. lets use inf planes
//i know i shouldnt do it. but we are in c and can play with pointer

ps: java sux :P
InfinitePlane down(leftDown, Vec3f(0,1,0) , (FlatShader*) 0x00000000);
InfinitePlane up(rightUp, Vec3f(0,1,0) , (FlatShader*) 0x00000000);
InfinitePlane back(rightUp, Vec3f(0,0,1) , (FlatShader*) 0x00000000);
InfinitePlane front(leftDown, Vec3f(0,0,1) , (FlatShader*) 0x00000000);
InfinitePlane left(leftDown, Vec3f(1,0,0), (FlatShader*) 0x00000000);
InfinitePlane right(rightUp, Vec3f(1,0,0), (FlatShader*) 0x00000000);
//lets just test every plane. if it hits our reflected ray, we use it if t is the smallest
if(left.Intersect(reflectedRay))
{
std::cout << "Was in LEFT (" << reflectedRay.direction() * reflectedRay.t() << " / " << reflectedRay.t() << ")!
";
oldt = reflectedRay.t();
use = 1;
}
if(right.Intersect(reflectedRay))
{
if(reflectedRay.t() < oldt)
{
use = 2;
oldt = reflectedRay.t();
}
}
if(up.Intersect(reflectedRay))
{
if(reflectedRay.t() < oldt)
{
use = 3;
oldt = reflectedRay.t();
}
}
if(down.Intersect(reflectedRay))
{
std::cout << "Was in DOWN (" << reflectedRay.direction() * reflectedRay.t() << " /" << reflectedRay.t() << ")!
";
if(reflectedRay.t() < oldt)
{
use = 4;
oldt = reflectedRay.t();
}
}
if(front.Intersect(reflectedRay))
{
if(reflectedRay.t() < oldt)
{
use = 5;
oldt = reflectedRay.t();
}
}
if(back.Intersect(reflectedRay))
{
if(reflectedRay.t() < oldt)
{
use = 6;
oldt = reflectedRay.t();
}
}
std::cout << "Hitpoint: " << reflectedRay.origin() + reflectedRay.direction() * reflectedRay.t() << " / " << use << std::endl;
std::cout << "Box: " << leftDown << " / " << rightUp << std::endl;
//1 is left
if(use == 1)
{
/*
C - D
| |
A - B
*/
//-1 because we start by 0,0
maxX = m_right->getX() - 1;
maxY = m_right->getY() - 1;
Vec3f a = leftDown;
Vec3f b(leftDown[0], leftDown[1], rightUp[2]);
Vec3f c(leftDown[0], rightUp[1], leftDown[2]);
Vec3f d(leftDown[0], rightUp[1], rightUp[2]);
TexturedSmoothTriangle one(a,b,c, Vec3f(1,0,0), Vec3f(1,0,0), Vec3f(1,0,0), Vec3f(0,maxY,0), Vec3f(maxX,maxY,0), Vec3f(0,0,0) ,(FlatShader*) 0x00000000);
TexturedSmoothTriangle two(b,d,c, Vec3f(1,0,0), Vec3f(1,0,0), Vec3f(1,0,0), Vec3f(maxX,maxY,0), Vec3f(maxX,0,0), Vec3f(0,0,0) ,(FlatShader*) 0x00000000);
if(one.Intersect(reflectedRay))
{
return(m_left->GetTexel(reflectedRay.u(), reflectedRay.v()));
}
else if(two.Intersect(reflectedRay))
{
return(m_left->GetTexel(reflectedRay.u(), reflectedRay.v()));
}
else
{
//std::cout << "Left: Env Shader error : the ray has not hitten one or two (the triangles of the env cube)
";
return(Vec3f(1,0,1));
}
}
//2 is right
else if(use == 2)
{
/*
C - D
| |
A - B
*/
maxX = m_right->getX() - 1;
maxY = m_right->getY() - 1;
Vec3f a(rightUp[0], leftDown[1], leftDown[2]);
Vec3f b(rightUp[0], leftDown[1], rightUp[2]);
Vec3f c(rightUp[0], rightUp[1], leftDown[2]);
Vec3f d = rightUp;
TexturedSmoothTriangle one(a,b,c, Vec3f(1,0,0), Vec3f(1,0,0), Vec3f(1,0,0), Vec3f(0,maxY,0), Vec3f(maxX,maxY,0), Vec3f(0,0,0) ,(FlatShader*) 0x00000000);
TexturedSmoothTriangle two(b,d,c, Vec3f(1,0,0), Vec3f(1,0,0), Vec3f(1,0,0), Vec3f(maxX,maxY,0), Vec3f(maxX,0,0), Vec3f(0,0,0) ,(FlatShader*) 0x00000000);
if(one.Intersect(reflectedRay))
{
return(m_right->GetTexel(reflectedRay.u(), reflectedRay.v()));
}
else if(two.Intersect(reflectedRay))
{
return(m_right->GetTexel(reflectedRay.u(), reflectedRay.v()));
}
else
{
//std::cout << "Right: Env Shader error : the ray has not hitten one or two (the triangles of the env cube)
";
return(Vec3f(0,0,1));
}
}
//3 is up
else if(use == 3)
{
/*
C - D
| |
A - B
*/
maxX = m_right->getX() - 1;
maxY = m_right->getY() - 1;
Vec3f a(leftDown[0], rightUp[1], leftDown[2]);
Vec3f b(rightUp[0], rightUp[1], leftDown[2]);
Vec3f c(leftDown[0], rightUp[1], rightUp[2]);
Vec3f d = rightUp;
TexturedSmoothTriangle one(a,b,c, Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,maxY,0), Vec3f(maxX,maxY,0), Vec3f(0,0,0) ,(FlatShader*) 0x00000000);
TexturedSmoothTriangle two(b,d,c, Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(maxX,maxY,0), Vec3f(maxX,0,0), Vec3f(0,0,0) ,(FlatShader*) 0x00000000);
if(one.Intersect(reflectedRay))
{
return(m_up->GetTexel(reflectedRay.u(), reflectedRay.v()));
}
else if(two.Intersect(reflectedRay))
{
return(m_up->GetTexel(reflectedRay.u(), reflectedRay.v()));
}
else
{
//std::cout << "Up: Env Shader error : the ray has not hitten one or two (the triangles of the env cube)
";
return(Vec3f(1,0,0));
}
}
//4 is down
else if(use == 4)
{
/*
C - D
| |
A - B
*/
maxX = m_right->getX() - 1;
maxY = m_right->getY() - 1;
Vec3f a = leftDown;
Vec3f b(rightUp[0], leftDown[1], leftDown[2]);
Vec3f c(leftDown[0], leftDown[1], rightUp[2]);
Vec3f d(rightUp[0],leftDown[1], rightUp[2]);
TexturedSmoothTriangle one(a,b,c, Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,maxY,0), Vec3f(maxX,maxY,0), Vec3f(0,0,0) ,(FlatShader*) 0x00000000);
TexturedSmoothTriangle two(b,d,c, Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(maxX,maxY,0), Vec3f(maxX,0,0), Vec3f(0,0,0) ,(FlatShader*) 0x00000000);
std::cout << "ReflectedRay: " << reflectedRay.origin() << " + t * " << reflectedRay.direction() << " / Hitpoint: " << reflectedRay.origin() + reflectedRay.direction() * reflectedRay.t() << "
";
std::cout << "TexturedSmoothTriangle one("<<a<<","<<b<<","<<c<<", Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,"<<maxY<<",0), Vec3f("<<maxX<<","<<maxY<<",0), Vec3f(0,0,0) ,(FlatShader*) 0x00000000)
";
std::cout << "TexturedSmoothTriangle two("<<b<<","<<d<<","<<c<<", Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(" << maxX<<","<<maxY<<",0), Vec3f("<<maxX<<",0,0), Vec3f(0,0,0) ,(FlatShader*) 0x00000000)
";
if(one.Intersect(reflectedRay))
{
return(m_down->GetTexel(reflectedRay.u(), reflectedRay.v()));
}
else if(two.Intersect(reflectedRay))
{
return(m_down->GetTexel(reflectedRay.u(), reflectedRay.v()));
}
else
{
std::cout << "Down: Env Shader error : the ray has not hitten one or two (the triangles of the env cube)
";
return(Vec3f(0,1,0));
}
}
//5 is front
else if(use == 5)
{
/*
C - D
| |
A - B
*/
maxX = m_right->getX() - 1;
maxY = m_right->getY() - 1;
Vec3f a = leftDown;
Vec3f b(rightUp[0], leftDown[1], leftDown[2]);
Vec3f c(leftDown[0], rightUp[1], leftDown[2]);
Vec3f d(rightUp[0], rightUp[1], leftDown[2]);
TexturedSmoothTriangle one(a,b,c, Vec3f(0,0,1), Vec3f(0,0,1), Vec3f(0,0,1), Vec3f(0,maxY,0), Vec3f(maxX,maxY,0), Vec3f(0,0,0) ,(FlatShader*) 0x00000000);
TexturedSmoothTriangle two(b,d,c, Vec3f(0,0,1), Vec3f(0,0,1), Vec3f(0,0,1), Vec3f(maxX,maxY,0), Vec3f(maxX,0,0), Vec3f(0,0,0) ,(FlatShader*) 0x00000000);
if(one.Intersect(reflectedRay))
{
return(m_front->GetTexel(reflectedRay.u(), reflectedRay.v()));
}
else if(two.Intersect(reflectedRay))
{
return(m_front->GetTexel(reflectedRay.u(), reflectedRay.v()));
}
else
{
//std::cout << "Front: Env Shader error : the ray has not hitten one or two (the triangles of the env cube)
";
return(Vec3f(1,0.5,0));
}
}
//6 is back
else if(use == 6)
{
/*
C - D
| |
A - B
*/
maxX = m_right->getX() - 1;
maxY = m_right->getY() - 1;
Vec3f a(leftDown[0], leftDown[1], rightUp[2]);
Vec3f b(rightUp[0], leftDown[1], rightUp[2]);
Vec3f c(leftDown[0], rightUp[1], rightUp[2]);
Vec3f d = rightUp;
TexturedSmoothTriangle one(a,b,c, Vec3f(0,0,1), Vec3f(0,0,1), Vec3f(0,0,1), Vec3f(0,maxY,0), Vec3f(maxX,maxY,0), Vec3f(0,0,0) ,(FlatShader*) 0x00000000);
TexturedSmoothTriangle two(b,d,c, Vec3f(0,0,1), Vec3f(0,0,1), Vec3f(0,0,1), Vec3f(maxX,maxY,0), Vec3f(maxX,0,0), Vec3f(0,0,0) ,(FlatShader*) 0x00000000);
if(one.Intersect(reflectedRay))
{
return(m_back->GetTexel(reflectedRay.u(), reflectedRay.v()));
}
else if(two.Intersect(reflectedRay))
{
return(m_back->GetTexel(reflectedRay.u(), reflectedRay.v()));
}
else
{
//std::cout << "BACK: Env Shader error : the ray has not hitten one or two (the triangles of the env cube)
";
return(Vec3f(0,0.6,0.6));
}
}
else
{
std::cout << "Env Shader error : the ray has not hitten any Infinte Plane
";
return(Vec3f(1,1,1));
}
}[/code]
Comments
[code]
Vec3f
EnvShader::Shade(Ray& ray)
{
//Thank you for the phong shader
Vec3f N = ray.hit()->GetNormal(ray);
if(N.dot(ray.direction()) > 0)
{
N *= -1;
}
Vec3f reflectedDirection = ray.direction() - N*2*N.dot(ray.direction());
reflectedDirection.normalize();
//Vec3f leftDown = Vec3f(-10,-10,-10);
//Vec3f rightUp = Vec3f(10,10,10);
//float oldt = 400020001;
//int use = 0;
//int maxX, maxY;
//cool even more code that can be used again.
//Vec3f hitPoint = ray.origin()+ray.direction()*ray.t();
//Ray reflectedRay(hitPoint, reflectedDirection);
//wow this class almost only use allready existent code
m_box = ray.hit()->CalcBounds();
//m_box = m_scene->GetSceneBox();
Vec3f leftDown = m_box.min();
Vec3f rightUp = m_box.max();
/*************************************/
Vec3f frontLeftDown(leftDown), frontRightDown(rightUp[0],leftDown[1],leftDown[2]), frontLeftUp(leftDown[0],rightUp[1],leftDown[2]), frontRightUp(rightUp[0],rightUp[1],leftDown[2]);
Vec3f backLeftDown(leftDown[0],leftDown[1],rightUp[2]), backRightDown(rightUp[0],leftDown[1],rightUp[2]), backLeftUp(leftDown[0],rightUp[1],rightUp[2]), backRightUp(rightUp);
/*************************************/
Ray bgRay = ray;
FlatShader myShader(m_scene, Vec3f(255,0,0));
Vec3f color;
//===============================================================================================
TexturedSmoothTriangle fl(frontLeftDown, frontRightDown, frontLeftUp, Vec3f(0,0,1), Vec3f(0,0,1), Vec3f(0,0,1), Vec3f(0,0,0), Vec3f(1,0,0), Vec3f(0,1,0), &myShader);
TexturedSmoothTriangle fr(frontLeftUp, frontRightUp, frontRightDown, Vec3f(0,0,1), Vec3f(0,0,1), Vec3f(0,0,1), Vec3f(0,1,0), Vec3f(1,1,0), Vec3f(1,0,0), &myShader);
TexturedSmoothTriangle tl(backLeftUp, backRightUp, frontLeftUp, Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,0,0), Vec3f(1,0,0), Vec3f(0,1,0), &myShader);
TexturedSmoothTriangle tr(frontLeftUp, frontRightUp, backRightUp, Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(1,1,0), Vec3f(1,0,0), &myShader);
TexturedSmoothTriangle ll(frontLeftDown, backLeftDown, frontLeftUp, Vec3f(1,0,0), Vec3f(1,0,0), Vec3f(1,0,0), Vec3f(0,0,0), Vec3f(1,0,0), Vec3f(0,1,0), &myShader);
TexturedSmoothTriangle lr(frontLeftUp, backLeftUp, frontLeftDown, Vec3f(1,0,0), Vec3f(1,0,0), Vec3f(1,0,0), Vec3f(0,1,0), Vec3f(1,1,0), Vec3f(1,0,0), &myShader);
TexturedSmoothTriangle rl(backRightDown, frontRightDown, backRightUp, Vec3f(1,0,0), Vec3f(1,0,0), Vec3f(1,0,0), Vec3f(0,0,0), Vec3f(1,0,0), Vec3f(0,1,0), &myShader);
TexturedSmoothTriangle rr(backRightUp, frontRightUp, frontRightDown, Vec3f(1,0,0), Vec3f(1,0,0), Vec3f(1,0,0), Vec3f(0,1,0), Vec3f(1,1,0), Vec3f(1,0,0), &myShader);
TexturedSmoothTriangle bal(backLeftDown, backRightDown, backLeftUp, Vec3f(0,0,1), Vec3f(0,0,1), Vec3f(0,0,1), Vec3f(0,0,0), Vec3f(1,0,0), Vec3f(0,1,0), &myShader);
TexturedSmoothTriangle bar(backLeftUp, backRightUp, backRightDown, Vec3f(0,0,1), Vec3f(0,0,1), Vec3f(0,0,1), Vec3f(0,1,0), Vec3f(1,1,0), Vec3f(1,0,0), &myShader);
TexturedSmoothTriangle dl(frontLeftDown, frontRightDown, backRightDown, Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(1,1,0), Vec3f(1,0,0), &myShader);
TexturedSmoothTriangle dr(backLeftDown, backRightDown, frontLeftDown, Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,1,0), Vec3f(0,0,0), Vec3f(1,0,0), Vec3f(0,1,0), &myShader);
////std::cout << "Before: fl
";
if(fl.Intersect(bgRay))
{
//std::cout << "fl
";
float u,v;
fl.GetUV(bgRay, u,v);
//color = m_textures[0]->GetTexel(u,v);
color = m_front->GetTexel(u,v);
//std::cout << "color: " << color << std::endl;
//color = bgRay.hit()->shader()->Shade(bgRay);
}
////std::cout << "Before: fr
";
else if(fr.Intersect(bgRay))
{
//std::cout << "fr
";
////std::cout << "FR: " << &fr << "
";
//color = bgRay.hit()->shader()->Shade(bgRay);
float u,v;
fr.GetUV(bgRay, u,v);
color = m_front->GetTexel(u,v);
}
else if(tl.Intersect(bgRay))
{
//std::cout << "tl
";
float u,v;
tl.GetUV(bgRay, u,v);
color = m_up->GetTexel(u,v);
//color = bgRay.hit()->shader()->Shade(bgRay);
}
////std::cout << "Before: fr
";
else if(tr.Intersect(bgRay))
{
//std::cout << "tr
";
////std::cout << "FR: " << &fr << "
";
//color = bgRay.hit()->shader()->Shade(bgRay);
float u,v;
tr.GetUV(bgRay, u,v);
color = m_up->GetTexel(u,v);
}
else if(ll.Intersect(bgRay))
{
//std::cout << "ll
";
////std::cout << "FR: " << &fr << "
";
//color = bgRay.hit()->shader()->Shade(bgRay);
float u,v;
ll.GetUV(bgRay, u,v);
color = m_left->GetTexel(u,v);
}
else if(lr.Intersect(bgRay))
{
//std::cout << "lr
";
////std::cout << "FR: " << &fr << "
";
//color = bgRay.hit()->shader()->Shade(bgRay);
float u,v;
lr.GetUV(bgRay, u,v);
color = m_left->GetTexel(u,v);
}
else if(rl.Intersect(bgRay))
{
//std::cout << "rl
";
////std::cout << "FR: " << &fr << "
";
//color = bgRay.hit()->shader()->Shade(bgRay);
float u,v;
rl.GetUV(bgRay, u,v);
color = m_right->GetTexel(u,v);
}
else if(rr.Intersect(bgRay))
{
//std::cout << "rr
";
////std::cout << "FR: " << &fr << "
";
//color = bgRay.hit()->shader()->Shade(bgRay);
float u,v;
rr.GetUV(bgRay, u,v);
color = m_right->GetTexel(u,v);
}
else if(bal.Intersect(bgRay))
{
//std::cout << "bal
";
////std::cout << "FR: " << &fr << "
";
//color = bgRay.hit()->shader()->Shade(bgRay);
float u,v;
bal.GetUV(bgRay, u,v);
color = m_back->GetTexel(u,v);
}
else if(bar.Intersect(bgRay))
{
//std::cout << "bar
";
////std::cout << "FR: " << &fr << "
";
//color = bgRay.hit()->shader()->Shade(bgRay);
float u,v;
bar.GetUV(bgRay, u,v);
color = m_back->GetTexel(u,v);
}
else if(dl.Intersect(bgRay))
{
//std::cout << "dl
";
////std::cout << "FR: " << &fr << "
";
//color = bgRay.hit()->shader()->Shade(bgRay);
float u,v;
dl.GetUV(bgRay, u,v);
color = m_down->GetTexel(u,v);
}
else if(dr.Intersect(bgRay))
{
//std::cout << "dr
";
////std::cout << "FR: " << &fr << "
";
//color = bgRay.hit()->shader()->Shade(bgRay);
float u,v;
dr.GetUV(bgRay, u,v);
color = m_down->GetTexel(u,v);
}
//return(color);
//===============================================================================================
//===============================================================================================
//lets use the phong shader. this thing hasmake so much work, we can reuse it^^
Vec3f shadow_org = ray.origin()+ray.direction()*ray.t();
Ray shadow_ray;
shadow_ray.setOrigin(shadow_org);
Vec3f diffuse_color = color;
color = m_ambient_color;
Vec3f R = ray.direction() - N*2*N.dot(ray.direction());
R.normalize();
float ks = 0.5, ke = 40;
int n_area_rays = 1000;
std::vector lights = m_scene->lights();
for(unsigned int i = 0; i < lights.size(); ++i)
{
Vec3f intensity;
int max_s = (lights[i]->IsArea()) ? n_area_rays : 1;
Vec3f color_l(0.0f,0.0f,0.0f);
for(int s = 0; s < max_s; ++s)
{
if(lights[i]->Illuminate(shadow_ray, intensity))
{
// check for occluders
if(m_scene->Occluded(shadow_ray))
{
continue;
}
float IdotN = shadow_ray.direction().dot(N);
if(IdotN > 0)
{
// diffuse term
color_l += diffuse_color * intensity * IdotN;
}
// specular term
float IdotR = shadow_ray.direction().dot(R);
if(IdotR > 0)
{
color_l += m_specular_color * intensity * pow(IdotR,ke) * ks;
}
}
}
color_l /= static_cast(max_s);
color += color_l;
}
color.clamp();
return(color);
//===============================================================================================
//Vec3f leftDown = Vec3f(-100,-100,-100);
//Vec3f rightUp = Vec3f(100,100,100);;
//ok the tnear and tfar stuff is complicated. lets use inf planes
//i know i shouldnt do it. but we are in c and can play with pointer
}[/code]
Thanks to share nice information. I think your topic content is very very important not only me but also all general public.This is Education information site,So any Education base topic and Result, Jobs Curricular, Popular News and Other information.resultinfo24