Oxygen Basic
Programming => Problems & Solutions => Topic started by: Aurel on January 25, 2020, 03:07:22 AM
-
Hello Charles.. and all orhers
I need small help about how to properly translate this C code to o2
struct pixel {
union {
struct {
/* 'a' unused, used for 32-bit alignment,
* could also be used to store pixel alpha
*/
unsigned char b, g, r, a;
};
int val;
};
pixel() {
val = 0;
}
};
thanks
-
Hi Aurel,
It simplifies to:
type pixel
ubyte b,g,r,a
=
int val
end type
and unlike C, All variables are automtically initialised to nul.
-
Hi Charles
..and thank you , i am trying to convert one simple but fast gdi dib example , i will post it here
;)
-
Hi Charles
I get really strange error about parameter mismatch
for gdi function CreateDIBSection()
in declaration i have exactly 6 params also as in setting subroutine
i am asking you what I made wrong ?
'fast GDI with DIB section
$ filename "FastGDI.exe"
include "RTL32.inc"
include "awinh037.inc"
#lookahead
' struct pixel
type PIXEL
ubyte b
ubyte g
ubyte r
ubyte a
=
int value
end type
type BITMAPINFOHEADER
DWORD biSize
LONG biWidth
LONG biHeight
WORD biPlanes
WORD biBitCount
DWORD biCompression
DWORD biSizeImage
LONG biXPelsPerMeter
LONG biYPelsPerMeter
DWORD biClrUsed
DWORD biClrImportant
end type
type RGBQUAD
BYTE rgbBlue
BYTE rgbGreen
BYTE rgbRed
BYTE rgbReserved
end type
type BITMAPINFO
BITMAPINFOHEADER bmiHeader
RGBQUAD bmiColors
end type
! CreateDIBSection Lib "gdi32.dll" (ByVal hDC As Long,byref pBitmapInfo As BITMAPINFO, ByVal un As Long, ByVal lplpVoid As Long, ByVal handle As Long, ByVal dw As Long) As Long
% DIB_RGB_COLORS = 0
' Window client size
int width = 375
int height = 375
% BI_RGB = 0
' Target fps, though it's hard to achieve this fps
' without extra timer functionality unless you have
' a powerfull processor. Raising this value will
' increase the speed, though it will use up more CPU.
int fps = 50
' Global Windows/Drawing variables
INT hbmp
INT hTickThread
INT hwnd
INT hdc
INT hdcMem
INT wstyle = WS_MINMAXSIZE or WS_CLIPCHILDREN
' Pointer to pixels (will automatically have space allocated by CreateDIBSection
PIXEL pixels
INT win
'reg class & create window using awinh037.inc ---------------------------------------
win = SetWindow("Fast_GDI", 300, 200, width, height, 0, wstyle)
'------------------------------------------------------------------------------------
RECT rcClient, rcWindow
POINTAPI ptDiff
' Get window and client sizes
GetClientRect( win, rcClient )
GetWindowRect( win, rcWindow )
' Find offset between window size and client size
ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right
ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom
' Resize client
MoveWindow( win, rcWindow.left, rcWindow.top, width + ptDiff.x, height + ptDiff.y, -1)
UpdateWindow( win )
' wmsg loop >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
while GetMessage(wm, 0, 0, 0)
TranslateMessage wm
DispatchMessage wm
wend
' <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Function WndProc( sys hwnd, wmsg, wParam, lParam) as sys callback
SELECT hwnd
CASE win
select wmsg
case WM_CREATE
' MakeSurface( hwnd )
case WM_PAINT
PAINTSTRUCT ps
hdc = BeginPaint( win, ps )
' Draw pixels to window when window needs repainting
BitBlt( hdc, 0, 0, width, height, hdcMem, 0, 0, SRCCOPY )
EndPaint( win, ps )
case WM_CLOSE
DestroyWindow( win )
case WM_DESTROY
'TerminateThread( hTickThread, 0 )
PostQuitMessage( 0 )
'case else
'return DefWindowProc( hwnd, wmsg, wParam, lParam )
end select
END SELECT
Return DefWindowProc(hwnd,wMsg,wParam,lParam)
End Function
'..................................................................
SUB MakeSurface(INT wnd)
' Use CreateDIBSection to make a HBITMAP which can be quickly
' blitted to a surface while giving 100% fast access to pixels before blit.
' Desired bitmap properties
BITMAPINFOHEADER bmi
bmi.biSize = sizeof(BITMAPINFOHEADER)
bmi.biWidth = width
bmi.biHeight = -height ' Order pixels from top to bottom
bmi.biPlanes = 1
bmi.biBitCount = 32 ' last byte not used, 32 bit for alignment
bmi.biCompression = BI_RGB
bmi.biSizeImage = 0
bmi.biXPelsPerMeter = 0
bmi.biYPelsPerMeter = 0
bmi.biClrUsed = 0
bmi.biClrImportant = 0
BITMAPINFO bmci
bmci.bmiColors[0].rgbRed = 0
bmci.bmiColors[0].rgbGreen = 0
bmci.bmiColors[0].rgbBlue = 0
bmci.bmiColors[0].rgbReserved = 0
hdc = GetDC( win )
lPtr as long
' Create DIB section to always give direct access to pixels
hbmp = CreateDIBSection( hdc, bmi, DIB_RGB_COLORS, pixels , 0, 0 )
DeleteDC( hdc )
' Create a new thread to use as a timer
'hTickThread = CreateThread( NULL, NULL, &tickThreadProc, 0, 0, 9 )
END SUB
-
o2 complain under this line : pass 2
hbmp = CreateDIBSection( hdc, bmi, DIB_RGB_COLORS, pixels , 0, 0 )
-
It should work using corewin
this will include gdi.inc
-
Well not work as i think with all possible problems with pointers and adresses
i really become confused.
I think ( only think) that createDIBsection well respond - not crush
CreateThread() not crush if is in SUSSPENDED mode ...hm.. never use this function before
very complex program for translation ...so if anyone have idea how this might work let me known..
i will try reconfigure program to work without Threading and without DIB
here is what i done today...in few hours ::)
Of course you don't need to use awinho37.inc .... it can be created directly with little bit more code
(i was tested awinh is not in any conflict with this two functions )
'fast GDI with DIB section
$ filename "FastGDI.exe"
include "RTL32.inc"
include "awinh037.inc"
#lookahead
' struct pixel
type PIXEL
ubyte b,g,r,a
=
int value
end type
type BITMAPINFOHEADER
LONG biSize
LONG biWidth
LONG biHeight
INTEGER biPlanes
INTEGER biBitCount
LONG biCompression
LONG biSizeImage
LONG biXPelsPerMeter
LONG biYPelsPerMeter
LONG biClrUsed
LONG biClrImportant
end type
type RGBQUAD
BYTE rgbBlue
BYTE rgbGreen
BYTE rgbRed
BYTE rgbReserved
end type
type BITMAPINFO
BITMAPINFOHEADER bmiHeader
RGBQUAD bmiColors
end type
Declare Function CreateDIBSection Lib "gdi32.dll" (ByVal hDC As Long, *pBitmapInfo As BITMAPINFO, ByVal usage As UINT, *lplpVoid As sys, ByVal hSection As Long, ByVal offset As Long) As Long
Declare Function CreateThread Lib "kernel32.dll" (byval lpThreadAttributes As Any, ByVal dwStackSize As Long,byval pStartAddress As long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadID As Long) As Long
Declare Function TerminateThread Lib "kernel32.dll" (ByVal hThread As Long, ByVal dwExitCode As Long) As Long
Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
% DIB_RGB_COLORS = 0
' Window client size
int width = 375
int height = 375
% BI_RGB = 0
' Target fps, though it's hard to achieve this fps
' without extra timer functionality unless you have
' a powerfull processor. Raising this value will
' increase the speed, though it will use up more CPU.
int fps = 50
' Global Windows/Drawing variables
INT hbmp
INT hTickThread
INT hwnd
INT hdc
INT hdcMem
INT wstyle = WS_MINMAXSIZE or WS_CLIPCHILDREN
' Pointer to pixels (will automatically have space allocated by CreateDIBSection
PIXEL *pixels
INT win
Dim lpThreadID As Long
'reg class & create window using awinh037.inc ---------------------------------------
win = SetWindow("Fast_GDI", 300, 200, width, height, 0, wstyle)
'------------------------------------------------------------------------------------
RECT rcClient, rcWindow
POINTAPI ptDiff
' Get window and client sizes
GetClientRect( win, rcClient )
GetWindowRect( win, rcWindow )
' Find offset between window size and client size
ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right
ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom
'MakeSurface( win)
' Resize client
MoveWindow( win, rcWindow.left, rcWindow.top, width + ptDiff.x, height + ptDiff.y, -1)
UpdateWindow( win )
' wmsg loop >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
while GetMessage(wm, 0, 0, 0)
TranslateMessage wm
DispatchMessage wm
wend
' <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Function WndProc( sys hwnd, wmsg, wParam, lParam) as sys callback
win=hwnd
'SELECT hwnd
'CASE win
select wmsg
case WM_CREATE
MakeSurface(win )
case WM_PAINT
PAINTSTRUCT ps
hdc = BeginPaint( win, ps )
'draw text to screen DC
TextOut hdc, 100,100, "FAST_GDI", 8
'SetPixel ( hdc, 200, 200, RGB( 100, 0,200) )
' Draw pixels to window when window needs repainting
BitBlt( hdc, 0, 0, width, height, hdcMem, 0, 0, SRCCOPY )
EndPaint( win, ps )
case WM_CLOSE
DestroyWindow( win )
case WM_DESTROY
TerminateThread( hTickThread, 0 )
PostQuitMessage( 0 )
end select
'END SELECT
Return DefWindowProc(hwnd,wMsg,wParam,lParam)
End Function
'..................................................................
SUB MakeSurface(INT wnd)
' Use CreateDIBSection to make a HBITMAP which can be quickly
' blitted to a surface while giving 100% fast access to pixels before blit.
' Desired bitmap properties
BITMAPINFOHEADER bmi
bmi.biSize = sizeof bmi
bmi.biWidth = width
bmi.biHeight = -height ' Order pixels from top to bottom
bmi.biPlanes = 1
bmi.biBitCount = 32 ' last byte not used, 32 bit for alignment
bmi.biCompression = BI_RGB
bmi.biSizeImage = 0
bmi.biXPelsPerMeter = 0
bmi.biYPelsPerMeter = 0
bmi.biClrUsed = 0
bmi.biClrImportant = 0
BITMAPINFO bmci
bmci.bmiColors[0].rgbRed = 0
bmci.bmiColors[0].rgbGreen = 0
bmci.bmiColors[0].rgbBlue = 0
bmci.bmiColors[0].rgbReserved = 0
hdc = GetDC( win )
' Create DIB section to always give direct access to pixels
hbmp = CreateDIBSection( hdc,byval &bmi, DIB_RGB_COLORS,byval &pixels , 0, 0 )
DeleteDC( hdc )
' Create a new thread to use as a timer
' Private Const CREATE_SUSPENDED = &H4
hTickThread = CreateThread(ByVal 0&, ByVal 0& ,byval &tickThreadProc , byval 0&, &H4 , lpThreadID)
print "TickTHREAD:" str hTickThread
END SUB
SUB tickThreadProc(int handle)
int on
print "TH-OK"
' Give plenty of time for main thread to finish setting up
Sleep( 50 )
ShowWindow( hwnd, SW_SHOW )
' Retrieve the window's DC
hdc = GetDC( hwnd )
' Create DC with shared pixels to variable 'pixels'
hdcMem = CreateCompatibleDC( hdc )
hbmOld = SelectObject( hdcMem, hbmp )
'Milliseconds to wait each frame
int delay = 100 / fps
for on = 0 to 100
' Do stuff with pixels
onFrame()
' Draw pixels to window
BitBlt( hdc, 0, 0, width, height, hdcMem, 0, 0, SRCCOPY )
' Wait
Sleep( delay )
next on
SelectObject( hdcMem, hbmOld )
DeleteDC( hdc )
END SUB
SUB onFrame()
' This is where all the drawing takes place
PIXEL *p
' +0.005 each frame
static float frameOffset = 0
float px '% of the way across the bitmap
float py '% of the way down the bitmap
for x = 0 to width
for y = 0 to height
p = y * width + x
px = (x) / (width)
py = (y) / (height)
p.r = ubyte(((cos(px + frameOffset * 10) / sin(py + frameOffset)) * cos(frameOffset * 3) * 10) * 127 + 127)
p.g = 100
p.b = 255
SetPixel ( hdc, px, py, RGB(p.r, p.g, p.b) )
next y
next y
frameOffset += 0.05
end sub
-
INTEGER should be replaced with WORD
MS definition:
typedef struct tagBITMAPINFOHEADER {
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;