rev |
line source |
nuclear@11
|
1 #include <float.h>
|
nuclear@0
|
2 #include "opengl.h"
|
nuclear@0
|
3 #include "board.h"
|
nuclear@1
|
4 #include "meshgen.h"
|
nuclear@6
|
5 #include "pnoise.h"
|
nuclear@0
|
6
|
nuclear@0
|
7 Board::Board()
|
nuclear@0
|
8 {
|
nuclear@2
|
9 puck_obj = 0;
|
nuclear@0
|
10 clear();
|
nuclear@0
|
11 }
|
nuclear@0
|
12
|
nuclear@0
|
13 Board::~Board()
|
nuclear@0
|
14 {
|
nuclear@0
|
15 destroy();
|
nuclear@0
|
16 }
|
nuclear@0
|
17
|
nuclear@0
|
18 bool Board::init()
|
nuclear@0
|
19 {
|
nuclear@4
|
20 if(!generate_textures()) {
|
nuclear@4
|
21 return false;
|
nuclear@4
|
22 }
|
nuclear@1
|
23 if(!generate()) {
|
nuclear@0
|
24 return false;
|
nuclear@0
|
25 }
|
nuclear@1
|
26
|
nuclear@0
|
27 return true;
|
nuclear@0
|
28 }
|
nuclear@0
|
29
|
nuclear@0
|
30 void Board::destroy()
|
nuclear@0
|
31 {
|
nuclear@2
|
32 for(size_t i=0; i<obj.size(); i++) {
|
nuclear@2
|
33 delete obj[i];
|
nuclear@1
|
34 }
|
nuclear@2
|
35 obj.clear();
|
nuclear@1
|
36
|
nuclear@2
|
37 delete puck_obj;
|
nuclear@2
|
38 puck_obj = 0;
|
nuclear@0
|
39 }
|
nuclear@0
|
40
|
nuclear@0
|
41 void Board::clear()
|
nuclear@0
|
42 {
|
nuclear@0
|
43 memset(slots, 0, sizeof slots);
|
nuclear@0
|
44 }
|
nuclear@0
|
45
|
nuclear@0
|
46 void Board::draw() const
|
nuclear@0
|
47 {
|
nuclear@2
|
48 for(size_t i=0; i<obj.size(); i++) {
|
nuclear@2
|
49 obj[i]->draw();
|
nuclear@1
|
50 }
|
nuclear@0
|
51 }
|
nuclear@0
|
52
|
nuclear@1
|
53 #define HSIZE 1.0
|
nuclear@1
|
54 #define VSIZE (2.0 * HSIZE)
|
nuclear@1
|
55 #define BOT_THICKNESS (HSIZE * 0.01)
|
nuclear@1
|
56 #define WALL_THICKNESS (HSIZE * 0.05)
|
nuclear@1
|
57 #define WALL_HEIGHT (HSIZE * 0.1)
|
nuclear@1
|
58 #define GAP (HSIZE * 0.025)
|
nuclear@1
|
59 #define HINGE_RAD (GAP * 0.5)
|
nuclear@1
|
60 #define HINGE_HEIGHT (VSIZE * 0.075)
|
nuclear@11
|
61 #define PIECE_RAD (0.45 * HSIZE / 5.0)
|
nuclear@11
|
62
|
nuclear@11
|
63 static const float piece_cp[][3][2] = {
|
nuclear@11
|
64 {{0, 0.25}, {1, 0.25}, {2, 0.5}},
|
nuclear@11
|
65 {{2, 0.5}, {2.5, 0.5}, {3, 0.5}},
|
nuclear@11
|
66 {{3, 0.5}, {4, 0.5}, {4, 0}},
|
nuclear@11
|
67 {{4, 0}, {4, -0.5}, {3, -0.5}},
|
nuclear@11
|
68 {{3, -0.5}, {2.5, -0.5}, {0, -0.5}},
|
nuclear@11
|
69 //{{2, -0.5}, {1, -0.25}, {0, -0.25}}
|
nuclear@11
|
70 };
|
nuclear@11
|
71 static const int piece_ncurves = sizeof piece_cp / sizeof *piece_cp;
|
nuclear@11
|
72
|
nuclear@11
|
73 static Vector2 piece_revol(float u, float v, void *cls)
|
nuclear@11
|
74 {
|
nuclear@11
|
75 if(v >= 1.0) v = 1.0 - 1e-6;
|
nuclear@11
|
76 int idx = std::min((int)(v * piece_ncurves), piece_ncurves - 1);
|
nuclear@11
|
77 float t = fmod(v * (float)piece_ncurves, 1.0);
|
nuclear@11
|
78
|
nuclear@11
|
79 Vector2 res;
|
nuclear@11
|
80 for(int i=0; i<2; i++) {
|
nuclear@11
|
81 float mid = piece_cp[idx][1][i];
|
nuclear@11
|
82 res[i] = bezier(piece_cp[idx][0][i], mid, mid, piece_cp[idx][2][i], t);
|
nuclear@11
|
83 }
|
nuclear@11
|
84 return res * 0.25 * PIECE_RAD;
|
nuclear@11
|
85 }
|
nuclear@1
|
86
|
nuclear@12
|
87 static Vector2 piece_revol_normal(float u, float v, void *cls)
|
nuclear@12
|
88 {
|
nuclear@12
|
89 if(v >= 1.0) v = 1.0 - 1e-6;
|
nuclear@12
|
90 int idx = std::min((int)(v * piece_ncurves), piece_ncurves - 1);
|
nuclear@12
|
91 float t = fmod(v * (float)piece_ncurves, 1.0);
|
nuclear@12
|
92
|
nuclear@12
|
93 Vector2 pprev, pnext;
|
nuclear@12
|
94 for(int i=0; i<2; i++) {
|
nuclear@12
|
95 float start = piece_cp[idx][0][i];
|
nuclear@12
|
96 float mid = piece_cp[idx][1][i];
|
nuclear@12
|
97 float end = piece_cp[idx][2][i];
|
nuclear@12
|
98
|
nuclear@12
|
99 pprev[i] = bezier(start, mid, mid, end, t - 0.05);
|
nuclear@12
|
100 pnext[i] = bezier(start, mid, mid, end, t + 0.05);
|
nuclear@12
|
101 }
|
nuclear@12
|
102
|
nuclear@12
|
103 float tx = pnext.x - pprev.x;
|
nuclear@12
|
104 float ty = pnext.y - pprev.y;
|
nuclear@12
|
105
|
nuclear@12
|
106 return Vector2(-ty, tx);
|
nuclear@12
|
107 }
|
nuclear@12
|
108
|
nuclear@1
|
109 bool Board::generate()
|
nuclear@0
|
110 {
|
nuclear@4
|
111 Mesh tmp;
|
nuclear@1
|
112 Matrix4x4 xform;
|
nuclear@1
|
113
|
nuclear@2
|
114 obj.clear();
|
nuclear@2
|
115
|
nuclear@4
|
116 for(int i=0; i<2; i++) {
|
nuclear@4
|
117 int sign = i * 2 - 1;
|
nuclear@1
|
118
|
nuclear@4
|
119 // generate bottom
|
nuclear@4
|
120 Mesh *bottom = new Mesh;
|
nuclear@4
|
121 gen_box(bottom, HSIZE, BOT_THICKNESS, HSIZE * 2.0);
|
nuclear@4
|
122 xform.set_translation(Vector3(0, -BOT_THICKNESS / 2.0, 0));
|
nuclear@4
|
123 bottom->apply_xform(xform);
|
nuclear@2
|
124
|
nuclear@4
|
125 Object *obottom = new Object;
|
nuclear@4
|
126 obottom->set_mesh(bottom);
|
nuclear@4
|
127 obottom->xform().set_translation(Vector3(sign * (HSIZE / 2.0 + WALL_THICKNESS + HINGE_RAD * 0.25), 0, 0));
|
nuclear@4
|
128 obottom->set_texture(img_field.texture());
|
nuclear@4
|
129 obj.push_back(obottom);
|
nuclear@2
|
130
|
nuclear@1
|
131
|
nuclear@4
|
132 // generate the 4 sides
|
nuclear@4
|
133 Mesh *sides = new Mesh;
|
nuclear@4
|
134 gen_box(sides, WALL_THICKNESS, WALL_HEIGHT, VSIZE + WALL_THICKNESS * 2);
|
nuclear@4
|
135 xform.set_translation(Vector3(-(HSIZE + WALL_THICKNESS) / 2.0,
|
nuclear@4
|
136 WALL_HEIGHT / 2.0 - BOT_THICKNESS, 0));
|
nuclear@4
|
137 sides->apply_xform(xform);
|
nuclear@1
|
138
|
nuclear@4
|
139 gen_box(&tmp, WALL_THICKNESS, WALL_HEIGHT, VSIZE + WALL_THICKNESS * 2);
|
nuclear@4
|
140 xform.set_translation(Vector3((HSIZE + WALL_THICKNESS) / 2.0,
|
nuclear@4
|
141 WALL_HEIGHT / 2.0 - BOT_THICKNESS, 0));
|
nuclear@4
|
142 tmp.apply_xform(xform);
|
nuclear@4
|
143 sides->append(tmp);
|
nuclear@4
|
144 tmp.clear();
|
nuclear@1
|
145
|
nuclear@4
|
146 gen_box(&tmp, HSIZE, WALL_HEIGHT, WALL_THICKNESS);
|
nuclear@4
|
147 xform.set_translation(Vector3(0, WALL_HEIGHT / 2.0 - BOT_THICKNESS,
|
nuclear@4
|
148 (VSIZE + WALL_THICKNESS) / 2.0));
|
nuclear@4
|
149 tmp.apply_xform(xform);
|
nuclear@4
|
150 sides->append(tmp);
|
nuclear@4
|
151 tmp.clear();
|
nuclear@1
|
152
|
nuclear@4
|
153 gen_box(&tmp, HSIZE, WALL_HEIGHT, WALL_THICKNESS);
|
nuclear@4
|
154 xform.set_translation(Vector3(0, WALL_HEIGHT / 2.0 - BOT_THICKNESS,
|
nuclear@4
|
155 -(VSIZE + WALL_THICKNESS) / 2.0));
|
nuclear@4
|
156 tmp.apply_xform(xform);
|
nuclear@4
|
157 sides->append(tmp);
|
nuclear@4
|
158 tmp.clear();
|
nuclear@4
|
159
|
nuclear@6
|
160 // generate texture coordinates
|
nuclear@6
|
161 sides->texcoord_gen_box();
|
nuclear@6
|
162
|
nuclear@4
|
163 Object *osides = new Object;
|
nuclear@4
|
164 osides->set_mesh(sides);
|
nuclear@4
|
165 osides->xform() = obottom->xform();
|
nuclear@6
|
166 osides->set_texture(img_wood.texture());
|
nuclear@6
|
167 osides->tex_xform().set_scaling(Vector3(2, 2, 2));
|
nuclear@6
|
168 osides->tex_xform().rotate(-Vector3(1, 0, 0.5), M_PI / 4.0);
|
nuclear@4
|
169 obj.push_back(osides);
|
nuclear@4
|
170
|
nuclear@4
|
171 }
|
nuclear@2
|
172
|
nuclear@2
|
173
|
nuclear@1
|
174 // generate the hinges
|
nuclear@1
|
175 Mesh *hinges = new Mesh;
|
nuclear@7
|
176 for(int i=0; i<2; i++) {
|
nuclear@7
|
177 float sign = i * 2 - 1;
|
nuclear@1
|
178
|
nuclear@7
|
179 // barrel
|
nuclear@11
|
180 gen_cylinder(&tmp, HINGE_RAD, HINGE_HEIGHT, 8, 1, 1);
|
nuclear@7
|
181 xform.reset_identity();
|
nuclear@7
|
182 xform.translate(Vector3(0, WALL_HEIGHT - HINGE_RAD * 0.5, sign * VSIZE / 4.0));
|
nuclear@7
|
183 xform.rotate(Vector3(-M_PI / 2.0, 0, 0));
|
nuclear@7
|
184 tmp.apply_xform(xform);
|
nuclear@7
|
185 hinges->append(tmp);
|
nuclear@1
|
186
|
nuclear@7
|
187 // flange
|
nuclear@7
|
188 gen_plane(&tmp, HINGE_HEIGHT * 0.6, HINGE_HEIGHT * 0.8);
|
nuclear@7
|
189 tmp.apply_xform(xform);
|
nuclear@7
|
190
|
nuclear@7
|
191 Matrix4x4 tex_xform;
|
nuclear@7
|
192 tex_xform.set_rotation(Vector3(0, 0, M_PI / 2.0));
|
nuclear@7
|
193 tmp.texcoord_apply_xform(tex_xform);
|
nuclear@7
|
194 hinges->append(tmp);
|
nuclear@7
|
195
|
nuclear@7
|
196 // studs
|
nuclear@7
|
197 for(int j=0; j<4; j++) {
|
nuclear@7
|
198 Vector3 pos;
|
nuclear@7
|
199
|
nuclear@7
|
200 pos.x = (float)((j & 1) * 2 - 1) * HINGE_HEIGHT * 0.2;
|
nuclear@7
|
201 pos.y = (float)((j & 2) - 1) * HINGE_HEIGHT * 0.3;
|
nuclear@7
|
202
|
nuclear@7
|
203 Matrix4x4 stud_xform = xform;
|
nuclear@7
|
204 stud_xform.translate(pos);
|
nuclear@7
|
205
|
nuclear@7
|
206 Matrix4x4 squash;
|
nuclear@7
|
207 squash.set_scaling(Vector3(1, 1, 0.5));
|
nuclear@7
|
208
|
nuclear@7
|
209 gen_sphere(&tmp, HINGE_RAD * 0.5, 8, 4);
|
nuclear@7
|
210 tmp.apply_xform(stud_xform * squash);
|
nuclear@7
|
211 hinges->append(tmp);
|
nuclear@7
|
212 }
|
nuclear@7
|
213 }
|
nuclear@1
|
214
|
nuclear@2
|
215 Object *ohinges = new Object;
|
nuclear@2
|
216 ohinges->set_mesh(hinges);
|
nuclear@7
|
217 ohinges->set_texture(img_hinge.texture());
|
nuclear@2
|
218 obj.push_back(ohinges);
|
nuclear@1
|
219
|
nuclear@6
|
220 // debug object
|
nuclear@7
|
221 /*
|
nuclear@7
|
222 Mesh *dbgmesh = new Mesh;
|
nuclear@6
|
223 gen_box(dbgmesh, 0.5, 0.5, 0.5);
|
nuclear@6
|
224 xform.set_translation(Vector3(0, 0.4, 0));
|
nuclear@7
|
225 xform.set_scaling(Vector3(1, 1, 1));
|
nuclear@6
|
226 dbgmesh->apply_xform(xform);
|
nuclear@6
|
227 Object *dbgobj = new Object;
|
nuclear@6
|
228 dbgobj->set_mesh(dbgmesh);
|
nuclear@7
|
229 dbgobj->set_texture(img_hinge.texture());
|
nuclear@7
|
230 //dbgobj->tex_xform().set_scaling(Vector3(3, 3, 3));
|
nuclear@7
|
231 obj.push_back(dbgobj);
|
nuclear@7
|
232 */
|
nuclear@2
|
233
|
nuclear@11
|
234 Mesh *piece = new Mesh;
|
nuclear@12
|
235 gen_revol(piece, 18, 17, piece_revol, piece_revol_normal, 0);
|
nuclear@11
|
236
|
nuclear@11
|
237 Object *opiece = new Object;
|
nuclear@11
|
238 opiece->set_mesh(piece);
|
nuclear@12
|
239 opiece->mtl.diffuse = Vector3(0.6, 0.6, 0.6);
|
nuclear@12
|
240 opiece->mtl.specular = Vector3(0.8, 0.8, 0.8);
|
nuclear@11
|
241 opiece->xform().set_translation(Vector3(0, 0.2, 0));
|
nuclear@11
|
242 obj.push_back(opiece);
|
nuclear@11
|
243
|
nuclear@11
|
244
|
nuclear@8
|
245 // meshgen stats
|
nuclear@8
|
246 printf("Generated board:\n %u meshes\n", (unsigned int)obj.size());
|
nuclear@8
|
247 unsigned int polycount = 0;
|
nuclear@8
|
248 for(size_t i=0; i<obj.size(); i++) {
|
nuclear@8
|
249 const Mesh *m = obj[i]->get_mesh();
|
nuclear@8
|
250 polycount += m->get_poly_count();
|
nuclear@8
|
251 }
|
nuclear@8
|
252 printf(" %u polygons\n", polycount);
|
nuclear@8
|
253
|
nuclear@1
|
254 return true;
|
nuclear@0
|
255 }
|
nuclear@4
|
256
|
nuclear@5
|
257 static float wood(float x, float y)
|
nuclear@5
|
258 {
|
nuclear@5
|
259 float u = x;
|
nuclear@5
|
260 float v = y;
|
nuclear@5
|
261 x += 1.0;
|
nuclear@5
|
262 x *= 10.0;
|
nuclear@5
|
263 y *= 20.0;
|
nuclear@5
|
264
|
nuclear@5
|
265 float len = sqrt(x * x + y * y) + turbulence2(u * 6.0, v * 12.0, 2) * 1.2 +
|
nuclear@5
|
266 turbulence2(u * 0.5, v, 2) * 15.0;
|
nuclear@5
|
267 float val = fmod(len, 1.0);
|
nuclear@5
|
268
|
nuclear@5
|
269 //val = val * 0.5 + 0.5;
|
nuclear@5
|
270 return val < 0.0 ? 0.0 : (val > 1.0 ? 1.0 : val);
|
nuclear@5
|
271 }
|
nuclear@5
|
272
|
nuclear@6
|
273 static float wood_tile(float x, float y)
|
nuclear@6
|
274 {
|
nuclear@6
|
275 float u = x;
|
nuclear@6
|
276 float v = y;
|
nuclear@6
|
277 x *= 10.0;
|
nuclear@6
|
278 y *= 10.0;
|
nuclear@6
|
279
|
nuclear@6
|
280 float val = x + pnoise2(u * 6.0, v, 6, 1) * 3.0 +
|
nuclear@6
|
281 pturbulence2(u * 4, v * 2, 4, 2, 2) * 1.5 + pturbulence2(u * 8, v * 8, 8, 8, 2) * 0.5;
|
nuclear@6
|
282
|
nuclear@6
|
283 val = fmod(val, 1.0);
|
nuclear@6
|
284 return val < 0.0 ? 0.0 : (val > 1.0 ? 1.0 : val);
|
nuclear@6
|
285 }
|
nuclear@6
|
286
|
nuclear@4
|
287 static bool spike(float x, float y)
|
nuclear@4
|
288 {
|
nuclear@4
|
289 x = fmod(x * 5.0, 1.0);
|
nuclear@4
|
290 return y < (x < 0.5 ? 2.0 * x : 2.0 - 2.0 * x);
|
nuclear@4
|
291 }
|
nuclear@4
|
292
|
nuclear@4
|
293 static bool circle(float x, float y, float rad)
|
nuclear@4
|
294 {
|
nuclear@4
|
295 x = fmod(x * 5.0, 1.0) - 0.5;
|
nuclear@4
|
296 y = (y - 0.65) * 5.0;
|
nuclear@4
|
297 float len = sqrt(x * x + y * y);
|
nuclear@4
|
298 return len < rad;
|
nuclear@4
|
299 }
|
nuclear@4
|
300
|
nuclear@4
|
301 static bool diamond(float x, float y)
|
nuclear@4
|
302 {
|
nuclear@4
|
303 return y >= (1.0 - (x < 0.5 ? 2.0 * x : 2.0 - 2.0 * x)) * 0.3333333 + 0.88;
|
nuclear@4
|
304 }
|
nuclear@4
|
305
|
nuclear@4
|
306 static bool center_circle(float x, float y, float rad)
|
nuclear@4
|
307 {
|
nuclear@4
|
308 x = x - 0.5;
|
nuclear@4
|
309 y = 1.0 - y;
|
nuclear@4
|
310 return sqrt(x * x + y * y) < rad;
|
nuclear@4
|
311 }
|
nuclear@4
|
312
|
nuclear@4
|
313 bool Board::generate_textures()
|
nuclear@4
|
314 {
|
nuclear@6
|
315 // ---- board field texture ----
|
nuclear@5
|
316 static const Vector3 wcol1 = Vector3(0.6, 0.4, 0.2);
|
nuclear@6
|
317 static const Vector3 wcol2 = Vector3(0.53, 0.32, 0.1);
|
nuclear@6
|
318 static const Vector3 wcol3 = Vector3(0.38, 0.25, 0.08);
|
nuclear@5
|
319
|
nuclear@8
|
320 img_field.create(1024, 1024);
|
nuclear@6
|
321 unsigned char *pptr = img_field.pixels;
|
nuclear@6
|
322 for(int i=0; i<img_field.height; i++) {
|
nuclear@6
|
323 float v = (float)i / (float)img_field.height;
|
nuclear@4
|
324
|
nuclear@6
|
325 for(int j=0; j<img_field.width; j++) {
|
nuclear@6
|
326 float u = (float)j / (float)img_field.width;
|
nuclear@4
|
327
|
nuclear@4
|
328 int r = 0, g = 0, b = 0;
|
nuclear@4
|
329
|
nuclear@5
|
330 float wood_val = wood(u, v);
|
nuclear@5
|
331
|
nuclear@5
|
332 // pattern mask
|
nuclear@4
|
333 float x = u;
|
nuclear@4
|
334 float y = v < 0.5 ? v * 2.0 : 2.0 - v * 2.0;
|
nuclear@4
|
335 bool inside = false;
|
nuclear@4
|
336
|
nuclear@4
|
337 inside |= (spike(x, y + 0.33333) && !spike(x, y + 0.4)) ||
|
nuclear@4
|
338 (spike(x, y + 0.5) && !spike(x, y + 0.68));
|
nuclear@4
|
339 inside |= (circle(x, y, 0.12) && !circle(x, y, 0.1)) || circle(x, y, 0.06);
|
nuclear@4
|
340 inside |= (diamond(x, y) && !diamond(x, y - 0.015)) ||
|
nuclear@4
|
341 (diamond(x, y - 0.023) && !diamond(x, y - 0.028));
|
nuclear@4
|
342 inside |= center_circle(x, y, 0.03);
|
nuclear@4
|
343
|
nuclear@5
|
344 Vector3 wood_color = lerp(wcol1, wcol2, wood_val) * 0.9;
|
nuclear@4
|
345 if(inside) {
|
nuclear@5
|
346 wood_color = lerp(wcol1, wcol2, 1.0 - wood_val) * 2.0;
|
nuclear@4
|
347 }
|
nuclear@4
|
348
|
nuclear@5
|
349 r = (int)(wood_color.x * 255.0);
|
nuclear@5
|
350 g = (int)(wood_color.y * 255.0);
|
nuclear@5
|
351 b = (int)(wood_color.z * 255.0);
|
nuclear@5
|
352
|
nuclear@5
|
353 pptr[0] = r > 255 ? 255 : r;
|
nuclear@5
|
354 pptr[1] = g > 255 ? 255 : g;
|
nuclear@5
|
355 pptr[2] = b > 255 ? 255 : b;
|
nuclear@4
|
356 pptr += 3;
|
nuclear@4
|
357 }
|
nuclear@4
|
358 }
|
nuclear@6
|
359 img_field.texture();
|
nuclear@4
|
360
|
nuclear@6
|
361 // ---- generic wood texture ----
|
nuclear@6
|
362 img_wood.create(256, 256);
|
nuclear@6
|
363 pptr = img_wood.pixels;
|
nuclear@6
|
364 for(int i=0; i<img_wood.height; i++) {
|
nuclear@6
|
365 float v = (float)i / (float)img_wood.height;
|
nuclear@6
|
366 for(int j=0; j<img_wood.width; j++) {
|
nuclear@6
|
367 float u = (float)j / (float)img_wood.width;
|
nuclear@6
|
368
|
nuclear@6
|
369 float wood_val = wood_tile(u, v);
|
nuclear@6
|
370 Vector3 wood_color = lerp(wcol2, wcol3, wood_val) * 0.7;
|
nuclear@6
|
371
|
nuclear@6
|
372 int r = (int)(wood_color.x * 255.0);
|
nuclear@6
|
373 int g = (int)(wood_color.y * 255.0);
|
nuclear@6
|
374 int b = (int)(wood_color.z * 255.0);
|
nuclear@6
|
375
|
nuclear@6
|
376 pptr[0] = r > 255 ? 255 : r;
|
nuclear@6
|
377 pptr[1] = g > 255 ? 255 : g;
|
nuclear@6
|
378 pptr[2] = b > 255 ? 255 : b;
|
nuclear@6
|
379 pptr += 3;
|
nuclear@6
|
380 }
|
nuclear@6
|
381 }
|
nuclear@6
|
382 img_wood.texture();
|
nuclear@7
|
383
|
nuclear@7
|
384 // ---- metal hinge diffuse texture ----
|
nuclear@7
|
385 Vector3 rusty_col1 = Vector3(0.43, 0.46, 0.52);
|
nuclear@7
|
386 Vector3 rusty_col2 = Vector3(0.52, 0.47, 0.43);
|
nuclear@7
|
387
|
nuclear@7
|
388 img_hinge.create(128, 128);
|
nuclear@7
|
389 pptr = img_hinge.pixels;
|
nuclear@7
|
390 for(int i=0; i<img_hinge.height; i++) {
|
nuclear@7
|
391 float v = (float)i / (float)img_hinge.height;
|
nuclear@7
|
392 for(int j=0; j<img_hinge.width; j++) {
|
nuclear@7
|
393 float u = (float)j / (float)img_hinge.width;
|
nuclear@7
|
394
|
nuclear@7
|
395 // rust pattern
|
nuclear@7
|
396 float w1 = fbm2(u * 4.0, v * 4.0, 3) * 0.5 + 0.5;
|
nuclear@9
|
397 //float w2 = fbm2(u * 8.0, v * 8.0, 1) * 0.5 + 0.5;
|
nuclear@7
|
398 Vector3 col = lerp(rusty_col1, rusty_col2 * 0.5, w1);
|
nuclear@7
|
399
|
nuclear@7
|
400 // center hinge split
|
nuclear@7
|
401 if(fabs(v - 0.5) < 0.01) {
|
nuclear@7
|
402 col *= 0.5;
|
nuclear@7
|
403 }
|
nuclear@7
|
404
|
nuclear@7
|
405 int r = (int)(col.x * 255.0);
|
nuclear@7
|
406 int g = (int)(col.y * 255.0);
|
nuclear@7
|
407 int b = (int)(col.z * 255.0);
|
nuclear@7
|
408
|
nuclear@7
|
409 pptr[0] = r > 255 ? 255 : (r < 0 ? 0 : r);
|
nuclear@7
|
410 pptr[1] = g > 255 ? 255 : (g < 0 ? 0 : g);
|
nuclear@7
|
411 pptr[2] = b > 255 ? 255 : (b < 0 ? 0 : b);
|
nuclear@7
|
412
|
nuclear@7
|
413 pptr += 3;
|
nuclear@7
|
414 }
|
nuclear@7
|
415 }
|
nuclear@7
|
416 img_hinge.texture();
|
nuclear@7
|
417
|
nuclear@4
|
418 return true;
|
nuclear@4
|
419 }
|