Oxygen Basic

Programming => Example Code => Topic started by: Peter on October 06, 2015, 10:28:01 AM

Title: OpenGl2D Library
Post by: Peter 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]
Title: Re: OpenGl2D Library
Post by: Peter 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]
Title: Re: OpenGl2D Library
Post by: Peter 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
Title: Re: OpenGl2D Library
Post by: Mike Lobanovsky on October 07, 2015, 11:21:57 AM
No, of course not! :D

This image (reduced!)

(http://i1240.photobucket.com/albums/gg490/FbslGeek/Ocean.png) (http://s1240.photobucket.com/user/FbslGeek/media/Ocean.png.html)

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? :)
Title: Re: OpenGl2D Library
Post by: Peter 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.   
 
Title: Re: OpenGl2D Library
Post by: Aurel 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 
Title: Re: OpenGl2D Library
Post by: Mike Lobanovsky 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. :)
Title: Re: OpenGl2D Library
Post by: Patrice Terrier 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.

...


Title: Re: OpenGl2D Library
Post by: Patrice Terrier 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.

...

Title: Re: OpenGl2D Library
Post by: Peter 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?
Title: Re: OpenGl2D Library
Post by: Aurel 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.... ;)
Title: Re: OpenGl2D Library
Post by: Patrice Terrier 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
Title: Re: OpenGl2D Library
Post by: Aurel 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?
Title: Re: OpenGl2D Library
Post by: Aurel 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.

 
Title: Re: OpenGl2D Library
Post by: Mike Lobanovsky 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)
Title: Re: OpenGl2D Library
Post by: Patrice Terrier on October 09, 2015, 12:53:49 AM
Mike

Maybe that rough PB SDK code translation, could help you to convert it into true compiled code.

ML.bas main code
Code: [Select]
#COMPILE EXE "ML.exe"

#INCLUDE "MiniPB.inc" '// Flat API declaration
'MACRO Pi = 3.141592653589793##
'MACRO HalfPI = 1.5707963267948965##
'MACRO PiDiv4 = 0.785398163397448##
MACRO M_TWOPI = 6.28318530718##

'SetWindowLong(ME, GWL_STYLE, &H6000000)
%ClientW            = 1024
%ClientH            = 768

TYPE PROP
    hMain           as dword
    MinTrackSizeW   as long
    MinTrackSizeH   as long
    col(1023, 767)  as long
    CC(128, 8)      as long
    NZ(511, 511)    as long
    WB(1024, 384 to 768) as single
    WX(1023, 384 to 767) as single
    WY(1023, 384 to 767) as single
    FC              as single
    SX              as single
    SY              as single
END TYPE

GLOBAL gP as PROP ''// Global class properties

function Lerp(byval c1 as single, byval c2 as single, byval k as single) as dword
    function = ((c1 and &HFF) * k + (c2 and &HFF) * (1 - k)) or (((c1 and &HFF00) * k + (c2 and &HFF00) * (1 - k)) and &HFF00) or (((c1 and &HFF0000) * k + (c2 and &HFF0000) * (1 - k)) and &HFF0000)
end function

function BC(byval x as single, byval y as single) as single
    local ix, iy as long
    ix = round(x, 0): iy = round(y, 0)
    gP.SX = x - ix: gP.SY = y - iy
    local c0, c1, c2, c3 as long
    local ixy, isyx, isxy, xy as single
    ixy = (1 - gP.SX) * (1 - gP.SY)
    isxy = gP.SX * (1 - gP.SY)
    isyx = gP.SY * (1 - gP.SX)
    xy = gP.SX * gP.SY

    c0 = gP.CC(ix and 127, iy mod 9)
    c1 = gP.CC((ix + 1) and 127, iy mod 9)
    c2 = gP.CC(ix and 127, (iy + 1) mod 9)
    c3 = gP.CC((ix + 1) and 127, (iy + 1) mod 9)

    function = (c0 and &HFF) * ixy + (c1 and &HFF) * isxy + (c2 and &HFF) * isyx + (c3 and &HFF) * xy + _
               ((c0 and &HFF00) * ixy + (c1 and &HFF00) * isxy + (c2 and &HFF00) * isyx + (c3 and &HFF00) * xy and &HFF00) + _
               ((c0 and &HFF0000) * ixy + (c1 and &HFF0000) * isxy + (c2 and &HFF0000) * isyx + (c3 and &HFF0000) * xy and &HFF0000)
end function

function BN(byval x as single, byval y as single) as long
    local ix, iy, idx, idy as long
    ix = round(x, 0): iy = round(y, 0)
    local ssx, ssy as single
    gP.SX = x - ix: gP.SY = y - iy
    ssx = 1 - gP.SX: ssy = 1 - gP.SY
    idx = (ix + 1) and 511: idy = (iy + 1) and 511
    ix = ix and 511: iy = iy and 511
    function = gP.NZ(ix, iy) * ssx * ssy + gP.NZ(idx, iy) * gP.SX * ssy + gP.NZ(ix, idy) * ssx * gP.SY + gP.NZ(idx, idy) * gP.SX * gP.SY
