Guest User

math error, SLine32 needed initialization

a guest
Nov 9th, 2014
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.16 KB | None | 0 0
  1. // math_failure.c -- fixed, was initialization on the SLine32 structure usage
  2. // Note: Compile as .C extension, with /Zp1 for MSVC, -fpack-struct=1 for GCC.
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <memory.h>
  7. #include <math.h>
  8.  
  9. #ifdef __GNUC__
  10. // gcc
  11. #include <stdint.h>
  12.  
  13. typedef uint64_t u64;
  14. typedef uint32_t u32;
  15. typedef uint16_t u16;
  16. typedef uint8_t u8;
  17.  
  18. typedef int64_t s64;
  19. typedef int32_t s32;
  20. typedef int16_t s16;
  21. typedef int8_t s8;
  22. #else
  23. typedef unsigned __int64 u64;
  24. typedef unsigned int u32;
  25. typedef unsigned short u16;
  26. typedef unsigned char u8;
  27.  
  28. // Signed
  29. typedef __int64 s64;
  30. typedef int s32;
  31. typedef short s16;
  32. typedef char s8;
  33. #endif
  34.  
  35. typedef u16 WORD;
  36. typedef u32 DWORD;
  37. typedef s32 LONG;
  38.  
  39. #ifndef bool
  40. typedef int bool;
  41. #endif
  42.  
  43. #ifndef true
  44. #define true 1
  45. #endif
  46.  
  47. #ifndef false
  48. #define false 0
  49. #endif
  50.  
  51. #ifndef min
  52. #define min(a,b) ((a <= b) ? a : b)
  53. #endif
  54.  
  55. #ifndef max
  56. #define max(a,b) ((a >= b) ? a : b)
  57. #endif
  58.  
  59. // Floating point
  60. typedef float f32;
  61. typedef double f64;
  62.  
  63. // Constant signed
  64. typedef const s8 cs8;
  65. typedef const s16 cs16;
  66. typedef const s32 cs32;
  67. typedef const s64 cs64;
  68.  
  69. // Constant unsigned
  70. typedef const u8 cu8;
  71. typedef const u16 cu16;
  72. typedef const u32 cu32;
  73. typedef const u64 cu64;
  74.  
  75. // Constant floating point
  76. typedef const f64 cf64;
  77. typedef const f64 cf64;
  78.  
  79. typedef struct tagBmpFileHeader {
  80. WORD bfType;
  81. DWORD bfSize;
  82. WORD bfReserved1;
  83. WORD bfReserved2;
  84. DWORD bfOffBits;
  85. } BFH;
  86.  
  87. typedef struct tagBmpInfoHeader {
  88. DWORD biSize;
  89. LONG biWidth;
  90. LONG biHeight;
  91. WORD biPlanes;
  92. WORD biBitCount;
  93. DWORD biCompression;
  94. DWORD biSizeImage;
  95. LONG biXPelsPerMeter;
  96. LONG biYPelsPerMeter;
  97. DWORD biClrUsed;
  98. DWORD biClrImportant;
  99. } BIH;
  100.  
  101. typedef struct SBmp
  102. {
  103. // Raw bitmap data (suitable for writing to disk)
  104. BFH bh;
  105. BIH bi;
  106. s8* bd;
  107. u32 rowWidth;
  108. } SBitmap;
  109.  
  110. typedef struct SF32
  111. {
  112. f32 x;
  113. f32 y;
  114. } SXYF32;
  115.  
  116. typedef struct SS32
  117. {
  118. s32 x;
  119. s32 y;
  120. } SXYS32;
  121.  
  122. typedef struct SLF32
  123. {
  124. union {
  125. SXYF32 start; // [input] Starting point
  126. SXYF32 p1;
  127. };
  128.  
  129. union {
  130. SXYF32 end; // [input] Ending point
  131. SXYF32 p2;
  132. };
  133.  
  134. // The following are computed with vvm_math_computeLine()
  135. SXYF32 delta; // Delta between start and end
  136. SXYF32 mid; // Midpoint
  137. union {
  138. f32 length; // Length
  139. f32 radius; // Radius for the trig function
  140. };
  141. f32 m; // Slope
  142. f32 mp; // Perpendicular slope
  143.  
  144. // Only used and computed if trig is true
  145. bool trig; // Should trig functions be computed?
  146. f32 theta; // Theta (from p1 to p2, note: add _PI to reverse the angle from p2 to p1)
  147.  
  148. // Only used and computed if ints is true
  149. bool ints; // Should integer approximations be calculated?
  150. union {
  151. SXYS32 starti; // Starting x,y
  152. SXYS32 p1i;
  153. };
  154. union {
  155. SXYS32 endi; // Ending x,y
  156. SXYS32 p2i;
  157. };
  158.  
  159. // Only used and computed if quads is true
  160. bool quads; // Should we compute quadrants?
  161. union {
  162. s32 start_quad; // What quadrant is start/p1 in?
  163. s32 p1_quad;
  164. };
  165. union {
  166. s32 end_quad; // What quadrant is end/p2 in?
  167. s32 p2_quad;
  168. };
  169. } SLineF32;
  170.  
  171. typedef struct sb
  172. {
  173. u8 blu;
  174. u8 grn;
  175. u8 red;
  176. } SBgr;
  177.  
  178. typedef struct Sba
  179. {
  180. union {
  181. u32 color;
  182. struct {
  183. u8 blu;
  184. u8 grn;
  185. u8 red;
  186. u8 alp;
  187. };
  188. };
  189. } SBgra;
  190.  
  191. SBgra blackColor;
  192.  
  193.  
  194.  
  195.  
  196. //////////
  197. //
  198. // Computes the row width of the pixels using BGR format (3 bytes per pixel) then rounded up to
  199. // the nearest DWORD.
  200. //
  201. //////
  202. s32 iBmp_computeRowWidth(SBitmap* bmp)
  203. {
  204. s32 lnWidth;
  205.  
  206.  
  207. // Make sure our environment is sane
  208. if (bmp)
  209. {
  210. // See the bit counts
  211. if (bmp->bi.biBitCount == 24)
  212. {
  213. // 24-bit formats are rounded up to nearest DWORD
  214. lnWidth = bmp->bi.biWidth * 3;
  215. if (lnWidth % 4 == 0)
  216. return(lnWidth);
  217.  
  218. // Increase the width
  219. lnWidth += (4 - (lnWidth % 4));
  220. return(lnWidth);
  221.  
  222.  
  223. } else if (bmp->bi.biBitCount == 32) {
  224. // 32-bit formats are also DWORD aligned, but naturally, of course. :-)
  225. return(bmp->bi.biWidth * 4);
  226.  
  227.  
  228. } else {
  229. // Uh oh, spaghetti-oh!
  230. return(bmp->bi.biSizeImage / bmp->bi.biHeight);
  231. }
  232. }
  233.  
  234. // Invalid
  235. return(0);
  236. }
  237.  
  238.  
  239.  
  240.  
  241. //////////
  242. //
  243. // Called to create an empty bitmap
  244. //
  245. //////
  246. void iBmp_populateBitmapStructure(SBitmap* bmp, u32 tnWidth, u32 tnHeight, u32 tnBitCount)
  247. {
  248. if (bmp)
  249. {
  250. memset(&bmp->bi, 0, sizeof(bmp->bi));
  251. bmp->bi.biSize = sizeof(bmp->bi);
  252. bmp->bi.biWidth = tnWidth;
  253. bmp->bi.biHeight = tnHeight;
  254. bmp->bi.biCompression = 0;
  255. bmp->bi.biPlanes = 1;
  256. bmp->bi.biBitCount = (u16)((tnBitCount == 24 || tnBitCount == 32) ? tnBitCount : 24);
  257. bmp->bi.biXPelsPerMeter = 2835; // Assume 72 dpi
  258. bmp->bi.biYPelsPerMeter = 2835;
  259. bmp->rowWidth = iBmp_computeRowWidth(bmp);
  260. bmp->bi.biSizeImage = bmp->rowWidth * tnHeight;
  261.  
  262. memset(&bmp->bh, 0, sizeof(bmp->bh));
  263. bmp->bh.bfType = 0x4d42; // BM file prefix
  264. bmp->bh.bfOffBits = sizeof(bmp->bh) + sizeof(bmp->bi);
  265. bmp->bh.bfSize = bmp->bh.bfOffBits + bmp->bi.biSizeImage;
  266. }
  267. }
  268.  
  269.  
  270.  
  271.  
  272. //////////
  273. //
  274. // Called to create a basic bitmap by the indicated size, and initially populate it to white
  275. //
  276. //////
  277. void iBmp_createBySize(SBitmap* bmp, u32 width, u32 height, u32 tnBitCount)
  278. {
  279. if (bmp)
  280. {
  281. // Populate the initial structure (min of 1x1, max of 7680x4320 (4x 1920x1080)
  282. iBmp_populateBitmapStructure(bmp, min(max(width, 1), 7680), min(max(height, 1), 4320), tnBitCount);
  283.  
  284. // Create the HDC and DIB Section
  285. bmp->bd = (s8*)malloc(bmp->bi.biSizeImage);
  286.  
  287. // Paint it white initially (the fast/easy way)
  288. if (bmp->bd)
  289. memset(bmp->bd, 255, bmp->bi.biSizeImage);
  290. }
  291. }
  292.  
  293.  
  294.  
  295.  
  296. //////////
  297. // Allocates a new structure
  298. //////
  299. SBitmap* iBmp_allocate(u32 width, u32 height, u32 tnBitCount)
  300. {
  301. SBitmap* bmp;
  302.  
  303.  
  304. // Allocate our new structure
  305. bmp = (SBitmap*)malloc(sizeof(SBitmap));
  306.  
  307. // Initialize if successful
  308. if (bmp)
  309. iBmp_createBySize(bmp, width, height, tnBitCount);
  310.  
  311. // Indicate our success or failure
  312. return(bmp);
  313. }
  314.  
  315.  
  316.  
  317.  
  318. //////////
  319. //
  320. // Adjusts theta into the 0..2pi range
  321. //
  322. //////
  323. #ifndef M_PI
  324. #define M_PI 3.14159265358979323846
  325. #endif
  326. const f32 _2PI = (f32)M_PI * 2.0f; // 2 * pi
  327.  
  328. f32 iivvm_math_adjustTheta(f32 tfTheta)
  329. {
  330. // Validate theta is positive
  331. while (tfTheta < 0.0)
  332. tfTheta += _2PI;
  333.  
  334. // Validate theta is 0..2pi
  335. while (tfTheta > _2PI)
  336. tfTheta -= _2PI;
  337.  
  338. return(tfTheta);
  339. }
  340.  
  341.  
  342.  
  343.  
  344. //////////
  345. //
  346. // Determines the quandrant of the point
  347. //
  348. //////
  349. s32 iivvm_math_computeQuadrant(SXYF32* p)
  350. {
  351. if (p->x >= 0.0)
  352. {
  353. // Either 1 or 4
  354. if (p->y >= 0.0) return(1); // X is positive, Y is positive
  355. else return(4); // X is positive, Y is negative
  356.  
  357. } else {
  358. // Either 2 or 3
  359. if (p->y >= 0.0) return(2); // X is negative, Y is positive
  360. else return(3); // X is negative, Y is negative
  361. }
  362. }
  363.  
  364. void iivvm_math_computeLine(SLineF32* line)
  365. {
  366. // Midpoint = (x2-x1)/2, (y2-y1)/2
  367. line->mid.x = (line->p1.x + line->p2.x) / 2.0f;
  368. line->mid.y = (line->p1.y + line->p2.y) / 2.0f;
  369.  
  370. // Compute our deltas
  371. line->delta.x = line->p2.x - line->p1.x;
  372. line->delta.y = line->p2.y - line->p1.y;
  373.  
  374. // Length
  375. line->length = (f32)sqrt(line->delta.x*line->delta.x + line->delta.y*line->delta.y);
  376.  
  377. // Slope = rise over run
  378. line->m = line->delta.y / ((line->delta.x == 0.0f) ? 0.000001f : line->delta.x);
  379.  
  380. // Perpendicular slope = -1/m
  381. line->mp = -1.0f / ((line->m == 0.0) ? 0.000001f : line->m);
  382.  
  383.  
  384. //////////
  385. // Compute theta if need be (radius is same as length)
  386. /////
  387. if (line->trig)
  388. line->theta = iivvm_math_adjustTheta((f32)atan2(line->delta.y, line->delta.x));
  389.  
  390.  
  391. //////////
  392. // Compute the integer roundings if need be
  393. //////
  394. if (line->ints)
  395. {
  396. // Start
  397. line->p1i.x = (s32)line->p1.x;
  398. line->p1i.y = (s32)line->p1.y;
  399. // End
  400. line->p2i.x = (s32)line->p2.x;
  401. line->p2i.y = (s32)line->p2.y;
  402. }
  403.  
  404.  
  405. //////////
  406. // Compute the quadrants if need be
  407. //////
  408. if (line->quads)
  409. {
  410. // Quads 1..4
  411. line->p1_quad = iivvm_math_computeQuadrant(&line->p1);
  412. line->p2_quad = iivvm_math_computeQuadrant(&line->p2);
  413. }
  414. }
  415.  
  416. void iivvm_copyLine(SLineF32* line, SXYF32* p1, SXYF32* p2, bool tlComputeLine)
  417. {
  418. // Copy
  419. memcpy(&line->p1, p1, sizeof(line->p1));
  420. memcpy(&line->p2, p2, sizeof(line->p2));
  421.  
  422. // Compute if need be
  423. if (tlComputeLine)
  424. iivvm_math_computeLine(line);
  425. }
  426.  
  427.  
  428.  
  429.  
  430. //////////
  431. //
  432. // Called to draw or generate the bezier using 3 points
  433. //
  434. //////
  435. SXYF32* iivvm_canvasBezier3(s32 tnSegments, SXYF32* tfP1, SXYF32* tfP2, SXYF32* tfP3)
  436. {
  437. s32 lnI;
  438. f32 lfPercent, lfCosTheta1, lfSinTheta1, lfCosTheta2, lfSinTheta2;
  439. SXYF32 p1, p2, pbez;
  440. SLineF32 l1, l2; // Lines from bez->p1 to bez->p2, and bez->p2 to bez->p3
  441. SLineF32 lmid; // Line from l1 to l2
  442. SXYF32* points;
  443.  
  444.  
  445. // Allocate our return buffer
  446. points = (SXYF32*)malloc(tnSegments * sizeof(SXYF32));
  447. memset(points, 0, tnSegments * sizeof(SXYF32));
  448.  
  449.  
  450. //////////
  451. // Copy and compute our lines
  452. //////
  453. memset(&l1, 0, sizeof(l1));
  454. memset(&l2, 0, sizeof(l1));
  455. l1.trig = true;
  456. l2.trig = true;
  457. iivvm_copyLine(&l1, tfP1, tfP2, true);
  458. iivvm_copyLine(&l2, tfP2, tfP3, true);
  459.  
  460.  
  461. //////////
  462. // Compute our thetas for rapid use
  463. //////
  464. // L1
  465. lfCosTheta1 = (f32)cos(l1.theta);
  466. lfSinTheta1 = (f32)sin(l1.theta);
  467. // L2
  468. lfCosTheta2 = (f32)cos(l2.theta);
  469. lfSinTheta2 = (f32)sin(l2.theta);
  470.  
  471.  
  472. //////////
  473. // Now, iterate through the bezier building the points
  474. //////
  475. for (lnI = 0; lnI < tnSegments; lnI++)
  476. {
  477. //////////
  478. // Get our percentage
  479. //////
  480. lfPercent = (f32)lnI / (f32)tnSegments;
  481.  
  482.  
  483. //////////
  484. // Determine the two points for l1 and l2
  485. //////
  486. // P1, L1
  487. p1.x = tfP1->x + (lfPercent * l1.radius * lfCosTheta1);
  488. p1.y = tfP1->y + (lfPercent * l1.radius * lfSinTheta1);
  489. // P2, L2
  490. p2.x = tfP2->x + (lfPercent * l2.radius * lfCosTheta2);
  491. p2.y = tfP2->y + (lfPercent * l2.radius * lfSinTheta2);
  492.  
  493.  
  494. //////////
  495. // Construct the line between
  496. //////
  497. iivvm_copyLine(&lmid, &p1, &p2, true);
  498.  
  499.  
  500. //////////
  501. // Derive the position of this bezier point
  502. //////
  503. // PBEZ
  504. pbez.x = lmid.p1.x + (lfPercent * lmid.radius * (f32)cos(lmid.theta));
  505. pbez.y = lmid.p1.y + (lfPercent * lmid.radius * (f32)sin(lmid.theta));
  506.  
  507.  
  508. //////////
  509. // Store the point
  510. //////
  511. points[lnI].x = pbez.x;
  512. points[lnI].y = pbez.y;
  513. }
  514.  
  515. return(points);
  516. }
  517.  
  518.  
  519.  
  520.  
  521. //////////
  522. //
  523. // Called to draw a point
  524. //
  525. //////
  526. void iBmp_drawPoint(SBitmap* bmp, s32 tnX, s32 tnY, SBgra color)
  527. {
  528. SBgr* lbgr;
  529. SBgra* lbgra;
  530.  
  531.  
  532. if (bmp)
  533. {
  534. // Make sure our coordinates are valid
  535. if (tnX >= 0 && tnX < bmp->bi.biWidth && tnY >= 0 && tnY < bmp->bi.biHeight)
  536. {
  537. if (bmp->bi.biBitCount == 24)
  538. {
  539. // Get our offset
  540. lbgr = (SBgr*)(bmp->bd + ((bmp->bi.biHeight - tnY - 1) * bmp->rowWidth) + (tnX * 3));
  541.  
  542. // Draw it
  543. lbgr->red = color.red;
  544. lbgr->grn = color.grn;
  545. lbgr->blu = color.blu;
  546.  
  547. } else if (bmp->bi.biBitCount == 32) {
  548. // Get our offset
  549. lbgra = (SBgra*)(bmp->bd + ((bmp->bi.biHeight - tnY - 1) * bmp->rowWidth) + (tnX * 4));
  550.  
  551. // Draw it
  552. lbgra->red = color.red;
  553. lbgra->grn = color.grn;
  554. lbgra->blu = color.blu;
  555. }
  556. }
  557. }
  558. }
  559.  
  560.  
  561.  
  562.  
  563. //////////
  564. //
  565. // Called to draw an arbitary line between two points. Does
  566. // not handle any anti-aliasing, but rather is a brute-force
  567. // method to present a simple line.
  568. //
  569. /////
  570. void iBmp_drawArbitraryLine(SBitmap* bmp, s32 tnX1, s32 tnY1, s32 tnX2, s32 tnY2, SBgra color)
  571. {
  572. f32 lfX, lfY, lfXStep, lfYStep, lfRadius, lfDeltaX, lfDeltaY;
  573.  
  574.  
  575. // Compute the distance
  576. lfDeltaX = (f32)(tnX2 - tnX1);
  577. lfDeltaY = (f32)(tnY2 - tnY1);
  578. lfRadius = (f32)sqrt((lfDeltaX*lfDeltaX) + (lfDeltaY*lfDeltaY));
  579. if (lfRadius < 1.0f)
  580. return;
  581.  
  582. // Compute our steps per pixel
  583. lfXStep = lfDeltaX / lfRadius;
  584. lfYStep = lfDeltaY / lfRadius;
  585.  
  586. // Iterate for each point
  587. for (lfX = (f32)tnX1, lfY = (f32)tnY1; lfRadius > 0.0f; lfRadius--, lfX += lfXStep, lfY += lfYStep)
  588. iBmp_drawPoint(bmp, (s32)lfX, (s32)lfY, color);
  589. }
  590.  
  591.  
  592.  
  593.  
  594. //////////
  595. //
  596. // Draws a rectange around an arbitrary line.
  597. //
  598. //////
  599. #ifndef _PI2
  600. #define _PI2 1.570796327
  601. #endif
  602. void iBmp_drawArbitraryQuad(SBitmap* bmp, s32 tnX1, s32 tnY1, s32 tnX2, s32 tnY2, s32 tnWidth, bool tlDrawEnds, SBgra color)
  603. {
  604. f32 lfX1, lfY1, lfX2, lfY2, lfX3, lfY3, lfX4, lfY4;
  605. SLineF32 line;
  606.  
  607.  
  608. //////////
  609. // Compute the line
  610. /////
  611. memset(&line, 0, sizeof(line));
  612. line.p1.x = (f32)tnX1;
  613. line.p1.y = (f32)tnY1;
  614. line.p2.x = (f32)tnX2;
  615. line.p2.y = (f32)tnY2;
  616. iivvm_math_computeLine(&line);
  617.  
  618.  
  619. //////////
  620. // Draw the line
  621. //////
  622. lfX1 = line.p1.x + ((f32)cos(line.theta + _PI2) * ((f32)tnWidth / 2.0f));
  623. lfY1 = line.p1.y + ((f32)sin(line.theta + _PI2) * ((f32)tnWidth / 2.0f));
  624. lfX2 = line.p1.x + ((f32)cos(line.theta - _PI2) * ((f32)tnWidth / 2.0f));
  625. lfY2 = line.p1.y + ((f32)sin(line.theta - _PI2) * ((f32)tnWidth / 2.0f));
  626. if (tlDrawEnds)
  627. iBmp_drawArbitraryLine(bmp, (s32)lfX1, (s32)lfY1, (s32)lfX2, (s32)lfY2, color);
  628.  
  629. lfX3 = line.p2.x + ((f32)cos(line.theta + _PI2) * ((f32)tnWidth / 2.0f));
  630. lfY3 = line.p2.y + ((f32)sin(line.theta + _PI2) * ((f32)tnWidth / 2.0f));
  631. lfX4 = line.p2.x + ((f32)cos(line.theta - _PI2) * ((f32)tnWidth / 2.0f));
  632. lfY4 = line.p2.y + ((f32)sin(line.theta - _PI2) * ((f32)tnWidth / 2.0f));
  633. if (tlDrawEnds)
  634. iBmp_drawArbitraryLine(bmp, (s32)lfX3, (s32)lfY3, (s32)lfX4, (s32)lfY4, color);
  635.  
  636. iBmp_drawArbitraryLine(bmp, (s32)lfX1, (s32)lfY1, (s32)lfX3, (s32)lfY3, color);
  637. iBmp_drawArbitraryLine(bmp, (s32)lfX2, (s32)lfY2, (s32)lfX4, (s32)lfY4, color);
  638. }
  639.  
  640.  
  641.  
  642.  
  643. //////////
  644. //
  645. // Create a two-part bezier-3 line, one from upper-left to center,
  646. // the other from lower-right to center.
  647. //
  648. //////
  649. void iTest_nodeLine(SBitmap* bmp, f32 lfFactorX, f32 lfFactorY)
  650. {
  651. s32 lnI, lnWidth;
  652. SXYF32* points1;
  653. SXYF32* points2;
  654. SXYF32 p1, p2, p3, p4, p5;
  655. f32 lfWidth, lfHeight;
  656.  
  657.  
  658. lfWidth = bmp->bi.biWidth * lfFactorX / 8.0f;
  659. lfHeight = bmp->bi.biHeight * lfFactorY / 8.0f;
  660.  
  661. p1.x = ((f32)bmp->bi.biWidth / 2.0f) - (lfWidth / 2.0f);
  662. p1.y = ((f32)bmp->bi.biHeight / 2.0f) - (lfHeight / 2.0f);
  663.  
  664. p2.x = ((f32)bmp->bi.biWidth / 2.0f) - (lfWidth / 4.0f);
  665. p2.y = ((f32)bmp->bi.biHeight / 2.0f) - (lfHeight / 2.0f);
  666.  
  667. p3.x = ((f32)bmp->bi.biWidth / 2.0f);
  668. p3.y = ((f32)bmp->bi.biHeight / 2.0f);
  669. points1 = iivvm_canvasBezier3(20, &p1, &p2, &p3);
  670.  
  671. p4.x = ((f32)bmp->bi.biWidth / 2.0f) + (lfWidth / 4.0f);
  672. p4.y = ((f32)bmp->bi.biHeight / 2.0f) + (lfHeight / 2.0f);
  673.  
  674. p5.x = ((f32)bmp->bi.biWidth / 2.0f) + (lfWidth / 2.0f);
  675. p5.y = ((f32)bmp->bi.biHeight / 2.0f) + (lfHeight / 2.0f);
  676. points2 = iivvm_canvasBezier3(20, &p5, &p4, &p3);
  677.  
  678. lnWidth = 5;
  679. for (lnI = 0; lnI < 20 - 1; lnI++)
  680. {
  681. iBmp_drawArbitraryQuad(bmp, (s32)points1[lnI].x, (s32)points1[lnI].y, (s32)points1[lnI+1].x, (s32)points1[lnI+1].y, lnWidth, true, blackColor);
  682. iBmp_drawArbitraryQuad(bmp, (s32)points2[lnI].x, (s32)points2[lnI].y, (s32)points2[lnI+1].x, (s32)points2[lnI+1].y, lnWidth, true, blackColor);
  683. }
  684. --lnI;
  685. iBmp_drawArbitraryQuad(bmp, (s32)points1[lnI].x, (s32)points1[lnI].y, (s32)points2[lnI].x, (s32)points2[lnI].y, lnWidth, true, blackColor);
  686. free(points1);
  687. free(points2);
  688. }
  689.  
  690.  
  691.  
  692.  
  693. //////////
  694. //
  695. // Create an 800x600 bitmap, populate it with a double bezier-3 curve,
  696. // and write the bitmap to disk.
  697. //
  698. //////
  699. int main(int argc, char* argv[])
  700. {
  701. size_t numwritten1, numwritten2, numwritten3;
  702. SBitmap* bmp;
  703. FILE* lfh;
  704.  
  705.  
  706. //////////
  707. // Create the bitmap
  708. //////
  709. bmp = iBmp_allocate(800, 600, 24);
  710. if (!bmp)
  711. {
  712. printf("Failure allocating bitmap.\n");
  713. return -1;
  714. }
  715.  
  716.  
  717. //////////
  718. // Draw the node line
  719. //////
  720. blackColor.color = 0;
  721. iTest_nodeLine(bmp, 7.0f, 7.0f);
  722.  
  723.  
  724. //////////
  725. // Write the output file
  726. //////
  727. lfh = fopen("output.bmp", "wb+");
  728. if (!lfh)
  729. {
  730. printf("Error creating output.bmp\n");
  731. return -2;
  732. }
  733. numwritten1 = fwrite(&bmp->bh, 1, sizeof(bmp->bh), lfh);
  734. numwritten2 = fwrite(&bmp->bi, 1, sizeof(bmp->bi), lfh);
  735. numwritten3 = fwrite(bmp->bd, 1, bmp->bi.biSizeImage, lfh);
  736. fclose(lfh);
  737. if (!(numwritten1 == sizeof(bmp->bh) && numwritten2 == sizeof(bmp->bi) && numwritten3 == bmp->bi.biSizeImage))
  738. {
  739. printf("Error writing output.bmp\n");
  740. return -3;
  741. }
  742.  
  743.  
  744. //////////
  745. // Indicate our status
  746. //////
  747. printf("Success. output.bmp created.\n");
  748. return 0;
  749. }
Advertisement
Add Comment
Please, Sign In to add comment