• Mint_21.3 drawing-area和goocanvas的FB笔记(八)


    FreeBASIC与TinyPTC绘图

    TinyPTC是个操作非常简单的库,有各平台用的版本,linux平台版本又分为sdl版和gfx版,gfx版本比sdl版本速度快,尺寸不大,可操作的函数只有3个:

    ptc_open,  ptc_update,  ptc_close

    sdl版本增加了一个回调函数 ptc_cleanup_callback , 在TinyPTC即将结束前的回调。gfx版本增加了像素格式转换,用asm写的,nasm编译,ar\as处理,但没实际意义、只是放在了那里,编译mmx.s和yvs12.s与gcc的其它.o不能链接成 .a 库,修改Makefiles配置文件将AOBJECTS去掉即可。

    FreeBASIC有它的.bi头文件,但没有它的.a库,所以需要自己编译(系统上要有gcc, make工具链)。对TinyPTC-SDL-0.3.2编译:到sourceforge下载后解压,在解压后的目录内执行:

    make && sudo make install 即可,libtinyptc.a 是它生成的库文件,如果不 sudo make install 则将这个文件考贝到 /usr/lib/x86_64-linux-gnu下即可。

    编译完成后生成一个测试程序 tinyptc_test,在终端上执行 ./tinyptc_test 显示不断变化的噪音信号,就好像老电视机收不信号满屏雪花一样。

    X11 gfx版本编译事项

    打开Makefile文件,将链接时的 $(AOBJECTS) 去掉。然后:

    make && sudo make install ,或是直接考贝到 /usr/lib/x86_64-linux-gnu 下。

    FreeBasic示例程序一:正弦曲线,中间画一条直线。

    ptc_open前定义一个宽w高h的像素数组,freebasic 整数是32位的,正好是rgba的像素数 4 个8bit, ptc_open后以这个w和h的一半计算出x点对应的y点,再折算成连续数组中的位置,然后 ptc_update这个数组,就显示到屏幕上了。如果是bmp位置,可以获取位置长宽后读取位置数据装入到数组中,然后ptc_update到屏幕上去。

    1. #include "tinyptc.bi"
    2. const SCR_WIDTH = 1024
    3. const SCR_HEIGHT = 768
    4. const SCR_SIZE = SCR_WIDTH*SCR_HEIGHT
    5. dim shared buffer( 0 to SCR_SIZE-1 ) as integer
    6. if( ptc_open( "Simple lines", SCR_WIDTH, SCR_HEIGHT ) = 0 ) then
    7. Print "Can not create ptc window!"
    8. end -1
    9. end if
    10. 'data buffer is integer, e.g. 32bit/4byte color in depth
    11. 'data arranged in ARGB order at each buffer cell &Haarrggbb
    12. Dim as integer x, y
    13. Dim as double rad = 0
    14. Dim as double PI = 3.1415926
    15. Do
    16. rad = 0
    17. for x = 0 to SCR_WIDTH/2 - 1
    18. ''Line diagonal
    19. 'y = x*(SCR_HEIGHT-1)/(SCR_WIDTH-1)
    20. 'buffer(y*SCR_WIDTH + x) = RGBA(255, 0, 255, 0)
    21. 'Sine wave
    22. y = SCR_HEIGHT/4 + (SCR_HEIGHT/5)*cos(rad)
    23. rad += 0.05
    24. if rad > 2*PI then
    25. rad = 0
    26. end if
    27. buffer(y*SCR_WIDTH + x) = RGBA(255, 255, 0, 0)
    28. 'axes
    29. y = SCR_HEIGHT/4
    30. buffer(y*SCR_WIDTH + x) = RGBA(255, 0, 0, 0)
    31. next x
    32. ptc_update @buffer(0)
    33. sleep 10
    34. loop until( inkey = chr( 27 ) )
    35. ptc_close

    FreeBasic示例程序二:雪花噪音信号发生器

    运算逻辑同示例一,只是算法不同,程序中有计算方法可细了解。

    1. ''
    2. '' ordinary TinyPTC test, based on the original
    3. ''
    4. #include "tinyptc.bi"
    5. 'const SCR_WIDTH = 320
    6. 'const SCR_HEIGHT = 200
    7. const SCR_WIDTH = 1850
    8. const SCR_HEIGHT =1000
    9. const SCR_SIZE = SCR_WIDTH*SCR_HEIGHT
    10. dim shared buffer( 0 to SCR_SIZE-1 ) as integer
    11. 'Integer is 8Bytes, e.g. 64bits per sizeof(integer)
    12. dim noise as integer, carry as integer, index as integer, seed as integer
    13. if( ptc_open( "freeBASIC v0.01 - tinyPTC test", SCR_WIDTH, SCR_HEIGHT ) = 0 ) then
    14. end -1
    15. end if
    16. seed = &h12345
    17. do
    18. for index = 0 to SCR_SIZE-1
    19. noise = (seed shr 3) xor seed
    20. carry = noise and 1
    21. noise = noise shr 1
    22. seed = seed shr 1
    23. seed = seed or (carry shl 30)
    24. noise = noise and &hFF
    25. buffer(index) = rgb( noise, noise, noise )
    26. next index
    27. ptc_update @buffer(0)
    28. loop until( inkey = chr( 27 ) )
    29. ptc_close

    FreeBasic示例程序二:朱丽叶环

    通过函数运算,将值放入数组,然后ptc_update到屏幕上。

    1. ' The Lord of the Julia Rings
    2. ' The Fellowship of the Julia Ring
    3. ' Free Basic
    4. ' Relsoft
    5. ' Rel.BetterWebber.com
    6. '
    7. #ifdef __FB_WIN32__
    8. #include once "windows.bi"
    9. #endif
    10. #include once "tinyptc.bi"
    11. '320*240
    12. 'const SCR_WIDTH = 640 * 1
    13. 'const SCR_HEIGHT = 480 * 1
    14. const SCR_WIDTH = 1850 * 1
    15. const SCR_HEIGHT = 1000 * 1
    16. const SCR_SIZE = SCR_WIDTH*SCR_HEIGHT
    17. const SCR_MIDX = SCR_WIDTH \ 2
    18. const SCR_MIDY = SCR_HEIGHT \ 2
    19. const PI = 3.141593
    20. const MAXITER = 20
    21. const MAXSIZE = 4
    22. dim shared Buffer(SCR_SIZE - 1) as integer
    23. dim Lx(SCR_WIDTH-1) as single
    24. dim Ly(SCR_HEIGHT-1) as single
    25. dim shared sqrt(SCR_SIZE - 1) as single
    26. if( ptc_open( "Julia (Relsoft)", SCR_WIDTH, SCR_HEIGHT ) = 0 ) then
    27. end -1
    28. end if
    29. dim px as integer, py as integer
    30. dim p as single, q as single
    31. dim xmin as single, xmax as single, ymin as single, ymax as single
    32. dim theta as single
    33. dim deltax as single, deltay as single
    34. dim x as single, y as single
    35. dim xsquare as single, ysquare as single
    36. dim ytemp as single
    37. dim temp1 as single, temp2 as single
    38. dim i as integer, pixel as integer
    39. dim p_buffer as integer ptr, p_bufferl as integer ptr
    40. dim t as uinteger, frame as uinteger
    41. dim ty as single
    42. dim r as integer, g as integer, b as integer
    43. dim red as integer, grn as integer, blu as integer
    44. dim tmp as integer, i_last as integer
    45. dim cmag as single
    46. dim cmagsq as single
    47. dim zmag as single
    48. dim drad as single
    49. dim drad_L as single
    50. dim drad_H as single
    51. dim ztot as single
    52. dim ztoti as integer
    53. xmin = -2.0
    54. xmax = 2.0
    55. ymin = -1.5
    56. ymax = 1.5
    57. deltax = (xmax - xmin) / (SCR_WIDTH - 1)
    58. deltay = (ymax - ymin) / (SCR_HEIGHT - 1)
    59. for i = 0 to SCR_WIDTH - 1
    60. lx(i) = xmin + i * deltax
    61. next i
    62. for i = 0 to SCR_HEIGHT - 1
    63. ly(i) = ymax - i * deltay
    64. next i
    65. for i = 0 to SCR_SIZE - 1
    66. sqrt(i) = sqr(i)
    67. next i
    68. #ifdef __FB_WIN32__
    69. dim hwnd as HWND
    70. hwnd = GetActiveWindow( )
    71. #endif
    72. dim stime as integer, Fps as single, Fps2 as single
    73. stime = timer
    74. do
    75. p_buffer = @buffer(0)
    76. p_bufferl = @buffer(SCR_SIZE-1)
    77. frame = (frame + 1) and &H7fffffff
    78. theta = frame * PI / 180
    79. p = cos(theta) * sin(theta * .7)
    80. q = sin(theta) + sin(theta)
    81. p = p * .6
    82. q = q * .6
    83. cmag = sqr(p *p + q* q)
    84. cmagsq = (p *p + q* q)
    85. drad = 0.04
    86. drad_L = (cmag - drad)
    87. drad_L = drad_L * drad_L
    88. drad_H = (cmag + drad)
    89. drad_H = drad_H * drad_H
    90. for py = 0 to (SCR_HEIGHT shr 1) - 1
    91. ty = ly(py)
    92. for px = 0 to SCR_WIDTH - 1
    93. x = Lx(px)
    94. y = ty
    95. xsquare = 0
    96. ysquare = 0
    97. ztot =0
    98. i = 0
    99. while (i < MAXITER) and (( xsquare + ysquare ) < MAXSIZE)
    100. xsquare = x * x
    101. ysquare = y * y
    102. ytemp = x * y * 2
    103. x = xsquare - ysquare + p
    104. y = ytemp + q
    105. zmag = (x * x + y * y)
    106. if (zmag < drad_H) then
    107. if (zmag > drad_L) and (i > 0) then
    108. ztot = ztot + ( 1 - (abs(zmag - cmagsq) / drad))
    109. i_last = i
    110. end if
    111. end if
    112. i = i + 1
    113. if zmag > 4.0 then
    114. exit while
    115. end if
    116. wend
    117. if ztot > 0 then
    118. i = cint(sqr(ztot) * 500)
    119. else
    120. i = 0
    121. end if
    122. if i < 256 then
    123. red = i
    124. else
    125. red = 255
    126. end if
    127. if i < 512 and i > 255 then
    128. grn = i - 256
    129. else
    130. if i >= 512 then
    131. grn = 255
    132. else
    133. grn = 0
    134. end if
    135. end if
    136. if i <= 768 and i > 511 then
    137. blu = i - 512
    138. else
    139. if i >= 768 then
    140. blu = 255
    141. else
    142. blu = 0
    143. end if
    144. end if
    145. tmp = cint((red+grn+blu) * 0.33)
    146. red = cint((red+grn+tmp) * 0.33)
    147. grn = cint((grn+blu+tmp) * 0.33)
    148. blu = cint((blu+red+tmp) * 0.33)
    149. select case (i_last and 3)
    150. case 1
    151. tmp = red
    152. red = grn
    153. grn = blu
    154. blu = tmp
    155. case 2
    156. tmp = red
    157. blu = grn
    158. red = blu
    159. grn = tmp
    160. end select
    161. pixel = rgb( red, grn, blu )
    162. *p_buffer = pixel
    163. *p_bufferl = pixel
    164. p_buffer = p_buffer + 1
    165. p_bufferl = p_bufferl - 1
    166. next px
    167. next py
    168. 'calc fps
    169. fps = fps + 1
    170. if stime + 1 < timer then
    171. fps2 = fps
    172. fps = 0
    173. stime = timer
    174. #ifdef __FB_WIN32__
    175. SetWindowText( hwnd, "FreeBasic Julia Rings FPS:" & Fps2 )
    176. #endif
    177. end if
    178. ptc_update @buffer(0)
    179. loop until inkey <> ""
    180. ptc_close
    181. end

    由于它体积小,在嵌入式设备上有一定用处,在数据算法绘图上也能用,操作步骤简单,也决定了操控灵活性上有局限性。CSDN 上也能找到 TinyPTC 的应用和简介,所以就把它编译和试运行效果贴上来了。

  • 相关阅读:
    不可错过的10本架构师必读书籍,带你嗨翻架构师之路,三连评论送书!
    【c++百日刷题计划】 ———— DAY9,奋战百天,带你熟练掌握基本算法
    LOAD_BALANCE=false 主在不会切换备
    小程序页面跳转
    【尘缘赠书活动:01期】Python数据挖掘——入门进阶与实用案例分析
    代码随想录 -- day60 -- 84.柱状图中最大的矩形
    Python --- GUI编程(1)
    MAC如何重装系统(怒冲30大洋,才拿到的教程~,收藏点赞兄弟们)
    下载和安装vscode教程和配置中文插件(超详细)
    如何使用ArcGIS Pro制作粉饰效果
  • 原文地址:https://blog.csdn.net/weixin_45707491/article/details/136639488