end function

Sub Air(byval hDC as dword)
    local x, y as long, c as dword, k1, k2, s as single
    'local gtc as dword: gtc = GetTickCount()
    'print "Running Air() ";
    for y = 0 to 767
        k1 = (1 - abs(383.5 - y) / 384) ^ 5
        for x = 0 to 1023
            if (y = gP.SY) then
                k2 = 0.25
            else
                k2 = atn((x - gP.SX) / (y - gP.SY)) / M_TWOPI + 0.25
            end if
            if (y - gP.SY < 0) then k2 = k2 + 0.5
            k2 = BN(k2 * 512, 0) * 0.03
            k2 = 0.2 - k2 ^ 2: if k2 < 0 then k2 = 0
            s = 30 / sqr((x - gP.SX) ^ 2 + (y - gP.SY) ^ 2)
            if (s > 1) then s = 1
            c = Lerp(&HFFFFFF, gP.FC, k2 * (1 - s))
            SetPixelV(hDC, x, y, Lerp(c, gP.col(x, y), k1))
        next
    next
    'Print GetTickCount() - gtc, " msec"
end sub

sub Water()
    local sx1, sy1, sx2, sy2 as single
    local x, y, x1, y1, k, kx as long
    'local gtc as dword: gtc = GetTickCount()
    'Print "Running Water() "

    for y = 767 to 384 step -1
        k = (y - 383) * 0.5: kx = (900 - y) / 580
        for x = 1023 to 0 step -1
            sy1 = 64000 / (y - 380)
            sx1 = (x - 511.5) * sy1 * 0.002
            sy2 = sy1 * 0.34 - sx1 * 0.71
            sx2 = sx1 * 0.34 + sy1 * 0.71
            sy1 = sy2 * 0.34 - sx2 * 0.21
            sx1 = sx2 * 0.34 + sy2 * 0.21
            gP.WB(x, y) = BN(sx1, sy1) - BN(sx2, sy2)
            gP.WX(x, y) = (gP.WB(x + 1, y) - gP.WB(x, y)) * k * kx
            gP.WY(x, y) = (gP.WB(x, y + 1) - gP.WB(x, y)) * k
            x1 = abs(x + gP.WX(x, y))
            y1 = 768 - y + gP.WY(x, y)
            if (y1 < 0) then
                y1 = 0
            elseif (y1 > 383) then
                y1 = 383
            end if
            gP.col(x, y) = Lerp(BC(x1 / 8 / 2, y1 / 48 / 2), &H251510, kx) ' water tint
        next
    next
    'Print GetTickCount() - gtc, " msec"
end sub

sub Sky()
    local x, y, k as long
    local c1, c2 as dword
    local s, sx1, sy1, dy as single
    'local gtc as dword: gtc = GetTickCount()
    'Print "Running Sky() ";

    gP.SX = 100 + rnd() * 824: gP.SY = 192 + rnd() * 157

    for y = 0 to 383
        sy1 = 100000 / (390 - y)
        for x = 0 to 1023
            sx1 = (x - 511.5) * sy1 * 0.0005
            k = BN(sx1, sy1) - BN(sx1 * 0.14 + sy1 * 0.21, sy1 * 0.14 - sx1 * 0.21)
            if (k < -8) then
                k = 0
            else
                k = (k + 8) * 0.02 ' cloud density
            end if
            if (k > 1) then k = 1
            dy = y / 384
            gP.FC = &H908000 + (gP.SY + 500) * 0.2 ' haze tint
            c1 = Lerp(gP.FC + 25, &H906050, dy)
            c2 = Lerp(&H807080, &HD0D0D0, dy)
            s = 30 / sqr((x - gP.SX) ^ 2 + (y - gP.SY) ^ 2) ' sun size
            if (s > 1) then s = 1
            c1 = Lerp(&HFFFFFF, c1, s)
            gP.col(x, y) = Lerp(c2, c1, k)
        next
    next
    'Print GetTickCount() - gtc, " msec"
end sub

sub Colorize()
    local x, y, xx, yy, c, r, g, b, nc as long
    'local gtc as dword: gtc = GetTickCount()
    'Print "Running Colorize() ";

    for x = 0 to 127
        for y = 0 to 7
            r = g = b = 0
            for yy = 0 to 47
                for xx = 0 to 7
                    c = gP.col(xx + x * 8, yy + y * 48)
                    r = r + (c and &HFF)
                    g = g + (c and &HFF00)
                    nc = c and &HFF0000: shift right nc, 8
                    b = b + nc
                next
            next
            nc = (b \ 384) and &HFF00: shift left nc, 8
            gP.CC(x, y) = r \ 384 + ((g \ 384) and &HFF00) + nc
        next
        gP.CC(x, 8) = gP.CC(x, 7)
    next
    'Print GetTickCount() - gtc, " msec"
