3 #include "transform.hpp"
4 #include "renderer.hpp"
13 #include <boost-1_46/boost/config/no_tr1/complex.hpp>
17 float randdiff(float scale
,float power
) {
18 float tmp
= ((float)rand())/RAND_MAX
; //value between 0 and 1
19 //cerr << "in: " << tmp <<"\n";
20 tmp
= (tmp
*2-1); // between -1 and 1
26 tmp
= pow(tmp
, power
);
30 //cerr << "out: " << tmp <<"\n";
34 int mod(int a
, int b
) {
42 terrain::terrain(int res
, float size
, float height
) : vertices(NULL
) {
44 this->height
= height
;
47 // cout << "allocating trrn ram size:" << res*res*sizeof(float) << endl;
49 data
= new float*[res
];
50 for(int x
= 0; x
< res
; x
++) {
51 data
[x
] = new float[res
];
52 for(int y
= 0; y
< res
; y
++) {
56 // cout << "done allocating" << endl;
61 for(int i
= 0; i
< res
; i
++) {
67 void terrain::generate(int randres
, float divisor
, float power
, int seed
){
69 cout
<< "generating trrn map" << endl
;
71 for(int x
= 0; x
< res
; x
++) for(int y
= 0; y
< res
; y
++){
75 //initialize randres with random values
76 for(int x
= 0; x
< res
; x
+= res
/randres
) for(int y
= 0; y
< res
; y
+= res
/randres
) {
77 data
[x
][y
] = 0.5 + randdiff(0.3, power
);
82 for(int level
= randres
; level
< res
; level
*= 2) {
86 for(int x
= res
/(2*level
); x
< res
; x
+= res
/level
) for(int y
= res
/(2*level
); y
< res
; y
+= res
/level
) {
88 (data
[mod(x
+s
, res
)][mod(y
+s
, res
)]
89 + data
[mod(x
+s
, res
)][mod(y
-s
, res
)]
90 + data
[mod(x
-s
, res
)][mod(y
+s
, res
)]
91 + data
[mod(x
-s
, res
)][mod(y
-s
, res
)]) / 4
92 + randdiff(coef
,power
);
96 for(int x
= 0; x
< res
; x
+= res
/(2*level
)) for(int y
= 0; y
< res
; y
+= res
/(2*level
))
97 if((x
% (res
/level
)) ^ (y
% (res
/level
))){
98 //cerr << "adding " << x << "x" << y << "\n";
100 (data
[mod(x
+s
, res
)][y
]
101 + data
[mod(x
-s
, res
)][y
]
102 + data
[x
][mod(y
+s
, res
)]
103 + data
[x
][mod(y
-s
, res
)]) / 4
104 + randdiff(coef
, power
);
108 cout
<< "done generating" << endl
;
111 float terrain::xVal(int x
, int y
) const {
112 return (float)x
* size
/ (float)res
- size
/2;
115 float terrain::yVal(int x
, int y
) const {
116 return height
* data
[mod(x
, res
)][mod(y
, res
)];
119 float terrain::zVal(int x
, int y
) const {
120 return (float)y
* size
/ (float)res
- size
/2;
123 float interpolWeight(float x
, float y
) {
124 return std::sqrt((x
* x
) + (y
* y
)) + 0.00001;
127 float terrain::heightAt(float x
, float y
) const {
128 float a
= (x
+ size
/2) * (float)res
/ size
;
129 float b
= (y
+ size
/2) * (float)res
/ size
;
138 tmp
= yVal(ra
, rb
)*interpolWeight(ra
-a
,rb
-b
)
139 +yVal(ra
+1, rb
)*interpolWeight(ra
+1-a
,rb
-b
)
140 +yVal(ra
, rb
+1)*interpolWeight(ra
-a
,rb
+1-b
)
141 +yVal(ra
+1, rb
+1)*interpolWeight(ra
-a
,rb
+1-b
);
142 tmp
/= interpolWeight(ra
-a
,rb
-b
)
143 +interpolWeight(ra
+1-a
,rb
-b
)
144 +interpolWeight(ra
-a
,rb
+1-b
)
145 +interpolWeight(ra
-a
,rb
+1-b
);
149 #define terrainindex(x, y) ((res * mod((y), res)) + mod((x), res))
151 void terrain::generateVertices() {
156 vertices
= new Vertex
[res
* res
];
158 glBufferData(GL_ARRAY_BUFFER
, res
* res
* sizeof(Vertex
), NULL
, GL_STATIC_DRAW
);
160 Vertex
* vert
= reinterpret_cast<Vertex
*>(glMapBuffer(GL_ARRAY_BUFFER
, GL_WRITE_ONLY
));
162 for(int y
= 0; y
< res
; y
++) for(int x
= 0; x
< res
; x
++) {
165 vec(xVal(x
+1, y
-1), yVal(x
+1, y
-1), zVal(x
+1, y
-1)),
166 vec(xVal(x
-1, y
-1), yVal(x
-1, y
-1), zVal(x
-1, y
-1)),
167 vec(xVal(x
-1, y
+1), yVal(x
-1, y
+1), zVal(x
-1, y
+1)),
168 vec(xVal(x
+1, y
+1), yVal(x
+1, y
+1), zVal(x
+1, y
+1))
171 Vertex
& v
= vertices
[terrainindex(x
, y
)];
173 v
.pos
= vec(xVal(x
, y
), yVal(x
, y
), zVal(x
, y
));
174 v
.normal
= calculateNormal(rect
, 4);
176 vert
[terrainindex(x
, y
)] = v
;
179 glUnmapBuffer(GL_ARRAY_BUFFER
);
181 checkGl("adding terrain vertices");
184 void terrain::setVertexArray(Vertex
* vert
) {
186 glEnableClientState(GL_VERTEX_ARRAY
);
187 glEnableClientState(GL_NORMAL_ARRAY
);
189 glVertexPointer(3, GL_FLOAT
, sizeof(Vertex
), &vert
->pos
);
190 glNormalPointer(GL_FLOAT
, sizeof(Vertex
), &vert
->normal
);
194 bool terrain::isSubdivided(int x0
, int x1
, int y0
, int y1
, vec pos
) const {
196 if(x1
- x0
<= 1 || y1
- y0
<= 1) {
200 int w
= (x1
- x0
), h
= (y1
- y0
);
201 int mx
= ((w
/ 2) + x0
), my
= ((h
/ 2) + y0
);
202 vec
center(xVal(mx
, my
), yVal(mx
, my
), zVal(mx
, my
));
204 float sfacor
= res
/ float(sqrt(w
* h
));
206 vec diff
= (pos
- center
);
208 float d
= diff
.det();
215 return (d
* sfacor
< 300.f
);
218 void terrain::addRect(std::vector
<unsigned short> & ind
, int x0
, int x1
, int y0
, int y1
, vec pos
, ToCenter tc
) const {
220 int w
= (x1
- x0
), h
= (y1
- y0
);
221 int mx
= (x0
+ (w
/2)), my
= (y0
+ (h
/2));
223 if(isSubdivided(x0
, x1
, y0
, y1
, pos
)) {
227 addRect(ind
, x0
, mx
, y0
, my
, pos
, None
);
228 addRect(ind
, x0
, mx
, my
, y1
, pos
, None
);
229 addRect(ind
, mx
, x1
, my
, y1
, pos
, None
);
230 addRect(ind
, mx
, x1
, y0
, my
, pos
, None
);
234 GLbyte
* c
= reinterpret_cast<GLbyte
*>(&data
[mod(x0
, res
)][mod(y0
, res
)]);
235 glColor3f(float(c
[0])/256 + .5f
, float(c
[1])/256 + .5f
, float(c
[2])/256 + .5f
);
238 tvert
|= ((tc
== X0
) || isSubdivided(x0
- w
, x0
, y0
, y1
, pos
)) ? X0
: 0;
239 tvert
|= ((tc
== X1
) || isSubdivided(x1
, x1
+ w
, y0
, y1
, pos
)) ? X1
: 0;
240 tvert
|= ((tc
== Y0
) || isSubdivided(x0
, x1
, y0
- h
, y0
, pos
)) ? Y0
: 0;
241 tvert
|= ((tc
== Y1
) || isSubdivided(x0
, x1
, y1
, y1
+ h
, pos
)) ? Y1
: 0;
249 drawGlVertex(x0
, y0
);
250 drawGlVertex(x0
, y1
);
251 drawGlVertex(x1
, y1
);
252 drawGlVertex(x1
, y0
);
261 glBegin(GL_TRIANGLES
);
263 drawGlVertex(x1
, y0
);
264 drawGlVertex(x0
, y0
);
265 drawGlVertex(x0
, my
);
267 drawGlVertex(x0
, my
);
268 drawGlVertex(x1
, y1
);
269 drawGlVertex(x1
, y0
);
271 drawGlVertex(x0
, my
);
272 drawGlVertex(x0
, y1
);
273 drawGlVertex(x1
, y1
);
282 glColor3f(1.f
, 1.f
, 1.f
);
284 glBegin(GL_TRIANGLES
);
286 drawGlVertex(x0
, my
);
287 drawGlVertex(mx
, y1
);
288 drawGlVertex(x1
, y0
);
290 drawGlVertex(x0
, my
);
291 drawGlVertex(x0
, y1
);
292 drawGlVertex(mx
, y1
);
294 drawGlVertex(x1
, y0
);
295 drawGlVertex(mx
, y1
);
296 drawGlVertex(x1
, y1
);
298 drawGlVertex(x0
, my
);
299 drawGlVertex(x1
, y0
);
300 drawGlVertex(x0
, y0
);
309 glColor3f(1.f
, 1.f
, 1.f
);
311 glBegin(GL_TRIANGLES
);
313 drawGlVertex(x0
, my
);
314 drawGlVertex(x1
, y1
);
315 drawGlVertex(mx
, y0
);
317 drawGlVertex(x0
, my
);
318 drawGlVertex(mx
, y0
);
319 drawGlVertex(x0
, y0
);
321 drawGlVertex(x1
, y1
);
322 drawGlVertex(x1
, y0
);
323 drawGlVertex(mx
, y0
);
325 drawGlVertex(x0
, my
);
326 drawGlVertex(x0
, y1
);
327 drawGlVertex(x1
, y1
);
359 case X0
| X1
| Y0
| Y1
: {
368 glBegin(GL_TRIANGLES
);
370 drawGlVertex(x1
, y0
);
371 drawGlVertex(x0
, y0
);
372 drawGlVertex(x1
, my
);
374 drawGlVertex(x1
, my
);
375 drawGlVertex(x0
, y0
);
376 drawGlVertex(x0
, y1
);
378 drawGlVertex(x1
, my
);
379 drawGlVertex(x0
, y1
);
380 drawGlVertex(x1
, y1
);
390 glColor3f(1.f
, 1.f
, 1.f
);
392 glBegin(GL_TRIANGLES
);
394 drawGlVertex(x1
, my
);
395 drawGlVertex(x0
, y0
);
396 drawGlVertex(mx
, y1
);
398 drawGlVertex(x1
, my
);
399 drawGlVertex(mx
, y1
);
400 drawGlVertex(x1
, y1
);
402 drawGlVertex(x0
, y0
);
403 drawGlVertex(x0
, y1
);
404 drawGlVertex(mx
, y1
);
406 drawGlVertex(x1
, my
);
407 drawGlVertex(x1
, y0
);
408 drawGlVertex(x0
, y0
);
418 glColor3f(1.f
, 1.f
, 1.f
);
420 glBegin(GL_TRIANGLES
);
422 drawGlVertex(x1
, my
);
423 drawGlVertex(mx
, y0
);
424 drawGlVertex(x0
, y1
);
426 drawGlVertex(x1
, my
);
427 drawGlVertex(x1
, y0
);
428 drawGlVertex(mx
, y0
);
430 drawGlVertex(x0
, y1
);
431 drawGlVertex(mx
, y0
);
432 drawGlVertex(x0
, y0
);
434 drawGlVertex(x1
, my
);
435 drawGlVertex(x0
, y1
);
436 drawGlVertex(x1
, y1
);
452 glBegin(GL_TRIANGLES
);
454 drawGlVertex(x0
, y0
);
455 drawGlVertex(x0
, y1
);
456 drawGlVertex(mx
, y0
);
458 drawGlVertex(mx
, y0
);
459 drawGlVertex(x0
, y1
);
460 drawGlVertex(x1
, y1
);
462 drawGlVertex(mx
, y0
);
463 drawGlVertex(x1
, y1
);
464 drawGlVertex(x1
, y0
);
480 glBegin(GL_TRIANGLES
);
482 drawGlVertex(x0
, y0
);
483 drawGlVertex(x0
, y1
);
484 drawGlVertex(mx
, y1
);
486 drawGlVertex(mx
, y1
);
487 drawGlVertex(x1
, y0
);
488 drawGlVertex(x0
, y0
);
490 drawGlVertex(mx
, y1
);
491 drawGlVertex(x1
, y1
);
492 drawGlVertex(x1
, y0
);
504 ind.push_back(terrainindex(x0, y0));
505 ind.push_back(terrainindex(x0, y1));
506 ind.push_back(terrainindex(x1, y1));
507 ind.push_back(terrainindex(x1, y0));*/
514 void terrain::drawVertices(vec pos
) const {
516 glDisable(GL_LINE_SMOOTH
);
517 glHint(GL_LINE_SMOOTH_HINT
, GL_NICEST
);
519 glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
);
523 std::vector
<unsigned short> indices
;
525 indices
.reserve(1000);
528 float a
= (pos
.x
+ size
/2) * (float)res
/ size
;
529 float b
= (pos
.z
+ size
/2) * (float)res
/ size
;
530 int ix
= int(a
+ .5f
), iy
= int(b
+ .5f
);
532 int depth
= abs(heightAt(pos
.x
, pos
.z
) - pos
.y
);
536 size_t r
= 2 << (size_t)log(depth
* 2);
538 addRect(indices
, ix
- r
, ix
, iy
- r
, iy
, pos
, None
);
539 addRect(indices
, ix
, ix
+ r
, iy
- r
, iy
, pos
, None
);
540 addRect(indices
, ix
, ix
+ r
, iy
, iy
+ r
, pos
, None
);
541 addRect(indices
, ix
- r
, ix
, iy
, iy
+ r
, pos
, None
);
543 for(int i
= 0; indices
.size() < 750 && i
< 20; r
*= 2, i
++) {
547 addRect(indices
, ix
- r2
, ix
- r
, iy
- r2
, iy
- r
, pos
, None
);
548 addRect(indices
, ix
- r
, ix
, iy
- r2
, iy
- r
, pos
, i
== 0 ? None
: Y1
);
549 addRect(indices
, ix
, ix
+ r
, iy
- r2
, iy
- r
, pos
, i
== 0 ? None
: Y1
);
550 addRect(indices
, ix
+ r
, ix
+ r2
, iy
- r2
, iy
- r
, pos
, None
);
551 addRect(indices
, ix
+ r
, ix
+ r2
, iy
- r
, iy
, pos
, i
== 0 ? None
: X0
);
552 addRect(indices
, ix
+ r
, ix
+ r2
, iy
, iy
+ r
, pos
, i
== 0 ? None
: X0
);
553 addRect(indices
, ix
+ r
, ix
+ r2
, iy
+ r
, iy
+ r2
, pos
, None
);
554 addRect(indices
, ix
, ix
+ r
, iy
+ r
, iy
+ r2
, pos
, i
== 0 ? None
: Y0
);
555 addRect(indices
, ix
- r
, ix
, iy
+ r
, iy
+ r2
, pos
, i
== 0 ? None
: Y0
);
556 addRect(indices
, ix
- r2
, ix
- r
, iy
+ r
, iy
+ r2
, pos
, None
);
557 addRect(indices
, ix
- r2
, ix
- r
, iy
, iy
+ r
, pos
, i
== 0 ? None
: X1
);
558 addRect(indices
, ix
- r2
, ix
- r
, iy
- r
, iy
, pos
, i
== 0 ? None
: X1
);
562 // setVertexArray(NULL);
564 glColor3f(0.5, 0.4, 0.2);
566 //glDrawElements(GL_QUADS, indices.size(), GL_UNSIGNED_SHORT, &indices.front());
568 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
570 checkGl("rendering terrain vertices");
573 void terrain::drawGlVertex(int x
, int y
) const {
575 /*float nx = yVal(x-1,y) - yVal(x+1,y); //Height[x-1][y] - Height[x+1][y];
576 float nz = 4 / (size/res);
577 float ny = yVal(x,y-1) - yVal(x,y+1); //Height[x][y-1] - Height[x][y+1];*/
579 vec(xVal(x+1, y-1), yVal(x+1, y-1), zVal(x+1, y-1)),
580 vec(xVal(x-1, y-1), yVal(x-1, y-1), zVal(x-1, y-1)),
581 vec(xVal(x-1, y+1), yVal(x-1, y+1), zVal(x-1, y+1)),
582 vec(xVal(x+1, y+1), yVal(x+1, y+1), zVal(x+1, y+1))
586 //glColor3f(0.5, 0.4, 0.2);
587 //glColor3f(x / res + .1f, y / res + .1f, randVal() + .1f);
588 //vec normal = calculateNormal(rect,4);
589 const vec
& normal
= vertices
[terrainindex(x
, y
)].normal
;
590 glNormal3f(normal
.x
, normal
.y
, normal
.z
);
593 vec
pos(xVal(x
, y
), yVal(x
, y
), zVal(x
, y
));
594 //const vec & pos = vertices[terrainindex(x, y)].pos;
595 glVertex3f(pos
.x
, pos
.y
, pos
.z
);
598 void terrain::drawGl() const {
600 for(int y
= 0; y
< res
; y
++) for(int x
= 0; x
< res
; x
++) {
601 drawGlVertex(x
+ 0, y
+ 0);
602 drawGlVertex(x
+ 0, y
+ 1);
603 drawGlVertex(x
+ 1, y
+ 1);
604 drawGlVertex(x
+ 1, y
+ 0);