Oxygen Basic
Information => Open Forum => Topic started by: Patrice Terrier on February 25, 2020, 04:53:18 AM
-
Charles
I have written a 64-bit DLL based on "ObjReader Lite 3.00".
While this DLL was first intended to work with WinDev, it should work with any 64-bit language.
If you are interrested to use it with O2, then let me know.
-
That would be a nice tribute to Mike for his efforts with your project.
-
You can figure what it could do, from the WinDev binary demo that is available here. (http://www.objreader.com/download/demo/OR17.7z)
Use the combobox to select a model.
Of course the same code in O2 should be much smaller (the PC-Soft framework is huge).
The ORDLL64.dll is only 193 Kb, and the GDImage64.dll framework only 410 Kb.
Note: To avoid any UAC problem unlock the .7z file before decompression.
-
Patrice,
If you were given a series of CT slices could you assemble them into a 3D object in your reader?
-
No, the DLL is a read only viewer.
When i nead to create or assemble new models, i am using C4D R21, and i export the resulting work into a wavefront .obj file.
Then i edit and customize the textures (with PSD or C4D) and the .mtl (material) file using the specific ObjReader #meta commands.
Some of the free models i posted into the collection have taken me literally weeks of work, to fix the many errors found in those downloaded from the internet or to create a new one from scratch.
-
As Reference:
3D Computed Tomography (CT) is a nondestructive scanning technology that allows you to view and inspect the external and internal structures of an object in 3D space. Computed Tomography works by taking hundreds or thousands of 2D Digital Radiography projections around a 360 degree rotation of an object.
3D CT (https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5531578/)
-
Certainly, Patrice,
We can include headers, and examples for ORDLL64.
I must join your forum, if I am tolerable :)
-
Charles
Of course you shall be warmly welcomed, just send me a message here:
http://www.objreader.com/index.php?topic=5.0
and let me know if you are using a .LIB or LoadLibrary with O2, and if you need a specific header.h file.
ORDLL64 is 64-bit only, written in C++ (C style) with the free "Visual Studio Community" version.
-
Hi Patrice,
How do we call ORDLL64.dll from an O2 program, can you please provide a simple code example?
Your supreme graphics will greatly compliment O2 capabilities
Regards
Karen
-
Being a C++ programmer, I am not familiar with O2, what i can do is to provide a mockup code like this
lp is POINT; ClientToScreen(Handle(Visual_Template..Name), lp)
gP.hOR3D = OR_CreateWindow(0, gP.hParent, WS_POPUP | WS_VISIBLE, lp.x, lp.y, Visual_Template..Width, Visual_Template..Height, 0)
IF gP.hOR3D THEN
//EnableWindow(gP.hOR3D, True)
gP.Msg = RegisterWindowMessage("WM_LOADED")
IF gP.Msg THEN Event(&OR_Message(), gP.hParent, gP.Msg)
END IF
OR_CreateWindow is the 3D graphic control to use, it could be a child or a popup window.
Further details are explained here
http://www.objreader.com/index.php?topic=322.msg5972#new
-
Thanks Patrice,
Perhaps Charles can help in providing some O2 code to call ORDLL64.dll ??
It would be good to be able to interface and communicate with a c++ dll
Regards
Karen
-
Thanks Patrice,
The only problem is We can't run ORDLL64.dll for testing without GDImage64.dll. (LoadLibrary won't work)
-
Charles
GDImage64.dll (and Bass.dll) are available altogether with 3D examples and resource folders, in the WD demo project here:
www.objreader.com/download/demo/OR17.7z
(111 Mb, because of the size of the 3D examples, and the bloated WD framework)
To avoid any UAC problem, make sure to unlock the .7z file before uncompression.
see inside the EXE folder.
The status of GDImage64.dll is the same than for Bass.dll, it is free for non-commercial use.
The demo could help you to figure what to do with O2 to replicate the project.
-
Thanks Patrice,
This o2 header is a lightly retouched verion of your c++ header:
'http://www.objreader.com/index.php?topic=322.msg5971#new
'dependencies:
' GDImage64.dll
' Bass.dll
'www.objreader.com/download/demo/OR17.7z
% IN
typedef sys HWND,HMENU
extern lib "ORDLL64.dll"
HWND OR_CreateWindow(IN dword dwExStyle, IN HWND hParent, IN dword dwStyle, IN long x, IN long y, IN long w, IN long h, IN HMENU CtrlID)
long OR_DetectGPU()
wchar* OR_GPUinfo()
wchar* OR_About()
void OR_ViewReset()
long OR_GetAudioVolume()
void OR_SetAudioVolume(IN long nVolume)
void OR_ProcessCommandLine(IN wchar* lpCmdLine)
wchar* OR_Vertices()
wchar* OR_Triangles()
wchar* OR_Indices()
wchar* OR_Meshes()
wchar* OR_Materials()
wchar* OR_ObjSize()
wchar* OR_LoadTime()
wchar* OR_Version()
end extern
and some very basic test code with ORDLL64.dll, GDImage64.dll and Bass.dll in the same folder.
filename "test.exe"
uses RTL64
'uses corewin
uses OR64
wstring cr=chr(13,10)
print OR_version() cr OR_About() cr OR_GPUinfo()
-
Assuming that you have the OR_resource folder (at the same location than ORDLL64.dll), you can also create a popup window using OR_CreateWindow
and use drag & drop of a 3D model (or a specific 3D model folder), that should work as well ;)
-
Hi Charles, in your reply#13
You mentioned that
This o2 header is a lightly retouched verion of your c++ header:
Do you mean that the code block be saved as OR64.inc ?
So that your Test.exe can Uses OR64 ?
Thanks and Regards
Karen
-
Hi Karen,
Yes, uses OR64 means include once "OR64.inc"
Patrice,
This is my Window code:
$filename "test.exe"
uses RTL64
uses corewin
uses OR64
'=========
'MAIN CODE
'=========
dim cmdline as asciiz ptr, hinst as sys
@cmdline=GetCommandLine
hinst=GetModuleHandle 0
'
Function WinMain(sys hinst, prevInst, asciiz*cmdline, sys show) as sys
'=====================================================================
WndClass wc
MSG wm
sys hwnd, wwd, wht, wtx, wty, tax
wc.style = CS_HREDRAW or CS_VREDRAW
wc.lpfnWndProc = @WndProc
wc.cbClsExtra = 0
wc.cbWndExtra = 0
wc.hInstance = hinst
wc.hIcon=LoadIcon 0, IDI_APPLICATION
wc.hCursor=LoadCursor 0,IDC_ARROW
wc.hbrBackground = GetStockObject WHITE_BRUSH
wc.lpszMenuName =null
wc.lpszClassName = strptr "Demo"
RegisterClass (@wc)
Wwd = 800 : Wht = 640
Tax = GetSystemMetrics SM_CXSCREEN
Wtx = (Tax - Wwd) /2
Tax = GetSystemMetrics SM_CYSCREEN
Wty = (Tax - Wht) /2
hwnd = CreateWindowEx 0,wc.lpszClassName,"OXYGEN BASIC",WS_OVERLAPPEDWINDOW,Wtx,Wty,Wwd,Wht,0,0,hinst,0
'OR_CreateWindow(IN dword dwExStyle, IN HWND hParent, IN dword dwStyle, IN long x, IN long y, IN long w, IN long h, IN HMENU CtrlID)
OR_CreateWindow(0, hWnd, WS_POPUP, 0,0,800,640, 0)
ShowWindow hwnd,SW_SHOW
UpdateWindow hwnd
'
sys bRet
'
do while bRet := GetMessage (@wm, 0, 0, 0)
if bRet = -1 then
'show an error message
else
TranslateMessage @wm
DispatchMessage @wm
end if
wend
End Function
function WndProc ( sys hWnd, wMsg, wParam, lparam ) as sys callback
'==================================================================
select wMsg
case WM_DESTROY
PostQuitMessage 0
case else
function=DefWindowProc hWnd,wMsg,wParam,lParam
end select
end function ' WndProc
WinMain hinst,0,cmdline,SW_NORMAL
After lauching the window I'm getting the error message below. My Pavilion laptop has Windows10 and Intel graphics hardware.
-
Charles
It looks like your graphic card doesn't use the current OpenGL extensions.
First thing is to check your hardware for OpenGL 4.00.
Then check if OR is working on your system, using the ObjReader64_Lite.7z attached to this post
http://www.objreader.com/index.php?topic=2.msg2#msg2
Then you can also check ORDLL64 with the WinDev project.
If they both work on your system, this means an error in O2.
I am using mostly nVidia on my computers, but one of them has an Intel 4000 and it works also well with it.
Added:
It works even on my little Windows Surface, using an Intel Atom, with only 2.00 Gb ram, and an Intel HD Graphic card.
-
Patrice,
ObjReader64.exe produced the same error message on launch.
I checked the intel model: Intel HD Graphics 520, supporting OpenGl 4.6. Opengl.dll was last updated in Oct 2019.
https://opengl.gpuinfo.org/displayreport.php?id=4569
-
Yes, so far, that is a requirement (see the code below in red).
That is the first time i had report of this problem, perhaps there is a specific setting on the graphic card to enable it ?
GLuint glsl_LoadShaderFromMemory(IN long pResourceId) {
GLuint program = 0;
GLuint vertShader = 0;
GLuint fragShader = 0;
GLuint geomShader = 0;
char* quadShader = "void main() {gl_Position = ftransform();}"; // MLL 03-30-2019: reusable
char* vs = NULL, *fs = NULL, *gs = NULL; // MLL 11-25-2018: geometry shader support
// Get the vertex shader source and compile it.
if (pResourceId == SHADER_BLINN) {
vs = "#extension GL_OES_standard_derivatives : require\n"
"#extension GL_OES_standard_derivatives : enable\n"
"uniform bool bDoSpherical;\n"
"varying vec3 vertex;\n"
"varying vec3 normal;\n"
"varying vec3 vertPos;\n"
"void main() {\n"
"vertex = gl_Vertex.xyz;\n"
"gl_Position = ftransform();\n"
"vec4 vertPos4 = gl_ModelViewMatrix * vec4(vertex, 1.0);\n"
"vertPos = vec3(vertPos4) / vertPos4.w;\n"
"normal = normalize(gl_NormalMatrix * gl_Normal);\n"
"if (bDoSpherical) {\n"
"vec3 u = normalize(vec3(gl_ModelViewMatrix * gl_Vertex));\n"
"vec3 r = reflect(u, normal);\n"
"float m = 1.0 / (2.0 * sqrt(r.x * r.x + r.y * r.y + (r.z + 1.0) * (r.z + 1.0)));\n"
"gl_TexCoord[0].s = r.x * m + 0.5;\n"
"gl_TexCoord[0].t = r.y * m + 0.5;\n"
"} else {\n"
"gl_TexCoord[0] = gl_MultiTexCoord0;\n"
"}\n"
"}";
-
Charles
Without the "GL_OES_standard_derivatives" extension, GLSL could be very problematic, including the hability to play shaders from the Internet. (see www.Shadertoy.com or www.SketchFab.com).
It is part of the WebGL API.
Added:
Could you send me your compiled O2 code to check how it works on my different computers, thank you!
-
Patrice,
Binaries and source for the 2 tests below:
attachments withdrawn
-
Charles
Thank you for the zip.
Here are the results.
test1:
it does not display the OR_GPUinfo (empty string)
test2:
The OR_CreateWindow, does not shows up, IsWindow(OR_CreateWindow) ?
So far, it doesn't seem to work, but if your graphic card is not GLSL compliant then you won't be able to check anything.
Thus don't waste anymore time on this, except if you can check this on another computer (nVidia is my favorite GPU).
Thank you for the time you spent on it.
-
If I run OR64test1.exe each item indicates null except the hardware brand. Is this expected? Clicking on Graphics Card Info in ObjReader viewer, this will show the values of my system.
-
Roland
Here is mine
-
I won't give just yet, Patrice,
There is something in my opengl framework that activates opengl for OR64
$filename "test3.exe"
uses RTL64
% Title "Console Demo"
'% Animated
'% ScaleUp
'% PlaceCentral
'% AnchorCentral
uses ConsoleG
uses OR64
sub main()
==========
string s
cls 0,0,0
scale 2,2
'typeface=1
printl OR_version()
'printl OR_About()
s=OR_GPUinfo()
printl mid(s,01,32)
printl mid(s,33,32)
printl mid(s,65,32)
printl mid(s,97,32)
printl mid(s,129,32)
printl mid(s,161,32)
printl mid(s,193,32)
printl mid(s,225,32)
scale .5,.5
sys i
printl
printl
PushState
color .20,.80,.00,.88
Scale 2.,2.
print "Enter: "
color .80,.80,.00,.88
typeface=1
input inputs
typeface=0
PopState
printl
color .00,.80,.80,1.
if LastInput
printl "Last input: " LastInput
end if
printl ""
lastkey=0
lastchar=0
'
shading 'opposite of 'flat'
GoldMaterial.act
move 2.,-2.,-1.0
go sphere
glTranslatef 0.,-2.0,0.
RedMaterial.act
go cube
move 2.00,.00,.00
rotateX -70
scale 4
color .70,.70,.20,.99
print3d "Solids",1
end sub
EndScript
-
both Roland and I, are using GLSL 4.60
About the refresh rate, in TURBO mode the OR FPS self adjust on it, meaning 75hz on my main display while only 60hz on the secondary display, and 150hz with the new display generation.
And see on the attachment the FPS rate when running at full speed (no VSYNC mode), and look about the model info on the right panel.
With lighter model i can jump to 677 FPS go figure!
Then you need to have a good GPU cooler !
-
Unfortunately, I still cannot persuade my system to support GL_OES_standard_derivatives
-
Charles
Being very graphic oriented i know that Intel comes last on my GPU favorite list, and i avoid like the plague shared memory.
Here is another screen shot of a model running in demo mode + play audio + sync audio + animation,
and look at the FPS rate on the top left corner.
OR FPS display returns exactly the same value than FRAPS.
-
Patrice
Would you consider incorporating some adaptive coding for mediochre graphics hardware?
-
That would break too much of the existing code, and the background shader animations won't work anymore.
It is like to return 10 years ago, restoring the code from the first release that won't work with the new materials.
On Windows 10, the use of GLSL is a mandatory with the modern internet browsers.
This is the reason why IE8 has been deprecated and replaced by Edge :(
-
My HP Pavilion notebook (2016) has no problems running WebGl
I came accross this cube-mapping demo:
https://webglsamples.org/dynamic-cubemap/dynamic-cubemap.html
and a water demo:
http://madebyevan.com/webgl-water/
-
Charles
What doesn't work by you is GLSL not WebGL.
Can you play this
https://www.shadertoy.com/view/4sXBRn
If it works, then try it with Internet Explorer and Chrome and see the difference.
If you want i can send you the whole shader code processed by the GPU, to see if you can let it run on your config.
-
Thanks Patrice,
Works smoothly with MSEdge, Firefox and Chrome, but not Explorer.
-
Charles
TRY WITH THE ATTACHED DLL, and let me know if it works by you.
I have disabled the GL_OES extension.
-
It works!
But how should it be set up in a proper window app (in C) ?
-
You must have the 2 folders OrResource and 3D_models into the same directory than the EXE and the ORDLL64.dll
Just like for the WinDev project here:
http://www.objreader.com/download/demo/OR17.7z
This one is provided with several 3D examples.
For now you can use drag & drop of 3D model onto the OpenGL display
Try with:
Dragster Engine
Nefertiti
Robots2
Star Surfer
Welcome
Note: you must have also Bass.dll, GDImage64.dll, and ORDLL64.dll into the same folder
And to better figure what it can do, run the WinDev project named OR17.exe (from the EXE folder)
Try also with the static shader Luminescence, that you must put inside of the 3D_models folder.
http://www.objreader.com/download/demo/Luminescence.zip
Better to post your questions from my forum, because you can download large attachments, that are impossible to use here, because of the small size limitation.
-
I forget to say that of course you must use the ORDLL64_Charles.zip version 😊
-
Thanks Patrice,
I've now got it workinging properly as a child window with a main parent window.
$filename "test2.exe"
uses RTL64
uses corewin
uses OR64
dim cmdline as asciiz ptr, hinst as sys
@cmdline=GetCommandLine
hinst=GetModuleHandle 0
'
Function WinMain(sys hinst, prevInst, asciiz*cmdline, sys show) as sys
'=====================================================================
WndClass wc
MSG wm
sys hwnd, chwnd
wc.style = CS_HREDRAW or CS_VREDRAW
wc.lpfnWndProc = @WndProc
wc.cbClsExtra = 0
wc.cbWndExtra = 0
wc.hInstance = hinst
wc.hIcon=LoadIcon 0, IDI_APPLICATION
wc.hCursor=LoadCursor 0,IDC_ARROW
wc.hbrBackground = GetStockObject WHITE_BRUSH
wc.lpszMenuName =null
wc.lpszClassName = strptr "Demo"
RegisterClass (@wc)
int Wwd = 800 , Wht = 640
hwnd = CreateWindowEx 0,wc.lpszClassName,"ObjectViewer using OxygenBasic",WS_OVERLAPPEDWINDOW,0,0,Wwd,Wht,0,0,hinst,0
'OR_CreateWindow(IN dword dwExStyle, IN HWND hParent, IN dword dwStyle, IN long x, IN long y, IN long w, IN long h, IN HMENU CtrlID)
chwnd=OR_CreateWindow(0, hwnd, WS_POPUP, 100,100,640,480, 0)
ShowWindow hwnd,SW_SHOW
UpdateWindow hwnd
ShowWindow chwnd,SW_SHOW
'
print OR_version() cr OR_About() cr OR_GPUinfo()
sys bRet
'
do while bRet := GetMessage (@wm, 0, 0, 0)
if bRet = -1 then
'show an error message
else
TranslateMessage @wm
DispatchMessage @wm
end if
wend
End Function
function WndProc ( sys hWnd, wMsg, wParam, lparam ) as sys callback
'==================================================================
select wMsg
case WM_DESTROY
PostQuitMessage 0
case else
function=DefWindowProc hWnd,wMsg,wParam,lParam
end select
end function ' WndProc
WinMain hinst,0,cmdline,SW_NORMAL
-
Charles
Yes, that seems to work fine.
I shall convert the WinDev demo to a C/C++ project, to help you better figure how to use the API wit O2.
But first thing, here are the default CreateWindow styles being used in OR_CreateWindow
HWND OR_CreateWindow (IN DWORD dwExStyle, IN HWND hParent, IN DWORD dwStyle, IN long x, IN long y, IN long w, IN long h, IN HMENU CtrlID) { // dllexport AS LONG
if (dwStyle == 0) dwStyle = WS_POPUP;
if (dwExStyle == 0) dwExStyle = WS_EX_TOOLWINDOW | WS_EX_ACCEPTFILES;
gP.hGL = 0;
WNDCLASSEX wcx = { 0 };
WCHAR zClass[] = L"ORWavefront64";
WCHAR zPath[MAX_PATH] = { 0 };
HINSTANCE hInstance = GetModuleHandle(NULL);
wcx.cbSize = sizeof(wcx);
long IsInitialized = GetClassInfoEx(hInstance, zClass, &wcx);
if (!IsInitialized) {
wcx.style = CS_OWNDC | CS_DBLCLKS;
wcx.lpfnWndProc = gl_WndProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = hInstance;
wcx.hIcon = NULL;
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hbrBackground = NULL;
wcx.lpszMenuName = NULL;
wcx.lpszClassName = zClass;
wcx.hIconSm = NULL;
if (RegisterClassEx(&wcx)) { IsInitialized = -1; }
}
if (IsInitialized) {
gP.hGL = CreateWindowEx(dwExStyle, zClass, NULL, dwStyle, x, y, w, h, hParent, (HMENU)CtrlID, hInstance, NULL);
if (IsWindow(gP.hGL)) {
CreateSyncThread();
Note the use of WS_EX_TOOLWINDOW that allows you to easily switch the OpenGL view port to full screen mode.
But you can also use the WS_CHILD style rather than WS_POPUP, to let it work as a regular child control, and anchor the control to match the parent window size, you can do the same in toolwindow mode, processing the WM_SIZE/WM_MOVE/MAXIMIZE/RESTORE messages.
Inside the control you can use the left mouse button to rotate the model, the right mouse button to pan up/down/left/right, and the mouse wheel for magnification.
You can use drag-and-drop of either a "3D model folder", or a "3Dmodel.obj" file, or any audio file and see the processing of the audio signal with models that have been designed to use it (sync mode), or just hear audio.
-
Hi Charles,
your test2.exe runs well with my system (apart from Patrice's notification) using both versions of ORDLL64.dll. Dragging the .obj models and applying the mouse buttons work as expected. Using version 0.2.8, I was also able to compile test2.o2bas to the exe file. ORDLL64.dll and Oxygenbasic seem to work very well together. This is really cool.
Roland
-
Charles,
I am writing the C++ template (with VS 2019), however no bells and whistles for now, just plain lean Windows controls...
-
Thanks Patrice,
I hope this is a good investment of your time for potential 'C' users of ObjReader.
-
Charles
Here is the first shot...
Put ORV64.exe into the same folder than the DLL(s) with the extra resource folders.
The C++ code has been written with Visual Studio 2019 (the free community version).
-
#define IDC_VERTICES 15
#define IDC_TRIANGLES 16
#define IDC_MESHES 17
#define IDC_MATERIALS 18
#define IDC_INDICES 18
#define IDC_OBJSIZE 20
#define IDC_LOADTIME 21
it should be 19, not 18
-
Charles
Here is the patch for the second shot of ORV64.
The user GUI is now using image buttons (in the "resource" folder) and tooltips have been used with buttons.
There is a new GDImage marquee control using the internal OR sync timer to perform the smooth animation.
All the core functions have been completed.
The next step, at least for me, would be to skin the application. ;)
-
Charles
In Main.cpp (around line 223) you should replace the existting line with the one in red below.
case LOADING:
SetWindowText(GetDlgItem(gP.hMain, IDC_VERTICES), NULL);
SetWindowText(GetDlgItem(gP.hMain, IDC_TRIANGLES), NULL);
SetWindowText(GetDlgItem(gP.hMain, IDC_INDICES), NULL);
SetWindowText(GetDlgItem(gP.hMain, IDC_MESHES), NULL);
SetWindowText(GetDlgItem(gP.hMain, IDC_MATERIALS), NULL);
SetWindowText(GetDlgItem(gP.hMain, IDC_OBJSIZE), NULL);
SetWindowText(GetDlgItem(gP.hMain, IDC_LOADTIME), NULL);
// SetWindowText(GetDlgItem(gP.hMain, LIB_About), NULL);
ClearMarquee();
WindowRedraw(gP.hMain);
break;
-
Charles
Here is a new version of the ORDLL64.
I have reworked the zoom function (mouse wheel) to be cooperative with the marquee scrolling effect (in previous version it was becoming idle while zooming).
-
And for the fun of it, here is screen shot of the skinned version that will be posted on my private forum. 8)
-
Thank you, Patrice.
I hope I've assembled it all correctly.
-
Charles
That is a good stress test for O2, and i am looking forward to see the size of the resulting binary compared to Visual Studio. 8)
BTW, i have exported a few more API...
-
Charles
Version 3.00.06 has been released with a couple of new API, including the CPU/GPU percentages used by the application.
More details there (http://www.objreader.com/index.php?topic=324.0)
Screen shot of the CPU/GPU percentages displayed in gauge view meters.
(http://www.objreader.com/download/demo/ORV30006.jpg)
And here is how to compute the CPU percentage:
int CPU_GetUsages() {
FILETIME idleTime, kernelTime, userTime;
static FILETIME last_idleTime, last_kernelTime, last_userTime;
LONGLONG usr, ker, idl, sys;
int cpu = 0;
LONGLONG LARGE_INTEGER1 = 0;
LONGLONG LARGE_INTEGER2 = 0;
MoveMemory(&LARGE_INTEGER1, &last_kernelTime, 8);
if (LARGE_INTEGER1) {
GetSystemTimes(&idleTime, &kernelTime, &userTime);
MoveMemory(&LARGE_INTEGER1, &userTime, 8); MoveMemory(&LARGE_INTEGER2, &last_userTime, 8); usr = LARGE_INTEGER1 - LARGE_INTEGER2;
MoveMemory(&LARGE_INTEGER1, &kernelTime, 8); MoveMemory(&LARGE_INTEGER2, &last_kernelTime, 8); ker = LARGE_INTEGER1 - LARGE_INTEGER2;
MoveMemory(&LARGE_INTEGER1, &idleTime, 8); MoveMemory(&LARGE_INTEGER2, &last_idleTime, 8); idl = LARGE_INTEGER1 - LARGE_INTEGER2;
sys = ker + usr;
if (sys) cpu = int((sys - idl) * 100 / sys);
}
GetSystemTimes(&last_idleTime, &last_kernelTime, &last_userTime);
return cpu;
}