A castle..

The place for artists, modellers, level designers et al to discuss their approaches for creating content for OGRE.
User avatar
RyanN
Halfling
Posts: 82
Joined: Thu Aug 19, 2004 6:41 am
Location: Victoria, Australia
Contact:

Post by RyanN »

how was the grass done? i found a grass shader that has wind sway and all that good stuff, would a shader work better than actual mesh with an animation?
Crashy
Google Summer of Code Student
Google Summer of Code Student
Posts: 1005
Joined: Wed Jan 08, 2003 9:15 pm
Location: Lyon, France
x 49
Contact:

Post by Crashy »

The grass is for still a "cross" plane mesh.

I've also found a windy grass shader on shadertech, but I've not tested it for the moment, and if it will be prettiest, I think the framerate will decrease strongly.
Follow la Moustache on Twitter or on Facebook
Image
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 67
Contact:

Post by sinbad »

Demo_Grass in CVS creates wavy grass using a vertex shader and batches the thousands of separate clumps using the new StaticGeometry class. Using a vertex shader is essential to keeping the framerate up, and in our case the waving is so cheap it doesn't affect the frame rate at all. If you tried doing sin/cos inside the shader, it would - we don't.
Crashy
Google Summer of Code Student
Google Summer of Code Student
Posts: 1005
Joined: Wed Jan 08, 2003 9:15 pm
Location: Lyon, France
x 49
Contact:

Post by Crashy »

I've not tested the CVS version yet(I wait the RC1 to switch to Azatoth), but it sounds very interesting :)
Follow la Moustache on Twitter or on Facebook
Image
Crashy
Google Summer of Code Student
Google Summer of Code Student
Posts: 1005
Joined: Wed Jan 08, 2003 9:15 pm
Location: Lyon, France
x 49
Contact:

Post by Crashy »

Ok, I explain how I load my scenes.
I use a little program to scann an image wich is a representation of the level in top view.
It there is a pixel with a "50" red part, the program will clone an entity wich type is corresponding to the "50" value, and will position it at coordinates that are corresponding to wordl coordinate:
-if the pixel position of the image is (50,50), the object will be placed to the "50,0,50" position of the world(if the scale is the same).

With this method, we can easily load a large number of meshes quite "automatically" . Just paint your top-level-view, and it works alone.
there are still a lots of personnal settings here, sorry :oops:

here is the .cpp file of the LevelMap program(wich analyses the images). Thx to EarthQuakeProof for this code :)

Code: Select all

#include "LevelMap.h"

#include <OgreConfigFile.h>
#include "OgreLogManager.h"


LevelMap::LevelMap(String configFile, String mapName) {
   ConfigFile config;
    config.load(configFile);
   String mapFilename = config.getSetting(mapName) ;
  
    mScale.x = StringUtil::toReal(config.getSetting("Scale.x"));
    mScale.y = StringUtil::toReal(config.getSetting("Scale.y"));
    mScale.z = StringUtil::toReal(config.getSetting("Scale.z"));

   ilGenImages(1, &id);
   ilBindImage(id);
  
   //const char*String s = (const char*) mapFilename ;
    char*s;
   strcpy(s, mapFilename.c_str());

   LogManager::getSingleton().logMessage(s) ;

   ilLoadImage((ILstring) s);  // Loads into the current bound image

   mWidth = ilGetInteger(IL_IMAGE_WIDTH) ;
   mHeight = ilGetInteger(IL_IMAGE_HEIGHT) ;

}


Real LevelMap::getWidth() {
   return mWidth ;
}

Real LevelMap::getHeight() {
   return mHeight ;
}
Vector3 LevelMap::getScale() {
   return mScale ;
}



void LevelMap::getRGBAt(Real x, Real z, int rgb[3]) {
   int int_x,int_z ;
   int_x = (int) floor(x/mScale.x) ;
   int_z = (int) floor(z/mScale.z) ;
   if (int_x> mWidth-1 || int_z>mHeight-1 || x<0 || z<0) {
      rgb[0] = 0;
      rgb[1] = 0;
      rgb[2] = 0;
      return ;
   }

   ilBindImage(id);
   ILubyte data[3] ;
   
   ilCopyPixels(int_x, int_z, 0, 1, 1, 1, IL_RGB, IL_UNSIGNED_BYTE, data);

   rgb[0] = data[0];   
   rgb[1] = data[1];
   rgb[2] = data[2];
}
the .h

Code: Select all

#ifndef LEVELMAP_H
#define LEVELMAP_H

class LevelMap ;

#include <Ogre.h>
#include <il/il.h>
#include <il/ilu.h>

using namespace Ogre;

class LevelMap {

public:
   LevelMap(String configFile, String mapName) ;


   void getRGBAt(Real x, Real z, int rgb[3]) ;

   Real getWidth() ;
   Real getHeight() ;
   Vector3 getScale() ;

protected:
   Vector3 mScale ;
   Real mWidth ;
   Real mHeight ;
   ILuint id ;
} ;


#endif 
And here the main PlatypAce code (uuhh, yes, I named it so, a long story :p )
the .cpp


Code: Select all

/*Some littles things:
-I apologize for my poor english comments and for french variables names:)
-This is not a definitive program, and I wrote it initially to be used by me alone, so
this is not very ergonomic. I tried to improve the ergonomy for this release, but It's very far to be perferct.
-Everywhere in this code, I use the Camera to call the SceneManager. I use it to load objects in the Frame listener, and it's the easiest way to do(I think).
-The PlatypAce will be a full level-loading program, wich determines what level he has to load(and to unload) with defined conditions. This is not operational for the moment
(It has already been so, but I've lost the sources some months ago). 
-The LevelMap program Is for EarthQuakeProof. Thx to him :)
-Be aware that if there is a coloured pixel on the image wich color is not corresponding to a defined Entity Type, you'll get an error. I've not "securised" it.
*/

