Author Topic: OpenGl2D Library  (Read 6248 times)

0 Members and 1 Guest are viewing this topic.

Peter

  • Guest
OpenGl2D Library
« on: October 06, 2015, 10:28:01 AM »
Hello,
yes I see, there's not much interest in sdl library.
what about OpenGl?

I wil start an attempt!
first example: graphics primitives
Code: [Select]
include "ogl.inc"
window 640,480,1

Enable GL_POINT_SMOOTH
Enable GL_LINE_SMOOTH

fontload(1,"glfonts/font15.bmp")

while key(27)=0
cls 100, 100, 100
color 255,255,0,255
line  0,100,639,100,6
color 255,255,0,200
line  0,106,639,106,6
color 255,255,0,128
line  0,112,639,112,6

color    255,200,200,255
box      50, 20,60,60,1
fillbox  110,20,60,60
circle   210,50,40,1
fillcircle 290,50,40
ellipse  370,50,40,20,1
fillellipse 430,50,20,40

color 0,255,255,255
for x=0 to 9
   SetPoint(150+rand(1,19),150+rand(1,19),8)
next

GetPixel(110,112)
text(1,0, 0,"RED   " + str(RED)  ,16,16)
text(1,0,12,"GREEN " + str(GREEN),16,16)
text(1,0,24,"BLUE  " + str(BLUE) ,16,16)

redraw
wait 10
wend
winExit



[attachment deleted by admin]

Peter

  • Guest
Re: OpenGl2D Library
« Reply #1 on: October 06, 2015, 10:31:35 AM »
Hi,
second example: lorenz
Code: [Select]
include "ogl.inc"
window 800,700,1

fontload 1,"glfonts/font01.bmp"
Enable GL_POINT_SMOOTH

float x,y,n
string s="LORENZ LANDSCAPE"
Color 255,255,255,255   
   
while key(27)=0
cls 0,0,0
for t=0 to 100000
    x=Sin(t*0.99)-0.7*cos(t*3.01)
    y=Cos(t*1.01)+0.1*sin(t*15.03)
    x=x*200+350
    y=y*200+360
    setpixel y,x
next

for i=1 to Len(s)
    text 1,700,32+i*16,Mid(s,i,1),16,16
next
swap
wait 10
wend
winExit

[attachment deleted by admin]

Peter

  • Guest
Re: OpenGl2D Library
« Reply #2 on: October 07, 2015, 01:40:15 AM »
My attempt seems to have failed!   ;D
What now,  GDI again or go to hell with your Libraries!  :D

Mein Versuch scheint gescheitert!  ;D
Was nun, wieder GDI oder geh zur Hölle mit deinen Bibliotheken!  :D

Mike Lobanovsky

  • Guest
Re: OpenGl2D Library
« Reply #3 on: October 07, 2015, 11:21:57 AM »
No, of course not! :D

This image (reduced!)



with all its skies, water, clouds, mist, light shafts is drawn entirely programmatically using a couple of Windows APIs and some very basic BASIC code. Its FBSL implementation is as follows: (watch out for line wrap!)

