tavli

annotate src/board.cc @ 19:37dead56f01e

fixed shadows
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 29 Jun 2015 06:18:45 +0300
parents 986c0b76513f
children c3fbf9616dbd
rev   line source
nuclear@11 1 #include <float.h>
nuclear@0 2 #include "opengl.h"
nuclear@0 3 #include "board.h"
nuclear@14 4 #include "game.h"
nuclear@1 5 #include "meshgen.h"
nuclear@6 6 #include "pnoise.h"
nuclear@14 7 #include "revol.h"
nuclear@17 8 #include "opt.h"
nuclear@17 9
nuclear@17 10
nuclear@17 11 #define HSIZE 1.0
nuclear@17 12 #define VSIZE (2.0 * HSIZE)
nuclear@17 13 #define BOT_THICKNESS (HSIZE * 0.01)
nuclear@17 14 #define WALL_THICKNESS (HSIZE * 0.05)
nuclear@17 15 #define WALL_HEIGHT (HSIZE * 0.1)
nuclear@17 16 #define GAP (HSIZE * 0.025)
nuclear@17 17 #define HINGE_RAD (GAP * 0.5)
nuclear@17 18 #define HINGE_HEIGHT (VSIZE * 0.075)
nuclear@17 19 #define PIECE_RAD (0.45 * HSIZE / 5.0)
nuclear@17 20 #define BOARD_OFFSET (HSIZE / 2.0 + WALL_THICKNESS + HINGE_RAD * 0.25)
nuclear@17 21 #define PIECES_PER_LAYER 5
nuclear@17 22
nuclear@17 23
nuclear@18 24 static const vec2_t piece_cp[] = {
nuclear@18 25 {0, 0.25},
nuclear@18 26 {1, 0.25}, // mid0
nuclear@18 27 {2, 0.5},
nuclear@18 28 {2.5, 0.5}, // mid1
nuclear@18 29 {3, 0.5},
nuclear@18 30 {4, 0.5}, // mid2
nuclear@18 31 {4, 0},
nuclear@18 32 {4, -0.5}, // mid3
nuclear@18 33 {3, -0.5},
nuclear@18 34 {2.5, -0.5}, // mid4
nuclear@18 35 {0, -0.5}
nuclear@18 36 };
nuclear@18 37 static const BezCurve piece_curve = {
nuclear@18 38 sizeof piece_cp / sizeof *piece_cp,
nuclear@18 39 (vec2_t*)piece_cp,
nuclear@18 40 0.25 * PIECE_RAD
nuclear@18 41 };
nuclear@18 42
nuclear@18 43 #define PIECE_HEIGHT (0.25 * PIECE_RAD)
nuclear@18 44
nuclear@18 45
nuclear@17 46 Piece::Piece()
nuclear@17 47 {
nuclear@17 48 owner = 0;
nuclear@17 49 slot = prev_slot = -1;
nuclear@17 50 level = 0;
nuclear@17 51 move_start = 0;
nuclear@17 52 }
nuclear@17 53
nuclear@17 54 void Piece::move_to(int slot, int level, bool anim)
nuclear@17 55 {
nuclear@17 56 int prev_slot = this->slot;
nuclear@17 57 int prev_level = this->level;
nuclear@17 58
nuclear@17 59 this->slot = slot;
nuclear@17 60 this->level = level;
nuclear@17 61
nuclear@17 62 if(anim) {
nuclear@17 63 this->prev_slot = prev_slot;
nuclear@17 64 this->prev_level = prev_level;
nuclear@17 65 move_start = cur_time;
nuclear@17 66 }
nuclear@17 67 }
nuclear@17 68
nuclear@0 69
nuclear@0 70 Board::Board()
nuclear@0 71 {
nuclear@17 72 piece_obj = 0;
nuclear@0 73 clear();
nuclear@0 74 }
nuclear@0 75
nuclear@0 76 Board::~Board()
nuclear@0 77 {
nuclear@0 78 destroy();
nuclear@0 79 }
nuclear@0 80
nuclear@0 81 bool Board::init()
nuclear@0 82 {
nuclear@4 83 if(!generate_textures()) {
nuclear@4 84 return false;
nuclear@4 85 }
nuclear@1 86 if(!generate()) {
nuclear@0 87 return false;
nuclear@0 88 }
nuclear@1 89
nuclear@0 90 return true;
nuclear@0 91 }
nuclear@0 92
nuclear@0 93 void Board::destroy()
nuclear@0 94 {
nuclear@2 95 for(size_t i=0; i<obj.size(); i++) {
nuclear@2 96 delete obj[i];
nuclear@1 97 }
nuclear@2 98 obj.clear();
nuclear@1 99
nuclear@17 100 delete piece_obj;
nuclear@17 101 piece_obj = 0;
nuclear@0 102 }
nuclear@0 103
nuclear@0 104 void Board::clear()
nuclear@0 105 {
nuclear@17 106 memset(hist, 0, sizeof hist);
nuclear@17 107
nuclear@17 108 for(int i=0; i<MAX_PIECES; i++) {
nuclear@17 109 pieces[i].owner = i < PLAYER_PIECES ? MINE : OTHER;
nuclear@17 110 move_piece(i, -1, false);
nuclear@17 111 }
nuclear@17 112 }
nuclear@17 113
nuclear@17 114 void Board::setup()
nuclear@17 115 {
nuclear@17 116 static const int initial[] = { 0, 0, 0, 0, 5, 0, 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
nuclear@17 117
nuclear@17 118 clear();
nuclear@17 119
nuclear@17 120 int id = 0;
nuclear@17 121 for(int i=0; i<NUM_SLOTS; i++) {
nuclear@17 122 for(int j=0; j<initial[i]; j++) {
nuclear@17 123 move_piece(id, i, false);
nuclear@17 124 move_piece(PLAYER_PIECES + id, NUM_SLOTS - i - 1, false);
nuclear@17 125 ++id;
nuclear@17 126 }
nuclear@17 127 }
nuclear@17 128 }
nuclear@17 129
nuclear@17 130 int Board::slot_pieces(int slot) const
nuclear@17 131 {
nuclear@17 132 return hist[slot + 1];
nuclear@17 133 }
nuclear@17 134
nuclear@17 135 bool Board::move_piece(int id, int slot, bool anim)
nuclear@17 136 {
nuclear@17 137 // TODO do validity checking first
nuclear@17 138 int prev_slot = pieces[id].slot;
nuclear@17 139
nuclear@17 140 pieces[id].move_to(slot, slot_pieces(slot), anim);
nuclear@17 141 --hist[prev_slot + 1];
nuclear@17 142 ++hist[slot + 1];
nuclear@17 143 return true;
nuclear@17 144 }
nuclear@17 145
nuclear@17 146 Vector3 Board::piece_pos(int slot, int level) const
nuclear@17 147 {
nuclear@17 148 int top_side = slot / 10;
nuclear@17 149 int sidx = (top_side ? (19 - slot) : slot) % 5;
nuclear@17 150 int left_side = (top_side ? (19 - slot) : slot) / 5;
nuclear@17 151
nuclear@17 152 Vector3 pos;
nuclear@17 153
nuclear@17 154 if(left_side) {
nuclear@17 155 pos.x = -(sidx * HSIZE / 5.0 + BOARD_OFFSET - HSIZE / 2.0) - PIECE_RAD;
nuclear@17 156 } else {
nuclear@17 157 pos.x = (4 - sidx) * HSIZE / 5.0 + BOARD_OFFSET - HSIZE / 2.0 + PIECE_RAD;
nuclear@17 158 }
nuclear@17 159
nuclear@17 160 int layer = level / PIECES_PER_LAYER;
nuclear@17 161 int layer_level = level % PIECES_PER_LAYER;
nuclear@17 162
nuclear@18 163 pos.y = (layer + 0.5) * PIECE_HEIGHT;
nuclear@17 164
nuclear@17 165 pos.z = (-VSIZE * 0.5 + PIECE_RAD + PIECE_RAD * 2.0 * layer_level);
nuclear@17 166 if(top_side) {
nuclear@17 167 pos.z = -pos.z;
nuclear@17 168 }
nuclear@17 169
nuclear@17 170 return pos;
nuclear@0 171 }
nuclear@0 172
nuclear@0 173 void Board::draw() const
nuclear@0 174 {
nuclear@19 175 bool use_shadows = opt.shadows && sdr_shadow;
nuclear@19 176 unsigned int board_sdr = use_shadows ? sdr_shadow : sdr_phong;
nuclear@19 177 unsigned int piece_sdr = use_shadows ? sdr_shadow_notex : sdr_phong_notex;
nuclear@19 178
nuclear@2 179 for(size_t i=0; i<obj.size(); i++) {
nuclear@14 180 if(wireframe) {
nuclear@14 181 obj[i]->draw_wire();
nuclear@14 182 obj[i]->draw_normals(0.075);
nuclear@14 183 } else {
nuclear@19 184 obj[i]->set_shader(board_sdr);
nuclear@14 185 obj[i]->draw();
nuclear@14 186 }
nuclear@1 187 }
nuclear@17 188
nuclear@17 189 for(int i=0; i<MAX_PIECES; i++) {
nuclear@17 190 Vector3 pos = piece_pos(pieces[i].slot, pieces[i].level);
nuclear@17 191 piece_obj->xform().set_translation(pos);
nuclear@17 192 piece_obj->mtl.diffuse = opt.piece_color[pieces[i].owner];
nuclear@19 193 piece_obj->set_shader(piece_sdr);
nuclear@17 194 piece_obj->draw();
nuclear@17 195 }
nuclear@0 196 }
nuclear@0 197
nuclear@13 198
nuclear@1 199 bool Board::generate()
nuclear@0 200 {
nuclear@18 201 static const float board_spec = 0.4;
nuclear@18 202
nuclear@4 203 Mesh tmp;
nuclear@1 204 Matrix4x4 xform;
nuclear@1 205
nuclear@2 206 obj.clear();
nuclear@2 207
nuclear@4 208 for(int i=0; i<2; i++) {
nuclear@4 209 int sign = i * 2 - 1;
nuclear@1 210
nuclear@4 211 // generate bottom
nuclear@4 212 Mesh *bottom = new Mesh;
nuclear@4 213 gen_box(bottom, HSIZE, BOT_THICKNESS, HSIZE * 2.0);
nuclear@4 214 xform.set_translation(Vector3(0, -BOT_THICKNESS / 2.0, 0));
nuclear@4 215 bottom->apply_xform(xform);
nuclear@2 216
nuclear@4 217 Object *obottom = new Object;
nuclear@4 218 obottom->set_mesh(bottom);
nuclear@17 219 obottom->xform().set_translation(Vector3(sign * BOARD_OFFSET, 0, 0));
nuclear@4 220 obottom->set_texture(img_field.texture());
nuclear@18 221 obottom->mtl.specular = Vector3(board_spec, board_spec, board_spec);
nuclear@4 222 obj.push_back(obottom);
nuclear@2 223
nuclear@1 224
nuclear@4 225 // generate the 4 sides
nuclear@4 226 Mesh *sides = new Mesh;
nuclear@4 227 gen_box(sides, WALL_THICKNESS, WALL_HEIGHT, VSIZE + WALL_THICKNESS * 2);
nuclear@4 228 xform.set_translation(Vector3(-(HSIZE + WALL_THICKNESS) / 2.0,
nuclear@4 229 WALL_HEIGHT / 2.0 - BOT_THICKNESS, 0));
nuclear@4 230 sides->apply_xform(xform);
nuclear@1 231
nuclear@4 232 gen_box(&tmp, WALL_THICKNESS, WALL_HEIGHT, VSIZE + WALL_THICKNESS * 2);
nuclear@4 233 xform.set_translation(Vector3((HSIZE + WALL_THICKNESS) / 2.0,
nuclear@4 234 WALL_HEIGHT / 2.0 - BOT_THICKNESS, 0));
nuclear@4 235 tmp.apply_xform(xform);
nuclear@4 236 sides->append(tmp);
nuclear@4 237 tmp.clear();
nuclear@1 238
nuclear@4 239 gen_box(&tmp, HSIZE, WALL_HEIGHT, WALL_THICKNESS);
nuclear@4 240 xform.set_translation(Vector3(0, WALL_HEIGHT / 2.0 - BOT_THICKNESS,
nuclear@4 241 (VSIZE + WALL_THICKNESS) / 2.0));
nuclear@4 242 tmp.apply_xform(xform);
nuclear@4 243 sides->append(tmp);
nuclear@4 244 tmp.clear();
nuclear@1 245
nuclear@4 246 gen_box(&tmp, HSIZE, WALL_HEIGHT, WALL_THICKNESS);
nuclear@4 247 xform.set_translation(Vector3(0, WALL_HEIGHT / 2.0 - BOT_THICKNESS,
nuclear@4 248 -(VSIZE + WALL_THICKNESS) / 2.0));
nuclear@4 249 tmp.apply_xform(xform);
nuclear@4 250 sides->append(tmp);
nuclear@4 251 tmp.clear();
nuclear@4 252
nuclear@6 253 // generate texture coordinates
nuclear@6 254 sides->texcoord_gen_box();
nuclear@6 255
nuclear@4 256 Object *osides = new Object;
nuclear@4 257 osides->set_mesh(sides);
nuclear@4 258 osides->xform() = obottom->xform();
nuclear@6 259 osides->set_texture(img_wood.texture());
nuclear@6 260 osides->tex_xform().set_scaling(Vector3(2, 2, 2));
nuclear@6 261 osides->tex_xform().rotate(-Vector3(1, 0, 0.5), M_PI / 4.0);
nuclear@18 262 osides->mtl.specular = Vector3(board_spec, board_spec, board_spec);
nuclear@4 263 obj.push_back(osides);
nuclear@4 264
nuclear@4 265 }
nuclear@2 266
nuclear@2 267
nuclear@1 268 // generate the hinges
nuclear@1 269 Mesh *hinges = new Mesh;
nuclear@7 270 for(int i=0; i<2; i++) {
nuclear@7 271 float sign = i * 2 - 1;
nuclear@1 272
nuclear@7 273 // barrel
nuclear@11 274 gen_cylinder(&tmp, HINGE_RAD, HINGE_HEIGHT, 8, 1, 1);
nuclear@7 275 xform.reset_identity();
nuclear@7 276 xform.translate(Vector3(0, WALL_HEIGHT - HINGE_RAD * 0.5, sign * VSIZE / 4.0));
nuclear@7 277 xform.rotate(Vector3(-M_PI / 2.0, 0, 0));
nuclear@7 278 tmp.apply_xform(xform);
nuclear@7 279 hinges->append(tmp);
nuclear@1 280
nuclear@7 281 // flange
nuclear@7 282 gen_plane(&tmp, HINGE_HEIGHT * 0.6, HINGE_HEIGHT * 0.8);
nuclear@7 283 tmp.apply_xform(xform);
nuclear@7 284
nuclear@7 285 Matrix4x4 tex_xform;
nuclear@7 286 tex_xform.set_rotation(Vector3(0, 0, M_PI / 2.0));
nuclear@7 287 tmp.texcoord_apply_xform(tex_xform);
nuclear@7 288 hinges->append(tmp);
nuclear@7 289
nuclear@7 290 // studs
nuclear@7 291 for(int j=0; j<4; j++) {
nuclear@7 292 Vector3 pos;
nuclear@7 293
nuclear@7 294 pos.x = (float)((j & 1) * 2 - 1) * HINGE_HEIGHT * 0.2;
nuclear@7 295 pos.y = (float)((j & 2) - 1) * HINGE_HEIGHT * 0.3;
nuclear@7 296
nuclear@7 297 Matrix4x4 stud_xform = xform;
nuclear@7 298 stud_xform.translate(pos);
nuclear@7 299
nuclear@7 300 Matrix4x4 squash;
nuclear@7 301 squash.set_scaling(Vector3(1, 1, 0.5));
nuclear@7 302
nuclear@7 303 gen_sphere(&tmp, HINGE_RAD * 0.5, 8, 4);
nuclear@7 304 tmp.apply_xform(stud_xform * squash);
nuclear@7 305 hinges->append(tmp);
nuclear@7 306 }
nuclear@7 307 }
nuclear@1 308
nuclear@2 309 Object *ohinges = new Object;
nuclear@2 310 ohinges->set_mesh(hinges);
nuclear@7 311 ohinges->set_texture(img_hinge.texture());
nuclear@2 312 obj.push_back(ohinges);
nuclear@1 313
nuclear@6 314 // debug object
nuclear@7 315 /*
nuclear@7 316 Mesh *dbgmesh = new Mesh;
nuclear@6 317 gen_box(dbgmesh, 0.5, 0.5, 0.5);
nuclear@6 318 xform.set_translation(Vector3(0, 0.4, 0));
nuclear@7 319 xform.set_scaling(Vector3(1, 1, 1));
nuclear@6 320 dbgmesh->apply_xform(xform);
nuclear@6 321 Object *dbgobj = new Object;
nuclear@6 322 dbgobj->set_mesh(dbgmesh);
nuclear@7 323 dbgobj->set_texture(img_hinge.texture());
nuclear@7 324 //dbgobj->tex_xform().set_scaling(Vector3(3, 3, 3));
nuclear@7 325 obj.push_back(dbgobj);
nuclear@7 326 */
nuclear@2 327
nuclear@11 328 Mesh *piece = new Mesh;
nuclear@14 329 gen_revol(piece, 18, 17, bezier_revol, bezier_revol_normal, (void*)&piece_curve);
nuclear@11 330
nuclear@11 331 Object *opiece = new Object;
nuclear@11 332 opiece->set_mesh(piece);
nuclear@12 333 opiece->mtl.diffuse = Vector3(0.6, 0.6, 0.6);
nuclear@12 334 opiece->mtl.specular = Vector3(0.8, 0.8, 0.8);
nuclear@11 335 opiece->xform().set_translation(Vector3(0, 0.2, 0));
nuclear@17 336 //obj.push_back(opiece);
nuclear@17 337
nuclear@17 338 piece_obj = opiece;
nuclear@11 339
nuclear@8 340 // meshgen stats
nuclear@8 341 printf("Generated board:\n %u meshes\n", (unsigned int)obj.size());
nuclear@8 342 unsigned int polycount = 0;
nuclear@8 343 for(size_t i=0; i<obj.size(); i++) {
nuclear@8 344 const Mesh *m = obj[i]->get_mesh();
nuclear@8 345 polycount += m->get_poly_count();
nuclear@8 346 }
nuclear@8 347 printf(" %u polygons\n", polycount);
nuclear@8 348
nuclear@1 349 return true;
nuclear@0 350 }
nuclear@4 351
nuclear@5 352 static float wood(float x, float y)
nuclear@5 353 {
nuclear@5 354 float u = x;
nuclear@5 355 float v = y;
nuclear@5 356 x += 1.0;
nuclear@5 357 x *= 10.0;
nuclear@5 358 y *= 20.0;
nuclear@5 359
nuclear@5 360 float len = sqrt(x * x + y * y) + turbulence2(u * 6.0, v * 12.0, 2) * 1.2 +
nuclear@5 361 turbulence2(u * 0.5, v, 2) * 15.0;
nuclear@5 362 float val = fmod(len, 1.0);
nuclear@5 363
nuclear@5 364 //val = val * 0.5 + 0.5;
nuclear@5 365 return val < 0.0 ? 0.0 : (val > 1.0 ? 1.0 : val);
nuclear@5 366 }
nuclear@5 367
nuclear@6 368 static float wood_tile(float x, float y)
nuclear@6 369 {
nuclear@6 370 float u = x;
nuclear@6 371 float v = y;
nuclear@6 372 x *= 10.0;
nuclear@6 373 y *= 10.0;
nuclear@6 374
nuclear@6 375 float val = x + pnoise2(u * 6.0, v, 6, 1) * 3.0 +
nuclear@6 376 pturbulence2(u * 4, v * 2, 4, 2, 2) * 1.5 + pturbulence2(u * 8, v * 8, 8, 8, 2) * 0.5;
nuclear@6 377
nuclear@6 378 val = fmod(val, 1.0);
nuclear@6 379 return val < 0.0 ? 0.0 : (val > 1.0 ? 1.0 : val);
nuclear@6 380 }
nuclear@6 381
nuclear@4 382 static bool spike(float x, float y)
nuclear@4 383 {
nuclear@4 384 x = fmod(x * 5.0, 1.0);
nuclear@4 385 return y < (x < 0.5 ? 2.0 * x : 2.0 - 2.0 * x);
nuclear@4 386 }
nuclear@4 387
nuclear@4 388 static bool circle(float x, float y, float rad)
nuclear@4 389 {
nuclear@4 390 x = fmod(x * 5.0, 1.0) - 0.5;
nuclear@4 391 y = (y - 0.65) * 5.0;
nuclear@4 392 float len = sqrt(x * x + y * y);
nuclear@4 393 return len < rad;
nuclear@4 394 }
nuclear@4 395
nuclear@4 396 static bool diamond(float x, float y)
nuclear@4 397 {
nuclear@4 398 return y >= (1.0 - (x < 0.5 ? 2.0 * x : 2.0 - 2.0 * x)) * 0.3333333 + 0.88;
nuclear@4 399 }
nuclear@4 400
nuclear@4 401 static bool center_circle(float x, float y, float rad)
nuclear@4 402 {
nuclear@4 403 x = x - 0.5;
nuclear@4 404 y = 1.0 - y;
nuclear@4 405 return sqrt(x * x + y * y) < rad;
nuclear@4 406 }
nuclear@4 407
nuclear@4 408 bool Board::generate_textures()
nuclear@4 409 {
nuclear@6 410 // ---- board field texture ----
nuclear@5 411 static const Vector3 wcol1 = Vector3(0.6, 0.4, 0.2);
nuclear@6 412 static const Vector3 wcol2 = Vector3(0.53, 0.32, 0.1);
nuclear@6 413 static const Vector3 wcol3 = Vector3(0.38, 0.25, 0.08);
nuclear@5 414
nuclear@8 415 img_field.create(1024, 1024);
nuclear@6 416 unsigned char *pptr = img_field.pixels;
nuclear@6 417 for(int i=0; i<img_field.height; i++) {
nuclear@6 418 float v = (float)i / (float)img_field.height;
nuclear@4 419
nuclear@6 420 for(int j=0; j<img_field.width; j++) {
nuclear@6 421 float u = (float)j / (float)img_field.width;
nuclear@4 422
nuclear@4 423 int r = 0, g = 0, b = 0;
nuclear@4 424
nuclear@5 425 float wood_val = wood(u, v);
nuclear@5 426
nuclear@5 427 // pattern mask
nuclear@4 428 float x = u;
nuclear@4 429 float y = v < 0.5 ? v * 2.0 : 2.0 - v * 2.0;
nuclear@4 430 bool inside = false;
nuclear@4 431
nuclear@4 432 inside |= (spike(x, y + 0.33333) && !spike(x, y + 0.4)) ||
nuclear@4 433 (spike(x, y + 0.5) && !spike(x, y + 0.68));
nuclear@4 434 inside |= (circle(x, y, 0.12) && !circle(x, y, 0.1)) || circle(x, y, 0.06);
nuclear@4 435 inside |= (diamond(x, y) && !diamond(x, y - 0.015)) ||
nuclear@4 436 (diamond(x, y - 0.023) && !diamond(x, y - 0.028));
nuclear@4 437 inside |= center_circle(x, y, 0.03);
nuclear@4 438
nuclear@5 439 Vector3 wood_color = lerp(wcol1, wcol2, wood_val) * 0.9;
nuclear@4 440 if(inside) {
nuclear@5 441 wood_color = lerp(wcol1, wcol2, 1.0 - wood_val) * 2.0;
nuclear@4 442 }
nuclear@4 443
nuclear@5 444 r = (int)(wood_color.x * 255.0);
nuclear@5 445 g = (int)(wood_color.y * 255.0);
nuclear@5 446 b = (int)(wood_color.z * 255.0);
nuclear@5 447
nuclear@5 448 pptr[0] = r > 255 ? 255 : r;
nuclear@5 449 pptr[1] = g > 255 ? 255 : g;
nuclear@5 450 pptr[2] = b > 255 ? 255 : b;
nuclear@4 451 pptr += 3;
nuclear@4 452 }
nuclear@4 453 }
nuclear@6 454 img_field.texture();
nuclear@4 455
nuclear@6 456 // ---- generic wood texture ----
nuclear@6 457 img_wood.create(256, 256);
nuclear@6 458 pptr = img_wood.pixels;
nuclear@6 459 for(int i=0; i<img_wood.height; i++) {
nuclear@6 460 float v = (float)i / (float)img_wood.height;
nuclear@6 461 for(int j=0; j<img_wood.width; j++) {
nuclear@6 462 float u = (float)j / (float)img_wood.width;
nuclear@6 463
nuclear@6 464 float wood_val = wood_tile(u, v);
nuclear@6 465 Vector3 wood_color = lerp(wcol2, wcol3, wood_val) * 0.7;
nuclear@6 466
nuclear@6 467 int r = (int)(wood_color.x * 255.0);
nuclear@6 468 int g = (int)(wood_color.y * 255.0);
nuclear@6 469 int b = (int)(wood_color.z * 255.0);
nuclear@6 470
nuclear@6 471 pptr[0] = r > 255 ? 255 : r;
nuclear@6 472 pptr[1] = g > 255 ? 255 : g;
nuclear@6 473 pptr[2] = b > 255 ? 255 : b;
nuclear@6 474 pptr += 3;
nuclear@6 475 }
nuclear@6 476 }
nuclear@6 477 img_wood.texture();
nuclear@7 478
nuclear@7 479 // ---- metal hinge diffuse texture ----
nuclear@7 480 Vector3 rusty_col1 = Vector3(0.43, 0.46, 0.52);
nuclear@7 481 Vector3 rusty_col2 = Vector3(0.52, 0.47, 0.43);
nuclear@7 482
nuclear@7 483 img_hinge.create(128, 128);
nuclear@7 484 pptr = img_hinge.pixels;
nuclear@7 485 for(int i=0; i<img_hinge.height; i++) {
nuclear@7 486 float v = (float)i / (float)img_hinge.height;
nuclear@7 487 for(int j=0; j<img_hinge.width; j++) {
nuclear@7 488 float u = (float)j / (float)img_hinge.width;
nuclear@7 489
nuclear@7 490 // rust pattern
nuclear@7 491 float w1 = fbm2(u * 4.0, v * 4.0, 3) * 0.5 + 0.5;
nuclear@9 492 //float w2 = fbm2(u * 8.0, v * 8.0, 1) * 0.5 + 0.5;
nuclear@7 493 Vector3 col = lerp(rusty_col1, rusty_col2 * 0.5, w1);
nuclear@7 494
nuclear@7 495 // center hinge split
nuclear@7 496 if(fabs(v - 0.5) < 0.01) {
nuclear@7 497 col *= 0.5;
nuclear@7 498 }
nuclear@7 499
nuclear@7 500 int r = (int)(col.x * 255.0);
nuclear@7 501 int g = (int)(col.y * 255.0);
nuclear@7 502 int b = (int)(col.z * 255.0);
nuclear@7 503
nuclear@7 504 pptr[0] = r > 255 ? 255 : (r < 0 ? 0 : r);
nuclear@7 505 pptr[1] = g > 255 ? 255 : (g < 0 ? 0 : g);
nuclear@7 506 pptr[2] = b > 255 ? 255 : (b < 0 ? 0 : b);
nuclear@7 507
nuclear@7 508 pptr += 3;
nuclear@7 509 }
nuclear@7 510 }
nuclear@7 511 img_hinge.texture();
nuclear@7 512
nuclear@4 513 return true;
nuclear@4 514 }