#include "LevelMap.h"
#include "OgrePagingLandScapeRaySceneQuery.h"

#include "platypace.h"





		//constructors and destructors are blanks for the moment :(
PlatypAce::PlatypAce()
{
}
PlatypAce::~PlatypAce()
{
	
}

void PlatypAce::entTypes(Camera*mCamera)//defines the array of entity types we will load
{
	//some examples of entities
	type[001]= mCamera->getSceneManager()->createEntity("type001", "rocher.mesh");

	type[100]= mCamera->getSceneManager()->createEntity("type100", "fish.mesh");
	type[101]= mCamera->getSceneManager()->createEntity("type101", "herbe.mesh");

}





//Loads the Level Meshes. 
//Todo: rework it as soon as I've the 1.0.0 compiled :) to us geometry batcher.

void PlatypAce::ChargerNiveau(LevelMap*Platypus,
				   SceneNode* Objnode,
				   Camera*mCamera,
				   char nom[]
				  
				   )
				   /*Description of parameters :
					-Platypus is referring to the LevelMap we are working on.
					I've made it a parameter in order to load several different levels wich entities' base names are different.
					-Objnode is the "Big" node wich is the father of all the "little" node, for all Level. So it is easy to 
					clear the level: just to do "Objnode->removeAndDestroyAllChildren();"
					-mCamera is the used Camera(yes! :D).
					-nom is the char array wich contains the base name of all entities loaded in this program.
				  
				   
				   */

{
				   
	entTypes(mCamera);						//defines the entities.
	RaySceneQuery* mRayQuery;				//I use A raySceneQuerry to calculate the terrain Height
	mRayQuery = mCamera->getSceneManager()->createRayQuery(Ray(Vector3(0.0f, 0.0f, 0.0f), Vector3::UNIT_Y));
	SceneNode*objnode;						//the "little" node
	int couleur[3];							
	Vector3 objPos;							//the position of the object.
	char cloneEntName[21];					//the definitive entity name.
	


	for (int x = 0; x < Platypus->getWidth(); ++x)// Scann the image for all X pixels
			{
				for (int z = 0; z < Platypus->getHeight(); ++z)	// Scann the image for all Z pixels(notice that I used "z" to be 
					{											//in the same coordinates name that the engine, and no the picture one's.
	
						 Platypus->getRGBAt(x,z,couleur);//Analyses the color of the scanned pixel; The color is stocked in "couleur" Vector3
					
			
						 if (couleur[0]!=0)			//if the pixel is not black
					{


			objnode = mCamera->getSceneManager()->createSceneNode();
           
     
            
            objPos.x = x*67-66666;//this are my own settings, calculated for my own needs, so do what you want :) ;
			objPos.z = z*67-66666;
			////Part Calculating the height of the terrain
			mRayQuery->setRay (Ray(objPos, Vector3::UNIT_Y)); 

                     mRayQuery->setQueryMask (RSQ_Height);
                    RaySceneQueryResult& qryResult = mRayQuery->execute();
                    RaySceneQueryResult::iterator it = qryResult.begin();
                    if (it != qryResult.end() && it->worldFragment)
                    {
                       objPos.y =  it->worldFragment->singleIntersection.y;
                       
                    	
					}
			////End of Part Calculating the height of the terrain
			
					//We position the object at world coordinates wich are corresponding to pixel position
			//objnode->setPosition( objPos.x,objPos.y+2.5,objPos.z);
			objnode->setPosition(objPos);
			Objnode->addChild(objnode);	//we attach the "little" node to the "big" one
		  
            sprintf(cloneEntName, nom,x,z);// generate the name of the cloned Entity.The name is XentNameZ formatted to have different name in all cases. 

			cloneEnt = type[couleur[0]]->clone(cloneEntName);	//we clone the entity wich type is the same as the red color value. 
																//this is the more important part of the program.
		


            // Attach to new node
            objnode->attachObject(cloneEnt);					//we attach the entity
						
			

		
			
	
		}
		

 }

 }
		
}
the .h

Code: Select all

class PlatypAce {





public:
	PlatypAce();
	~PlatypAce();
	void PlatypusEnt(Entity*type[],Camera*mCamera);


	void ChargerNiveau(LevelMap*Platypus,
				   SceneNode* Objnode,
				   Camera*mCamera,
				   char nom[]
				   );
	protected:

	char NewLevel;
	Entity*type[256];
	void entTypes(Camera*);
	Entity*cloneEnt;
	
};

The LevelMap config file has this format

Code: Select all

platypus=platypus.png
Scale.x=1
Scale.y=1
Scale.z=1
Follow la Moustache on Twitter or on Facebook
Image
RoundSparrow
Greenskin
Posts: 145
Joined: Wed Jan 19, 2005 4:36 am
Location: Arica, Chile

Post by RoundSparrow »

Crashy: Thanks!
Crashy
Google Summer of Code Student
Google Summer of Code Student
Posts: 1005
Joined: Wed Jan 08, 2003 9:15 pm
Location: Lyon, France
x 49
Contact:

Post by Crashy »

No matter! :)
Follow la Moustache on Twitter or on Facebook
Image
User avatar
Telamon
Kobold
Posts: 26
Joined: Mon Feb 28, 2005 9:34 am
x 1
Contact:

Post by Telamon »

Any chance of getting the source or pre-compiled binary of your demo? It looks really cool and I'd love to try it out!
Post Reply