Code: OxygenBasic
  1. #AppType Console
  2. #Include <Include/Windows.inc>
  3.  
  4. Dim %NZ[511, 511], !WB[1024, 384 To 768], !WX[1023, 384 To 767], !WY[1023, 384 To 767]
  5. Dim %Col[1023, 767], %CC[128, 8]
  6. Dim FC, SX, SY, $PS * 64
  7.  
  8. SetWindowLong(ME, GWL_STYLE, &H6000000)
  9. Resize(ME, 0, 0, 1024, 768)
  10. Center(ME): Show(ME)
  11.  
  12. Begin Events
  13.   Select Case CBMSG
  14.     Case WM_NCHITTEST
  15.       Return HTCAPTION
  16.     Case WM_COMMAND
  17.       If CBWPARAM = 2 Then PostMessage(ME, WM_CLOSE, 0, 0)
  18.     Case WM_PAINT
  19.       InvalidateRect(ME, NULL, FALSE)
  20.       Render(BeginPaint(ME, PS)): EndPaint(ME, PS): Return 0
  21.   End Select
  22. End Events
  23.  
  24. Sub Render(hDC)
  25.   Initialize()
  26.   Sky()
  27.   Colorize()
  28.   Water()
  29.   Air(hDC)
  30. End Sub
  31.  
  32. Sub Initialize()
  33.   Dim x, y, d = 64, d2 = 128, gtc = GetTickCount()
  34.  
  35.   Print "Running Initialize() ";
  36.   Randomize
  37.   Do
  38.         For y = 0 To 511 Step d2
  39.                 For x = 0 To 511 Step d2
  40.                         NZ[(x + d) BAnd 511, y] = (NZ[x, y] + NZ[(x + d2) BAnd 511, y]) * 0.5 + d * (Rnd() - 0.5)
  41.                         NZ[x, (y + d) BAnd 511] = (NZ[x, y] + NZ[x, (y + d2) BAnd 511]) * 0.5 + d * (Rnd() - 0.5)
  42.                         NZ[(x + d) BAnd 511, (y + d) BAnd 511] = (NZ[x, y] + NZ[(x + d2) BAnd 511, (y + d2) BAnd 511] + NZ[x, (y + d2) BAnd 511] + NZ[(x + d2) BAnd 511, y]) * 0.25 + d * (Rnd() - 0.5)
  43.                 Next
  44.         Next
  45.         If d = 1 Then Exit Do
  46.         d = d \ 2: d2 = d + d
  47.   Loop
  48.   Print GetTickCount() - gtc, " msec"
  49. End Sub
  50.  
  51. Sub Air(hDC)
  52.   Dim x, y, c, k1, k2, s, gtc = GetTickCount()
  53.  
  54.   Print "Running Air() ";
  55.   For y = 0 To 767
  56.     k1 = (1 - Abs(383.5 - y) / 384) ^ 5
  57.     For x = 0 To 1023
  58.       If y = SY Then
  59.         k2 = 0.25
  60.       Else
  61.         k2 = ATn((x - SX) / (y - SY)) / M_TWOPI + 0.25
  62.       End If
  63.       If y - SY < 0 Then k2 = k2 + 0.5
  64.       k2 = BN(k2 * 512, 0) * 0.03
  65.       k2 = 0.2 - k2 ^ 2: If k2 < 0 Then k2 = 0
  66.       s = 30 / SqR((x - SX) ^ 2 + (y - SY) ^ 2)
  67.       If s > 1 Then s = 1
  68.       c = Lerp(&HFFFFFF, FC, k2 * (1 - s))
  69.       SetPixelV(hDC, x, y, Lerp(c, Col[x, y], k1))
  70.     Next
  71.   Next
  72.   Print GetTickCount() - gtc, " msec"
  73. End Sub
  74.  
  75. Sub Water()
  76.   Dim x, y, x1, y1, k, kx, sx1, sy1, sx2, sy2, gtc = GetTickCount()
  77.  
  78.   Print "Running Water() ";
  79.   For y = 767 DownTo 384
  80.     k = (y - 383) * 0.5: kx = (900 - y) / 580
  81.     For x = 1023 DownTo 0
  82.       sy1 = 64000 / (y - 380)
  83.       sx1 = (x - 511.5) * sy1 * 0.002
  84.       sy2 = sy1 * 0.34 - sx1 * 0.71
  85.       sx2 = sx1 * 0.34 + sy1 * 0.71
  86.       sy1 = sy2 * 0.34 - sx2 * 0.21
  87.       sx1 = sx2 * 0.34 + sy2 * 0.21
  88.       WB[x, y] = BN(sx1, sy1) - BN(sx2, sy2)
  89.       WX[x, y] = (WB[x + 1, y] - WB[x, y]) * k * kx
  90.       WY[x, y] = (WB[x, y + 1] - WB[x, y]) * k
  91.       x1 = Abs(x + WX[x, y])
  92.       y1 = 768 - y + WY[x, y]
  93.       If y1 < 0 Then
  94.         y1 = 0
  95.       ElseIf y1 > 383 Then
  96.         y1 = 383
  97.       End If
  98.       Col[x, y] = Lerp(BC(x1 / 8 / 2, y1 / 48 / 2), &H251510, kx) ' water tint
  99.    Next
  100.   Next
  101.   Print GetTickCount() - gtc, " msec"
  102. End Sub
  103.  
  104. Sub Sky()
  105.   Dim x, y, c1, c2, k, s, sx1, sy1, dy, gtc = GetTickCount()
  106.  
  107.   Print "Running Sky() ";
  108.   SX = 100 + Rnd() * 824: SY = 192 + Rnd() * 157
  109.   For y = 0 To 383
  110.     sy1 = 100000 / (390 - y)
  111.     For x = 0 To 1023
  112.       sx1 = (x - 511.5) * sy1 * 0.0005
  113.       k = BN(sx1, sy1) - BN(sx1 * 0.14 + sy1 * 0.21, sy1 * 0.14 - sx1 * 0.21)
  114.       If k < -8 Then
  115.         k = 0
  116.       Else
  117.         k = (k + 8) * 0.02 ' cloud density
  118.      End If
  119.       If k > 1 Then k = 1
  120.       dy = y / 384
  121.       FC = &H908000 + (SY + 500) * 0.2 ' haze tint
  122.      c1 = Lerp(FC + 25, &H906050, dy)
  123.       c2 = Lerp(&H807080, &HD0D0D0, dy)
  124.       s = 30 / SqR((x - SX) ^ 2 + (y - SY) ^ 2) ' sun size
  125.      If s > 1 Then s = 1
  126.       c1 = Lerp(&HFFFFFF, c1, s)
  127.       Col[x, y] = Lerp(c2, c1, k)
  128.     Next
  129.   Next
  130.   Print GetTickCount() - gtc, " msec"
  131. End Sub
  132.  
  133. Sub Colorize()
  134.   Dim x, y, xx, yy, c, r, g, b, gtc = GetTickCount()
  135.  
  136.   Print "Running Colorize() ";
  137.   For x = 0 To 127
  138.         For y = 0 To 7
  139.                 Let(r, g, b) = 0
  140.                 For yy = 0 To 47
  141.                         For xx = 0 To 7
  142.                                 c = Col[xx + x * 8, yy + y * 48]
  143.                                 r = r + (c BAnd &HFF)
  144.                                 g = g + (c BAnd &HFF00)
  145.                                 b = b + ((c BAnd &HFF0000) >> 8)
  146.                         Next
  147.                 Next
  148.                 CC[x, y] = r \ 384 + ((g \ 384) BAnd &HFF00) + (((b \ 384) BAnd &HFF00) << 8)
  149.         Next
  150.         CC[x, 8] = CC[x, 7]
  151.   Next
  152.   Print GetTickCount() - gtc, " msec"
  153. End Sub
  154.  
  155. Function BC(x, y)
  156.   Dim ix = Floor(x), iy = Floor(y), SX = x - ix, SY = y - iy, c0, c1, c2, c3
  157.   Dim ixy = (1 - SX) * (1 - SY), isxy = SX * (1 - SY), isyx = SY * (1 - SX), xy = SX * SY
  158.  
  159.   c0 = CC[ix BAnd 127, iy Mod 9]
  160.   c1 = CC[(ix + 1) BAnd 127, iy Mod 9]
  161.   c2 = CC[ix BAnd 127, (iy + 1) Mod 9]
  162.   c3 = CC[(ix + 1) BAnd 127, (iy + 1) Mod 9]
  163.  
  164.   Return (c0 BAnd &HFF) * ixy + (c1 BAnd &HFF) * isxy + (c2 BAnd &HFF) * isyx + (c3 BAnd &HFF) * xy + _
  165.   ((c0 BAnd &HFF00) * ixy + (c1 BAnd &HFF00) * isxy + (c2 BAnd &HFF00) * isyx + (c3 BAnd &HFF00) * xy BAnd &HFF00) + _
  166.   ((c0 BAnd &HFF0000) * ixy + (c1 BAnd &HFF0000) * isxy + (c2 BAnd &HFF0000) * isyx + (c3 BAnd &HFF0000) * xy BAnd &HFF0000)
  167. End Function
  168.  
  169. Function BN(x, y)
  170.   Dim ix = Floor(x), iy = Floor(y), SX = x - ix, SY = y - iy, isx = 1 - SX, isy = 1 - SY, dx = (ix + 1) BAnd 511, dy = (iy + 1) BAnd 511
  171.  
  172.   ix = ix BAnd 511: iy = iy BAnd 511
  173.   Return NZ[ix, iy] * isx * isy + NZ[dx, iy] * SX * isy + NZ[ix, dy] * isx * SY + NZ[dx, dy] * SX * SY
  174. End Function
  175.  
  176. Function Lerp(c1, c2, k)
  177.         Return((c1 BAnd &HFF) * k + (c2 BAnd &HFF) * (1 - k)) BOr (((c1 BAnd &HFF00) * k + (c2 BAnd &HFF00) * (1 - k)) BAnd &HFF00) BOr (((c1 BAnd &HFF0000) * k + (c2 BAnd &HFF0000) * (1 - k)) BAnd &HFF0000)
  178. End Function

