1#include <VG/openvg.h> 2#include <VG/vgu.h> 3#include <math.h> 4#include <string.h> 5 6#include "eglut.h" 7 8#define ELEMENTS(x) (sizeof(x)/sizeof((x)[0])) 9 10struct object { 11 VGPath path; 12 VGPaint fill; 13 VGPaint stroke; 14 VGint draw_mode; 15 VGfloat matrix[9]; 16 VGfloat stroke_width; 17}; 18 19struct character { 20 struct object objects[32]; 21 VGint num_objects; 22}; 23VGfloat identity_matrix[] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; 24 25struct character cartman; 26 27static void add_object_fill(const VGubyte *segments, VGint num_segments, 28 const VGfloat *coords, 29 VGuint color) 30{ 31 struct object object; 32 33 object.path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 34 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); 35 vgAppendPathData(object.path, num_segments, segments, coords); 36 37 object.fill = vgCreatePaint(); 38 vgSetColor(object.fill, color); 39 memcpy(object.matrix, identity_matrix, 9 * sizeof(VGfloat)); 40 object.draw_mode = VG_FILL_PATH; 41 42 cartman.objects[cartman.num_objects] = object; 43 ++cartman.num_objects; 44} 45 46 47static void add_object_stroke(const VGubyte *segments, VGint num_segments, 48 const VGfloat *coords, 49 VGuint color, VGfloat width) 50{ 51 struct object object; 52 53 object.path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 54 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); 55 vgAppendPathData(object.path, num_segments, segments, coords); 56 57 object.stroke = vgCreatePaint(); 58 vgSetColor(object.stroke, color); 59 memcpy(object.matrix, identity_matrix, 9 * sizeof(VGfloat)); 60 object.draw_mode = VG_STROKE_PATH; 61 object.stroke_width = width; 62 63 cartman.objects[cartman.num_objects] = object; 64 ++cartman.num_objects; 65} 66 67 68static void add_object_fillm(const VGubyte *segments, VGint num_segments, 69 const VGfloat *coords, 70 VGuint color, 71 VGfloat *matrix) 72{ 73 struct object object; 74 75 object.path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 76 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); 77 vgAppendPathData(object.path, num_segments, segments, coords); 78 79 object.fill = vgCreatePaint(); 80 vgSetColor(object.fill, color); 81 memcpy(object.matrix, matrix, 9 * sizeof(VGfloat)); 82 object.draw_mode = VG_FILL_PATH; 83 84 cartman.objects[cartman.num_objects] = object; 85 ++cartman.num_objects; 86} 87 88 89static void add_object_m(const VGubyte *segments, VGint num_segments, 90 const VGfloat *coords, 91 VGuint fill_color, 92 VGuint stroke_color, VGfloat stroke_width, 93 VGfloat *matrix) 94{ 95 struct object object; 96 97 object.path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 98 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); 99 vgAppendPathData(object.path, num_segments, segments, coords); 100 memcpy(object.matrix, matrix, 9 * sizeof(VGfloat)); 101 102 object.fill = vgCreatePaint(); 103 vgSetColor(object.fill, fill_color); 104 object.draw_mode = VG_FILL_PATH | VG_STROKE_PATH; 105 106 object.stroke = vgCreatePaint(); 107 vgSetColor(object.stroke, stroke_color); 108 object.stroke_width = stroke_width; 109 110 cartman.objects[cartman.num_objects] = object; 111 ++cartman.num_objects; 112} 113 114static void init_character() 115{ 116 { 117 const VGubyte segments[] = {VG_MOVE_TO_ABS, 118 VG_CUBIC_TO_ABS, 119 VG_CUBIC_TO_ABS, 120 VG_CUBIC_TO_ABS, 121 VG_CUBIC_TO_ABS, 122 VG_CLOSE_PATH}; 123 const VGfloat coords[] = {181.83267, 102.60408, 124 181.83267,102.60408, 185.53793,114.5749, 186.5355,115.00243, 125 187.53306,115.42996, 286.0073,115.00243, 286.0073,115.00243, 126 286.0073,115.00243, 292.70526,103.45914, 290.85263,101.03648, 127 289.00001,98.61381, 181.54765,102.31906, 181.83267,102.60408 128 }; 129 VGuint color = 0x7c4e32ff; 130 add_object_fill(segments, ELEMENTS(segments), 131 coords, color); 132 } 133 { 134 const VGubyte segments[] = { 135 VG_MOVE_TO_ABS, 136 VG_CUBIC_TO_ABS, 137 VG_CUBIC_TO_ABS, 138 VG_LINE_TO_ABS, 139 VG_CUBIC_TO_ABS, 140 VG_CUBIC_TO_ABS, 141 VG_CUBIC_TO_ABS, 142 VG_CUBIC_TO_ABS, 143 VG_CUBIC_TO_ABS, 144 VG_CUBIC_TO_ABS, 145 VG_CLOSE_PATH 146 }; 147 const VGfloat coords[] = {188.62208,50.604156, 148 188.62208,50.604156, 176.73127,60.479579, 170.68509,69.548844, 149 164.63892,78.618109, 175.11895,79.827344, 175.11895,79.827344, 150 176.52973,98.368952, 151 176.52973,98.368952, 189.83131,110.05823, 208.97754,110.25976, 152 228.12377,110.46131, 244.24691,111.67054, 247.06846,110.25976, 153 249.89,108.849, 258.95927,106.8336, 260.16851,105.01975, 154 261.37774,103.2059, 296.84865,106.43053, 297.05019,91.919698, 155 297.25172,77.408874, 306.11945,64.308824, 282.13628,51.611853, 156 258.15311,38.914882, 189.2267,49.999539, 188.62208,50.604156 157 }; 158 159 VGuint color = 0xe30000ff; 160 add_object_fill(segments, ELEMENTS(segments), 161 coords, color); 162 } 163 { 164 const VGubyte segments[] = { 165 VG_MOVE_TO_ABS, 166 VG_CUBIC_TO_ABS, 167 VG_CUBIC_TO_ABS, 168 VG_CUBIC_TO_ABS, 169 VG_CUBIC_TO_ABS, 170 VG_CLOSE_PATH 171 }; 172 const VGfloat coords[] = { 173 68.25, 78.875, 174 68.25,93.296, 54.642,105, 37.875,105, 175 21.108,105, 7.5,93.296, 7.5,78.875, 176 7.5,64.454, 21.108,52.75, 37.875,52.75, 177 54.642,52.75, 68.25,64.454, 68.25,78.875 178 }; 179 180 VGuint color = 0xffe1c4ff; 181 VGfloat matrix[] = { 182 1.6529, 0, 0, 183 0, 1.582037, 0, 184 172.9649,-90.0116, 1 185 }; 186 add_object_fillm(segments, ELEMENTS(segments), 187 coords, color, matrix); 188 } 189 { 190 const VGubyte segments[] = { 191 VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, 192 VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CLOSE_PATH 193 }; 194 const VGfloat coords[] = { 195 170.14687,71.536958, 196 173.53626,68.814326, 176.70232,68.971782, 180.55009,71.679467, 197 184.39785,74.387153, 199.19294,80.036105, 191.52334,86.500482, 198 189.02942,88.6025, 183.97032,85.787933, 180.26507,86.928011, 199 178.8737,87.356121, 174.71827,89.783259, 171.8028,87.494856, 200 166.95426,83.689139, 163.51779,76.861986, 170.14687,71.536958 201 }; 202 203 VGuint color = 0xfff200ff; 204 add_object_fill(segments, ELEMENTS(segments), 205 coords, color); 206 } 207 { 208 const VGubyte segments[] = { 209 VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, 210 VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, 211 VG_CUBIC_TO_ABS, VG_CLOSE_PATH 212 }; 213 const VGfloat coords[] = { 214 299.83075,66.834136, 215 299.83075,66.834136, 287.85993,64.69649, 284.15467,72.962055, 216 280.44942,81.227621, 280.1644,78.234916, 280.1644,79.374994, 217 280.1644,80.515072, 278.16927,84.077816, 284.86722,83.792796, 218 291.56518,83.507777, 291.99271,86.785501, 294.84291,86.642991, 219 297.6931,86.500482, 303.536,85.645423, 303.67851,80.657582, 220 303.82102,75.66974, 302.68094,65.551548, 299.83075,66.834136 221 }; 222 223 VGuint color = 0xfff200ff; 224 add_object_fill(segments, ELEMENTS(segments), 225 coords, color); 226 } 227 { 228 const VGubyte segments[] = { 229 VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS 230 }; 231 const VGfloat coords[] = { 232 240.83171,75.81225, 233 240.83171,75.81225, 241.54426,88.495618, 242.25681,91.488323, 234 242.96936,94.481028, 240.6892,108.01945, 240.83171,110.01459, 235 240.97422,112.00973, 240.97422,111.01216, 240.97422,111.01216 236 }; 237 VGuint color = 0x000000ff; 238 VGfloat swidth = 1.14007807; 239 add_object_stroke(segments, ELEMENTS(segments), coords, color, swidth); 240 } 241 { 242 const VGubyte segments[] = { 243 VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, 244 VG_CUBIC_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS, VG_CLOSE_PATH 245 }; 246 const VGfloat coords[] = { 247 83.375, 95.5, 248 83.375,96.121, 83.067,96.625, 82.6875,96.625, 249 82.308,96.625, 82,96.121, 82,95.5, 250 82,94.879, 82.308,94.375, 82.6875,94.375, 251 83.066677,94.375, 83.374492,94.878024, 83.374999,95.498494, 252 82.6875,95.5, 253 83.375,95.5 254 }; 255 VGuint fill_color = 0x000000ff; 256 VGuint stroke_color = 0x000000ff; 257 VGfloat swidth = 0.60000002; 258 VGfloat matrix1[] = { 259 1.140078, 0, 0, 260 0, 1.140078, 0, 261 145.4927, -15.10897, 1 262 }; 263 VGfloat matrix2[] = { 264 1.140078,0, 0, 265 0,1.140078, 0, 266 144.2814,-27.93485, 1 267 }; 268 VGfloat matrix3[] = { 269 1.140078,0, 0, 270 0,1.140078, 0, 271 144.1388,-3.70819, 1 272 }; 273 add_object_m(segments, ELEMENTS(segments), coords, 274 fill_color, stroke_color, swidth, matrix1); 275 add_object_m(segments, ELEMENTS(segments), coords, 276 fill_color, stroke_color, swidth, matrix2); 277 add_object_m(segments, ELEMENTS(segments), coords, 278 fill_color, stroke_color, swidth, matrix3); 279 } 280 { 281 const VGubyte segments[] = { 282 VG_MOVE_TO_ABS, 283 VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, 284 VG_LINE_TO_ABS, VG_CLOSE_PATH 285 }; 286 const VGfloat coords[] = { 287 179.41001,115.28745, 288 179.41001,115.28745, 207.48443,109.30204, 236.84144,115.14494, 289 236.84144,115.14494, 274.74903,109.87208, 291.8502,115.42996, 290 179.41001,115.28745 291 }; 292 293 VGuint color = 0x000000ff; 294 add_object_fill(segments, ELEMENTS(segments), 295 coords, color); 296 } 297 { 298 const VGubyte segments[] = { 299 VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, 300 VG_CUBIC_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS, VG_CLOSE_PATH 301 }; 302 const VGfloat coords[] = { 303 83.792156,68.157364, 304 83.792156,69.669865, 82.72301,70.897403, 81.40567,70.897403, 305 80.08833,70.897403, 79.019185,69.669865, 79.019185,68.157364, 306 79.019185,66.644862, 80.08833,65.417325, 81.40567,65.417325, 307 82.721887,65.417325, 83.790391,66.642485, 83.792153,68.153696, 308 81.40567,68.157364, 309 83.792156,68.157364 310 }; 311 VGuint fill_color = 0x000000ff; 312 VGuint stroke_color = 0x000000ff; 313 VGfloat swidth = 0.52891117; 314 VGfloat matrix1[] = { 315 1.140078,0, 0, 316 0,1.140078, 0, 317 145.2489,-15.58714, 1 318 }; 319 add_object_m(segments, ELEMENTS(segments), coords, 320 fill_color, stroke_color, swidth, matrix1); 321 } 322 { 323 const VGubyte segments[] = { 324 VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS 325 }; 326 const VGfloat coords[] = { 327 232.28113,66.976646, 328 232.28113,66.976646, 237.98152,70.539389, 245.39202,66.549116 329 }; 330 VGuint color = 0x000000ff; 331 VGfloat swidth = 0.60299999; 332 add_object_stroke(segments, ELEMENTS(segments), coords, color, swidth); 333 } 334 { 335 const VGubyte segments[] = { 336 VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, 337 VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CLOSE_PATH 338 }; 339 const VGfloat coords[] = { 340 185.96908,30.061986, 341 185.96908,30.061986, 187.76995,14.508377, 203.23909,3.7427917, 342 209.95028,-0.92779696, 219.37764,-4.9841866, 232.1078,-6.00046, 343 246.13578,-7.1203411, 256.92106,-2.8560739, 264.81774,1.9451947, 344 280.60485,11.543934, 284.31582,25.937274, 284.08015,26.526452, 345 283.7266,27.410336, 240.83461,1.9346323, 185.96908,30.061986 346 }; 347 VGuint color = 0x8ed8f8ff; 348 add_object_fill(segments, ELEMENTS(segments), coords, color); 349 } 350 { 351 const VGubyte segments[] = { 352 VG_MOVE_TO_ABS, VG_LINE_TO_ABS, VG_CUBIC_TO_ABS, 353 VG_LINE_TO_ABS, VG_CUBIC_TO_ABS, VG_CLOSE_PATH 354 }; 355 const VGfloat coords[] = { 356 185.39542,32.061757, 357 185.82295,29.211562, 358 185.82295,29.211562, 234.70379,2.277219, 284.01217,25.078779, 359 284.86722,27.643954, 360 284.86722,27.643954, 236.69893,4.5573746, 185.39542,32.061757 361 }; 362 VGuint color = 0xfff200ff; 363 add_object_fill(segments, ELEMENTS(segments), coords, color); 364 } 365 366 { 367 const VGubyte segments[] = { 368 VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, 369 VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, 370 VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, 371 VG_CUBIC_TO_ABS, VG_CLOSE_PATH 372 }; 373 const VGfloat coords[] = { 374 219.74027,-5.917093, 375 220.49206,-8.44929, 225.15564,-10.904934, 230.21473,-11.189954, 376 235.27383,-11.474973, 243.27521,-13.287236, 249.21385,-5.724198, 377 249.89961,-4.850868, 249.28247,-4.332166, 248.62298,-3.971398, 378 247.79117,-3.516361, 247.13703,-3.392737, 246.16222,-3.408047, 379 243.63973,-3.447664, 242.54183,-3.850701, 242.54183,-3.850701, 380 242.54183,-3.850701, 238.78367,-1.737343, 236.20014,-3.565682, 381 233.88436,-5.204544, 234.27626,-4.56325, 234.27626,-4.56325, 382 234.27626,-4.56325, 232.33303,-2.975658, 230.85603,-2.995643, 383 228.59433,-3.025282, 227.73672,-4.501857, 227.21966,-4.93027, 384 226.76318,-4.932008, 226.50948,-4.491995, 226.50948,-4.491995, 385 226.50948,-4.491995, 224.53199,-2.085883, 222.51431,-2.467064, 386 221.48814,-2.66093, 218.91968,-3.15318, 219.74027,-5.917093 387 }; 388 VGuint color = 0xfff200ff; 389 add_object_fill(segments, ELEMENTS(segments), coords, color); 390 } 391 { 392 const VGubyte segments[] = { 393 VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, 394 VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CLOSE_PATH 395 }; 396 const VGfloat coords[] = { 397 178.97347,166.06432, 398 178.97347,181.2154, 168.0245,193.51193, 154.53381,193.51193, 399 141.04312,193.51193, 130.09416,181.2154, 130.09416,166.06432, 400 130.09416,150.91323, 141.04312,138.6167, 154.53381,138.6167, 401 168.0245,138.6167, 178.97347,150.91323, 178.97347,166.06432 402 }; 403 VGuint color = 0xffffffff; 404 VGfloat matrix1[] = { 405 0.466614,-0.23492, 0, 406 0.108683,0.436638, 0, 407 134.5504,-0.901632, 1 408 }; 409 VGfloat matrix2[] = { 410 -0.466614,-0.23492, 0, 411 -0.108683,0.436638, 0, 412 338.4496,-0.512182, 1 413 }; 414 add_object_fillm(segments, ELEMENTS(segments), coords, color, matrix1); 415 add_object_fillm(segments, ELEMENTS(segments), coords, color, matrix2); 416 } 417 { 418 const VGubyte segments[] = { 419 VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, 420 VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CLOSE_PATH 421 }; 422 const VGfloat coords[] = { 423 123.82758,165.06168, 424 123.82758,166.79125, 122.59232,168.19497, 121.07029,168.19497, 425 119.54826,168.19497, 118.313,166.79125, 118.313,165.06168, 426 118.313,163.3321, 119.54826,161.92839, 121.07029,161.92839, 427 122.59232,161.92839, 123.82758,163.3321, 123.82758,165.06168 428 }; 429 VGuint color = 0x000000ff; 430 VGfloat matrix1[] = { 431 0.525719,0, 0, 432 0,0.479931, 0, 433 178.9702,-43.3532, 1 434 }; 435 VGfloat matrix2[] = { 436 0.525719,0, 0, 437 0,0.479931, 0, 438 165.258,-43.46162, 1 439 }; 440 add_object_fillm(segments, ELEMENTS(segments), coords, color, matrix1); 441 add_object_fillm(segments, ELEMENTS(segments), coords, color, matrix2); 442 } 443 { 444 const VGubyte segments[] = { 445 VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS 446 }; 447 const VGfloat coords[] = { 448 197.25,54.5, 449 197.25,54.5, 211.75,71.5, 229.25,71.5, 450 246.75,71.5, 261.74147,71.132714, 277.75,50.75 451 }; 452 VGuint color = 0x000000ff; 453 VGfloat swidth = 0.60299999; 454 add_object_stroke(segments, ELEMENTS(segments), coords, color, swidth); 455 } 456} 457 458 459static void 460init(void) 461{ 462 float clear_color[4] = {1.0, 1.0, 1.0, 1.0}; 463 vgSetfv(VG_CLEAR_COLOR, 4, clear_color); 464 465 init_character(); 466} 467 468/* new window size or exposure */ 469static void 470reshape(int w, int h) 471{ 472} 473 474static void 475draw(void) 476{ 477 VGint i; 478 VGfloat save_matrix[9]; 479 480 vgClear(0, 0, eglutGetWindowWidth(), eglutGetWindowHeight()); 481 482 vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); 483 vgLoadIdentity(); 484 vgScale(2, 2); 485 vgTranslate(160, 60); 486 vgRotate(180); 487 vgTranslate(-160, -100); 488 vgGetMatrix(save_matrix); 489 for (i = 0; i < cartman.num_objects; ++i) { 490 struct object object = cartman.objects[i]; 491 if ((object.draw_mode & VG_STROKE_PATH)) { 492 vgSetf(VG_STROKE_LINE_WIDTH, object.stroke_width); 493 vgSetPaint(object.stroke, VG_STROKE_PATH); 494 } 495 if ((object.draw_mode & VG_FILL_PATH)) 496 vgSetPaint(object.fill, VG_FILL_PATH); 497 vgMultMatrix(object.matrix); 498 vgDrawPath(object.path, object.draw_mode); 499 vgLoadMatrix(save_matrix); 500 } 501 502 vgFlush(); 503} 504 505 506int main(int argc, char **argv) 507{ 508 eglutInitWindowSize(400, 400); 509 eglutInitAPIMask(EGLUT_OPENVG_BIT); 510 eglutInit(argc, argv); 511 512 eglutCreateWindow("sp"); 513 514 eglutReshapeFunc(reshape); 515 eglutDisplayFunc(draw); 516 517 init(); 518 519 eglutMainLoop(); 520 521 return 0; 522} 523