Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/nico/src/importer/heightMapTerrain.cc @ 3391

Last change on this file since 3391 was 3390, checked in by bensch, 19 years ago

orxonox/branches/nico: heightmap now compiles on all platforms

File size: 6.4 KB
Line 
1/*
2 *  ldrawparser.cpp
3 *  legotown3d
4 *
5 *  Created by Nico Bernold on 08.01.05.
6 *  Copyright 2005 __MyCompanyName__. All rights reserved.
7 *
8 */
9
10#include "heightMapTerrain.h"
11
12HeightMapTerrain::HeightMapTerrain()
13{       
14}
15
16HeightMapTerrain::~HeightMapTerrain()
17{
18}
19
20bool HeightMapTerrain::loadBitmap(char* fileName)
21{
22        return bitmap = SDL_LoadBMP(fileName); 
23}
24
25bool HeightMapTerrain::createDisplayLists(int width, int height, int levelOfDetail)
26{
27        if (bitmap == NULL) return false;
28       
29        cout << "bitmap-dimensions:             " << bitmap->w << " x " << bitmap->h << endl;
30        cout << "bitmap-pitch:                  " << bitmap->pitch << endl;
31        cout << "bitmap->format->BytesPerPixel: " << (int)bitmap->format->BytesPerPixel << endl;
32        cout << "bitmap->format->BitsPerPixel:  " << (int)bitmap->format->BitsPerPixel << endl;
33         
34        if (bitmap->w % width != 0) return false;
35        if (bitmap->h % height != 0) return false;
36       
37        if (levelOfDetail < 1 || levelOfDetail > 10) return false;
38       
39        int howManyListsWide = bitmap->w / width;
40        int howManyListsHigh = bitmap->h / height;
41       
42        // calculate how many displayLists we'll create
43        displayListCount = howManyListsWide * howManyListsHigh; 
44
45        cout << "lists-information: " << howManyListsWide << " * " << howManyListsHigh << " = " << displayListCount << " display lists." << endl;
46       
47        displayListStart = glGenLists(displayListCount);
48        if (displayListStart == 0)
49        {
50                cout << "could not generate " << displayListCount << " display lists. exiting. " << endl;
51                return false;
52        }
53       
54        cout << displayListCount << " display lists generated. starting at: " << displayListStart << endl;
55
56
57        int i,j;
58       
59        for (i=0; i<howManyListsHigh; i++)
60        {
61                for (j=0; j<howManyListsWide; j++)
62                {
63                        if (readIntoList(j*width,i*height,width,height,levelOfDetail,i*howManyListsHigh + j) == false)
64                        {
65                                cout << "error while generating display lists. exiting. " << endl;
66                                return false;
67                        }
68
69                }
70        }
71       
72        return true;
73}
74
75bool HeightMapTerrain::readIntoList(int left, int top, int width, int height, int levelOfDetail, GLuint displayListNr)
76{
77        cout << "creating list Nr " << displayListNr << endl;
78        cout << "left, top, width, height: " << left << ", " << top << ", " << width << ", " << height << endl; 
79       
80        // y is the height value in OpenGL convention
81        int x,y,z;
82        GLfloat col;
83
84        // used for normal calculations
85        Vector O; // origin: the vertex where i'm standing
86        Vector N,E,S,W,NE,SE,SW,NW; // vectors pointing to north, east, ...
87
88        bool eightTriangles = false;
89       
90       
91        // contains a normal vector for every vertex
92        normals = new Vector[width*height];
93
94        // precalculate all vertex normals for later use in display list generation
95        // many superflous calculations i know...
96        for (z=top; z<top+height; z++)
97        {
98                for (x=left; x<left+width; x++)
99                {
100                        O = Vector(x,getHeightValue(x,z),z);
101
102                        N = Vector(x,getHeightValue(x,z-1),z-1) - O;
103                        E = Vector(x+1,getHeightValue(x+1,z),z) - O;
104                        S = Vector(x,getHeightValue(x,z+1),z+1) - O;
105                        W = Vector(x-1,getHeightValue(x-1,z),z) - O;
106
107                        if (eightTriangles == false)
108                                // calculate the average normal vector by adding up all 4 adjacent triangle normal vectors
109                                normals[(z-top) * height + (x-left)] = N.cross(W) + W.cross(S) + S.cross(E);
110
111                        else
112                        {
113                                NE = Vector(x+1,getHeightValue(x+1,z-1),z-1) - O;
114                                SE = Vector(x+1,getHeightValue(x+1,z+1),z+1) - O;
115                                SW = Vector(x-1,getHeightValue(x-1,z+1),z+1) - O;
116                                NW = Vector(x-1,getHeightValue(x-1,z-1),z-1) - O;
117                                // calculate the average normal vector by adding up all 8 adjacent triangle normal vectors
118                                normals[(z-top) * height + (x-left)] = N.cross(NW) + NW.cross(W) + W.cross(SW) + SW.cross(S) + S.cross(SE) + SE.cross(E) + E.cross(NE) + NE.cross(N);
119                        }
120
121                        // every second vertex is the edge of eightTriangles (the others have only four triangles)
122                        eightTriangles = !eightTriangles;
123                }
124        }
125       
126        cout << "normals precalculated for list " << displayListNr << endl;
127       
128        glNewList(displayListStart + displayListNr,GL_COMPILE);
129        {
130                glBegin(GL_TRIANGLES);
131                {
132                        // don't go through last col and row, because they are already done by second last col&row
133                        for (z = top; z < (top + height) - 1; z++)
134                        {
135                                for (x = left; x < (left + width) - 1; x++)
136                                {
137                                        // draw 2 triangles per (x,z) pair
138                                       
139                                        if (eightTriangles)
140                                        {
141                                                call_glNormal_and_glVertex(x,z,top,left,height);
142                                                call_glNormal_and_glVertex(x,z+1,top,left,height);
143                                                call_glNormal_and_glVertex(x+1,z,top,left,height);
144                                       
145                                                call_glNormal_and_glVertex(x+1,z,top,left,height);
146                                                call_glNormal_and_glVertex(x,z+1,top,left,height);
147                                                call_glNormal_and_glVertex(x+1,z+1,top,left,height);
148                                        }
149                                       
150                                        else
151                                        {
152                                                call_glNormal_and_glVertex(x,z,top,left,height);
153                                                call_glNormal_and_glVertex(x,z+1,top,left,height);
154                                                call_glNormal_and_glVertex(x+1,z+1,top,left,height);
155                                               
156                                                call_glNormal_and_glVertex(x+1,z,top,left,height);
157                                                call_glNormal_and_glVertex(x,z,top,left,height);
158                                                call_glNormal_and_glVertex(x+1,z+1,top,left,height);
159                                        }
160                                       
161                                       
162                                        // use the same trick to change the triangles everytime. once |/| and once |\|
163                                        eightTriangles = !eightTriangles;
164
165                                }
166                        }
167                }
168                glEnd();
169
170        }
171        glEndList();
172
173       
174        delete[] normals;
175       
176        return true;
177}
178
179
180void HeightMapTerrain::call_glNormal_and_glVertex(int x,int z,int top,int left,int height)
181{
182/*
183        GLfloat color[4];           // color parameter for glMaterial
184       
185        int heightVal = getHeightValue(x,z);
186
187        color[0] = 1.0 / 256.0 * heightVal;
188        color[1] = 1.0 / 256.0 * heightVal;
189        color[2] = 1.0 / 256.0 * heightVal;
190        color[3] = 1;  // alpha channel (1 = solid)
191
192        glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
193*/
194        glNormal3f(normals[(z-top) * height + (x-left)].x,normals[(z-top) * height + (x-left)].y,normals[(z-top) * height + (x-left)].z);
195        glVertex3i(x,getHeightValue(x,z),z);
196}
197
198
199GLint HeightMapTerrain::getHeightValue(int x, int z)
200{
201        if (bitmap == NULL) return 0;
202
203        // catch out of image access
204        int X = x % bitmap->w;
205        int Z = z % bitmap->h;
206       
207        /*
208        if (X != x) cout << "x lies outside of image (" << x << "," << z << ")" << endl;
209        if (Z != z) cout << "z lies outside of image (" << x << "," << z << ")" << endl;
210        */
211       
212        // if x or z exeed the image size, return 0 as height value
213        if (X != x || Z != z) return 0;
214       
215       
216        Uint8 index;
217        SDL_Color color;
218       
219        SDL_LockSurface(bitmap);
220
221        index = *((Uint8*)bitmap->pixels + Z * bitmap->pitch + X * bitmap->format->BytesPerPixel);
222        color = bitmap->format->palette->colors[index];
223
224        SDL_UnlockSurface(bitmap);
225       
226        // return the red component, because in a grayscale pic, r,g and b are all the same value
227        return (GLint)color.r;
228}
Note: See TracBrowser for help on using the repository browser.