where % stands for As Long or Cast Long, ! same for Single, $ same for String, BAnd means binary And, and M_TWOPI denotes Pi * 2. Untyped variables are of type As Variant, which means they will store or pass any type assigned to them according to the types of expression operands and operators used for their assignment. For example, a Variant will become Double if floating-point division / is used, or Long if integer division \ is used.


Can any of your libraries or Win API + O2 code draw a similar picture? :)

Peter

  • Guest
Re: OpenGl2D Library
« Reply #4 on: October 07, 2015, 12:29:39 PM »
Hi Mike
Great thing what you are showing here!

Quote
Can any of your libraries or Win API + O2 code draw a similar picture?
Of course not!

These libraries haven't enough power like FBSL.

Quote
Dim %NZ[511, 511], !WB[1024, 384 To 768], !WX[1023, 384 To 767], !WY[1023, 384 To 767]
Dim %Col[1023, 767], %CC[128, 8]
Quote
NZ[(x + d) BAnd 511, y] = (NZ[x, y] + NZ[(x + d2) BAnd 511, y]) * 0.5 + d * (Rnd() - 0.5)

This would be a handicap with OxygenBasic.
I think it's very much work, qualitatively to do the same with my puny libraries & OxygenBasic.

Many thanks for asking.   
 

Aurel

  • Guest
