Hi: I'm trying to use the material map on the terrain from C++, I did a very simple example based on simple1 tutorial (code attached). But when I run it I get "simpleterrain: plugins/mesh/terrain/brute/brute.cpp:249: void CS::Plugin::BruteBlock::csTerrBlock::SetupMesh():`alphadata != 0'." from the assert.
If I remove one material from the palette it runs ok but don't use the material map. (I attach the materialmap image that I'm using too) I don't know why, I tried to follow the steps of walktest into terrain plugin but I get no clues about the problem. Anyone could help me? Thanks
/*
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::Frame ()
{
// 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_TAB))
{
//Esto no funciona
/* iI=loader->LoadImage("/lib/std/alturas2.png",CS_IMGFMT_ANY);
iSFS->SetHeightmap(iI);*/
// Testing code: Using Regions
//Region1->DeleteAll();
}
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);
if (kbd->GetKeyState (CSKEY_PGUP))
rotZ += speed;
if (kbd->GetKeyState (CSKEY_PGDN))
rotZ -= 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) *csZRotMatrix3(rotZ);
csOrthoTransform ot (rot, c->GetTransform().GetOrigin ());
c->SetTransform (ot);
}
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 csevQuit 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(
csevQuit(GetObjectRegistry()));
}
}
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!");
// "Warm up" the event handler so it can interact with the world
csBaseEventHandler::Initialize(GetObjectRegistry());
// Now we need to register the event handler for our application.
// Crystal Space is fully event-driven. Everything (except for this
// initialization) happens in an event.
// Rather than simply handling all events, we subscribe to the
// particular events we're interested in.
csEventID events[] = {
csevFrame (GetObjectRegistry()),
csevKeyboardEvent (GetObjectRegistry()),
CS_EVENTLIST_END
};
if (!RegisterQueue(GetObjectRegistry(), events))
return ReportError("Failed to set up event handler!");
// Report success
return true;
}
void Simple::OnExit()
{
// Shut down the event handlers we spawned earlier.
drawer.Invalidate();
printer.Invalidate();
}
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!");
if (SetupModules()) {
// This calls the default runloop. This will basically just keep
// broadcasting process events to keep the game going.
Run();
}
return true;
}
bool Simple::SetupModules ()
{
// 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));
csRef <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 = rotZ = 0;
// Now we need to position the camera in our world.
view->GetCamera ()->SetSector (room);
view->GetCamera ()->GetTransform ().SetOrigin (csVector3 (0, 5, -3));
// We use some other "helper" event handlers to handle
// pushing our work into the 3D engine and rendering it
// to the screen.
drawer.AttachNew(new FrameBegin3DDraw (GetObjectRegistry (), view));
printer.AttachNew(new FramePrinter (GetObjectRegistry ()));
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/bomb002.gif"))
ReportError("Error loading 'stone4' texture!");
// iMaterialWrapper* tm = engine->GetMaterialList ()->FindByName ("stone");
csRef<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<iMeshObject> walls_object = walls->GetMeshObject ();
csRef<iMeshObjectFactory> walls_factory = walls_object->GetFactory();
csRef<iThingFactoryState> walls_state =
scfQueryInterface<iThingFactoryState> (walls_factory);
walls_state->AddInsideBox (csVector3 (-1000, -1000, -1000), csVector3 (1000, 1000, 1000));
walls_state->SetPolygonMaterial (CS_POLYRANGE_LAST, tm);
walls_state->SetPolygonTextureMapping (CS_POLYRANGE_LAST, 2000);
//-----------------------------------------------------------------------------------------------
// Testing code: Using Regions
//Region1=engine->CreateRegion("Region1");
//Imagen para el mapa de alturas
iI=loader->LoadImage("/lib/std/alturas.png",CS_IMGFMT_ANY);
csRef<iImage> matmap=loader->LoadImage("/lib/std/negra.png",CS_IMGFMT_ANY);
//Textura base para la malla del terrain
loader->LoadTexture("base","/lib/std/alturas.png");
loader->LoadTexture("base2","/lib/std/loading2.png");
Base=engine->GetMaterialList()->FindByName("base");
Base2=engine->GetMaterialList()->FindByName("base2");
//Cargador de plugins. Es una vista del objeto registro con la interfaz iPluginManager
plugin_mgr=CS_QUERY_REGISTRY(GetObjectRegistry(),iPluginManager);
//Objeto para obtener los datos del terreno
iTF=CS_LOAD_PLUGIN(plugin_mgr,"crystalspace.terraformer.simple",iTerraFormer);
//Objeto para establecer los parametros sdel iTerraFormer.
//Es una interfaz
iSFS=SCF_QUERY_INTERFACE(iTF,iSimpleFormerState);
iSFS->SetScale(csVector3(100,100000,100));
iSFS->SetHeightmap(iI);
//Objeto para interactuar con la factoria a nivel del motor.
//Es decir, es una envoltura de la factoria.
iMFW=engine->CreateMeshFactory("crystalspace.mesh.object.terrain.bruteblock","iMFW");
//Objecto para establecer los parametros genericos de los objetos terrenos.
//En concreto nos sirve para indicar que region de la textura va a usar como mapa de alturas.
//Esta incialización obtiene el objeto factoria enganchado al motor y lo muestra como una interfaz Factory State.
iTFS=SCF_QUERY_INTERFACE(iMFW->GetMeshObjectFactory(),iTerrainFactoryState);
iTFS->SetTerraFormer(iTF);
iTFS->SetSamplerRegion(csBox2(-100,-100,100,100));
//Objeto para interactuar con el objeto Mesh del motor.
iMW=engine->CreateMeshWrapper(iMFW,"iMW", room, csVector3(0,0,0));
iMW->GetMeshObject()->SetMaterialWrapper(Base);
iMW->SetZBufMode(CS_ZBUF_USE);
iMW->SetRenderPriority(engine->GetObjectRenderPriority());
//Objeto para interactuar con el estado del Mesh del motor de otra manera
iTOS=SCF_QUERY_INTERFACE(iMW->GetMeshObject(),iTerrainObjectState);
Materiales.Push(Base);
Materiales.Push(Base2);
iTOS->SetMaterialPalette(Materiales);
iTOS->SetMaterialMap(matmap);
iTOS->SetLODValue("splatting distance",10000.0);
iTOS->SetLODValue("minimum block size",1);
iTOS->SetLODValue("block split distance",32);
// Testing code: Using Regions
// Region1->Add(iMW->QueryObject());
//-----------------------------------------------------------------------------------------------
// Now we need light to see something.
csRef<iLight> light;
csRef<iLightList> ll = room->GetLights ();
light = engine->CreateLight(0, csVector3(0, 0, 0), 9000, csColor(1, 1, 1));
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,rotZ;
/// Event handlers to draw and print the 3D canvas on each frame
csRef<FrameBegin3DDraw> drawer;
csRef<FramePrinter> printer;
csRef<iImage> iI;
csRef<iMaterialWrapper> Base;
csRef<iMaterialWrapper> Base2;
csRef<iPluginManager> plugin_mgr;
csRef<iTerraFormer> iTF;
csRef<iSimpleFormerState> iSFS;
csRef<iMeshFactoryWrapper> iMFW;
csRef<iTerrainFactoryState> iTFS;
csRef<iMeshWrapper> iMW;
csRef<iTerrainObjectState> iTOS;
csArray<iMaterialWrapper *> Materiales;
// Testing code: Using regions
//csRef<iRegion> Region1;
public:
bool SetupModules ();
/**
* 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 csevFrame
* message, and is called in the "logic" phase (meaning that all
* event handlers for 3D, 2D, Console, Debug, and Frame phases
* will be called after this one).
*/
void Frame ();
/// Here we will create our little, simple world.
void CreateRoom ();
/// 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 ();
/* Declare the name by which this class is identified to the event scheduler.
* Declare that we want to receive the frame event in the "LOGIC" phase,
* and that we're not terribly interested in having other events
* delivered to us before or after other modules, plugins, etc. */
CS_EVENTHANDLER_PHASE_LOGIC("application.simple1")
};
#endif // __SIMPLE1_H__
negra.png
Description: PNG image
------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys -- and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________ Crystal-main mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/crystal-main Unsubscribe: mailto:[EMAIL PROTECTED]
