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]