Re: OpenGl2D Library
« Reply #5 on: October 07, 2015, 12:31:02 PM »
Hey Mike
you must post this on bp.org forum  and ask super ZXdunny is
there a way in spec<bas to draw uch a image  ;D ;D

well i think that is possible to draw such a image with winApi in o2 

Mike Lobanovsky

  • Guest
Re: OpenGl2D Library
« Reply #6 on: October 07, 2015, 03:06:35 PM »
Hello Peter,

First of all, I must note you're making remarkably good progress with your English. My sincere compliments! :)

Secondly, please get me right; I was not trying to mock or diminish your work or your libraries. I just know that uneasy feeling very well when you've been working on something for a long time only to find in the end that nobody seems to take visible interest in your results. Then you get frustrated, and everything is falling out of your hands, and you can't find anything to occupy yourself with and recover from depression and despondency. :)

Porting someone else's code proved a good remedy for me in the past and I just thought that perhaps you might find it useful as well.


Hello Aurel,

Yes, I think it is perfectly feasible to translate this code to OxygenBasic. Each two-dimensional array will just have to be split in two linear arrays of matching size. The lower bound of those formerly second-dimension arrays can start at 0 and you can simply ignore those lower elements that aren't useful for your code. Similar to VB, FBSL has means to eliminate them completely in order to reduce memory usage because every FBSL variable regardless of its data type is in fact at least a 20 byte long Variant structure.

On splitting the arrays, most headaches will be over because O2 seems to have all other instruments to reimplement this code almost word for word.

But no, I won't be showing off anything at BP. I'm waking up from my usual standby lurking mode only when Jochen attacks the C language (that's my everyday programming instrument) over there for no apparent reason. :)

Patrice Terrier

  • Guest
Re: OpenGl2D Library
« Reply #7 on: October 08, 2015, 01:04:12 AM »
Mike--

Do you have the same source code in either plain PowerBASIC or C++ (without variant) ?

I would like to give it a try in true compiled mode, thank you.

...



Patrice Terrier

  • Guest
Re: OpenGl2D Library
« Reply #8 on: October 08, 2015, 07:16:44 AM »
I did translate Mike's code to PB, however i must have done several errors in the translation, because what i get is rather far from the posted screen shot.

I would say however than the use of SetPixel (even SetPixelV) is known to be notoriously slow, and i would rather use a memory DIB bitmap to setup the pixels using direct addressing (pointer), then BitBlting everything in WM_PAINT in a blink eye.

...


Peter

  • Guest
Re: OpenGl2D Library
« Reply #9 on: October 08, 2015, 09:06:10 AM »
Hello,

Quote
I did translate Mike's code to PB, however i must have done several errors in the translation, because what i get is rather far from the posted screen shot.
How does it look?

Aurel

  • Guest
Re: OpenGl2D Library
« Reply #10 on: October 08, 2015, 09:22:57 AM »
Quote
and i would rather use a memory DIB bitmap to setup the pixels using direct addressing (pointer), then BitBlting everything in WM_PAINT in a blink eye.
yes we like to know that ...if is not a problem.... ;)

