You should call factory state Invalidate() after changing the vertex
data in any way.

Greetings,

On 11/21/05, Philipp Wojke <[EMAIL PROTECTED]> wrote:
> Hello,
>
> I posted some days ago about this problem:
>
> When I modify vertex and triangle information of a genmeshfactory I get
> some strange behavior. It looks like vertex colors are totally random,
> even if set to fixed values.
>
> To demonstrate this I have modified the simple1 tutorial. Could someone
> look at it and check if I made an error in creating or updating the
> factory or if CS has some bug here?
>
> I have tested it with pseudo stable release from 3 of September and with
> CVS snapshot from 12 and 21 of November, all the same effect. It worked
> fine with a snapshot from December of last year.
>
> Philipp
>
>
> /*
>     Copyright (C) 2001 by Jorrit Tyberghein
>
>     This library is free software; you can redistribute it and/or
>     modify it under the terms of the GNU Library General Public
>     License as published by the Free Software Foundation; either
>     version 2 of the License, or (at your option) any later version.
>
>     This library is distributed in the hope that it will be useful,
>     but WITHOUT ANY WARRANTY; without even the implied warranty of
>     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>     Library General Public License for more details.
>
>     You should have received a copy of the GNU Library General Public
>     License along with this library; if not, write to the Free
>     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> */
>
> #include "simple1.h"
>
> CS_IMPLEMENT_APPLICATION
>
> //---------------------------------------------------------------------------
>
> Simple::Simple ()
> {
>   SetApplicationName ("CrystalSpace.Simple1");
> }
>
> Simple::~Simple ()
> {
> }
>
> void Simple::ProcessFrame ()
> {
>   // First get elapsed time from the virtual clock.
>   csTicks elapsed_time = vc->GetElapsedTicks ();
>   // Now rotate the camera according to keyboard state
>   float speed = (elapsed_time / 1000.0) * (0.06 * 20);
>
>   iCamera* c = view->GetCamera();
>
>   if (kbd->GetKeyState (CSKEY_SHIFT))
>   {
>     // If the user is holding down shift, the arrow keys will cause
>     // the camera to strafe up, down, left or right from it's
>     // current position.
>     if (kbd->GetKeyState (CSKEY_RIGHT))
>       c->Move (CS_VEC_RIGHT * 4 * speed);
>     if (kbd->GetKeyState (CSKEY_LEFT))
>       c->Move (CS_VEC_LEFT * 4 * speed);
>     if (kbd->GetKeyState (CSKEY_UP))
>       c->Move (CS_VEC_UP * 4 * speed);
>     if (kbd->GetKeyState (CSKEY_DOWN))
>       c->Move (CS_VEC_DOWN * 4 * speed);
>   }
>   else
>   {
>     // left and right cause the camera to rotate on the global Y
>     // axis; page up and page down cause the camera to rotate on the
>     // _camera's_ X axis (more on this in a second) and up and down
>     // arrows cause the camera to go forwards and backwards.
>     if (kbd->GetKeyState (CSKEY_RIGHT))
>       rotY += speed;
>     if (kbd->GetKeyState (CSKEY_LEFT))
>       rotY -= speed;
>     if (kbd->GetKeyState (CSKEY_PGUP))
>       rotX += speed;
>     if (kbd->GetKeyState (CSKEY_PGDN))
>       rotX -= speed;
>     if (kbd->GetKeyState (CSKEY_UP))
>       c->Move (CS_VEC_FORWARD * 4 * speed);
>     if (kbd->GetKeyState (CSKEY_DOWN))
>       c->Move (CS_VEC_BACKWARD * 4 * speed);
>   }
>
>   // We now assign a new rotation transformation to the camera.  You
>   // can think of the rotation this way: starting from the zero
>   // position, you first rotate "rotY" radians on your Y axis to get
>   // the first rotation.  From there you rotate "rotX" radians on the
>   // your X axis to get the final rotation.  We multiply the
>   // individual rotations on each axis together to get a single
>   // rotation matrix.  The rotations are applied in right to left
>   // order .
>   csMatrix3 rot = csXRotMatrix3 (rotX) * csYRotMatrix3 (rotY);
>   csOrthoTransform ot (rot, c->GetTransform().GetOrigin ());
>   c->SetTransform (ot);
>
>
>
>     csRef<iGeneralFactoryState> factoryState    = 
> SCF_QUERY_INTERFACE(meshFactoryWrapper->GetMeshObjectFactory(), 
> iGeneralFactoryState);
>
>     int poincount   = (vc->GetCurrentTicks() / 1000) % 10 + 1;
>
>     factoryState->SetVertexCount(poincount * 2);
>         factoryState->SetTriangleCount((poincount - 1) * 2);
>
>     csVector3*  vertices    = factoryState->GetVertices();
>     csVector3*  normals     = factoryState->GetNormals();
>     csVector2*  uvs         = factoryState->GetTexels();
>     csTriangle* triangles   = factoryState->GetTriangles();
>     csColor4*   colors      = factoryState->GetColors();
>
>     for (int i = 0; i < poincount; i++)
>     {
>         int     k   = 2 * i;
>         int     d   = 2 * (i - 1);
>
>         vertices[k+0].Set(1, 1, i/3.0);
>         vertices[k+1].Set(-1, 1, i/3.0);
>
>         normals[k+0].Set(0, 1, 0);
>         normals[k+1].Set(0, 1, 0);
>
>         if ((i & 1) == 0)
>         {
>             uvs[k+0].Set(0, 0);
>             uvs[k+1].Set(1, 0);
>         }
>         else
>         {
>             uvs[k+0].Set(0, 1);
>             uvs[k+1].Set(1, 1);
>         }
>
>         if (i > 0)
>         {
>             triangles[d+0].Set(k-1, k+1, k+0);
>             triangles[d+1].Set(k-2, k-1, k+0);
>         }
>
>         colors[k+0] = csColor(1, 1, 1);
>         colors[k+1] = csColor(1, 1, 1);
>     }
>
>   // Tell 3D driver we're going to display 3D things.
>   if (!g3d->BeginDraw (engine->GetBeginDrawFlags () | CSDRAW_3DGRAPHICS))
>     return;
>
>   // Tell the camera to render into the frame buffer.
>   view->Draw ();
> }
>
> void Simple::FinishFrame ()
> {
>   // Just tell the 3D renderer that everything has been rendered.
>   g3d->FinishDraw ();
>   g3d->Print (0);
> }
>
> bool Simple::OnKeyboard(iEvent& ev)
> {
>   // We got a keyboard event.
>   csKeyEventType eventtype = csKeyEventHelper::GetEventType(&ev);
>   if (eventtype == csKeyEventTypeDown)
>   {
>     // The user pressed a key (as opposed to releasing it).
>     utf32_char code = csKeyEventHelper::GetCookedCode(&ev);
>     if (code == CSKEY_ESC)
>     {
>       // The user pressed escape to exit the application.
>       // The proper way to quit a Crystal Space application
>       // is by broadcasting a cscmdQuit event. That will cause the
>       // main runloop to stop. To do that we get the event queue from
>       // the object registry and then post the event.
>       csRef<iEventQueue> q =
>         csQueryRegistry<iEventQueue> (GetObjectRegistry());
>       if (q.IsValid()) q->GetEventOutlet()->Broadcast(cscmdQuit);
>     }
>   }
>   return false;
> }
>
> bool Simple::OnInitialize(int /*argc*/, char* /*argv*/ [])
> {
>   // RequestPlugins() will load all plugins we specify. In addition
>   // it will also check if there are plugins that need to be loaded
>   // from the config system (both the application config and CS or
>   // global configs). In addition it also supports specifying plugins
>   // on the commandline.
>   if (!csInitializer::RequestPlugins(GetObjectRegistry(),
>     CS_REQUEST_VFS,
>     CS_REQUEST_OPENGL3D,
>     CS_REQUEST_ENGINE,
>     CS_REQUEST_FONTSERVER,
>     CS_REQUEST_IMAGELOADER,
>     CS_REQUEST_LEVELLOADER,
>     CS_REQUEST_REPORTER,
>     CS_REQUEST_REPORTERLISTENER,
>     CS_REQUEST_END))
>     return ReportError("Failed to initialize plugins!");
>
>   // Now we need to setup an event handler for our application.
>   // Crystal Space is fully event-driven. Everything (except for this
>   // initialization) happens in an event.
>   if (!RegisterQueue(GetObjectRegistry()))
>     return ReportError("Failed to set up event handler!");
>
>   return true;
> }
>
> void Simple::OnExit()
> {
> }
>
> bool Simple::Application()
> {
>   // Open the main system. This will open all the previously loaded plug-ins.
>   // i.e. all windows will be opened.
>   if (!OpenApplication(GetObjectRegistry()))
>     return ReportError("Error opening system!");
>
>   // Now get the pointer to various modules we need. We fetch them
>   // from the object registry. The RequestPlugins() call we did earlier
>   // registered all loaded plugins with the object registry.
>   g3d = csQueryRegistry<iGraphics3D> (GetObjectRegistry());
>   if (!g3d) return ReportError("Failed to locate 3D renderer!");
>
>   engine = csQueryRegistry<iEngine> (GetObjectRegistry());
>   if (!engine) return ReportError("Failed to locate 3D engine!");
>
>   vc = csQueryRegistry<iVirtualClock> (GetObjectRegistry());
>   if (!vc) return ReportError("Failed to locate Virtual Clock!");
>
>   kbd = csQueryRegistry<iKeyboardDriver> (GetObjectRegistry());
>   if (!kbd) return ReportError("Failed to locate Keyboard Driver!");
>
>   loader = csQueryRegistry<iLoader> (GetObjectRegistry());
>   if (!loader) return ReportError("Failed to locate Loader!");
>
>   // We need a View to the virtual world.
>   view.AttachNew(new csView (engine, g3d));
>   iGraphics2D* g2d = g3d->GetDriver2D ();
>   // We use the full window to draw the world.
>   view->SetRectangle (0, 0, g2d->GetWidth (), g2d->GetHeight ());
>
>   // First disable the lighting cache. Our app is simple enough
>   // not to need this.
>   engine->SetLightingCacheMode (0);
>
>   // Here we create our world.
>   CreateRoom();
>
>   // Let the engine prepare all lightmaps for use and also free all images
>   // that were loaded for the texture manager.
>   engine->Prepare ();
>
>   // these are used store the current orientation of the camera
>   rotY = rotX = 0;
>
>   // Now we need to position the camera in our world.
>   view->GetCamera ()->SetSector (room);
>   view->GetCamera ()->GetTransform ().SetOrigin (csVector3 (0, 5, -3));
>
>     meshFactoryWrapper    = 
> engine->CreateMeshFactory("crystalspace.mesh.object.genmesh", NULL);
>     meshWrapper           = engine->CreateMeshWrapper(meshFactoryWrapper, 
> NULL, room);
>     meshWrapper->SetRenderPriority(engine->GetObjectRenderPriority());
>     meshWrapper->SetZBufMode(CS_ZBUF_USE);
>     meshWrapper->GetFlags().Set(CS_ENTITY_NOLIGHTING);
>
>     iMaterialWrapper* tm = engine->GetMaterialList()->FindByName ("stone");
>     csRef<iGeneralMeshState>    meshState   = 
> SCF_QUERY_INTERFACE(meshWrapper->GetMeshObject(), iGeneralMeshState);
>     meshState->SetMaterialWrapper(tm);
>     //meshState->SetColor(csColor(1.0, 1.0, 1.0));
>     meshState->SetManualColors(true);
>
>
>   // This calls the default runloop. This will basically just keep
>   // broadcasting process events to keep the game going.
>   Run();
>
>   return true;
> }
>
> void Simple::CreateRoom ()
> {
>   // Load the texture from the standard library.  This is located in
>   // CS/data/standard.zip and mounted as /lib/std using the Virtual
>   // File System (VFS) plugin.
>   if (!loader->LoadTexture ("stone", "/lib/std/stone4.gif"))
>     ReportError("Error loading 'stone4' texture!");
>
>   iMaterialWrapper* tm = engine->GetMaterialList ()->FindByName ("stone");
>
>   // We create a new sector called "room".
>   room = engine->CreateSector ("room");
>
>   // Creating the walls for our room.
>   csRef<iMeshWrapper> walls (engine->CreateSectorWallsMesh (room, "walls"));
>   csRef<iThingState> ws =
>     SCF_QUERY_INTERFACE (walls->GetMeshObject (), iThingState);
>   csRef<iThingFactoryState> walls_state = ws->GetFactory ();
>   walls_state->AddInsideBox (csVector3 (-5, 0, -5), csVector3 (5, 20, 5));
>   walls_state->SetPolygonMaterial (CS_POLYRANGE_LAST, tm);
>   walls_state->SetPolygonTextureMapping (CS_POLYRANGE_LAST, 3);
>
>   // Now we need light to see something.
>   csRef<iLight> light;
>   iLightList* ll = room->GetLights ();
>
>   light = engine->CreateLight(0, csVector3(-3, 5, 0), 10, csColor(1, 0, 0));
>   ll->Add (light);
>
>   light = engine->CreateLight(0, csVector3(3, 5,  0), 10, csColor(0, 0, 1));
>   ll->Add (light);
>
>   light = engine->CreateLight(0, csVector3(0, 5, -3), 10, csColor(0, 1, 0));
>   ll->Add (light);
> }
>
> /*-------------------------------------------------------------------------*
>  * Main function
>  *-------------------------------------------------------------------------*/
> int main (int argc, char* argv[])
> {
>   /* Runs the application.
>    *
>    * csApplicationRunner<> is a small wrapper to support "restartable"
>    * applications (ie where CS needs to be completely shut down and loaded
>    * again). Simple1 does not use that functionality itself, however, it
>    * allows you to later use "Simple.Restart();" and it'll just work.
>    */
>   return csApplicationRunner<Simple>::Run (argc, argv);
> }
>
>
> /*
>     Copyright (C) 2001 by Jorrit Tyberghein
>
>     This library is free software; you can redistribute it and/or
>     modify it under the terms of the GNU Library General Public
>     License as published by the Free Software Foundation; either
>     version 2 of the License, or (at your option) any later version.
>
>     This library is distributed in the hope that it will be useful,
>     but WITHOUT ANY WARRANTY; without even the implied warranty of
>     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>     Library General Public License for more details.
>
>     You should have received a copy of the GNU Library General Public
>     License along with this library; if not, write to the Free
>     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> */
>
> #ifndef __SIMPLE1_H__
> #define __SIMPLE1_H__
>
> #include <crystalspace.h>
>
> /**
>  * This is the main class of this Tutorial. It contains the
>  * basic initialization code and the main event handler.
>  *
>  * csApplicationFramework provides a handy object-oriented wrapper around the
>  * Crystal Space initialization and start-up functions.
>  *
>  * csBaseEventHandler provides a base object which does absolutely nothing
>  * with the events that are sent to it.
>  */
> class Simple : public csApplicationFramework, public csBaseEventHandler
> {
> private:
>
>   /// A pointer to the 3D engine.
>   csRef<iEngine> engine;
>
>   /// A pointer to the map loader plugin.
>   csRef<iLoader> loader;
>
>   /// A pointer to the 3D renderer plugin.
>   csRef<iGraphics3D> g3d;
>
>   /// A pointer to the keyboard driver.
>   csRef<iKeyboardDriver> kbd;
>
>   /// A pointer to the virtual clock.
>   csRef<iVirtualClock> vc;
>
>   /// A pointer to the view which contains the camera.
>   csRef<iView> view;
>
>   /// A pointer to the sector the camera will be in.
>   iSector* room;
>
>   /// Current orientation of the camera.
>   float rotX, rotY;
>
>   csRef<iMeshFactoryWrapper>    meshFactoryWrapper;
>   csRef<iMeshWrapper>           meshWrapper;
>
>   /**
>    * Handle keyboard events - ie key presses and releases.
>    * This routine is called from the event handler in response to a
>    * csevKeyboard event.
>    */
>   bool OnKeyboard (iEvent&);
>
>   /**
>    * Setup everything that needs to be rendered on screen. This routine
>    * is called from the event handler in response to a cscmdProcess
>    * broadcast message.
>    */
>   void ProcessFrame ();
>
>   /**
>    * Finally render the screen. This routine is called from the event
>    * handler in response to a cscmdFinalProcess broadcast message.
>    */
>   void FinishFrame ();
>
>   /// Here we will create our little, simple world.
>   void CreateRoom ();
>
> public:
>
>   /// Construct our game. This will just set the application ID for now.
>   Simple ();
>
>   /// Destructor.
>   ~Simple ();
>
>   /// Final cleanup.
>   void OnExit ();
>
>   /**
>    * Main initialization routine. This routine will set up some basic stuff
>    * (like load all needed plugins, setup the event handler, ...).
>    * In case of failure this routine will return false. You can assume
>    * that the error message has been reported to the user.
>    */
>   bool OnInitialize (int argc, char* argv[]);
>
>   /**
>    * Run the application.
>    * First, there are some more initialization (everything that is needed
>    * by Simple1 to use Crystal Space), then this routine fires up the main
>    * event loop. This is where everything starts. This loop will  basically
>    * start firing events which actually causes Crystal Space to function.
>    * Only when the program exits this function will return.
>    */
>   bool Application ();
>
> };
>
> #endif // __SIMPLE1_H__
>
>
>


--
Project Manager of Crystal Space (http://www.crystalspace3d.org)
and CEL (http://cel.crystalspace3d.org)
Support Crystal Space. Donate at
https://sourceforge.net/donate/index.php?group_id=649


-------------------------------------------------------
This SF.Net email is sponsored by the JBoss Inc.  Get Certified Today
Register for a JBoss Training Course.  Free Certification Exam
for All Training Attendees Through End of 2005. For more info visit:
http://ads.osdn.com/?ad_idv28&alloc_id845&op=click
_______________________________________________
Crystal-main mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/crystal-main
Unsubscribe: mailto:[EMAIL PROTECTED]

Reply via email to