end sub

sub Initialize()
    local x, y, d, d2 as long
    d = 64: d2 = 128

    'local gtc as dword: gtc = GetTickCount()
    'Print "Running Initialize() ";

    randomize
    do
        for y = 0 to 511 step d2
            for x = 0 to 511 step d2
                gP.NZ((x + d) and 511, y) = (gP.NZ(x, y) + gP.NZ((x + d2) and 511, y)) * 0.5 + d * (rnd() - 0.5)
                gP.NZ(x, (y + d) and 511) = (gP.NZ(x, y) + gP.NZ(x, (y + d2) and 511)) * 0.5 + d * (rnd() - 0.5)
                gP.NZ((x + d) and 511, (y + d) and 511) = (gP.NZ(x, y) + gP.NZ((x + d2) and 511, (y + d2) and 511) + gP.NZ(x, (y + d2) and 511) + gP.NZ((x + d2) and 511, y)) * 0.25 + d * (rnd() - 0.5)
            next
        next
        if d = 1 then exit do
        d = d \ 2: d2 = d + d
    loop
    'Print GetTickCount() - gtc, " msec"
end sub

sub RenderScene(byval hDC as dword)
    Initialize()
    Sky()
    Colorize()
    Water()
    Air(hDC)
end sub

function WndProc(byval hWnd as dword, byval Msg as dword, byval wParam as dword, byval lParam as dword) as long
    LOCAL ps as PAINTSTRUCT
    LOCAL rc as RECT

    SELECT CASE long Msg

    CASE %WM_GETMINMAXINFO
         LOCAL pMM as MINMAXINFO PTR
         pMM = lParam
         @pMM.ptMinTrackSize.x = gP.MinTrackSizeW
         @pMM.ptMinTrackSize.y = gP.MinTrackSizeH

    'case %WM_NCHITTEST
    '     function = 2 ' %HTCAPTION
    '     exit function

    CASE %WM_SIZE
         InvalidateRect(hWnd, byval(%NULL), %TRUE)

    CASE %WM_COMMAND
         LOCAL wmId, wmEvent as long
         wmID    = LOINT(wParam)
         wmEvent = HIINT(wParam)
         '//SELECT CASE long LOWRD(wParam)
         '//
         '//END SELECT

    CASE %WM_PAINT
         LOCAL hDC as dword
         'InvalidateRect(hWnd, %NULL, %FALSE)
         hDC = BeginPaint(hWnd, ps)
         '// Paint the window content here
         RenderScene(hDC)
         EndPaint(hWnd, ps)
         function = 0: EXIT function

    CASE %WM_DESTROY
         PostQuitMessage(0)
         function = 0: EXIT function

    END SELECT

    function = DefWindowProc(hWnd, Msg, wParam, lParam)

end function

function WinMain (byval hInstance     as long, _
                  byval hPrevInstance as long, _
                  byval lpCmdLine     as ASCIIZ PTR, _
                  byval iCmdShow      as long) as long

    LOCAL nRet     as dword
    LOCAL wcx      as WNDCLASSEXA
    LOCAL szClass  as ASCIIZ * 16
    szClass = "FLAT_API_POPUP" '// The class name of our popup window.

    wcx.cbSize = SIZEOF(wcx)
    LOCAL IsInitialized as long
    IsInitialized = GetClassInfoEx(hInstance, szClass, wcx)
    if IsInitialized&   = 0 then
        wcx.style         = %CS_HREDRAW OR %CS_VREDRAW
        wcx.lpfnWndProc   = CODEPTR(WndProc)
        wcx.cbClsExtra    = 0
        wcx.cbWndExtra    = 0 '// %EXTEND_EXTRA * 4
        wcx.hInstance     = hInstance
        wcx.hIcon         = %NULL
        wcx.hCursor       = LoadCursor(%NULL, byval %IDC_ARROW)
        wcx.hbrBackground = GetStockObject(%WHITE_BRUSH)
        wcx.lpszMenuName  = %NULL
        wcx.lpszClassName = VARPTR(szClass)
        wcx.hIconSm       = wcx.hIcon
        if RegisterClassEx(wcx) then IsInitialized = %TRUE
    end if

    if (IsInitialized) then
        LOCAL r as RECT
        LOCAL uMsg as TagMSG
        LOCAL dwExStyle, dwStyle, hMain as dword
        LOCAL x, y as long

        dwExStyle = %WS_EX_APPWINDOW OR %WS_EX_WINDOWEDGE
        dwStyle = %WS_POPUP OR %WS_CAPTION OR %WS_SYSMENU OR %WS_THICKFRAME OR %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN

        SetRect(r, 0, 0, %ClientW, %ClientH)
        AdjustWindowRectEx(r, dwStyle, %FALSE, dwExStyle)

        gP.MinTrackSizeW = r.nRight - r.nLeft
        gP.MinTrackSizeH = r.nBottom - r.nTop
        x = MAX&((GetSystemMetrics(%SM_CXSCREEN) - gP.MinTrackSizeW) \ 2, 0)
        y = MAX&((GetSystemMetrics(%SM_CYSCREEN) - gP.MinTrackSizeH) \ 2, 0)

        gP.hMain = CreateWindowEx(dwExStyle, szClass, "Popup window 32-bit", dwStyle, _
                                  x, y, gP.MinTrackSizeW, gP.MinTrackSizeH, 0, 0, hInstance, byval %NULL)

        if (gP.hMain) then

            ShowWindow(gP.hMain, iCmdShow)
            SetForegroundWindow(gP.hMain) '// Slightly Higher Priority

            WHILE GetMessage(uMsg, %NULL, 0, 0)
                 TranslateMessage(uMsg)
                 DispatchMessage(uMsg)
            WEND

            nRet = uMsg.wParam
        end if

    end if

    function = nRet