Patrice Terrier

  • Guest
Re: OpenGl2D Library
« Reply #11 on: October 08, 2015, 09:35:52 AM »
Mike is using a client size of 1024 x 768, and a fixed window (no resize), then all you have to do is to create a memory bitmap of the same size using for example CreateDIBSection.

Code: [Select]
FUNCTION zCreateDIBSection(BYVAL hDC AS LONG, BYVAL nWidth AS LONG, BYVAL nHeight AS LONG, BYVAL BitCount AS LONG) AS LONG
    LOCAL bi AS BITMAPINFO
    bi.bmiHeader.biSize = SIZEOF(bi.bmiHeader)
    bi.bmiHeader.biWidth = nWidth
    bi.bmiHeader.biHeight = nHeight
    bi.bmiHeader.biPlanes = 1
    bi.bmiHeader.biBitCount = BitCount
    bi.bmiHeader.biCompression = %BI_RGB
    FUNCTION = CreateDIBSection(hDC, bi, %DIB_RGB_COLORS, 0, 0, 0)
END FUNCTION
« Last Edit: October 08, 2015, 09:44:47 AM by Patrice Terrier »

Aurel

  • Guest
Re: OpenGl2D Library
« Reply #12 on: October 08, 2015, 09:49:57 AM »
Thanks Patrice...
but if I understand ..first we must define BITMAPINFO header ..right?
just a function is not enough...

which other api functions are required?

Aurel

  • Guest
Re: OpenGl2D Library
« Reply #13 on: October 08, 2015, 09:56:59 AM »
I just look into Jose Roca site and found this :

Description

 

The DIBSECTION structure contains information about a DIB created by calling the CreateDIBSection function. A DIBSECTION structure includes information about the bitmap's dimensions, color format, color masks, optional file mapping object, and optional bit values storage offset. An application can obtain a filled-in DIBSECTION structure for a given DIB by calling the GetObject function.

 

C++ Syntax

 

typedef struct tagDIBSECTION {

BITMAP              dsBm;

BITMAPINFOHEADER    dsBmih;

DWORD               dsBitfields[3];

HANDLE              dshSection;

DWORD               dsOffset;

} DIBSECTION, *PDIBSECTION;

 

PowerBASIC Syntax

 

TYPE DIBSECTION

dsBm AS BITMAP

dsBmih AS BITMAPINFOHEADER

dsBitfields(2) AS DWORD

dshSection AS DWORD

dsOffset AS DWORD

END TYPE

 

Members

 

dsBm

 

A BITMAP data structure that contains information about the DIB: its type, its dimensions, its color capacities, and a pointer to its bit values.

 

dsBmih

 

A BITMAPINFOHEADER structure that contains information about the color format of the DIB.

 

dsBitfields

 

Specifies three color masks for the DIB. This field is only valid when the BitCount member of the BITMAPINFOHEADER structure has a value greater than 8. Each color mask indicates the bits that are used to encode one of the three color channels (red, green, and blue).

 

dshSection

 

Contains a handle to the file mapping object that the CreateDIBSection function used to create the DIB. If CreateDIBSection was called with a NULL value for its hSection parameter, causing the system to allocate memory for the bitmap, the dshSection member will be NULL.

 

dsOffset

 

Specifies the offset to the bitmap's bit values within the file mapping object referenced by dshSection. If dshSection is NULL, the dsOffset value has no meaning.

 

Mike Lobanovsky

  • Guest
Re: OpenGl2D Library
« Reply #14 on: October 08, 2015, 04:39:29 PM »
Hi Patrice,

Currently, this code exists only in FBSL BASIC and VB6. The VB6 implementation uses Form.AutoRedraw = TRUE which effectively means its internal PSet() interpretation (~ SetPixelV() here) draws directly into the DIB section pixel array and then simply blits the array on screen as needed in response to the incoming WM_PAINT messages. But even when compiled to native code, autoredraw-able VB6 is only some 5 times faster than this interpretative FBSL script.

I can try and re-write it in FBSL's Dynamic C, which will make the script code suitable for use in any static C compiler with just a couple of C-language standard system include files and a few extra lines to create a window to draw to instead of FBSL's default main window created automatically at app start (in FBSL, we refer to its hWnd traditionally as ME) that DynC will be using for its graphic output.

Please stay tuned. :)

(Note that each generated image is unique in size and position of sun, light shafts, clouds, and sea waves)