tavli

view src/board.cc @ 9:8a167149985d

unused var
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 26 Jun 2015 05:34:01 +0300
parents 464c45a0bc24
children a8e26f163f99
line source
1 #include "opengl.h"
2 #include "board.h"
3 #include "meshgen.h"
4 #include "pnoise.h"
6 Board::Board()
7 {
8 puck_obj = 0;
9 clear();
10 }
12 Board::~Board()
13 {
14 destroy();
15 }
17 bool Board::init()
18 {
19 if(!generate_textures()) {
20 return false;
21 }
22 if(!generate()) {
23 return false;
24 }
26 return true;
27 }
29 void Board::destroy()
30 {
31 for(size_t i=0; i<obj.size(); i++) {
32 delete obj[i];
33 }
34 obj.clear();
36 delete puck_obj;
37 puck_obj = 0;
38 }
40 void Board::clear()
41 {
42 memset(slots, 0, sizeof slots);
43 }
45 void Board::draw() const
46 {
47 for(size_t i=0; i<obj.size(); i++) {
48 obj[i]->draw();
49 }
50 }
52 #define HSIZE 1.0
53 #define VSIZE (2.0 * HSIZE)
54 #define BOT_THICKNESS (HSIZE * 0.01)
55 #define WALL_THICKNESS (HSIZE * 0.05)
56 #define WALL_HEIGHT (HSIZE * 0.1)
57 #define GAP (HSIZE * 0.025)
58 #define HINGE_RAD (GAP * 0.5)
59 #define HINGE_HEIGHT (VSIZE * 0.075)
61 bool Board::generate()
62 {
63 Mesh tmp;
64 Matrix4x4 xform;
66 obj.clear();
68 for(int i=0; i<2; i++) {
69 int sign = i * 2 - 1;
71 // generate bottom
72 Mesh *bottom = new Mesh;
73 gen_box(bottom, HSIZE, BOT_THICKNESS, HSIZE * 2.0);
74 xform.set_translation(Vector3(0, -BOT_THICKNESS / 2.0, 0));
75 bottom->apply_xform(xform);
77 Object *obottom = new Object;
78 obottom->set_mesh(bottom);
79 obottom->xform().set_translation(Vector3(sign * (HSIZE / 2.0 + WALL_THICKNESS + HINGE_RAD * 0.25), 0, 0));
80 obottom->set_texture(img_field.texture());
81 obj.push_back(obottom);
84 // generate the 4 sides
85 Mesh *sides = new Mesh;
86 gen_box(sides, WALL_THICKNESS, WALL_HEIGHT, VSIZE + WALL_THICKNESS * 2);
87 xform.set_translation(Vector3(-(HSIZE + WALL_THICKNESS) / 2.0,
88 WALL_HEIGHT / 2.0 - BOT_THICKNESS, 0));
89 sides->apply_xform(xform);
91 gen_box(&tmp, WALL_THICKNESS, WALL_HEIGHT, VSIZE + WALL_THICKNESS * 2);
92 xform.set_translation(Vector3((HSIZE + WALL_THICKNESS) / 2.0,
93 WALL_HEIGHT / 2.0 - BOT_THICKNESS, 0));
94 tmp.apply_xform(xform);
95 sides->append(tmp);
96 tmp.clear();
98 gen_box(&tmp, HSIZE, WALL_HEIGHT, WALL_THICKNESS);
99 xform.set_translation(Vector3(0, WALL_HEIGHT / 2.0 - BOT_THICKNESS,
100 (VSIZE + WALL_THICKNESS) / 2.0));
101 tmp.apply_xform(xform);
102 sides->append(tmp);
103 tmp.clear();
105 gen_box(&tmp, HSIZE, WALL_HEIGHT, WALL_THICKNESS);
106 xform.set_translation(Vector3(0, WALL_HEIGHT / 2.0 - BOT_THICKNESS,
107 -(VSIZE + WALL_THICKNESS) / 2.0));
108 tmp.apply_xform(xform);
109 sides->append(tmp);
110 tmp.clear();
112 // generate texture coordinates
113 sides->texcoord_gen_box();
115 Object *osides = new Object;
116 osides->set_mesh(sides);
117 osides->xform() = obottom->xform();
118 osides->set_texture(img_wood.texture());
119 osides->tex_xform().set_scaling(Vector3(2, 2, 2));
120 osides->tex_xform().rotate(-Vector3(1, 0, 0.5), M_PI / 4.0);
121 obj.push_back(osides);
123 }
126 // generate the hinges
127 Mesh *hinges = new Mesh;
128 for(int i=0; i<2; i++) {
129 float sign = i * 2 - 1;
131 // barrel
132 gen_cylinder(&tmp, HINGE_RAD, HINGE_HEIGHT, 10, 1, 1);
133 xform.reset_identity();
134 xform.translate(Vector3(0, WALL_HEIGHT - HINGE_RAD * 0.5, sign * VSIZE / 4.0));
135 xform.rotate(Vector3(-M_PI / 2.0, 0, 0));
136 tmp.apply_xform(xform);
137 hinges->append(tmp);
139 // flange
140 gen_plane(&tmp, HINGE_HEIGHT * 0.6, HINGE_HEIGHT * 0.8);
141 tmp.apply_xform(xform);
143 Matrix4x4 tex_xform;
144 tex_xform.set_rotation(Vector3(0, 0, M_PI / 2.0));
145 tmp.texcoord_apply_xform(tex_xform);
146 hinges->append(tmp);
148 // studs
149 for(int j=0; j<4; j++) {
150 Vector3 pos;
152 pos.x = (float)((j & 1) * 2 - 1) * HINGE_HEIGHT * 0.2;
153 pos.y = (float)((j & 2) - 1) * HINGE_HEIGHT * 0.3;
155 Matrix4x4 stud_xform = xform;
156 stud_xform.translate(pos);
158 Matrix4x4 squash;
159 squash.set_scaling(Vector3(1, 1, 0.5));
161 gen_sphere(&tmp, HINGE_RAD * 0.5, 8, 4);
162 tmp.apply_xform(stud_xform * squash);
163 hinges->append(tmp);
164 }
165 }
167 Object *ohinges = new Object;
168 ohinges->set_mesh(hinges);
169 ohinges->set_texture(img_hinge.texture());
170 obj.push_back(ohinges);
172 // debug object
173 /*
174 Mesh *dbgmesh = new Mesh;
175 gen_box(dbgmesh, 0.5, 0.5, 0.5);
176 xform.set_translation(Vector3(0, 0.4, 0));
177 xform.set_scaling(Vector3(1, 1, 1));
178 dbgmesh->apply_xform(xform);
179 Object *dbgobj = new Object;
180 dbgobj->set_mesh(dbgmesh);
181 dbgobj->set_texture(img_hinge.texture());
182 //dbgobj->tex_xform().set_scaling(Vector3(3, 3, 3));
183 obj.push_back(dbgobj);
184 */
186 // meshgen stats
187 printf("Generated board:\n %u meshes\n", (unsigned int)obj.size());
188 unsigned int polycount = 0;
189 for(size_t i=0; i<obj.size(); i++) {
190 const Mesh *m = obj[i]->get_mesh();
191 polycount += m->get_poly_count();
192 }
193 printf(" %u polygons\n", polycount);
195 return true;
196 }
198 static float wood(float x, float y)
199 {
200 float u = x;
201 float v = y;
202 x += 1.0;
203 x *= 10.0;
204 y *= 20.0;
206 float len = sqrt(x * x + y * y) + turbulence2(u * 6.0, v * 12.0, 2) * 1.2 +
207 turbulence2(u * 0.5, v, 2) * 15.0;
208 float val = fmod(len, 1.0);
210 //val = val * 0.5 + 0.5;
211 return val < 0.0 ? 0.0 : (val > 1.0 ? 1.0 : val);
212 }
214 static float wood_tile(float x, float y)
215 {
216 float u = x;
217 float v = y;
218 x *= 10.0;
219 y *= 10.0;
221 float val = x + pnoise2(u * 6.0, v, 6, 1) * 3.0 +
222 pturbulence2(u * 4, v * 2, 4, 2, 2) * 1.5 + pturbulence2(u * 8, v * 8, 8, 8, 2) * 0.5;
224 val = fmod(val, 1.0);
225 return val < 0.0 ? 0.0 : (val > 1.0 ? 1.0 : val);
226 }
228 static bool spike(float x, float y)
229 {
230 x = fmod(x * 5.0, 1.0);
231 return y < (x < 0.5 ? 2.0 * x : 2.0 - 2.0 * x);
232 }
234 static bool circle(float x, float y, float rad)
235 {
236 x = fmod(x * 5.0, 1.0) - 0.5;
237 y = (y - 0.65) * 5.0;
238 float len = sqrt(x * x + y * y);
239 return len < rad;
240 }
242 static bool diamond(float x, float y)
243 {
244 return y >= (1.0 - (x < 0.5 ? 2.0 * x : 2.0 - 2.0 * x)) * 0.3333333 + 0.88;
245 }
247 static bool center_circle(float x, float y, float rad)
248 {
249 x = x - 0.5;
250 y = 1.0 - y;
251 return sqrt(x * x + y * y) < rad;
252 }
254 bool Board::generate_textures()
255 {
256 // ---- board field texture ----
257 static const Vector3 wcol1 = Vector3(0.6, 0.4, 0.2);
258 static const Vector3 wcol2 = Vector3(0.53, 0.32, 0.1);
259 static const Vector3 wcol3 = Vector3(0.38, 0.25, 0.08);
261 img_field.create(1024, 1024);
262 unsigned char *pptr = img_field.pixels;
263 for(int i=0; i<img_field.height; i++) {
264 float v = (float)i / (float)img_field.height;
266 for(int j=0; j<img_field.width; j++) {
267 float u = (float)j / (float)img_field.width;
269 int r = 0, g = 0, b = 0;
271 float wood_val = wood(u, v);
273 // pattern mask
274 float x = u;
275 float y = v < 0.5 ? v * 2.0 : 2.0 - v * 2.0;
276 bool inside = false;
278 inside |= (spike(x, y + 0.33333) && !spike(x, y + 0.4)) ||
279 (spike(x, y + 0.5) && !spike(x, y + 0.68));
280 inside |= (circle(x, y, 0.12) && !circle(x, y, 0.1)) || circle(x, y, 0.06);
281 inside |= (diamond(x, y) && !diamond(x, y - 0.015)) ||
282 (diamond(x, y - 0.023) && !diamond(x, y - 0.028));
283 inside |= center_circle(x, y, 0.03);
285 Vector3 wood_color = lerp(wcol1, wcol2, wood_val) * 0.9;
286 if(inside) {
287 wood_color = lerp(wcol1, wcol2, 1.0 - wood_val) * 2.0;
288 }
290 r = (int)(wood_color.x * 255.0);
291 g = (int)(wood_color.y * 255.0);
292 b = (int)(wood_color.z * 255.0);
294 pptr[0] = r > 255 ? 255 : r;
295 pptr[1] = g > 255 ? 255 : g;
296 pptr[2] = b > 255 ? 255 : b;
297 pptr += 3;
298 }
299 }
300 img_field.texture();
302 // ---- generic wood texture ----
303 img_wood.create(256, 256);
304 pptr = img_wood.pixels;
305 for(int i=0; i<img_wood.height; i++) {
306 float v = (float)i / (float)img_wood.height;
307 for(int j=0; j<img_wood.width; j++) {
308 float u = (float)j / (float)img_wood.width;
310 float wood_val = wood_tile(u, v);
311 Vector3 wood_color = lerp(wcol2, wcol3, wood_val) * 0.7;
313 int r = (int)(wood_color.x * 255.0);
314 int g = (int)(wood_color.y * 255.0);
315 int b = (int)(wood_color.z * 255.0);
317 pptr[0] = r > 255 ? 255 : r;
318 pptr[1] = g > 255 ? 255 : g;
319 pptr[2] = b > 255 ? 255 : b;
320 pptr += 3;
321 }
322 }
323 img_wood.texture();
325 // ---- metal hinge diffuse texture ----
326 Vector3 rusty_col1 = Vector3(0.43, 0.46, 0.52);
327 Vector3 rusty_col2 = Vector3(0.52, 0.47, 0.43);
329 img_hinge.create(128, 128);
330 pptr = img_hinge.pixels;
331 for(int i=0; i<img_hinge.height; i++) {
332 float v = (float)i / (float)img_hinge.height;
333 for(int j=0; j<img_hinge.width; j++) {
334 float u = (float)j / (float)img_hinge.width;
336 // rust pattern
337 float w1 = fbm2(u * 4.0, v * 4.0, 3) * 0.5 + 0.5;
338 //float w2 = fbm2(u * 8.0, v * 8.0, 1) * 0.5 + 0.5;
339 Vector3 col = lerp(rusty_col1, rusty_col2 * 0.5, w1);
341 // center hinge split
342 if(fabs(v - 0.5) < 0.01) {
343 col *= 0.5;
344 }
346 int r = (int)(col.x * 255.0);
347 int g = (int)(col.y * 255.0);
348 int b = (int)(col.z * 255.0);
350 pptr[0] = r > 255 ? 255 : (r < 0 ? 0 : r);
351 pptr[1] = g > 255 ? 255 : (g < 0 ? 0 : g);
352 pptr[2] = b > 255 ? 255 : (b < 0 ? 0 : b);
354 pptr += 3;
355 }
356 }
357 img_hinge.texture();
359 return true;
360 }