hi,
I have large problems doing water reflection with cs, I have
attacked the problem with many ppl, but without luck. Problem starts
when I rotate the camera along x axis and the reflection looks like
that: http://www.ragecomm.com/obi/reflectionsuxx.JPG, when in
'normal' situation it looks like here:
http://www.ragecomm.com/obi/reflection.JPG;
I have tried many combinations with reflection camera:
1. rotating camera by xz reflection matrix
1 0 0
0 -1 0
0 0 1
2. transform.GetReflect(csPlane3(0,1,0,waterHeight)) but I couldn't get
right reflection.
Here is the code I was writing about :
#include <cssysdef.h>
#include <physicallayer/persist.h>
#include <physicallayer/pl.h>
#include <csutil/documentcommon.h>
#include "water.h"
CS_IMPLEMENT_PLUGIN
CEL_IMPLEMENT_FACTORY (Water, "pcwater")
//******************************************celPcWater*******************************************
static bool Report (iObjectRegistry* object_reg, const char* msg, ...)
{
va_list arg;
va_start (arg, msg);
csRef<iReporter> rep (CS_QUERY_REGISTRY (object_reg, iReporter));
if (rep)
rep->ReportV (CS_REPORTER_SEVERITY_ERROR, "class or something",
msg, arg);
else
{
csPrintfV (msg, arg);
csPrintf ("\n");
fflush (stdout);
}
va_end (arg);
return false;
}
csStringID celPcWater::action_createwater = csInvalidStringID;
csStringID celPcWater::action_setspeed = csInvalidStringID;
csStringID celPcWater::action_setheight = csInvalidStringID;
csStringID celPcWater::id_position = csInvalidStringID;
csStringID celPcWater::id_size = csInvalidStringID;
csStringID celPcWater::id_sector = csInvalidStringID;
csStringID celPcWater::id_height = csInvalidStringID;
csStringID celPcWater::id_speed = csInvalidStringID;
csStringID celPcWater::id_tex_diffuse = csInvalidStringID;
csStringID celPcWater::id_tex_water = csInvalidStringID;
celPcWater::celPcWater (iObjectRegistry* object_reg)
: scfImplementationType (this, object_reg)
{
oreg = object_reg;
wh = 1;
speed = 0.002f;
ww = 0.01f;
scfiCelTimerListener = new CelTimerListener (this);
pl->CallbackEveryFrame ((iCelTimerListener*)this, CEL_EVENT_PRE);
if (action_createwater == csInvalidStringID)
{
action_createwater = pl->FetchStringID ("cel.action.CreateWater");
action_setspeed = pl->FetchStringID ("cel.action.SetSpeed");
action_setheight = pl->FetchStringID ("cel.action.SetHeight");
id_position = pl->FetchStringID ("cel.parameter.position");;
id_size = pl->FetchStringID ("cel.parameter.size");
id_sector = pl->FetchStringID ("cel.parameter.sector");
id_height = pl->FetchStringID ("cel.parameter.height");
id_speed = pl->FetchStringID ("cel.parameter.speed");
id_tex_diffuse = pl->FetchStringID ("cel.parameter.TexDiffuse");
id_tex_water = pl->FetchStringID ("cel.parameter.TexWater");
}
vc = CS_QUERY_REGISTRY (object_reg, iVirtualClock);
}
celPcWater::~celPcWater()
{
}
bool celPcWater::GenerateWater (csVector3 position, unsigned int size, iSector*
sector,
iTextureWrapper* wt,iTextureWrapper* rt)
{
csRef<iVFS> vfs (CS_QUERY_REGISTRY(object_reg, iVFS));
water_texture = wt;
water_sector = sector;
gMesh = 0;
gFact = 0;
gMeshState = 0;
gFactState = 0;
gMeshW = 0;
if (!engine)
{
engine = CS_QUERY_REGISTRY (object_reg, iEngine);
if (engine == 0) return Report (object_reg, "can't get engine");
}
csRef<iPluginManager> plugin_mgr (
CS_QUERY_REGISTRY (object_reg, iPluginManager));
csRef<iStringSet> strings =
CS_QUERY_REGISTRY_TAG_INTERFACE (object_reg,
"crystalspace.shared.stringset", iStringSet);
//loading shader
csRef<iFile> shaderFile = vfs->Open ("/shader/water/water2.xml",
VFS_FILE_READ);
csRef<iDocumentSystem> docsys (
CS_QUERY_REGISTRY(object_reg, iDocumentSystem));
csRef<iDocument> shaderDoc = docsys->CreateDocument ();
shaderDoc->Parse (shaderFile, true);
csRef<iShader> shader;
csRef<iShaderManager> shmgr (CS_QUERY_REGISTRY(object_reg, iShaderManager));
csRef<iShaderCompiler> shcom (shmgr->GetCompiler ("XMLShader"));
shader = shcom->CompileShader (shaderDoc->GetRoot ()->GetNode ("shader"));
// setup the mesh
csRef<iMeshObjectType> gType = CS_QUERY_PLUGIN_CLASS(plugin_mgr,
"crystalspace.mesh.object.genmesh", iMeshObjectType);
if (!gType)
{
gType = CS_LOAD_PLUGIN(plugin_mgr,
"crystalspace.mesh.object.genmesh", iMeshObjectType);
if (!gType)
{
return Report (object_reg, "couldn't find genmesh plugin");
}
}
gFact = gType->NewFactory ();
csRef<iMeshFactoryWrapper> fw = engine->CreateMeshFactory (gFact,
"waterFactory");
gFactState = SCF_QUERY_INTERFACE(gFact, iGeneralFactoryState);
gMesh = gFact->NewInstance ();
gMeshState = SCF_QUERY_INTERFACE(gMesh, iGeneralMeshState);
//setup a material
csRef<iMaterial> mat = engine->CreateBaseMaterial (engine->FindTexture
("white.bmp"));
mat->SetShader (strings->Request ("standard"), shader);
csRef<iMaterialWrapper> matW = engine->GetMaterialList ()->NewMaterial (mat,
"walls.jpg");
csRef<csShaderVariable> attvar1 (csPtr<csShaderVariable> (
new csShaderVariable (strings->Request ("tex refract"))));
attvar1->SetValue (water_texture);
mat->AddVariable (attvar1);
csRef<csShaderVariable> attvar2 (csPtr<csShaderVariable> (
new csShaderVariable (strings->Request ("tex diffuse"))));
attvar2->SetValue (rt);
mat->AddVariable (attvar2);
//shader expression (we must get things moving)
// <shadervar name="time" type="expression">
// <mul><atom type="var">standard time</atom><atom
type="num">.25</atom></mul>
//</shadervar>
csShaderExpression *ex = new csShaderExpression(object_reg);
//expression node
csRef<iDocumentSystem> xml(new csTinyDocumentSystem());
csRef<iDocument> doc = xml->CreateDocument ();
csRef<iDocumentNode> root = doc->CreateRoot ();
csRef<iDocumentNode> exp_node = root->CreateNodeBefore (CS_NODE_ELEMENT, 0);
exp_node->SetAttribute ("name", "time");
exp_node->SetAttribute ("type", "expression");
exp_node->SetValue ("shadervar");
//espresion contents
csRef<iDocumentNode> mul_node = exp_node->CreateNodeBefore (CS_NODE_ELEMENT,
0);
mul_node->SetValue ("mul");
//atom1
csRef<iDocumentNode> atom1_node = mul_node->CreateNodeBefore
(CS_NODE_ELEMENT, 0);
atom1_node->SetValue ("atom");
atom1_node->SetAttribute ("type", "var");
csRef<iDocumentNode> atom1value_node = atom1_node->CreateNodeBefore
(CS_NODE_TEXT, 0);
atom1value_node->SetValue ("standard time");
//atom2
csRef<iDocumentNode> atom2_node = mul_node->CreateNodeBefore
(CS_NODE_ELEMENT, 0);
atom2_node->SetValue ("atom");
atom2_node->SetAttribute ("type", "num");
csRef<iDocumentNode> atom2value_node = atom2_node->CreateNodeBefore
(CS_NODE_TEXT, 0);
atom2value_node->SetValueAsFloat (speed);
csRef<csShaderVariable> attvar3 (csPtr<csShaderVariable> (
new csShaderVariable (strings->Request ("time"))));
ex->Parse (mul_node);
csRef<csShaderExpressionAccessor> ex_accesor
(csPtr<csShaderExpressionAccessor> (
new csShaderExpressionAccessor (object_reg, ex)));
attvar3->SetType (csShaderVariable::VECTOR4);
attvar3->SetAccessor (ex_accesor);
mat->AddVariable (attvar3);
gMeshState->SetMaterialWrapper (matW);
//setup a wrapper too
gMeshW = engine->CreateMeshWrapper (gMesh, "water", sector);
csMatrix3 m;
m.Identity ();
gMeshW->GetMovable ()->SetTransform (m);
gMeshW->GetMovable ()->SetPosition (position);
gMeshW->GetMovable ()->UpdateMove ();
gMeshW->SetRenderPriority (engine->GetObjectRenderPriority ());
//gMeshW->SetZBufMode (CS_ZBUF_MESH);
gMesh->SetMaterialWrapper (matW);
Width = Height = 128;
GridSize = size / Width;
//setup the mesh
gFactState->GenerateBox (csBox3 (0,0, 0, size,0, size));
//for (int i = 0; i < gFactState->GetVertexCount (); i++)
//{
// vect[i] *= 1000;
//}
//gFactState->SetVertexCount (Width*Height);
//gFactState->SetTriangleCount (2*((Width-1)*(Height-1)));
////setup ibuf
//unsigned int x, z, cnt=0,idx;
//csTriangle *ibuf=gFactState->GetTriangles ();
//for(x=0;x<(Height-1);x++)
//{
// for(z=0;z<(Width-1);z++)
// {
// idx = 2*(x*(Width-1)+z);
// ibuf[idx].a = x*Width+z;
// ibuf[idx].b = x*Width+z+1;
// ibuf[idx].c = (x+1)*Width+z;
// idx++;
// ibuf[idx].a = x*Width+z+1;
// ibuf[idx].b = (x+1)*Width+(z+1);
// ibuf[idx].c = (x+1)*Width+z;
// }
//}
////setup our vbuf
//csVector3 *vbuf = gFactState->GetVertices ();
//cnt = 0;
//for(x=0;x<Height;x++)
//{
// for(z=0;z<Width;z++)
// {
// idx = x*Width+z;
// vbuf[idx].x = x*GridSize;
// vbuf[idx].y = 0;
// vbuf[idx].z = z*GridSize;
// }
//}
////setup texture
//csVector2 *tbuf = gFactState->GetTexels ();
//for(x=0;x<Height;x++)
//{
// for(z=0;z<Width;z++)
// {
// idx = x*Width+z;
// tbuf[idx].x = (float)x/(float)Height;
// tbuf[idx].y = (float)z/(float)Width;
// }
//}
gFactState->CalculateNormals ();
gFactState->Invalidate ();
csVector3 vertices [4];
vertices[0] = csVector3 (0,0,0);
vertices[1] = csVector3 (size,0,0);
vertices[2] = csVector3 (size, 0, size);
vertices[3] = csVector3 (0,0, size);
dummy_sector = engine->CreateSector ("dummy_sector");
portal_mesh = engine->CreatePortal (0,
dummy_sector, position, engine->FindSector ("x0y0"), vertices, 4,
dummy_portal);
dummy_portal->GetFlags ().Set (CS_PORTAL_CLIPDEST, CS_PORTAL_CLIPDEST);
portal_mesh->GetMovable ()->SetTransform (gMeshW->GetMovable ()->GetTransform
());
portal_mesh->GetMovable ()->UpdateMove ();
//gMeshW->GetMovable ()->SetTransform (portal_mesh->GetMovable
()->GetTransform ());
//gMeshW->GetMovable ()->UpdateMove ();
return true;
}
//TODO: make it more general
void celPcWater::TickEveryFrame ()
{
iCamera* c = view->GetCamera();
csOrthoTransform oldCameraTransform = c->GetTransform();
csOrthoTransform newCameraTransform = csOrthoTransform ();
// Find water plane
csVector3 waterOrigin = gMeshW->GetMovable()->GetTransform().GetOrigin();
float waterHeight = waterOrigin.y;
// Set up the reflection camera
newCameraTransform =
oldCameraTransform.GetReflect(csPlane3(0,1,0,waterHeight));
newCameraTransform.SetOrigin (csVector3 (oldCameraTransform.GetOrigin ().x,
-oldCameraTransform.GetOrigin ().y + waterHeight*2,
oldCameraTransform.GetOrigin ().z));
//c->SetSector (dummy_sector);
c->SetTransform(newCameraTransform);
// Remove the watermesh
gMeshW->GetFlags ().Set(CS_ENTITY_INVISIBLE, CS_ENTITY_INVISIBLE);
// Setup the clipper
// CSDRAW_CLEARSCREEN
g2d->Clear (g2d->FindRGB (255, 0, 255));
g3d->SetRenderTarget (water_texture->GetTextureHandle ());
if (!g3d->BeginDraw (engine->GetBeginDrawFlags () | CSDRAW_3DGRAPHICS))
return;
view->Draw();
// Render target switches back to screen after FinishDraw
g3d->FinishDraw();
// Put the watermesh back
gMeshW->GetFlags ().Set(CS_ENTITY_INVISIBLE, 0);
// Reset the camera
//c->SetSector (water_sector);
c->SetTransform(oldCameraTransform);
}
csPtr<iCelDataBuffer> celPcWater::Save ()
{
return (csPtr<iCelDataBuffer>)NULL;
}
bool celPcWater::Load (iCelDataBuffer* databuf)
{
return false;
}
bool celPcWater::PerformAction (csStringID actionId, iCelParameterBlock* params)
{
if (actionId == action_createwater)
{
CEL_FETCH_VECTOR3_PAR (pos, params, id_position);
if (!p_pos)
return Report (object_reg,
"Missing parameter 'position' for action CreateWater!");
CEL_FETCH_LONG_PAR (size, params, id_size);
if (!p_size)
return Report (object_reg,
"Missing parameter 'size' for action CreateWater!");
CEL_FETCH_STRING_PAR (sector, params, id_sector);
if (!sector)
return Report (object_reg,
"Missing parameter 'sector' for action CreateWater!");
CEL_FETCH_STRING_PAR (texw, params, id_tex_water);
if (!texw)
return Report (object_reg,
"Missing parameter 'tex water' for action CreateWater!");
CEL_FETCH_STRING_PAR (texr, params, id_tex_diffuse);
if (!texr)
return Report (object_reg,
"Missing parameter 'tex diffuse' for action CreateWater!");
if (!engine)
{
engine = CS_QUERY_REGISTRY (object_reg, iEngine);
view = CS_QUERY_REGISTRY (object_reg, iView);
g3d = CS_QUERY_REGISTRY (object_reg, iGraphics3D);
g2d = g3d->GetDriver2D ();
if (engine == 0) return Report (object_reg, "can't get engine");
}
GenerateWater (pos, size, engine->FindSector (sector),
engine->FindTexture (texw), engine->FindTexture (texr));
} else if (actionId == action_setspeed)
{
CEL_FETCH_FLOAT_PAR (speed, params, id_speed);
if (!p_speed)
return Report (object_reg,
"Missing parameter 'speed' for action SetSpeed!");
celPcWater::speed = speed;
}
else if (actionId == action_setheight)
{
CEL_FETCH_FLOAT_PAR (height, params, id_height);
if (!p_height)
return Report (object_reg,
"Missing parameter 'height' for action SetHeight!");
wh = height;
}
return true;
}
any idea?
--
greetings,
Piotr Obrzut mailto:[EMAIL PROTECTED]
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Crystal-main mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/crystal-main
Unsubscribe: mailto:[EMAIL PROTECTED]