-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathTrees.cpp
154 lines (122 loc) · 3.06 KB
/
Trees.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include "Trees.h"
/**
* Tree code heavily adapted from a misplaced online tutorial (sorry can't find it)
*/
Trees::Trees(void) {
level = 4;
loaded = false;
}
Trees::~Trees(void) {
}
// decrease tree complexity
void Trees::DecreaseComplexity(void) {
for (unsigned int i = 0; i < numTrees; i++) {
glDeleteLists(treeLists[i], 1);
}
if (level > 1) level--;
Init();
}
// increase tree complexity
void Trees::IncreaseComplexity(void) {
for (unsigned int i = 0; i < numTrees; i++) {
glDeleteLists(treeLists[i], 1);
}
if (level < 8) level++;
Init();
}
// regenerate trees
void Trees::Regen(void) {
for (unsigned int i = 0; i < numTrees; i++) {
glDeleteLists(treeLists[i], 1);
}
Init();
}
// return tree complexity
int Trees::GetComplexity(void) {
return level;
}
// setup the locations of trees
void Trees::SetUpHeights(Terrain &terrain, float lavaHeight) {
srand(rand());
for (int i = 0; i < numTrees; i++) {
SetUpHeight(i, terrain, lavaHeight);
}
}
// set up tree location
void Trees::SetUpHeight(int i, Terrain &terrain, float lavaHeight) {
float x = (float)random(1, 1024);
float z = (float)random(1, 1024);
float y = terrain.GetHeightAt((unsigned int)x, (unsigned int)z);
if (y < (lavaHeight + 50)) {
SetUpHeight(i, terrain, lavaHeight);
} else {
randomHeights[i].x = x;
randomHeights[i].y = y;
randomHeights[i].z = z;
}
}
/**
* Initialise by loading textures etc.
*/
void Trees::Init() {
//load textures
RawLoader rawLoader;
Shapes shapes;
if (!loaded) {
quadric = gluNewQuadric();
gluQuadricNormals(quadric, GL_TRUE);
gluQuadricTexture(quadric, 1);
woodTexture = rawLoader.LoadTextureRAW("woodtexture.raw", 1, 512, 512);
loaded = true;
}
srand(rand());
for (unsigned int i = 0; i < numTrees; i++) {
treeLists[i] = glGenLists(1);
glNewList(treeLists[i], GL_COMPILE);
glScalef(17.0f, 17.0f, 17.0f);
tree(level);
glEndList();
}
}
void Trees::Display() {
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, woodTexture); // bind the texture
for (unsigned int i = 0; i < numTrees; i++) {
glPushMatrix();
glTranslatef(randomHeights[i].x, randomHeights[i].y, randomHeights[i].z);
glCallList(treeLists[i]);
glPopMatrix();
}
glPopMatrix();
}
// Draw the tree recursively
void Trees::tree(int stage) {
if (stage == 0) {
glPushMatrix();
float length = random(70, 110); // randomise branch length
length /= 100.0f;
glRotatef(-90.0f, 1.0f, 0, 0);
gluCylinder(quadric, 0.102, 0.08, length + 0.025f, 8, 1);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glTranslatef(0, length, 0);
} else {
tree(0); // first stage
for (int i = 0; i < 3; i++) {
glPushMatrix();
glScalef(0.6f, 0.6f, 0.6f);
// Random angle for the three branches (per parent branch)
float randAngle = (float)random(0 + (i * 100), ((i + 1) * 100));
glRotatef(randAngle, 0.0, 1.0, 0.0);
randAngle = (float)random(25, 35);
glRotatef(-randAngle, 0.0, 0.0, 1.0);
tree(stage - 1);
glPopMatrix();
}
}
}
// return a random number in a range
int Trees::random(int min, int max) {
int randNum = (rand() % max) + min;
return randNum;
}