Problems with reading a File

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Fliege_reloaded
Posts: 40
Joined: Wed Oct 06, 2004 7:48 pm

Problems with reading a File

Post by Fliege_reloaded »

I'd like to read a path to a heighmap out of a file IN IRRLICHT (no ifstrem, no string, just Irrlicht). Then I want to create a Terrain with this path. Please give me an example to load a file, read a line out, and creates a Terrain with it.
Hopefull
Fliege_reloaded
Guest

Post by Guest »

do you mean something like this?

Code: Select all

ITexture* terraintexture = driver->createImageFromFile("data/textures/grass.jpg");
IImage* terrainheightmap = driver->createImageFromFile("data/textures/heightmaps/heightmap.jpg");

terrain = smgr->addTerrainMesh("terrain",
	terraintexture,			
	terrainheightmap,			
	dimension2d< f32 >(128.0f, 128.0f),	
	2000.0f,				
	dimension2d< s32 >(128, 128));	

terrainnode = smgr->addAnimatedMeshSceneNode(terrain);
terrainnode->setPosition(vector3df(0,0,0));
smgr->getMeshManipulator()->makePlanarTextureMapping(terrain->getMesh(0), 0.004f);
Guest

Post by Guest »

I thin you are a German, also sprechen wir deutsch :wink:
Das Beispiel zeigt es schon fast, nur das ich noch über Irrlicht (ReadFile heißt es glaub' ich) eine Zeile aus einer Datei einlesen möchte. Und diese dann als terrainheighmap definieren. Aber soweit schon mal danke.
Fliege_reloaded
jox
Bug Slayer
Posts: 726
Joined: Thu Apr 22, 2004 6:55 pm
Location: Germany

Post by jox »

If you talk german here, how should all non-germans follow the thread and possibly help you with your problem? :wink:
It is like it is. And because it is like it is, things are like they are.
Fliege_reloaded
Posts: 40
Joined: Wed Oct 06, 2004 7:48 pm

Post by Fliege_reloaded »

Sorry, but I wrote into a German forum before.
Here in English(in a German - Englisch):
His example shows really good stuff, but I miss the reading of a line in Irrlicht with ReadFile and Read. I want to read a line out of a file and then take that string and load a Terrain. I hope, you understand this.
Fliege_reloaded
(If you don't understand, you know, why I'm writing German if I can:mrgreen:)
Guest

Post by Guest »

do you want to know how to scan a heightmap pixel by pixel?
then maybe this helps you too :)

Code: Select all

IImage*	terrainheightmap = driver->createImageFromFile("data/textures/heightmaps/heightmap.jpg");
IImage*	colormap = driver->createImageFromFile("data/textures/heightmaps/vegetationmap.bmp");

int rgb_vec[3]		= { 0,0,0 };
int wantedcolors[3]	= { 0,0,0 };
int colormap_line	= 1;
int colormap_column	= 1;
SColor scpixelcolor;

void readColormap(int wanted1, int wanted2, int wanted3)
{
	wantedcolors[1]	= wanted1;
	wantedcolors[2]	= wanted2;
	wantedcolors[3]	= wanted3;

	dimension2d<s32> heightmap_s = terrainheightmap->getDimension();
	dimension2d<s32> colormap_s = colormap->getDimension();

	colormap->grab();

	while(colormap_line < colormap_s.Height)
	{
		while(colormap_column < colormap_s.Width)
		{
			scpixelcolor = colormap->getPixel(colormap_column, colormap_line);
			rgb_vec[1] = scpixelcolor.getRed();
			rgb_vec[2] = scpixelcolor.getGreen();
			rgb_vec[3] = scpixelcolor.getBlue();
			colormap_column += 1;
		}
		}
		colormap_column	 = 0;
		colormap_line	+= 1;
	}
 

its a piece of code from my vegetationmap loader, maybe not the best but it works :roll:
Fliege_reloaded
Posts: 40
Joined: Wed Oct 06, 2004 7:48 pm

Post by Fliege_reloaded »

NO, I think you don't understand.
Here we start again.
I open a File with ReadFile, let us say "xyz.schabernak"
I have a stringc called heigh_path.
I read one line out of the file, into the string.
I create a Terrain.
The heighmappath is the line in the file, contained in the string.
Like:

ITexture* terraintexture = driver->createImageFromFile("data/textures/grass.jpg");
IImage* terrainheightmap = driver->createImageFromFile("THE STRING "heigh_path"");

terrain = smgr->addTerrainMesh("terrain",
terraintexture,
terrainheightmap,
dimension2d< f32 >(128.0f, 128.0f),
2000.0f,
dimension2d< s32 >(128, 128));

terrainnode = smgr->addAnimatedMeshSceneNode(terrain);
terrainnode->setPosition(vector3df(0,0,0));
smgr->getMeshManipulator()->makePlanarTextureMapping(terrain->getMesh(0), 0.004f);
Fliege_reloaded
Posts: 40
Joined: Wed Oct 06, 2004 7:48 pm

Post by Fliege_reloaded »

Is here nobody who could help me?
Guest

Post by Guest »

Fliege, if you want good answers, you need to ask good (clear) questions.

If you ask me, I'd say you're asking the same question you asked before:
How to read a line from a file

That's been answered before: NOT using ReadFile, because that is buffer-oriented, not character-oriented.
Lines are delimited by newlines, which means you're better off looking at individual characters.
You can use streams or stdio instead.

Maybe you can explain why you are so bent on using stringc instead of char * and why you're so bent on using ReadFile instead of the standard methods to read data from text-files.