end function

MiniPB.inc include
Code: [Select]
'// Flat API declaration

%CS_VREDRAW             = &H0001
%CS_HREDRAW             = &H0002

%SM_CXSCREEN            = 0
%SM_CYSCREEN            = 1

%IDC_ARROW              = 32512

%WS_BORDER              = 8388608
%WS_POPUP               = -2147483648
%WS_CHILD               = 1073741824
%WS_VISIBLE             = 268435456
%WS_CLIPSIBLINGS        = 67108864
%WS_CLIPCHILDREN        = 33554432
%WS_CAPTION             = 12582912
%WS_SYSMENU             = 524288
%WS_THICKFRAME          = 262144
%WS_MINIMIZEBOX         = 131072
%WS_MAXIMIZEBOX         = 65536
%WS_TABSTOP             = %WS_MAXIMIZEBOX
%WS_VSCROLL             = 2097152

%WS_EX_APPWINDOW        = 262144
%WS_EX_WINDOWEDGE       = 256

%WM_CREATE              = &H1
%WM_DESTROY             = &H2
%WM_PAINT               = &HF
%WM_CLOSE               = &H10
%WM_COMMAND             = &H111
%WM_GETMINMAXINFO       = &H24

%TRUE                   = 1
%FALSE                  = 0
%NULL                   = 0

%SW_HIDE                = 0
%SW_SHOW                = 5

%WHITE_BRUSH            = 0

TYPE POINT
    x AS LONG   '// long x
    y AS LONG   '// long y
END TYPE

TYPE TagMSG
    hWnd     AS DWORD   '// HWND hwnd
    nMessage AS DWORD   '// UINT Message
    wParam   AS DWORD   '// WPARAM wParam
    lParam   AS DWORD   '// LPARAM lParam
    nTime    AS DWORD   '// DWORD time
    pt       AS POINT   '// POINT pt
END TYPE

TYPE RECT
    nLeft   AS LONG   '// long Left
    nTop    AS LONG   '// long top
    nRight  AS LONG   '// long Right
    nBottom AS LONG   '// long bottom
END TYPE

TYPE WNDCLASSEXA
    cbSize          AS DWORD        '//Type C : UINT
    style           AS DWORD        '//Type C : UINT
    lpfnWndProc     AS DWORD        '//Type C : WNDPROC
    cbClsExtra      AS LONG         '//Type C : int
    cbWndExtra      AS LONG         '//Type C : int
    hInstance       AS DWORD        '//Type C : HINSTANCE
    hIcon           AS DWORD        '//Type C : HICON
    hCursor         AS DWORD        '//Type C : HCURSOR
    hbrBackground   AS DWORD        '//Type C : HBRUSH
    lpszMenuName    AS DWORD        '//Type C : LPCSTR
    lpszClassName   AS DWORD        '//Type C : LPCSTR
    hIconSm         AS DWORD        '//Type C : HICON   
END TYPE

TYPE PAINTSTRUCT
    hdc             AS DWORD        '//Type C : HDC
    fErase          AS LONG         '//Type C : BOOL
    rcPaint         AS RECT         '//RECT est une autre structure
    fRestore        AS LONG         '//Type C : BOOL
    fIncUpdate      AS LONG         '//Type C : BOOL
    rgbReserved     AS ASCIIZ * 32  '//Type C : BYTE
END TYPE

TYPE MINMAXINFO
    ptReserved      AS POINT
    ptMaxSize       AS POINT
    ptMaxPosition   AS POINT
    ptMinTrackSize  AS POINT
    ptMaxTrackSize  AS POINT
END TYPE

