Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/height_map/src/lib/graphics/importer/height_map.cc @ 6227

Last change on this file since 6227 was 6227, checked in by bottac, 18 years ago

getHeight implemented
support for 'colour maps'

  • Property svn:executable set to *
File size: 14.8 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: bottac@ee.ethz.ch
13*/
14
15#include "height_map.h"
16#include "model.h"
17#include "texture.h"
18#include "vector.h"
19#include "material.h"
20#include "p_node.h"
21#include "state.h"
22#include "resource_manager.h"
23
24#include "debug.h"
25
26// INCLUDING SDL_Image
27#ifdef HAVE_SDL_IMAGE_H
28#include <SDL_image.h>
29#else
30#include <SDL/SDL_image.h>
31#endif
32
33HeightMap::HeightMap()
34{
35
36}
37
38HeightMap::HeightMap(const char* height_map_name = NULL) 
39{
40   this->setClassID(CL_HEIGHT_MAP, "HeightMap");
41   heightMap =  IMG_Load(height_map_name);
42   if(heightMap!=NULL) {
43       
44                 PRINTF(0)("loading Image %s\n", height_map_name);
45                 PRINTF(0)("width : %i\n", heightMap->w);
46                 PRINTF(0)("hight : %i\n", heightMap->h);
47                 PRINTF(0)("%i Byte(s) per Pixel \n", heightMap->format->BytesPerPixel);
48                 PRINTF(0)("Rshift : %i\n", heightMap->format->Rshift);
49                 PRINTF(0)("Bshift: %i\n", heightMap->format->Bshift);
50                 PRINTF(0)("Gshift: %i\n", heightMap->format->Gshift);
51                 PRINTF(0)("Rmask: %i\n", heightMap->format->Rmask);
52                 PRINTF(0)("Gmask: %i\n", heightMap->format->Gmask);           
53                }
54                 
55     else       PRINTF(4)("oops! couldn't load %s for some reason.\n", height_map_name);
56
57               
58           generateNormalVectorField();
59           
60           
61 //Defines 2 Materials (for testing only!)
62 this->tmp_mat = new Material(); 
63  tmp_mat->setTransparency(1.0);
64  tmp_mat->setIllum(0.3);
65  tmp_mat->setDiffuse(0.55,0.4,0.2);
66  tmp_mat->setAmbient(0.6,0.4,0.2);
67  tmp_mat->setSpecular(0.02,0.02,0.02);
68  tmp_mat->setShininess(.1);
69  tmp_mat->setTransparency(1.0);
70
71  tmp_mat->diffuseTexture = NULL;
72  tmp_mat->ambientTexture = NULL;
73  tmp_mat->specularTexture = NULL;
74
75 this->red_mat = new Material(); 
76  red_mat->setTransparency(1.0);
77  red_mat->setIllum(0.3);
78  red_mat->setDiffuse(0.55,0.1,0.1);
79  red_mat->setAmbient(0.55,0.1,0.1);
80  red_mat->setSpecular(0.02,0.02,0.02);
81  red_mat->setShininess(.1);
82  red_mat->setTransparency(1.0);
83
84  red_mat->diffuseTexture = NULL;
85  red_mat->ambientTexture = NULL;
86  red_mat->specularTexture = NULL;
87
88}
89
90HeightMap::HeightMap(const char* height_map_name = NULL, const char* colour_map_name = NULL) 
91{
92this->setClassID(CL_HEIGHT_MAP, "HeightMap");
93
94   heightMap =  IMG_Load(height_map_name);
95   if(heightMap!=NULL) {
96       
97                 PRINTF(0)("loading Image %s\n", height_map_name);
98                 PRINTF(0)("width : %i\n", heightMap->w);
99                 PRINTF(0)("hight : %i\n", heightMap->h);
100                 PRINTF(0)("%i Byte(s) per Pixel \n", heightMap->format->BytesPerPixel);
101                 PRINTF(0)("Rshift : %i\n", heightMap->format->Rshift);
102                 PRINTF(0)("Bshift: %i\n", heightMap->format->Bshift);
103                 PRINTF(0)("Gshift: %i\n", heightMap->format->Gshift);
104                 PRINTF(0)("Rmask: %i\n", heightMap->format->Rmask);
105                 PRINTF(0)("Gmask: %i\n", heightMap->format->Gmask);           
106                }
107                 
108     else       PRINTF(4)("oops! couldn't load %s for some reason.\n", height_map_name);
109
110               
111           generateNormalVectorField();
112           
113           
114 //Defines 2 Materials (for testing only!)
115 this->tmp_mat = new Material("tmp"); 
116  tmp_mat->setTransparency(1.0);
117  tmp_mat->setIllum(0.3);
118  tmp_mat->setDiffuse(1.0,1.0,1.0);
119 tmp_mat->setAmbient(1.0,1.0,1.0);
120
121  tmp_mat->setSpecular(0.0,0.00,0.00);
122  tmp_mat->setShininess(1.0);
123 
124
125
126
127 this->red_mat = new Material("red"); 
128  red_mat->setTransparency(1.0);
129  red_mat->setIllum(3);
130  red_mat->setDiffuse(0.55,0.1,0.1);
131  red_mat->setAmbient(0.55,0.1,0.1);
132  red_mat->setSpecular(0.0,0.0,0.0);
133  red_mat->setShininess(1.0);
134  red_mat->setTransparency(1.0);
135
136 // red_mat->diffuseTexture = NULL;
137 // red_mat->ambientTexture = NULL;
138  //red_mat->specularTexture = NULL;
139 
140  if(colour_map_name != NULL)
141  {
142  colourMap = IMG_Load(colour_map_name);
143  if(colourMap != NULL)
144                {
145                 PRINTF(0)("loading Image %s\n", colour_map_name);
146                 PRINTF(0)("width : %i\n", colourMap->w);
147                 PRINTF(0)("hight : %i\n", colourMap->h);
148                 PRINTF(0)("%i Byte(s) per Pixel \n", colourMap->format->BytesPerPixel);
149                 PRINTF(0)("Rshift : %i\n", colourMap->format->Rshift);
150                 PRINTF(0)("Bshift: %i\n", colourMap->format->Bshift);
151                 PRINTF(0)("Gshift: %i\n", colourMap->format->Gshift);
152                 PRINTF(0)("Rmask: %i\n", colourMap->format->Rmask);
153                 PRINTF(0)("Gmask: %i\n", colourMap->format->Gmask);
154                 }
155                 else       PRINTF(4)("oops! couldn't load %s for some reason.\n", colour_map_name);
156                 
157  const  char* texture_name = "pictures/ground1.tga";
158  tmp_mat->setDiffuseMap(texture_name);
159  if(colourMap != NULL)
160  {
161  colours = (unsigned char *) colourMap->pixels;
162  hasColourMap = true;
163  }
164  else
165  {
166  hasColourMap = false;
167 
168 
169  }
170 
171 // tmp_mat->setAmbientMap(texture_name);
172  //tmp_mat->setSpecularMap(texture_name);
173 
174  // red_mat->setDiffuseMap(texture_name);
175  // red_mat->setAmbientMap(texture_name);
176  //red_mat->setSpecularMap(texture_name);                             
177  }
178 
179 
180}
181HeightMap::~HeightMap()
182{
183        delete heightMap;
184}
185
186void HeightMap::load()
187{
188
189}
190
191
192void HeightMap::draw() 
193{
194
195this->camera = State::getCamera();
196this->camCoords = this->camera->getAbsCoor();
197float x = this->camCoords.x + 300;
198float y = this->camCoords.+ 100;
199
200// Draw a red rectangle to test getHeight
201
202red_mat->select();
203glBegin(GL_TRIANGLE_STRIP);
204glNormal3f(0,1,0);
205glTexCoord2d(1.0,0.0);
206 glVertex3f(x-10,getHeight(x-10,y+10)+5.0f       ,y+10); // Top Left
207 
208
209glNormal3f(0,1,0);
210glTexCoord2d(1.0,1.0);
211 glVertex3f(x+10,getHeight(x+10,y+10)+5.0f ,y+10); // Top Left
212 
213
214glNormal3f(0,1,0);
215glTexCoord2d(0.0,0.0);
216 glVertex3f(x-10,getHeight(x-10,y-10)+5.0f ,y-10); // Top Left
217 
218
219glNormal3f(0,1,0);
220glTexCoord2d(0.0,1.0);
221 glVertex3f(x+10,getHeight(x+10,y-10)+5.0f ,y-10); // Top Left
222 
223glEnd();
224
225tmp_mat->select();
226
227unsigned char height = 0; 
228 int offset = 0;
229 int g = 0;
230 float old_r = 0.0f;
231 float old_g = 0.0f;
232 float old_b = 0.0f;
233 heights  = (unsigned char*) heightMap->pixels;
234
235 bool colourChanged = true;
236 
237  if(heightMap != NULL && heightMap->format->BitsPerPixel == 8 )
238        {
239        SDL_LockSurface(heightMap);
240
241               
242        for(int i = 0 ; i < heightMap->h -sampleRate ; i +=sampleRate)
243        {
244
245
246
247                   glBegin(GL_TRIANGLE_STRIP); 
248                int j = 0;
249       
250/*
251                height = heights[j + i*(heightMap->w )];
252                glNormal3f(normalVectorField[i][j].y,normalVectorField[i][j].z,normalVectorField[i][j].x);
253                glVertex3f(20*(heightMap->h -(i))-1000,(double)((double)(height)/1-300),20*(j)-1000); // Top Left
254
255                        height = heights[j + (i+2)*(heightMap->w )];
256                glNormal3f(normalVectorField[i+2][j].y,normalVectorField[i+2][j].z,normalVectorField[i+2][j].x);
257                glVertex3f(20*(heightMap->h -(i+2))-1000,(double)((double)(height)/1-300),20*(j)-1000); // Bottom Left
258*/
259               
260
261            for(int j = 0 ; j < heightMap->w -sampleRate  ;  j += sampleRate)
262            {
263                if(hasColourMap)
264                {
265                float r = (float)colours[3*j+2  + 3*i*(heightMap->w )];
266                float g = (float)colours[3*j+1 + 3*i*(heightMap->w)];
267                float b = (float)colours[3*j+0 + 3*i*(heightMap->w)];
268                colourChanged = old_r != r || old_g != g || old_b != b;
269                old_r = r;
270                old_g = g;
271                old_b = b;
272                if(colourChanged)
273                {
274                 tmp_mat->setAmbient(r/255.0,g/255.0,b/255.0);
275                 tmp_mat->setDiffuse(r/255.0,g/255.0,b/255.0);
276                tmp_mat->select();     
277                }
278                }
279               
280                if(true/*(abs(-scaleX*i-x+5000) > 1100 || abs(scaleZ*j-y-2000)  > 1100 )*/){ //subdivide??
281               
282                height = heights[j+sampleRate + i*(heightMap->w )];
283                glNormal3f(normalVectorField[i][j+sampleRate].y,normalVectorField[i][j+sampleRate].z,normalVectorField[i][j+2].x);
284                glTexCoord2f(((j/sampleRate)%4)/4.0,((i/sampleRate)%4)/4.0);
285                ///glTexCoord2f(1.0,1.0);
286                glVertex3f(scaleX*(heightMap->h -i),(double)((double)(height)*scaleY),scaleZ*(j+sampleRate)); // Top Right             
287                               
288                height = heights[j+sampleRate + (i+sampleRate)*(heightMap->w )];
289                glNormal3f(normalVectorField[i+sampleRate][j+sampleRate].y,normalVectorField[i+sampleRate][j+sampleRate].z,normalVectorField[i+sampleRate][j+sampleRate].x);
290                glTexCoord2f(((j/sampleRate)%4)/4.0,1/4.0+((i/sampleRate)%4)/4.0);
291                //glTexCoord2f(0.0,0.0);
292                glVertex3f(scaleX*(heightMap->h -(i+sampleRate)),(double)((double)(height)*scaleY),scaleZ*(j+sampleRate)); // Bottom Right
293 
294       
295
296        /*
297                                height = heights[j+2 + (i+2)*(heightMap->w )];
298                glNormal3f(normalVectorField[i+2][j+2].y,normalVectorField[i+2][j+2].z,normalVectorField[i+2][j+2].x);
299                glVertex3f(20*(heightMap->h -(i+2)),(double)((double)(height)/1-300),20*(j+2)); // Bottom Right
300
301
302                             height = heights[j + i*(heightMap->w )];
303                glNormal3f(normalVectorField[i][j].y,normalVectorField[i][j].z,normalVectorField[i][j].x);
304                glVertex3f(20*(heightMap->h -(i)),(double)((double)(height)/1-300),20*(j)); // Top Left
305
306        */
307                g=j;
308
309
310                }
311                else
312                {
313                        //red_mat->select();
314                        //glEnd();
315                       
316                       
317                       
318                        glBegin(GL_TRIANGLE_STRIP);     
319                       
320                                drawRect(j,i+sampleRate/2,j+sampleRate/2,i);
321                        glEnd();
322                        glBegin(GL_TRIANGLE_STRIP);
323                               
324                               
325                                drawRect(j+sampleRate/2,i+sampleRate/2,j+sampleRate,i);
326                        glEnd();
327                        glBegin(GL_TRIANGLE_STRIP);
328                               
329                       
330                                drawRect(j,i+sampleRate,j+sampleRate/2,i+sampleRate/2);
331                        glEnd();
332                        glBegin(GL_TRIANGLE_STRIP);
333                                drawRect(j+sampleRate/2,i+sampleRate,j+sampleRate,i+sampleRate/2);
334                       
335                        glEnd();
336                       
337                        /*glBegin(GL_TRIANGLE_STRIP);
338
339                height = heights[j+sampleRate + i*(heightMap->w )];
340                glNormal3f(normalVectorField[i][j+sampleRate].y,normalVectorField[i][j+sampleRate].z,normalVectorField[i][j+sampleRate].x);
341                glVertex3f(scaleX*(heightMap->h -i),(double)((double)(height)*scaleY),scaleZ*(j+sampleRate)); // Top Right             
342               
343
344                height = heights[j+sampleRate + (i+sampleRate)*(heightMap->w )];
345                glNormal3f(normalVectorField[i+sampleRate][j+sampleRate].y,normalVectorField[i+sampleRate][j+sampleRate].z,normalVectorField[i+sampleRate][j+sampleRate].x);
346                glVertex3f(scaleX*(heightMap->h -(i+sampleRate)),(double)((double)(height)*scaleY),scaleZ*(j+sampleRate)); // Bottom Right
347                */     
348
349                       
350                       
351                        //subdivide
352                }
353
354       
355
356             } 
357                glEnd();       
358           
359        }
360        SDL_UnlockSurface(heightMap);
361       
362}
363
364
365/*      int c = (heightMap->w)/4 ; // One line
366        for(int i = 0; i < (heightMap->w)/4  -4  ; i ++)
367        {
368            for(int j = 0; j < (heightMap->h)/4 - 4; j++)
369            {
370               
371                this->addFace (3, VERTEX_ONLY,j + (i+1)*c,j+1+i*c , j + i*c );
372                this->addFace (3, VERTEX_ONLY,j + (i+1)*c,j + (i+1)*c +1 ,j+i*c +1 );                           
373                         
374               
375            }
376                               
377                       
378                               
379        }
380
381*/
382}
383
384void HeightMap::generateNormalVectorField()
385{
386int delta = 1;
387heights  = (unsigned char*) heightMap->pixels;
388
389//Create a Dynamicly sized 2D-Array to store our normals
390normalVectorField =  new Vector* [heightMap->h];
391for(int i=0;i<heightMap->h;i++)
392normalVectorField [i]= new (Vector [heightMap->w]);
393
394
395
396// !!! Does not yet calculate any normals for some border points!!!!!
397
398if(heightMap != NULL && heightMap->format->BitsPerPixel == 8 )
399        {
400        SDL_LockSurface(heightMap);
401        for(int i = 0 ; i < heightMap->h -1  ; i ++)
402        {
403            for(int j = 0; j < heightMap->-1  ;  j ++)
404            {
405               
406
407                delta = (int)heights[j + (i+1)*(heightMap->w )] -  (int) heights[j + i*(heightMap->w )];
408                Vector a =  Vector(-20.0,(float)delta  ,0.0f);
409       
410                delta = (int)heights[j+1 + i*(heightMap->w )] - (int)heights[j + i*(heightMap->w )];
411                Vector b =  Vector(0.0f,(float) delta ,20.0);
412               
413       
414                 normalVectorField[i][j] = b.cross(a);
415                 normalVectorField[i][j].normalize();
416       
417             } 
418        }
419        SDL_UnlockSurface(heightMap);
420
421}
422
423}
424
425void HeightMap::drawRect(int xBottom, int yBottom, int xTop, int yTop )
426{
427        int height = 0;
428        if(true)
429        {
430               
431                height = heights[xTop + yTop*(heightMap->w )];
432                glNormal3f(normalVectorField[yTop][xTop].y,normalVectorField[yTop][xTop].z,normalVectorField[yTop][xTop].x);
433                glTexCoord2f(((yBottom/sampleRate)%8)/8.0+0.125,((xBottom/sampleRate)%8)/8.0+0.125);
434                glVertex3f(scaleX*(heightMap->h - yTop),(double)((double)(height)*scaleY),scaleZ*(xTop)); // Top Right
435
436                height = heights[xBottom + yTop*(heightMap->w )];
437                glNormal3f(normalVectorField[yTop][xBottom].y,normalVectorField[yTop][xBottom].z,normalVectorField[yTop][xBottom].x);
438                glTexCoord2f(((yBottom/sampleRate)%8)/8.0,((xBottom/sampleRate)%8)/8.0+0.125);
439                glVertex3f(scaleX*(heightMap->h -(yTop)),(double)((double)(height)*scaleY),scaleZ*(xBottom)); // Top Left
440               
441                height = heights[xTop + (yBottom)*(heightMap->w )];
442                glNormal3f(normalVectorField[yBottom][xTop].y,normalVectorField[yBottom][xTop].z,normalVectorField[yBottom][xTop].x);
443                glTexCoord2f(((yBottom/sampleRate)%8)/8.0+0.125,((yBottom/sampleRate)%8)/8.0);
444                glVertex3f(scaleX*(heightMap->h -(yBottom)),(double)((double)(height)*scaleY),scaleZ*(xTop)); // Bottom Right
445               
446height = heights[xBottom + (yBottom)*(heightMap->w )];
447                glNormal3f(normalVectorField[yBottom][xBottom].y,normalVectorField[yBottom][xBottom].z,normalVectorField[yBottom][xBottom].x);
448                glTexCoord2f(((yBottom/sampleRate)%8)/8.0,((yBottom/sampleRate)%8)/8.0);
449                glVertex3f(scaleX*(heightMap->h -(yBottom)),(double)((double)(height)*scaleY),scaleZ*(xBottom)); // Bottom Left
450
451               
452
453        }
454        else
455        {
456                // subdivide
457        }
458       
459}
460
461
462void HeightMap::fixBoarder(int xBottomLeft, int yBottomLeft, int xTopRight, int yTopRight)
463{
464
465        int height = 0;
466       
467        for(int i= xTopRight; i < xBottomLeft ; i+= sampleRate)
468        {
469       
470        glBegin(GL_TRIANGLES);
471                       
472                        height = heights[yBottomLeft + (i + sampleRate)*(heightMap->w )];
473                        glNormal3f(0,1,0);
474                        glVertex3f(scaleX*(heightMap->h -i-sampleRate),scaleY*height,scaleZ*(yBottomLeft));
475                       
476                        height = heights[yBottomLeft + i*(heightMap->w )];
477                        glNormal3f(0,1,0);
478                        glVertex3f(scaleX*(heightMap->h -i),scaleY*height,scaleZ*(yBottomLeft)); 
479                       
480                        height = heights[yBottomLeft + (i + sampleRate/2)*(heightMap->w )];
481                        glNormal3f(0,1,0);
482                        glVertex3f(scaleX*(heightMap->h -i - sampleRate/2),scaleY*height,scaleZ*(yBottomLeft)); 
483                       
484                         
485                       
486                        glEnd();
487                               
488                       
489                               
490       
491        }
492        for(int j= yBottomLeft; j < yTopRight; j+= sampleRate)
493        {
494                   glBegin(GL_TRIANGLES);
495                        height = heights[j + (xBottomLeft+sampleRate)*(heightMap->w )];
496                        glNormal3f(-1,0,0);
497                        glVertex3f(scaleX*(heightMap->h -xBottomLeft -sampleRate),scaleY*height,scaleZ*(j)); 
498                       
499                        height = heights[j + sampleRate/2  + (xBottomLeft + sampleRate)*(heightMap->w )];
500                        glNormal3f(-1,0,0);
501                        glVertex3f(scaleX*(heightMap->h -xBottomLeft - sampleRate),scaleY*height,scaleZ*(j+sampleRate/2)); 
502                       
503                        height = heights[j + sampleRate + (xBottomLeft + sampleRate)*(heightMap->w )];
504                        glNormal3f(-1,0,0);
505                        glVertex3f(scaleX*(heightMap->h -xBottomLeft-sampleRate),scaleY*height,scaleZ*(j+sampleRate)); 
506                       
507                        glEnd();
508        }
509}
510
511void HeightMap::scale(Vector v)
512{
513 scaleX = v.x;
514 scaleY = v.y;
515 scaleZ = v.z;
516}
517
518// Accepts Coordinates relative to HeightMap
519float HeightMap::getHeight(float x, float y)
520{
521 int xInt = (int)x / scaleX;  x -= (float)xInt*scaleX; xInt = heightMap->h - xInt;
522 int yInt = (int)y / scaleZ;    y -= (float)yInt*scaleZ; 
523 if(xInt <= 0 || xInt >= heightMap->h || yInt <= 0 || yInt >= heightMap->) return 0.0f;
524 float height = heights[yInt + (xInt)*heightMap->w]*scaleY;
525 float a = normalVectorField[(xInt)][yInt].x;
526 float b = normalVectorField [(xInt)][yInt].z;
527 float c = normalVectorField [(xInt)][yInt].y;
528  height -= ( (a/c)*(x) + (b/c)*(y))*scaleY;
529 return height;
530}
Note: See TracBrowser for help on using the repository browser.