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]

Reply via email to