DECLARE FUNCTION AdjustWindowRectEx LIB "USER32.DLL" ALIAS "AdjustWindowRectEx" (lpRect AS RECT, BYVAL dsStyle AS LONG, BYVAL bMenu AS LONG, BYVAL dwEsStyle AS DWORD) AS LONG
DECLARE FUNCTION BeginPaint LIB "USER32.DLL" ALIAS "BeginPaint" (BYVAL hWnd AS DWORD, lpPaint AS PAINTSTRUCT) AS LONG
DECLARE FUNCTION CreateWindowEx LIB "USER32.DLL" ALIAS "CreateWindowExA" (BYVAL dwExStyle AS DWORD, lpClassName AS ASCIIZ, lpWindowName AS ASCIIZ, BYVAL dwStyle AS DWORD, BYVAL x AS LONG, BYVAL y AS LONG, _
                 BYVAL nWidth AS LONG, BYVAL nHeight AS LONG, BYVAL hWndParent AS DWORD, BYVAL hMenu AS DWORD, BYVAL hInstance AS DWORD, lpParam AS ANY) AS DWORD
DECLARE FUNCTION DefWindowProc LIB "USER32.DLL" ALIAS "DefWindowProcA" (BYVAL hWnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
DECLARE FUNCTION DispatchMessage LIB "USER32.DLL" ALIAS "DispatchMessageA" (lpMsg AS tagMSG) AS LONG
DECLARE FUNCTION EndPaint LIB "USER32.DLL" ALIAS "EndPaint" (BYVAL hWnd AS DWORD, lpPaint AS PAINTSTRUCT) AS LONG
DECLARE FUNCTION GetClassInfoEx LIB "USER32.DLL" ALIAS "GetClassInfoExA" (BYVAL hInst AS DWORD, lpszClass AS ASCIIZ, lpWndClass AS WNDCLASSEXA) AS LONG
DECLARE FUNCTION GetMessage LIB "USER32.DLL" ALIAS "GetMessageA" (lpMsg AS tagMSG, BYVAL hWnd AS DWORD, BYVAL uMsgFilterMin AS DWORD, BYVAL uMsgFilterMax AS DWORD) AS LONG
DECLARE FUNCTION GetStockObject LIB "GDI32.DLL" ALIAS "GetStockObject" (BYVAL nIndex AS LONG) AS DWORD
DECLARE FUNCTION GetSystemMetrics LIB "USER32.DLL" ALIAS "GetSystemMetrics" (BYVAL nIndex AS LONG) AS LONG
DECLARE FUNCTION InvalidateRect LIB "USER32.DLL" ALIAS "InvalidateRect" (BYVAL hWnd AS DWORD, lpRect AS RECT, BYVAL bErase AS LONG) AS LONG
DECLARE SUB      PostQuitMessage LIB "USER32.DLL" ALIAS "PostQuitMessage" (BYVAL nExitCode AS LONG)
DECLARE FUNCTION RegisterClassEx LIB "USER32.DLL" ALIAS "RegisterClassExA" (pcWndClassEx AS WNDCLASSEXA) AS WORD
DECLARE FUNCTION SetForegroundWindow LIB "USER32.DLL" ALIAS "SetForegroundWindow" (BYVAL hWnd AS DWORD) AS LONG
DECLARE FUNCTION SetRect LIB "USER32.DLL" ALIAS "SetRect" (lpRect AS RECT, BYVAL X1 AS LONG, BYVAL Y1 AS LONG, BYVAL X2 AS LONG, BYVAL Y2 AS LONG) AS LONG
DECLARE FUNCTION ShowWindow LIB "USER32.DLL" ALIAS "ShowWindow" (BYVAL hWnd AS DWORD, BYVAL nCmdShow AS LONG) AS LONG
DECLARE FUNCTION TranslateMessage LIB "USER32.DLL" ALIAS "TranslateMessage" (lpMsg AS tagMSG) AS LONG
DECLARE FUNCTION LoadCursor LIB "USER32.DLL" ALIAS "LoadCursorA" (BYVAL hInstance AS DWORD, lpCursorName AS ASCIIZ) AS DWORD
declare function SetPixelV lib "GDI32.DLL" alias "SetPixelV" (byval hDC as dword, byval x as long, byval y as long, byval crColor as dword) as long

This pure SDK code could be easily translated to C/C++, however this one will produce a small 16384 bytes standalone EXE (when compiled with PB 10), and 15872 bytes (with PB 9.05).  ;)

Note: for speed and to keep the code small,  avoid to use variant like the plague.

...
Title: Re: OpenGl2D Library
Post by: Mike Lobanovsky on October 09, 2015, 04:23:16 AM
Hi Patrice,

Thanks for the PB code! I've got the translation early in the morning but John's servers weren't accessible from this country for quite some time, hence the delay, for which I apologize.

Here comes the Dynamic C script. It uses FBSL's default window to draw to but some generic main window code may be easily added if the DynC portion is used with another static C compiler.