Are you looking for code to read .ini style files maybe?
I.e. reading a text file that looks something like this?

[level1]
title: Introduction
terraintexture: data/textures/grass.jpg
heightmap: data/levels/level1/heightmap.bmp
startpos: 200,300

Tell me if that's what you want. If so, I'll post something when I get home (I've done that sort of stuff before - I can just copy and paste something) - but I have to warn you: I really like my C functions - it's going to use stdio.h! :twisted:
Fliege_reloaded
Posts: 40
Joined: Wed Oct 06, 2004 7:48 pm

Post by Fliege_reloaded »

It's ok when you want to use stdio.h
yes so it looks like, but no:
[level1] or terraintexture = ...
just:
11
data/levels/level1/grass.bmp
...and then the next thing and the next and the next...
The 11 is the code I want to read, then the load_Terrain function should read the next line, the texture line, load it and texture the Terrain.
The thing why I'm so bent on using strinc is:
I cannot open something with chars, likle this:

char filename[80];
void load(char mapname[80])
{
...
}

and char filename should be defined by the user.
Please give me an example for this....
Sorry if you don't understand it again
Fliege_reloaded
Guest

Post by Guest »

OK. About that last part:

In C/C++ there is NO difference between a char[80] and a char *, except that the first is a pointer to allocated memory and the second is just a pointer.

The convention for strings in C/C++ is to use a pointer to char (char *).
The length of such a string is not the same as the allocated buffer for it.
You can have a buffer of 80 characters, or of 65536 characters, or even bigger, but the length of the string is determined by only one thing:
the terminating \0 character. (Since a char is one byte in size, that is a byte with value 0).
All string functions expect a char * in that way.
The compiler writes constant strings that way.
When you write:
char mystring[]="hello world"

What happens is that the compiler counts the number of characters in the constant "hello world" (11 characters), adds one, and allocates at least that number of bytes. It then sets the variable mystring to the address of that allocated unit - and copies the characters plus the terminating \0 to that allocated chunk of memory.

This method of storing strings makes loops such as this possible:
// loops through all characters of s[] and outputs them to the console
for(i=0;s;i++)
putc(s);

The issue with reading input - whether from the user or from a file - is that you don't know the size of a line before you read it. The simplest way to deal with that is to just use a large buffer that you can be pretty sure of will not be too small. So you allocate a buffer of, say 4096 chars - meaning the maximum size of a line is 4096 - 1 (for the \0) = 4095 characters.
The example code I posted on your previous thread does exactly that.

All the functions that accept a C type string (that includes many Irrlicht functions) simply accept a char *.

In short: you don't declare your function as
void load(char mapname[80])

You declare it as
void load(char * mapname)

or, if you prefer array notation:
void load(char mapname[])

It is only when you start manipulating strings in memory that you have a true advantage (a programmer productivity advantage) to using more advanced string classes.

W.r.t. the file format:
I'll post my code when I get home - parsing your format would be even simpler - presuming it's always one line with a code, and then the next with the data.
T101
Posts: 44
Joined: Thu Jul 29, 2004 4:41 pm

Post by T101 »

OK. This is one way to read .ini style files (although this is one that does not support sections):

Code: Select all

// necessary headers
#include <stdio.h>

// these are some - in this case - global variables that will be set from ini-file
char devicefilename[1024];
char ipa_font[1024];
int defaultsamplerate;

// call this function as e.g.: loadinifile("mysettings.ini");
void loadinifile(char *inifilename)
{
 FILE *fp;
 int i,c;
 char line[1024];
 char field[1024];
 char value[1024];
 
 fp=fopen(inifilename,"r");
 if(fp) {

  i=0;
  while((c=fgetc(fp))!=EOF) {
   if(c=='\n') {
    line[i]='\0';

    for(i=0;line[i]!='\0' && line[i]!='=';i++)
     ;
    strncpy(field,line,i); // copy everything before the = sign
    field[i]='\0'; // terminate the fieldname since strncpy does not do that

    if(line[i]=='=')
     strcpy(value,line+i+1);
    else
     strcpy(value,"");

    if(field[0]!='\0' && value[0]!='\0') { // only set when both a fieldname and a value are given

     if(strcmp(field,"device")==0)
      strcpy(devicefilename,value);
     else
     if(strcmp(field,"ipa_font")==0)
      strcpy(ipa_font,value);
     else
     if(strcmp(field,"sample_rate")==0)
      sscanf(value,"%d",&defaultsamplerate);
    }
    i=0;   
   }
   else
   if(i<1023)
    line[i++]=c;
  }
  fclose(fp);
 }
}
Fliege_reloaded
Posts: 40
Joined: Wed Oct 06, 2004 7:48 pm

Post by Fliege_reloaded »

Ok, this is waht I wanted to know, thank you all for that time youe spent.
Fliege_reloaded
bal
Posts: 829
Joined: Fri Jun 18, 2004 5:19 pm
Location: Geluwe, Belgium

Post by bal »

I would use an XML-file for this kind of task. Because Irrlicht already contains an XML-reader and -writer. Just proposing :).
General Tools List
General FAQ
System: AMD Barton 2600+, 512MB, 9600XT 256MB, WinXP + FC3
Fliege_reloaded
Posts: 40
Joined: Wed Oct 06, 2004 7:48 pm

Post by Fliege_reloaded »

There is a new problem...

I want to read a line, just a line.
T101 example withou reading before a "=" and after a "=", please... I'm working in three languages now, so I can't do all at the same time. Here a server, there a Game,...I'm confused enough.
So please write me another example, thanks.
Fliege_reloaded
Post Reply