I used a 24-bit DIB and SetPixelV() because it doesn't add much overhead. It adds less than 100 ms extra as compared to setting the DIB pixel values directly but direct writes would require transposition of the array which would also take time and would drive me dizzy. I'm leaving SetPixelV() to you to substitute if necessary. :)

Overall startup time is approx. 0.5 sec on my PC. A precompiled executable is also attached in the zip below. Enjoy! :)

Code: C
  1. // VB6 code  (c)2014 Mikle           http://www.fbsl.net/phpbb2
  2. // FBSL port (c)2015 Mike Lobanovsky http://www.fbsl.net/phpbb2
  3.  
  4. #Include <Include/Windows.inc>
  5.  
  6. Type BITMAPINFOHEADER Align 2
  7.   %biSize
  8.   %biWidth
  9.   %biHeight
  10.   %biPlanes * 16
  11.   %biBitCount * 16
  12.   %biCompression
  13.   %biSizeImage
  14.   %biXPelsPerMeter
  15.   %biYPelsPerMeter
  16.   %biClrUsed
  17.   %biClrImportant
  18. End Type
  19.  
  20. Type BITMAPINFO
  21.   bmiHeader As BITMAPINFOHEADER
  22.   %bmiColors
  23. End Type
  24.  
  25. Dim %Pixdata[1023, 767]
  26. Dim Dib As BITMAPINFO
  27.  
  28. With Dib.bmiHeader
  29.   .biSize = SizeOf(BITMAPINFOHEADER)
  30.   .biWidth = 1024
  31.   .biHeight = 768
  32.   .biPlanes = 1
  33.   .biBitCount = 24
  34.   .biCompression = BI_RGB
  35. End With
  36.  
  37. Dim Bmp = CreateDIBSection(GetDC(ME), @Dib, DIB_RGB_COLORS, NULL, NULL, 0)
  38. Dim MemDC = CreateCompatibleDC(GetDC)
  39.  
  40. SetDIBits(GetDC, Bmp, 0, 768, @Pixdata, @Dib, DIB_RGB_COLORS)
  41. SelectObject(MemDC, Bmp)
  42. ReleaseDC(ME, GetDC)
  43.  
  44. Render(MemDC)
  45.  
  46. SetWindowLong(ME, GWL_STYLE, &H6000000)
  47. FbslTile(ME, Bmp)
  48. Resize(ME, 0, 0, 1024, 768)
  49. Center(ME): Show(ME)
  50.  
  51. Begin Events
  52.   Select Case CBMSG
  53.     Case WM_NCHITTEST
  54.       Return HTCAPTION
  55.     Case WM_COMMAND
  56.       If CBWPARAM = 2 Then PostMessage(ME, WM_CLOSE, 0, 0)
  57.     Case WM_DESTROY
  58.       DeleteDC(MemDC)
  59.       DeleteObject(Bmp)
  60.   End Select
  61. End Events
  62.  
  63. DynC Render(%dc)
  64.   #ifndef M_TWOPI
  65.     #define M_TWOPI 6.28318530717958647692 // Pi * 2
  66.   #endif
  67.   #ifdef RAND_MAX
  68.     #undef RAND_MAX
  69.   #endif
  70.   #define RAND_MAX 32767.0
  71.  
  72.   // *********************************************
  73.   // For other C compilers, replace this part with
  74.   // #include <windows.h>
  75.   // #include <math.h>
  76.   // Standard headers may require much stricter
  77.   // func parm and local var type definitions
  78.   // *********************************************
  79.  
  80.   #ifndef STDCALL
  81.     #define STDCALL __attribute__((stdcall))
  82.   #endif
  83.  
  84.   double pow(double, double);
  85.   double fabs(double);
  86.   double atan(double);
  87.   double sqrt(double);
  88.   double floor(double);
  89.  
  90.   int STDCALL RtlZeroMemory(void*, int);
  91.   int STDCALL GetTickCount(void);
  92.   int STDCALL SetPixelV(int, int, int, int);
  93.  
  94.   // *********************************************
  95.  
  96.   #define Rnd() rand() / RAND_MAX
  97.   #define Randomize() srand(GetTickCount())
  98.  
  99.   static int Col[1024][768], CC[128][8], NZ[512][512], WB[1024][768], WX[1024][768], WY[1024][768];
  100.   static double SX = 0.0, SY = 0.0, FC = 0.0;
  101.  
  102.   int Lerp(int c1, int c2, double k)
  103.   {
  104.     double d = 1.0 - k;
  105.    
  106.     return (int)((c1 & 0xFF)* k + (c2 & 0xFF)* d)
  107.       | ((int)((c1 & 0xFF00)* k + (c2 & 0xFF00)* d) & 0xFF00)
  108.       | ((int)((c1 & 0xFF0000)* k + (c2 & 0xFF0000)* d) & 0xFF0000);
  109.   }
  110.  
  111.   double BN(double x, double y) {
  112.     int ix = (int)floor(x), iy = (int)floor(y), dx = (ix + 1) & 511, dy = (iy + 1) & 511;
  113.     double SX = x - ix, SY = y - iy, isx = 1.0 - SX, isy = 1.0 - SY;
  114.    
  115.     ix &= 511; iy &= 511;
  116.     return NZ[ix][iy] * isx * isy + NZ[dx][iy] * SX * isy + NZ[ix][dy] * isx* SY + NZ[dx][dy] * SX * SY;
  117.   }
  118.  
  119.   int BC(double x, double y) {
  120.     int ix = (int)floor(x), iy = (int)floor(y), c0, c1, c2, c3;
  121.     double SX = x - ix, SY = y - iy, ixy = (1.0 - SX) * (1.0 - SY);
  122.     double isxy = SX * (1.0 - SY), isyx = SY * (1.0 - SX), xy = SX * SY;
  123.    
  124.     c0 = CC[ix & 127][iy % 9];
  125.     c1 = CC[(ix + 1) & 127][iy % 9];
  126.     c2 = CC[ix & 127][(iy + 1) % 9];
  127.     c3 = CC[(ix + 1) & 127][(iy + 1) % 9];
  128.    
  129.     return (c0 & 0xFF)* ixy + (c1 & 0xFF)* isxy + (c2 & 0xFF)* isyx + (c3 & 0xFF)* xy
  130.       + ((int)((c0 & 0xFF00)* ixy + (c1 & 0xFF00)* isxy + (c2 & 0xFF00)* isyx + (c3 & 0xFF00)* xy) & 0xFF00)
  131.       + ((int)((c0 & 0xFF0000)* ixy + (c1 & 0xFF0000)* isxy + (c2 & 0xFF0000)* isyx + (c3 & 0xFF0000)* xy) & 0xFF0000);
  132.   }
  133.  
  134.   void Initialize()
  135.   {
  136.     int x, y, d = 64, d2 = 128;
  137.    
  138.     Randomize();
  139.     while (1) {
  140.       for (y = 0; y < 512; y += d2) {
  141.         for (x = 0; x < 512; x += d2) {
  142.           NZ[(x + d) & 511][y] = (NZ[x][y] + NZ[(x + d2) & 511][y])* 0.5 + d * (Rnd() - 0.5);
  143.           NZ[x][(y + d) & 511] = (NZ[x][y] + NZ[x][(y + d2) & 511]) * 0.5 + d * (Rnd() - 0.5);
  144.           NZ[(x + d) & 511][(y + d) & 511] = (NZ[x][y] + NZ[(x + d2) & 511][(y + d2) & 511]
  145.             + NZ[x][(y + d2) & 511] + NZ[(x + d2) & 511][y]) * 0.25 + d * (Rnd() - 0.5);
  146.         }
  147.       }
  148.       if (d == 1) break;
  149.       d >>= 1; d2 = d + d;
  150.     }
  151.   }
  152.  
  153.   void Colorize()
  154.   {
  155.     int x, y, xx, yy, c, r, g, b;
  156.    
  157.     for (x = 0; x < 128; x++) {
  158.       for (y = 0; y < 8; y++) {
  159.         r = g = b = 0;
  160.         for (yy = 0; yy < 48; yy++) {
  161.           for (xx = 0; xx < 8; xx++) {
  162.             c = Col[xx + x * 8][yy + y * 48];
  163.             r += (c & 0xFF);
  164.             g += (c & 0xFF00);
  165.             b += ((c & 0xFF0000) >> 8);
  166.           }
  167.         }
  168.         CC[x][y] = r / 384 + ((g / 384) & 0xFF00) + (((b / 384) & 0xFF00) << 8);
  169.       }
  170.       CC[x][8] = CC[x][7];
  171.     }
  172.   }
  173.  
  174.   void Sky()
  175.   {
  176.     int x, y, c1, c2;
  177.     double k, s, sx1, sy1, dy;
  178.    
  179.     Initialize();
  180.    
  181.     SX = 100 + Rnd() * 824; SY = 192 + Rnd() * 157;
  182.     for (y = 0; y < 384; y++) {
  183.       sy1 = 100000.0 / (390.0 - y);
  184.       for (x = 0; x < 1024; x++) {
  185.         sx1 = (x - 511.5) * sy1 * 0.0005;
  186.         k = BN(sx1, sy1) - BN(sx1 * 0.14 + sy1 * 0.21, sy1 * 0.14 - sx1 * 0.21);
  187.         if (k < -8.0)
  188.           k = 0.0;
  189.         else
  190.           k = (k + 8.0) * 0.02; // cloud density
  191.         if (k > 1.0) k = 1.0;
  192.         dy = y / 384.0;
  193.         FC = 0x908000 + (SY + 500.0) * 0.2; // haze tint
  194.         c1 = Lerp(FC + 25, 0x906050, dy);
  195.         c2 = Lerp(0x807080, 0xD0D0D0, dy);
  196.         s = 30.0 / sqrt((x - SX) * (x - SX) + (y - SY) * (y - SY)); // sun size
  197.         if (s > 1.0) s = 1.0;
  198.         c1 = Lerp(0xFFFFFF, c1, s);
  199.         Col[x][y] = Lerp(c2, c1, k);
  200.       }
  201.     }
  202.   }
  203.  
  204.   void Water()
  205.   {
  206.     int x, y;
  207.     double x1, y1, k, kx, sx1, sy1, sx2, sy2;
  208.    
  209.     Colorize();
  210.    
  211.     for (y = 767; y >= 384; y--) {
  212.       k = (y - 383) * 0.5; kx = (900 - y) / 580.0;
  213.       for (x = 1023; x >= 0; x--) {
  214.         sy1 = 64000.0 / (y - 380);
  215.         sx1 = (x - 511.5) * sy1 * 0.002;
  216.         sy2 = sy1 * 0.34 - sx1 * 0.71;
  217.         sx2 = sx1 * 0.34 + sy1 * 0.71;
  218.         sy1 = sy2 * 0.34 - sx2 * 0.21;
  219.         sx1 = sx2 * 0.34 + sy2 * 0.21;
  220.         WB[x][y] = BN(sx1, sy1) - BN(sx2, sy2);
  221.         WX[x][y] = (WB[x + 1][y] - WB[x][y]) * k * kx;
  222.         WY[x][y] = (WB[x][y + 1] - WB[x][y]) * k;
  223.         x1 = fabs(x + WX[x][y]);
  224.         y1 = 768.0 - y + WY[x][y];
  225.         if (y1 < 0.0)
  226.           y1 = 0.0;
  227.         else if (y1 > 383.0)
  228.           y1 = 383.0;
  229.         Col[x][y] = Lerp(BC(x1 / 8, y1 / 48), 0x251510, kx); // water tint
  230.       }
  231.     }
  232.   }
  233.  
  234.   void Air(int hDC)
  235.   {
  236.     int x, y, c;
  237.     double k1, k2, s;
  238.    
  239.     for (y = 0; y < 768; y++) {
  240.       k1 = pow((1.0 - fabs(383.5 - y) / 384.0), 5.0);
  241.       for (x = 0; x < 1024; x++) {
  242.         if (y == SY)
  243.           k2 = 0.25;
  244.         else
  245.           k2 = atan((x - SX) / (y - SY)) / M_TWOPI + 0.25;
  246.         if (y - SY < 0) k2 = k2 + 0.5;
  247.         k2 = BN(k2 * 512.0, 0.0) * 0.03;
  248.         k2 = 0.2 - k2 * k2; if (k2 < 0.0) k2 = 0.0;
  249.         s = 30.0 / sqrt((x - SX) * (x - SX) + (y - SY) * (y - SY));
  250.         if (s > 1.0) s = 1.0;
  251.         c = Lerp(0xFFFFFF, FC, k2 * (1.0 - s));
  252.         SetPixelV(hDC, x, y, Lerp(c, Col[x][y], k1));
  253.       }
  254.     }
  255.   }
  256.  
  257.   void main(int hDC)
  258.   {
  259.     RtlZeroMemory(Col, 1024 * 768 * sizeof(int));
  260.     RtlZeroMemory(CC,  128  * 8   * sizeof(int));
  261.     RtlZeroMemory(NZ,  512  * 512 * sizeof(int));
  262.     RtlZeroMemory(WB,  1024 * 768 * sizeof(int));
  263.     RtlZeroMemory(WX,  1024 * 768 * sizeof(int));
  264.     RtlZeroMemory(WY,  1024 * 768 * sizeof(int));
  265.    
  266.     Sky();
  267.     Water();
  268.     Air(hDC);
  269.   }
  270. End DynC

[attachment deleted by admin]
Title: Re: OpenGl2D Library
Post by: JRS on October 09, 2015, 04:54:25 AM
Quote
John's servers weren't accessible from this country for quite some time,

And why was that?
Why didn't you e-mail me with the issue on your end?

There was only a short outage a while back due to the All BASIC Blog (WP) with hacking issues turning the server into a spam server and eating resources. (China 'friends')

Title: Re: OpenGl2D Library
Post by: Mike Lobanovsky on October 09, 2015, 05:08:51 AM
Hi John,

Why didn't you e-mail me with the issue on your end?

I would, if only the problem persisted for over 12 hours but it didn't. The outage does happen from time to time, probably once in two or three weeks for a few hours but of course not as often as in the BP case. At any rate, we aren't as active here now as we used to be, so that isn't a problem for me really. As it happens, fbsl dot net is usually out for a few hours late on Wednesday nights as well (it uses a U.S. server provider) but there it's usually due to maintenance hours.

No big deal, really. :)