ObjReader Community

WIP => WIP => Topic started by: Michael Lobko-Lobanovsky on October 24, 2018, 03:59:37 am

Title: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 24, 2018, 03:59:37 am
Patrice,

I know it's usually annoying to wait and overtake, so here's an early beginning of our sync process. I'll be adding more features marked with TODO in the code, menus, and text below in the next few days:

Mods dated "MLL 10-18-2018:"

0.  Fixed clearing old geometry data on model reload
1.  Fixed mipmapping on texture reload
2.  Fixed material initialization for models with missing MAT files
3.  Fixed model and mesh rotation stop/resume/reset angles
4.  Fixed deletion of shader programs
5.  Fixed and refactored frenglish func names to common style
6.  Refactored PROPM structure into PROPM and RHANDL structures
7.  Refactored main and sub menus to allow new functionalities
8.  Isolated shaders and render procs into separate project files
9.  Removed lots of obsolete Mobj_xxx code
10. Added:
   - scene grid
   - TODO: inertial mouse
   - TODO: axis aligned bounding boxes
   - TODO: viewport tooltip to report material names under cursor
   - TODO: model Z rotation on Alt+LMB drag
   - flat shaders to support glShadeModel(GL_SMOOTH | GL_FLAT) (except normal map shader for now)
   - shader for discrete texture and geo inspection in design mode


I'm slow because I'm fixing everything that I find buggy or unhandy until it works and looks flawlessly by my standards. It involves a hellofalot of time and experimentation.

But many fixes and features are already working and ready for your criticism. ;) Some provisions are already included in the code for the coming features too.

Please copy the files from the zip below into their respective project folders (same project paths considering the zip as the solution root) and let them overwrite the old files. Don't forget to add the two new files (renderers.h and shaders.h) to the project.

Do not attempt a usual merger as there are far too many differences. Just copy, recompile, and enjoy. And criticize if needed. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 24, 2018, 10:16:28 am
The new features are great, some of them could be duplicated onto the control panel to ease the model inspection (i can do it if you want).

Thank you!
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 24, 2018, 10:18:54 am
Thanks for the appreciation! I tried hard. :)

OK, I'm ready for work. Please post any comments or fixes you might have in this thread. :)

Let me finish the eye candies first and then we'll talk on how to refactor the GUI, OK?


(IronMan's occlusion looks terrific!!! My congratulations! :D)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 24, 2018, 02:30:46 pm
I am trying to deal with the case or name changes, to see what is really new in the code

Generally i prefer to put all my properties in lowercase to avoid remembering where to put the upper cases  :-[
I was accustomed for years to use non-case sensitive programming languages ;)

Quote
and looks flawlessly by my standards
Fortunatly i shall have to do this check only once, since starting from now i shall use your preferences ;)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 24, 2018, 04:31:37 pm
I'm used to camel case in the C sources, and my gradual change from Mobj_FooBar to fooBar also helps me to intuitively keep track of what code I've already worked on vs. that not yet touched by me.

Another reason to use camel case in mobj.h is to keep track of which functions are fundamental (Mobj_xxx) vs. those that are auxiliary helper routines (camelCase). Also, I'm not very fond of underlining names and labels because it makes them far longer to type than they really should be.

Then, why I'm moving certain functions out of mobj.h is because they are not specific to the OBJ format but rather belong to the OR's own framework regardless of what particular format it's going to display now or in the future.

And finally, I just like the code being kept in separate relatively small and functionally complete files. I'll be also moving all texture handling routines out of mobj.h into a separate dedicated textures.h file. (it may require adding a few function prototype headers at the top of mobj.h though)

Generally i prefer to put all my properties in lowercase to avoid remembering where to put the upper cases  :-[
I was accustomed for years to use non-case sensitive programming languages ;)

While we're at it, did you know that OR is case sensitive regarding material names? It refuses to apply the material if its name case in the MAT files differs from that in the OBJ file. This is one thing I'd like to ask you to fix in the sources now if you don't mind... :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 24, 2018, 05:05:14 pm
OR also doesn't accept to use a fully qualified path, perhaps we should be more permissive (as long as the target file exist) ?

Quote
did you know that OR is case sensitive regarding material names

This is because of this in Mobj_importGeometrySecondPass

        case 'u': // usemtl
            fgets(buffer, sizeof(buffer), pFile);
            sscanf(buffer, "%s %s", buffer, buffer);
            //name = buffer;
            iter = m_materialCache.find(buffer);
            activeMaterial = (iter == m_materialCache.end()) ? 0 : iter->second;
            break;

I am not comfortable with the use of iterator myself, and the problem is that find in the class map is always case sensitive.  :-\

 
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 24, 2018, 10:59:00 pm
This isn't the only weird thing about C++ std::vectors. You're using them unsparingly, but have you ever checked how actually spacious the vectors are to reach their .end or .size? You'll be surprised but the actual .size of texture vectors we iterate through many times in search of duplicates varies somewhere between 17500 and 45000 elements on my PC! There is no way to limit the size of memory C++ allocates for its std::vectors nor is there any way to deallocate it when no longer needed.

No wonder texture creation takes probably up to half the overall time the model loads...

Anyway, we need case-insensitive materials and other labels used throughout MAT and OBJ files. Do whatever you see fit but please fix that preternatural glitch.

Fully qualified paths would also be welcome, and even more so because they are allowed by the Wavefront OBJ format.

Tip of the Day #2: did you know that OR allows more than one word long material names? IIRC one of your latest models contains and actually displays the material(s) whose name is xxxx_yyyy zzzz. (I'm sure that was a typo but it somehow worked in both MAT and OBJ nonetheless :o)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 24, 2018, 11:23:01 pm
Probably the names should be lowercased before they go into the material cache?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 24, 2018, 11:29:07 pm
Please see above, post #6, about: gl_LoadModel
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 24, 2018, 11:48:47 pm
Please, check the case of gP.modelpath into the gl_LoadModel procedure, it should be gl.modelPath with the new PROP member name.

OK thanks!

Quote
Why did you use (+Alt) in this
            wcscopy(szCaption, L"  Mouse buttons:\n- Left(+Alt), rotate.\n- Right, pan.\n- Wheel, zoom.");

Alt+LMB will allow the model to be rotated with the mouse not only around X and Y axes like it does now, but also around Z. This label, together with the two new textures in the \Release\Reader subfolder and two new functions commented out in renderers.h, is a provision for this new functionality I'm working on right now.

Pressing Alt will show the target ellipse on the screen as in the snapshot below, whereby you'll be able to rotate the model:
-- by dragging anywhere inside the ellipse with LMB down exactly as you do now
-- strictly around X only when the left mouse button is pressed in the yellow boxes and then dragged
-- strictly around Y only when the left mouse button is pressed in the cyan boxes and then dragged
-- strictly around Z only when LMB'ed and dragged anywhere outside the ellipse.

The ellipse will disappear again when you release the Alt button.

Quote
Also change the version number to 2.55, see my Main.cpp sync in the attached zip file.

Will do, thanks again! :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 25, 2018, 06:19:27 am
Regarding (+Alt), I just thought we can also use it for many other purposes in the future, so it will probably be not so wise to spring up the ellipse every time the Alt button is pressed...

Alternatively we can use the letter Z as sort of a hotkey to initiate Z-axis rotation and show the ellipse in response, inviting the user to start this operation. Z is rare to use as a hotkey because there are few words to start with it, but in this case it will be kind of meaningful and appropriate.

What's your opinion?

Please, check the case of gP.modelpath into the gl_LoadModel procedure, it should be gl.modelPath with the new PROP member name.

Why, everything's all right with the gP.modelPath case in both Main.cpp (yours and mine) and mobj.h, and the project compiles fine for me... ???
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 25, 2018, 10:03:25 am
OK, i have fixed the case sensitive mtl name problem.

I shall work on the new dialog now.

Added:
The new dialog is ready to be customized. ;)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 25, 2018, 10:08:29 pm
Here we are…

Put the "trebuc.ttf" font into the Reader folder.

For now, and for test purpose the toolwindow is currently visible at startup, but it should start hidden and get visible only when the Ctrl key is being used (not done yet).
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 26, 2018, 03:03:14 am
Excellent!

In the meantime, here are a few lightweight fancy mode shaders with hardcoded parameters. I'm going to merge your tool window and then re-send the mods to you.

Thanks a million for your help! :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 26, 2018, 09:29:44 am
Quote
Thanks a million for your help!
Thanks to you, for all the great work you are doing on the new features, but we are partners aren't we, and this project is the result of our common work, that is a real pleasure to work with you, and see OR becoming better and better.

About the new Tool window i did it using the WinLIFT features, because i thought it was easiest for you to customize things from the standard ToolProc callback, rather than using a transparent overlay and a GDImageCallBack.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 26, 2018, 11:04:39 am
... i thought it was easiest for you to customize things from the standard ToolProc callback ...

You guessed right. GDImage remains a Pandora box for me. But I think that once we get it all up and running, we can discuss moving the toolbox functionality over to the overlay(s) just to maintain the uniformity of OR controls. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 26, 2018, 01:44:34 pm
To fix the problem of material files using a qualified path, change this into Tools.h

Code: [Select]
//char* Path_CombineA(OUT char* zResource, IN char* path, IN char* combine) {
//    long offset = lstrlenA(path);
//    ClearMemory(zResource, MAX_PATH);
//    MoveMemory(zResource, path, offset);
//    MoveMemory(&zResource[offset], &combine[0], strlen(combine));
//    return zResource;
//}

char* Path_CombineA(OUT char* zResource, IN char* path, IN char* combine) {
    long offset = lstrlenA(path);
    ClearMemory(zResource, MAX_PATH);
    if (strstr(combine, "\\")) {
        strcpy(zResource, combine);
    } else {
        MoveMemory(zResource, path, offset);
        MoveMemory(&zResource[offset], &combine[0], strlen(combine));
    }
    return zResource;
}

Note: To detect the use of Ctrl key, you can use the built-in  ZI_IsCtrlKeyPressed() API.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 26, 2018, 04:11:45 pm
Thanks for the fix and tip, Patrice!
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 26, 2018, 04:43:51 pm
Mike

I have written the Ctrl key detection to show or hide the toolwindow,
but i was forced to make a couple changes into the code of
1 - ToolWindow.h
2 - Main.cpp

I am performing the CTRL key detection directly inside of the main message pump, from
DetectCtrlKey(&msg);

That solves a focus conflict that could occure at startup, causing the main caption bar to stay grayed, and a Windows redraw problem of the toolwindow when switching between visible and hidden.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 26, 2018, 09:48:20 pm
Thanks for the update Patrice!

That solves a focus conflict that could occure at startup ...

Yet another reason to stay away from 3rd party black box frameworks. ;)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 26, 2018, 11:59:06 pm
The X-Ray transparency is my favorite one!  8)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 27, 2018, 09:45:45 am
Yes, it helps to easily inspect the model's innards. :)

I'm planning on adding yet another shader (and render mode), the model slicer, to the menu Design section. It allows the model to be split interactively into visible/invisible quadrants along the X,Y,Z movable planes that pass through the model parallel to its axes, while rendering the model in its textured state. I think it's going to be even more handy for further inner inspection under more natural conditions. 8)

Regarding diffuse reflection (that's a classic Minnaert per vertex lighting shader, an alternative to OpenGL's built in lambertian lighting model), I've chosen to include it because it renders the model in shades of black, which sometimes gives more spectacular results than model inspection in its original or default material colors. The light spot size will be adjustable via the shader controller tool window. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 27, 2018, 10:00:35 am
I find some of them useless (goosh, cartoon), but generally speaking anything that could help to better inspect the model is a great addition.

Note: With the latest VS2017 Community version i am able to run OR in debug mode, but i keep using VS2010 for code production because of  much smaller binary size...
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 27, 2018, 11:43:49 am
I find some of them useless (goosh, cartoon), but generally speaking anything that could help to better inspect the model is a great addition.

Pretty much like your own model-wide "ambient reflection". :P ;)

No, I think the ability to get some aesthetic satisfaction from models with missing/unavailable MAT files is in fact great. There are other lightweight shaders like "polka dot" or "hatch" or "stripes" and similar -- those are really of low aesthetic value and that's why I didn't include them in the list. BTW this gooch is a deviation from classic; it misses black outlines of model overall shape. I'm going to replace this shader when I find some free to use classic one.

Quote
With the latest VS2017 Community version i am able to run OR in debug mode, but i keep using VS2010 for code production because of  much smaller binary size...

I'm not sure but probably yet smaller binary could be generated if the cplusplus-ish vectors are substituted with classic arrays, and the code is fixed in compliance with standard ANSI C that would incur just one dependency -- msvcrt.dll. :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 28, 2018, 12:06:10 pm
Patrice,

I managed to get Z rotation up and running. It wasn't that easy due to numerous keyboard focus issues and as well as bloated viewport coords calc in ProcessMouseInput().

I fixed most focus issues but I decided to use the Design menu to launch the Z rotation mode, rather than the Alt or Z keyboard "hotkey" approach, for consistency with OR's current practices.

Do you want me to send you my fixes right away or can you wait till I finish off shader control via the new tool window?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 28, 2018, 05:07:56 pm
I can wait until you finish off shader control via the new tool window.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 28, 2018, 07:02:41 pm
OK :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 28, 2018, 08:48:46 pm
BTW spot the two differences:  :D

8)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 29, 2018, 09:11:41 am
Brighter lighting, and more contrast because of higher straylight.

And… of course "Obj size" and "Load in", taking benefit of the extra height size added to the window and its right panel  :)

BTW: The "load in" time, seems to be almost the same than on my computer.
What woul be nice would be to update the display in real time while loading the model, to get this final report 02:02,82 (like for a StopWatch, see MBox64).

Code: [Select]
void SetStatusTime(const MFTIME &time, IN long nID, IN long redraw) {
    static MFTIME wastime = -1;
    if (wastime != time) {
        HRESULT hr = S_OK;
        WCHAR szTimeStamp[32];

        long T = (long) (time / ONE_SECOND);
        long HH = T / 3600;
        long MM = (T - HH * 3600) / 60;
        long SS = T - HH * 3600 - MM * 60;

        hr = StringCchPrintf(szTimeStamp, strSize(szTimeStamp), L"%02d:%02d:%02d", HH, MM, SS);

        if (SUCCEEDED(hr)) {
            ZD_SetObjectTextEx(nID, szTimeStamp, redraw);
        }
    }
    wastime = time;
}
Title: Re: Early WIP on v2.55:: AHTUNG!!!
Post by: Michael Lobko-Lobanovsky on October 29, 2018, 08:15:00 pm
Patrice my friend,

I have a simple and nice model I'm often using for experimentation. It has the following MAT file:

newmtl 08___Default
illum 4
Ka 1 1 1
Kd .6 .6 .6
Ks 1 1 1
Ke 0 0 0
Ns 500
map_Ka ./Textures\Raw/Cerberus_AO.tga
map_Kd .\Textures\Cerberus_A.tga
map_Ks ./Textures/Cerberus_R.tga
map_bump .\Textures/Raw\Cerberus_N.tga


Below are the snapshots of this model rendered in an OR recompilation with Intel C++ I made two weeks ago to test its new free license I'm supposed to renew every three months, and the same model rendered in our latest "reference" OR. :'(

... GDIplus requires a fully qualified path.

Why should I care? :o

i) Wavefront OBJ format, ii) ObjReader, and iii) myself all require fully qualified, 8.3, absolute and relative paths and slashes both ways in an arbitrary order. When dealing with pathnames, first REPLACE$ their possible '/' forward slashes with '\\' back slashes and then reparse them as usual.

Quote
See this API ...

Is this supposed to mean that it is I who is supposed to fix this glitch? I have every reason to believe the regression appeared as a result of you recent material name case insensitivity "hotfix".

Can you work on it a little more, please? ::)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 29, 2018, 08:57:24 pm
send me the obj model altogether with the faulty mtl file, and i shall fix it.
Title: Re: Early WIP on v2.55 :: AHTUNG!!!
Post by: Michael Lobko-Lobanovsky on October 29, 2018, 09:42:03 pm
... the obj model altogether with the faulty mtl file, and i shall fix it.

The MTL file is not faulty, and it needs not any fixing. Rather it is the hotfixed OR that's faulty and in need of more work to be able to display the model properly with the existing MAT file. ;)

Thanks!
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 29, 2018, 10:02:46 pm
Matching slash and anti_slash is a very bad practice, but i will take care of it, no problem, this is easy to solve.

Will do it tomorrow morning, first thing  8)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 30, 2018, 12:27:22 am
The model and its textures import flawlessly with the current MAT file into all 3D editors and viewers I have, including 3ds Max. If anything's wrong with at least one index, 3ds Max always aborts import and throws an error message. I'm inclined to believe it more than the debugger.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 30, 2018, 01:38:48 am
Here is the new Tools.h to fix the relative path problem, and remove the duplicated slash.

See the new function replaceA, and the changes done into Path_CombineA

Warning for dynamic memory allocation, replaceA uses malloc, thus don't forget to use free once done.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 30, 2018, 01:06:22 pm
Hi Patrice,

The fixes seem to work fine for me, thank you! :)

BTW I cannot compile my VS 2013 solution in the Debug mode; I'm getting three linker errors:

error LNK2001: unresolved external symbol __imp_DwmGetCompositionTimingInfo   Main.obj   ObjReader64
error LNK2001: unresolved external symbol __imp_timeBeginPeriod               Main.obj   ObjReader64
error LNK2001: unresolved external symbol __imp_timeEndPeriod                 Main.obj   ObjReader64

Does that mean I'm missing some WinAPI debug mode library(-ies) or #pragma lib(-s), do you think?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 30, 2018, 01:34:08 pm
Put this in the debug Property Pages
Linker -> Input section

Additional Dependencies
Winmm.lib;Dwmapi.lib;pdh.lib;UxTheme.lib;Comctl32.lib;Glu32.lib;Shlwapi.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;%(AdditionalDependencies)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 30, 2018, 01:41:47 pm
Small fix to change into replaceA

    // Making new string of enough length
    long nLen = (K + cnt * (newlen - oldlen) + 1) * 2;

shoul be

    // Making new string of enough length
    long nLen = (K + cnt * (newlen - oldlen) + 1); // * 2; we are using char here rather than WCHAR
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 30, 2018, 02:43:51 pm
Put this in the debug Property Pages

That did the trick, thanks! :) (how could I overlook such an obvious thing? :o)

Small fix to change into replaceA

Done!
Title: Re: Early WIP on v2.55 :: !!! AHTUNG, Part II !!!
Post by: Michael Lobko-Lobanovsky on October 31, 2018, 07:05:42 am
Patrice,

I'm sorry to say but I have every reason to believe that your

!!! ZI_SPINNER LEAKS GDI OBJECTS !!!

at a rate of 8 handles each time it pops up and down at model load time under my Win 7.

Will you please fix that leak in your GDImage?

(Please don't ask me for proof; I'm pretty good at isolating and fixing the source of GDI memory leaks. I am 100% sure the problem exists under your Win 10 as well though the exact number of handles may differ.)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 31, 2018, 09:51:53 am
May i send you a spinner.h to use with OR (in debug mode), as i have no way to check it with Seven  :-[

Note: I am using the undocumented API RtlDecompressBuffer, but i could use my proprietary png animation rather than a .ski file, or even just a simple .png
Title: Re: Early WIP on v2.55 :: !!! AHTUNG, Part II !!!
Post by: Michael Lobko-Lobanovsky on October 31, 2018, 10:13:46 am
Of course you may, my friend.

Re. your RtlDecompressBuffer, I know. It's in the import table of all the spinners you've ever used. ;) Remember I re-implemented your spinner in multi-threaded OOP FBSL in my Objector? :)

But no, RtlDecompressBuffer has no relation to GDI objects. I'm sure the problem is seen also under your Win 10. I can check it here too but I just was too lazy to switch on my own Win 10 box.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 31, 2018, 10:32:53 am
As far as i can say i couldn't see anything wrong both DeleteObject and GdipDisposeImage are being called.

But because 4 eyes are better than two, here is the Spinner.h to check in debug mode with OR, just add the include at the top of Main.cpp, and replace all call to ZI_Spinner* with OR_Spinner.

I have some urgent home work to do, but i will check again later on.
Title: Re: Early WIP on v2.55 :: !!! AHTUNG, Part II !!!
Post by: Michael Lobko-Lobanovsky on October 31, 2018, 10:35:02 am
OK thanks and take your time! :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 31, 2018, 12:56:24 pm
I did check in Debug mode, using _CrtDumpMemoryLeaks();

it does detect memory leaks  :-[
but not in the spinner function.

I shall have to investigate more…
seems there is one in Tools.h when using PARSE and AllocTmpStr(lstrlen(sMain), 1, 1);
uing calloc (this function was given to me by James, but i never checked it thoroughly)
Title: Re: Early WIP on v2.55 :: !!! AHTUNG, Part II !!!
Post by: Michael Lobko-Lobanovsky on October 31, 2018, 04:45:57 pm
Patrice,

I am talking not about conventional memory leaks but rather about GDI object leaks like HDC, HPEN, HBRUSH, HBITMAP, etc. handles. Those that you create then select/deselect and then delete or release. These are leaking (i.e. are created but not destroyed, or fail to be destroyed, after use) at a rate of 8 handles per spinner popup. ???

You should examine it not in the debug mode but rather in your Task Manager if you inspect its GDI Objects table column.

Such a leak is usually observed when one attempts to delete the objects that are currently selected in a DC, or DCs with non-native GDI objects created by the user and selected into them. All such deletions fail silently, which results in the app's GDI object count growing rapidly as more and more models are reloaded into the app throughout the same session.

When the ZI_Spinner calls are commented out, my OR GDI object count is absolutely steady at 141/143 GDI handles throughout the entire session. I'm seeing this issue with the ZI_Spinner both precompiled into GDImage and as a standalone include you sent me.

This gives me a reason to believe that the cause of leakage lies in an improper use of GDI handles in the ZI_Spinner source code.

[UPD]  I was lucky to reduce the leakage to 6 handles per popup. So far so good...
Title: Re: Early WIP on v2.55 :: !!! AHTUNG, Part II !!!
Post by: Michael Lobko-Lobanovsky on October 31, 2018, 05:46:02 pm
Patrice,

The spinner include file is not full. It misses the zBitmapToImage (IN HDC hDC) function that is still in GDImage.dll.

Will you please supply me with the function source code now?

TIA
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 31, 2018, 06:21:42 pm

Here it is
Code: [Select]
LONG_PTR zBitmapToImage (IN HDC hDC) { // dllexport AS LONG
    BITMAPINFO bi = {0};
    BITMAP bm = {0};
    LONG_PTR lpImg = NULL;
    long MaxBound;

    HBITMAP hBitmap = ZI_GetBitmapFromDC(hDC);
    if (hBitmap) {
       GetObject(hBitmap, sizeof(bm), &bm);

       bi.bmiHeader.biSize        = sizeof(bi.bmiHeader);
       bi.bmiHeader.biWidth       = bm.bmWidth;
       bi.bmiHeader.biHeight      = -bm.bmHeight; // Put top in TOP instead on bottom!
       bi.bmiHeader.biPlanes      = 1;
       bi.bmiHeader.biBitCount    = 32;
       bi.bmiHeader.biCompression = BI_RGB;

       MaxBound = bm.bmWidth * bm.bmHeight * 4;
       if ((long)g_ByteArray.max_size() < MaxBound) { g_ByteArray.resize(MaxBound); }
       //vector<BYTE>::pointer ptr = &g_ByteArray[0];
       if (GetDIBits(hDC, hBitmap, 0, bm.bmHeight, &g_ByteArray[0], &bi, DIB_RGB_COLORS)) {
          if (GdipCreateBitmapFromScan0(bm.bmWidth, bm.bmHeight, bm.bmWidth * 4, PixelFormat32bppARGB, &g_ByteArray[0], lpImg) != 0) {
              lpImg = NULL;
          }
       }
    }
    return lpImg;
}

BTW, did you see what happen to the GDI count each time we enable/disable mipmap textures...
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 31, 2018, 06:36:09 pm
1. Thank you but the code is still incomplete. That function pulls in another ZI_GetBitmapFromDC(IN HDC hDC). Can I have it too? (that's exactly why I'm usually reluctant to work with 3rd party pandora boxes ;) )

2. Let's make it one at a time. Perhaps our current effort will help reduce total losses in the other parts of OR project. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 31, 2018, 06:42:57 pm
Code: [Select]
HBITMAP ZI_GetBitmapFromDC(IN HDC hDC) {
    HBITMAP nRet = NULL;
    if (hDC) {
        nRet = HBITMAP(GetCurrentObject(hDC, OBJ_BITMAP));
    }
    return nRet;
}
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 31, 2018, 06:48:00 pm
Thanks!

And while we're at it, can you also tell me (in terms of lfFaceName, lfWeight, dpi() height, and kerning width) exactly which font your geo data skinned edit boxes are using with the current SKS settings?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 31, 2018, 06:57:23 pm
Code: [Select]
HFONT skFontDlg() { // dllexport
    static HFONT hFont;
    LOGFONT lf = {0};
    if (hFont == 0) {
       lf.lfHeight         = -13;
       lf.lfWidth          = 0;
       lf.lfCharSet        = 1; // DEFAULT_CHARSET;
       lf.lfOutPrecision   = 6; // OUT_DEFAULT_PRECIS;
       lf.lfClipPrecision  = 0; // OUT_DEFAULT_PRECIS;
       lf.lfQuality        = 0; // DEFAULT_QUALITY;
       lf.lfPitchAndFamily = 0; // DEFAULT_PITCH | FF_DONTCARE;
       lf.lfWeight         = 800;
       wstring sUseFont = UseThisFont();
       wcscpy_s(lf.lfFaceName, (WCHAR*) sUseFont.c_str());
       hFont = CreateFontIndirect(&lf);
    }
    return hFont;
}
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 31, 2018, 07:04:19 pm
Thanks again! :D

Now I need zCreateDIBSection() too...  :'(
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 31, 2018, 07:22:01 pm
Code: [Select]
HBITMAP zCreateDIBSection (IN HDC hDC, IN long nWidth, IN long nHeight, IN long nBitCount) { // exportdll
    BITMAPINFO bi = { 0 };
    BYTE* lpBitmapBits = NULL;
    bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
    bi.bmiHeader.biWidth = nWidth;
    bi.bmiHeader.biHeight = nHeight;
    bi.bmiHeader.biPlanes = 1;
    bi.bmiHeader.biBitCount = (WORD) nBitCount;
    bi.bmiHeader.biCompression = BI_RGB;
    return CreateDIBSection(hDC, &bi, DIB_RGB_COLORS, (LPVOID*)&lpBitmapBits, NULL, 0);
}
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 31, 2018, 07:33:02 pm
Thanks, thanks, and thanks!  ;D

Quote
wstring sUseFont = UseThisFont(); // MLL ???
wcscpy_s(lf.lfFaceName, (WCHAR*)sUseFont.c_str());

So you mean to say you do not know exactly the answer to my question?

Actually, it seems to be Trebuchet MS at lf.lfHeight = -11 and lf.lfWeight = 400...  :-\
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on October 31, 2018, 07:55:46 pm
Done as advised, thanks a million! :)

I was asking because I had implemented the model load time counter in a separate thread but I can't modify the edit box text across threads (and that's natural), especially when the main thread is totally blocked out by the tight loops while parsing, triangulating, calculating normals, tangents and bitangents etc. etc. etc.

So I'm using a worker thread window that overlays the edit box and mimics its looks quite nicely, but there's a very very subtle difference in the font look and most probably in the glyph kerning (separation) value... ???

But it looks and works like a charm even the way it is now. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 31, 2018, 08:42:33 pm
Here is the "Quark.png" that could be used to replace the ObjReader.ski, but that doesn't make any difference, i suspect the use of thread to be the culprit.
Title: Re: Early WIP on v2.55 :: !!! AHTUNG NUMMER DREI !!!
Post by: Michael Lobko-Lobanovsky on October 31, 2018, 09:09:57 pm
Yes, you shouldn't select the brush into hDC. FillRect() doesn't need it.

BUT IF YOU STILL SELECTED IT, YOU SHOULD HAVE SAVED THE OLD BRUSH AND RESELECTED IT THERE AGAIN BEFORE HDC DELETION!

---------------------------------------------------------------------------------------

Thanks for the image, I'll use it for my tests.

Quote
... the use of thread to be the culprit.

Negative:The rest of Spinner.h + dependent functions seems now OK, GDI-wise, including RenderAnimation(). Next I'll have to read up more on GDI+ and see if there are any peculiarities about the deletion of its objects too.

But!

Regarding texture reload and mipmapping, IMHO there are no outstanding problems, but not so with the skinned menu.

!!! Gosh, it's leaking GDI objects like hell by hundreds !!!

:o ??? :'(
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on October 31, 2018, 10:51:45 pm
I just checked the latest ObjReader32 written in PowerBASIC, and the problem is there also.  :'(

Added:
Looks likes the use of checkbox in menu is causing the havoc.
The skMarlett font must be created once for all, and removed at the end of session.

DeleteObject(Fmarlett);
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 01, 2018, 07:47:19 am
Did you go to sleep last night at all, my friend? :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 01, 2018, 08:16:25 am
DeleteObject(Fmarlett);

Ha-ha, congrats my friend! That did the trick!!!  :D

Here is the new WLFT pandora, you know what to do once downloaded  :-X

Deleted without downloading. I was able to spot the target you were hinting at, and recompiled myself. Everything's in perfect order with the menu now. :)

Quote
But there is still the 6 GDI leaks when using the spinner  ::)

We'll fix those ones eventually as well, my friend, won't we? :D


Thanks for your great effort! And your projects are awesome pieces of programming art! :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 01, 2018, 10:13:11 am
I think i have found what causes the 6 extra GDI leak, i am doing a few more tests before posting the fix

You will have to restore the ZI_SpinnerInit and ZI_SpinnerClose to avoid code duplication with the DLL, and remove the spinner.h from the OR project.

Added
Here is the new pandora…

Hunting is closed for now  8)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 01, 2018, 01:46:10 pm
YOU DID IT!!! :o

"You're my hero!" (c) 8)

:D

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 01, 2018, 09:35:50 pm
OK Patrice,

I'm feeling a bit ashamed of not being so fast with my fixes as you are. :)

Here are my fixes dated MLL 10-28-2018. They include:Don't forget to copy a new ellipse texture from the zip into the \Reader subfolder overwriting the old one. The texture is color mapped to match the colors of respective axes on the scene grid.

Shader controls aren't ready yet due to my recent agitation caused by the GDI object leaks. ;)

Your feedback will be much appreciated.


[ADD] Oh, and one more thing: being a lazy bones, I haven't tried it out under Windows 10 . However I will if you report anything wrong with my code on your machine. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 01, 2018, 10:52:02 pm
I have downloaded the patch and merged the last changes, thank you!

Right now i am too tired to check it, and i am going to bed.
You will have my feedback tomorrow. Zzzz!
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 02, 2018, 08:55:45 am
Quote
•Model rotation around the Z axis implemented as a Design modes menu entry. I find this style more common to the existing UI.
That works nicely, thank you!

Quote
•Model loading timer implemented in a worker thread.
BTW to avoid the use of a new thread, i have been working myself on an enhancement of the GDImage/spinner that now displays a chrono hover the animation, and returns the total time ellapsed when closing the spinner.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 02, 2018, 10:28:29 am
Thanks for a favorable feedback! :)

BTW to avoid the use of a new thread, i have been working myself on an enhancement of the GDImage/spinner that now displays a chrono hover the animation, and returns the total time ellapsed when closing the spinner.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 02, 2018, 10:50:41 am
Quote
3.I doubt your time readings are going to be seen clearly against the flashing spinner and possible near-white wallpapers
Hey Thomas, you will see the result, even on white wallpapers. 8)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 02, 2018, 12:42:21 pm
I'm always open to discussions, but of course it's you who's the boss here. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 02, 2018, 10:02:51 pm
Mike

Could you Please check the attached GDImage.dll with OR on Seven.

You must change this in the GDImage.h
Code: [Select]
C_IMPORT WCHAR*    ZI_SpinnerClose();
C_IMPORT HWND      ZI_SpinnerInit(IN HWND hParent, IN WCHAR* szFileName, IN long nSpeeDelay, IN LONG_PTR UseFont);

and use this in
Code: [Select]
void gl_LoadTextures(IN long nSpinnerFlag, OUT long &nBump) { // 05-24-2015 setup the new nBump value.
    MobjMat* pMaterial = 0;
    long nI = 0, nCount = 0;
    nBump = 0; // 05-24-2015
    if (nSpinnerFlag) {
        WCHAR szFile[MAX_PATH] = { 0 };
        Path_Combine(szFile, EXEresource(), L"ObjReader.ski");
        ZI_SpinnerInit(gP.hGL, szFile, 0, 0);
    }

and this in void gl_InitRenderProps() {
Code: [Select]
    // Start spinner animation
    WCHAR szFile[MAX_PATH] = { 0 };
    Path_Combine(szFile, EXEresource(), L"ObjReader.ski");
    ZI_SpinnerInit(gP.hGL, szFile, 0, skCaptionFontPlus());

Note: ZI_SpinnerClose();
returns a pointer to the formated string, matching the last chrono.

if it works by you, then i will send you the updated pandora...
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 03, 2018, 02:08:44 am
Hehe, it works and looks not so bad as I would expect! 8)

If used in parallel with my loadTimer, the spinner shows the time a few fractions of a second longer because it starts not exactly when the new model begins to load but rather when the old model is still deleting its data.

(Anyway, I guess there's nothing preventing me from using my own neat loadTimer in my in-house OR builds similar to the "lightweight Fraps" I'm using instead of the standard FPS counter. ::) )
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 03, 2018, 08:44:38 am
Indeed, i have a much better one that is based on my bluring function, unfortunatly it works only when the code is put into OR.
Because of thread priority, there is a flickering line when the same code is put into the DLL.

If you want i can send you the bluring version if you want to test it inside of OR.

Your loadtimer is fine, however the text size used, being very small, is very hard to read for old eyes like myself.

Adding the chrono inside of the spinner (this is an optional feature) is a good addition to the GDImage engine, especially because we can adjust the text size and because we can use any private font, including LED display if we want.  :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 03, 2018, 09:21:02 am
About your "lightweight Fraps", to make our life easier, switch to "PAT's gasoline station" and use the attached "fraps.png" instead of "digit.png".

Then just change this in the code
Path_Combine(gP.mt.FullName, skSkinFolder(), L"fraps.png");//L"digit.png");

easier isn't it  :)

Or even more easier, without changing anything in the code, just keep the name digit.png and overwrite digit.png with fraps.png into your Reader folder.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 03, 2018, 09:46:52 am
Thank you for the new fraps PNG. So its kerning satisfies the metrics of your gasoline station calc, doesn't it? If so then I'll sure use it instead of my monospaced font image and custom code.

Re. my custom code pieces, I grouped them all in a MLL_DEV.h file and added global commentable #define MLL_DEV and conditional #include MLL_DEV.h statements at the top of Main.cpp. Now I'm using just a few #ifdef MLL_DEV/#ifndef MLL_DEV statements throughout the code to attach/detach the MLL_DEV.h code versions instead of main code automatically as necessary.

This way there won't be any variations in the main code any more, and hence no need to exchange MLL_DEV.h between us to be able to compile the project both ourselves and at the user's. Just comment out the #define MLL_DEV directive and off you go with your compilation.

So, where's the promised pandora? Or does it depend on my willingness to use the chronoized spinner? ;D OK, I will use it. Please send me the sources (and the blurred/flickering spinner) for respective sync'ing and testing. :)

Note I'll also need your Main.cpp file to sync with my OR. Actually there are two places where the spinner is called to pop up: gl_LoadModel() and gl_LoadTextures(). I want to know how you prevent yet another spinner thread from launching when two of them are called, directly and indirectly, from gl_LoadModel() sequentially at model load time as opposed to the re-mipmapping of textures when only one spinner is called from gl_LoadTextures() alone.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 03, 2018, 10:59:25 am
Got it, thanks! Off for testing.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 03, 2018, 11:13:49 am
I am not seeing how the spinner sets the final time reading in the Load in edit box.

[EDIT] OK no problem, it was "left as an exercise for the reader" (c). ;)

I think ZI_SpinnerClose(); in gl_LoadModel() should be moved down to the place where killLoadTimer() now resides. If not, some UI finalization steps are excluded from the overall loading time. This isn't fair, because until those are completed ObjReader is not yet ready for user interaction, i.e. the model loading process isn't fully over yet.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 03, 2018, 11:54:18 am
You are not seeing it, because i am not doing it, but that's easy just update the Load in with the string returned by ZI_CloseSpinner.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 03, 2018, 11:58:50 am
Yeah, I updated my message above. Please respond to my suggestion.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 03, 2018, 12:01:57 pm
SetWindowText(GetDlgItem(gP.hMain, IDC_LOAD_TIME),  ZI_SpinnerClose());

    SetWindowText(GetDlgItem(gP.hMain, IDC_VERTICES), STRL(Mobj_getNumberOfVertices()));
    SetWindowText(GetDlgItem(gP.hMain, IDC_TRIANGLES), STRL(gM.numberOfTriangles));
    SetWindowText(GetDlgItem(gP.hMain, IDC_INDICES), STRL(gM.numberOfTriangles * 3));
    SetWindowText(GetDlgItem(gP.hMain, IDC_MESHES), STRL(gM.numberOfMeshes));
    SetWindowText(GetDlgItem(gP.hMain, IDC_MATERIALS), STRL(gM.numberOfMaterials));
    // MLL 10-28-2018: ============================
    WCHAR buf[64] = { 0 };
    swprintf_s(buf, strSize(buf), L"%.3f %s", FileSize(pszFilename) / 1048576.0f, L"MB");
    SetWindowText(GetDlgItem(gP.hMain, IDC_OBJ_SIZE), buf);
    killLoadTimer(); // stop model load timer
    // ============================================
    SetWindowText(GetDlgItem(gP.hMain, IDC_LOAD_TIME), ZI_SpinnerClose());
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 03, 2018, 12:20:29 pm
Yeah, the bottom-most line's placement is correct while the topmost isn't.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 03, 2018, 12:33:07 pm
Now how do I test Spinner.h blur in the DLL? And should I use the same SKI?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 03, 2018, 12:36:48 pm
To test bluring in the DLL, just unREM this code section (line 14739-14740)

    //RECT rb; SetRect(&rb, x + r.left, y + r.top, x + r.left + Width(r), y + r.top + Height(r));
    //BlurTextPlus(hdc, g_SP.szTime, rb, g_SP.font, 4, nStrFormat);
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 03, 2018, 06:28:31 pm
I have improved the ZI_SpinnerInit parameters.

Now it can use a specific private font of any size and color (with the new GDImage function zUsePrivateFont).

Example:
    Path_Combine(gP.mt.FullName, skSkinFolder(), L"lcd.ttf");
    ZI_SpinnerInit(gP.hGL, szFile, 0, zUsePrivateFont(gP.mt.FullName, 22), ZD_ARGB(255, 0,255,0));

Perhaps i should switch the layered window to a DWM composited to see if the DLL blur problem goes away  :-\
(like in my DwmSpinner demo)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 03, 2018, 09:22:15 pm
Patrice,

1. Sorry for not responding; I got an unexpected visit by my son.

2. When talking about blur flicker in the DLL, do you mean that dark topmost scanline that appears running randomly along the top edge of the quark frame window?

3. If yes then I'd say the pictures are looking quite differently in Spinner.h and the DLL. The .DLL blur looks much darker (and better at that!) than the .H blur (which is too thin IMHO), as if i) blur algos are different, or ii) alpha premultiplication algos are different, or iii) sizes or scale of the spinner quark texture are different so that an extra scan line is rendered by the DLL compared to the .H file. Or something else of such geometric kind, rather than DWM compositing or thread priority which would affect the entire spinner display rather than its border scan line only... :-\

Generally I like the .DLL version more than the .H one except for the offending scan line.

4. The green digital font looks very nice and a perfect match to the one used in the alpha threshold display. I'd rather we use that one instead of the cheaper looking white font... Any similar blur problems with the green digital font in the DLL spinner?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 03, 2018, 10:02:18 pm
Quote
2. When talking about blur flicker in the DLL, do you mean that dark topmost scanline that appears running randomly along the top edge of the quark frame window?
YES

Added:
Here is how it looks with a text size of 30

Shall send you pandora with the latest spinner change tomorrow morning...
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 03, 2018, 11:23:55 pm

To test bluring in the DLL, just unREM this code section (line 14739-14740)

    //RECT rb; SetRect(&rb, x + r.left, y + r.top, x + r.left + Width(r), y + r.top + Height(r));
    //BlurTextPlus(hdc, g_SP.szTime, rb, g_SP.font, 4, nStrFormat);


This recommendation was obviously incomplete. In fact I asked how I could switch between seeing an include spinner (I falsely assumed I was seeing it on default) and a DLL spinner.

Having got your patches and seeing Spinner.h included in the project, I thought the patches were set to use it. But in fact the calls were set to the library functions and I wasn't ever seeing how the spinner behaved in the include file. All I was seeing so far was just blur or no blur in the library spinner. It was my bad, I'm sorry to admit it, but I think next time I receive a patch I'd be grateful to be told what the patch's initial state is -- just in order to avoid losing my precious lifetime decoding it myself.

Now I can see blur in both include file and spinner and yes, its quality is identical and there's just that offending noisy scan line in the DLL that seems very much like a geometrical (spinner frame size?) issue...

Let's do the tests tomorrow. Seems like I'm too tired tonight if I overlooked such a trivial thing as finding out exactly what it was that I was looking at but not seeing. ;)

Zzzzzz...
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 04, 2018, 01:35:03 am
If you goto line 14707 in void RenderAnimation() and change this funny if/else-condition as follows:

............
if (g_SP.ishorizontal) {
    GdipDrawImageRectRectI(graphics, g_SP.img, 0, -2, g_SP.imgH, g_SP.imgH, g_SP.imgH * g_SP.frametouse - g_SP.imgH, 0, g_SP.imgH, g_SP.imgH, 2, 0, NULL, NULL); // MLL: brush misalignment?
} else {
    GdipDrawImageRectRectI(graphics, g_SP.img, 0, 0, g_SP.imgW, g_SP.imgW, g_SP.imgW * g_SP.frametouse - g_SP.imgW, 0, g_SP.imgW, g_SP.imgW, 2, 0, NULL, NULL);
}
............


you'll see no scan line flicker in the DLL spinner any more.

So this is a geometrical issue and most probably, its random nature is related to brush misalignment at some stage of GDI+ image creation process. There's a lot of work going on directly in memory rather than in a specific DC canvas, and such manipulations are sensitive to proper brush alignment with calls to SetBrushOrgEx() when the canvases and brushes in question are not managed directly by Windows itself (i.e. do not belong to the OS stock objects). Especially when world transforms are in progress, and image scaling inherent in GdipDrawImageRectRectI() is one of such transforms.

This solution is definitely a crutch but as long as it works, it is just as good as any other one.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 04, 2018, 08:22:46 am
Mike

Thank you for the crutch solution, i will try it and see how it works by me.

About the use of a layered window for the spinner, this was a survival of the XP's days, before Vista and the great DWM addition.

Nowdays i would have used compositing, just like what i did for the OR overlay, or for my C++ DwmSpinner project (I could  use it to solve definitly the problem, and get rid of the old layered stuff).
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 04, 2018, 08:53:36 am
Here is the latest pandora, altogether with the OR.zip i have been using for test purpose.

There is no more line flicker in the DLL, thank you!

What about the LCD digit size, is it good for you?
 
Do you know of a good free antimalware for Android?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 04, 2018, 09:14:01 am
You know what, if we use another FONT than the lcd.ttf, then the flicker is back again  :-\

I shall definitly give a go to the DwmSpinner version, to see if there is the same problem.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 04, 2018, 09:24:58 am
Here is the latest pandora, altogether with the OR.zip i have been using for test purpose.

Thank you, DL'ed OK and deleted!

Quote
There is no more line flicker in the DLL, thank you!

Excellent! :)

Quote
What about the LCD digit size, is it good for you?

What if we make it exactly the size that's used in the alpha threshold display? The earlier screenie gave me an impression it was a little larger than that obscuring too much of quark...
 
Quote
Do you know of a good free antimalware for Android?

Sorry Patrice, I've got absolutely no experience with Android except using my smartphone on rare occasions when I'm away from my workstation and optical land line web connection. It is my good old classic Nokia 3310 that I'm using on a regular basis instead. :)

I'm sorta squeamish towards slack-baked modern gimmicks and for me, there's nothing better than a well-packed desktop PC. :)

You know what, if we use another FONT than the lcd.ttf, then the flicker is back again  :-\

For me, it's OK with the font you used before lcd.ttf. (see below)

I haven't yet tried lcd.ttf because I was busy typing this response...

Re. DWM, please don't rush if it needs much effort. Let me see first what's going on with the fonts under my Win 7 and 10...
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 04, 2018, 10:01:08 am
OK, is that good to you ?

    Path_Combine(gP.mt.FullName, skSkinFolder(), L"LCD.ttf");
    ZI_SpinnerInit(gP.hGL, szFile, 0, zUsePrivateFont(gP.mt.FullName, 18), ZD_ARGB(255, 0,255,0));
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 04, 2018, 10:03:39 am
Patrice,

Chez moi, both lcd.ttf and skCaptionFontPlus() (and my loadTimer, for that matter :) ) display flawlessly under my Windows 7 and 10. Absolutely no trace of any offending scanlines.

Hm-m-m... ::)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 04, 2018, 10:05:48 am
18 is fine for me. Is it OK with your own eyesight?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 04, 2018, 10:11:04 am
OK, let's go for 18  :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 04, 2018, 10:14:46 am
OK :)

What about my Win 10 report? Does it agree with what you're seeing under yours?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 04, 2018, 10:18:42 am
Quote
What about my Win 10 report? Does it agree with what you're seeing under yours?
YES

Have you seen my post about the 3D KitBash mesh resource(s).
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 04, 2018, 10:21:39 am
I've noticed it but haven't seen the resource yet. I fear I may easily lose another couple of days on it ignoring my arrears in the shader control code development. ;D

Re. DWM experiments, then it's up to you if you go for it or not in your spare time. Let's agree on what we have now in our pandoras for the time being and proceed with the planned work.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 04, 2018, 10:27:10 am
Quote
Let's agree on what we have now in our pandoras for the time being and proceed with the planned work.
For the time being, i consider the current pandora status to be the official one  ;)

The new zUsePrivateFont is a nice addition...
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 04, 2018, 11:02:14 am
For the time being, i consider the current pandora status to be the official one  ;)

So be it! :D
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 04, 2018, 11:38:23 am
Re. 3D KitBash, it's a pity they are all for a fee except 4 small demos.

I sent them my address but I can't DL the demos from my Google Drive. I can see them allegedly accessible and I can inspect the zip contents but FF reports the associated redirections are incorrect and does nothing when I try to DL the zips... :-[
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 04, 2018, 01:38:18 pm
https://www.youtube.com/watch?v=2UJ5yO_vhTc
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 05, 2018, 03:11:22 pm
https://www.youtube.com/watch?v=2UJ5yO_vhTc

Got all 5 Gigs of this free 3D stuff. :)

Why am I doing this?! ;D
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 05, 2018, 03:53:33 pm
Quote
Why am I doing this?!
Masochism i presume  :)
Title: Re: Early WIP on v2.55 :: !!! AHTUNG in Main Menu !!!
Post by: Michael Lobko-Lobanovsky on November 06, 2018, 07:31:04 am
Patrice,

Sorry to distract you from your creative work but the skinned main menu metrics requires your attention.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 06, 2018, 01:21:46 pm
Ok, thanks, working on it…
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 06, 2018, 11:13:41 pm
I couldn't get the correct size of the menu font (using skFontMenu) within the UpdateMenuBar, with the CetTextExtentPoint32 API.

This is the reason of the misalignment   :(

I shall try another approach tomorrow.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 07, 2018, 10:11:31 am
I couldn't get the correct size of the menu font ... with the CetTextExtentPoint32 API.

You're drawing your menu text using GDI+. You should probably retrieve the text metrics using GdipMeasureString() rather than an ordinary WinAPI?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 07, 2018, 11:47:09 am
No, i have switched back to DrawTextEx (GDI32).

I think i have fixed the problem, but that was a hard one to deal with, because the value returned by Windows when using owner drawn menu doesn't match the size returned by the GetTextExtentPoint32.

GdipMeasureString is also returning values not always reliable, i had to do all kind of contorsion to live with it in GDImage…  ???

I shall send you a new pandora to test on Seven as soon as i have cleaned up the code from all the changes i have done.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 07, 2018, 12:11:43 pm
Good news!

BTW can your skinned trackbars display tooltips as per their TBS_TOOLTIPS style?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 07, 2018, 01:45:33 pm
Mike

While testing the new menu, i came upon a small glitch when using "Fancy modes" altogether with Mesh animation (animation is ignored).
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 07, 2018, 02:05:36 pm
Here is pandora, tell me how it goes by you (and Seven).

If it works, then i will create the official binary with VS2010.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 07, 2018, 02:19:57 pm
Will do, thank you!

... a small glitch ... animation is ignored ...

It isn't a glitch but a feature. ;D

Texture inspection and fancy modes use their own common render procs except for the historical "ambient reflection". They are lightweight simplified procedures with minimum if-branching, no lighting or texturing (in fancy modes) but basic material colors only, no transparencies nor billboards nor animation, mesh-wise or model-wise. All this stuff would only distract the user from the main objectives of the two modes -- close examination of texture looks and quality, and awesome shader admiration, respectively. :)

What about the tooltips in your skinned trackbars?
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 07, 2018, 02:33:09 pm
The new menubar draws as expected and looks beautiful. 8)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 07, 2018, 02:42:12 pm
Perhaps we could use this.

void skSetToolTipText (IN HWND hObj, IN WCHAR* zText) { // dllexport
    TOOLINFO ti = {0};
    wstring sText;
    if (zText) { sText = REPLACE(zText, $ZLIM, $CR); }
    HWND hTooltip = zToolTipData(0, 0);
    if (IsWindow(hTooltip)) {
        ti.cbSize   = sizeof(ti);
        ti.hinst    = skInstance();
        ti.uFlags   = TTF_IDISHWND;
        ti.hwnd     = skPopupOwner(hObj);
        ti.uId      = (UINT_PTR) hObj;
        ti.lpszText = (WCHAR*) sText.c_str();
        // Add tooltip now.
        SendMessage(hTooltip, TTM_UPDATETIPTEXT, 0, (LPARAM) &ti);
    }
}

I must investigate...
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 07, 2018, 02:53:47 pm
OK so I get it there is no built in support for automatic tooltips in skinned trackbars ATM, contrary to what we can get using a TBS_TOOLTIPS style in a Windows ordinary trackbar?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 07, 2018, 03:01:22 pm
New pandora on its way to check it when the TBS_TOOLTIPS style is being used.

Added:

Ok check with this, and tell me if this is what you want.

void SetThumbLocation(IN HWND hWnd, IN long x, IN long y) {
    RECT rc = {0}; float sIncrement = 0.0f;
    long tx = 0, ty = 0, tMin = 0, tMax = 0, tVal = 0, nRange = 0, nWidth = 0, nHeight = 0, imgW = 0, imgH = 0;
    UINT uMsg = 0;

    skGetBitmapSize(g_BtnTrack, imgW, imgH);
    imgW = imgW / 2;

    tMin = (long) SendMessage(hWnd, TBM_GETRANGEMIN, 0, 0);
    tMax = (long) SendMessage(hWnd, TBM_GETRANGEMAX, 0, 0);

    GetClientRect(hWnd, &rc);
    nWidth = rc.right; nHeight = rc.bottom;

    if (TrackOrientation(hWnd) == TRACK_HORZ) {
        tx = min(max(x - imgW / 2, 0), nWidth - imgW);
        ty = (nHeight - imgW) / 2;
        nRange = nWidth - imgW;
        sIncrement = (float) ((float) (tMax - tMin) / (float) nRange);
        tVal = (long) ((sIncrement * tx) + tMin);
        uMsg = WM_HSCROLL; }
    else {
        tx = (nWidth - imgW) / 2;
        ty = min(max(y - imgH / 2, 0), nHeight - imgH);
        nRange = nHeight - imgH;
        sIncrement = (float) ((float)(tMax - tMin) / (float) nRange);
        tVal = (long) ((sIncrement * ty) + tMin);
        uMsg = WM_VSCROLL;
    }
    SendMessage(hWnd, TBM_SETPOS, 0, tVal);
    SendMessage(skPopupOwner(hWnd), uMsg, MAKLNG(GetDlgCtrlID(hWnd), tVal), (LPARAM) hWnd);

    if (CheckWindowStyle(hWnd, TBS_TOOLTIPS)) { skSetToolTipText(hWnd, STRL(tVal)); }
}


Note: You must have first used something like this:
skCreateToolTip(hCtrl, L"  Stray light intensity  ");
at the time of the control skinning.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 07, 2018, 04:45:23 pm
Dastisch fantastisch! :o It works!!! ;D

But Patrice, my trackbars are gradated in integer steps of their full integer ranges and that's what the automatic tooltip displays. But I'd rather the tooltip displays the true value of my resultant parameter which is a float result of (float)curpos * (float)step, where curpos may be e.g. 12345 and step, 0.001f.

Can we bypass this automated way and probably not use TBS_TOOLTIPS but still be able to display my current true float parameters?

Perhaps something with TTN_NEEDTEXT?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 07, 2018, 04:53:48 pm
Mike

I can create a specific static function for that purpose, where you post in real time the WCHAR string that must be shown while dragging the trackbar thumb. But we must use a new TBS_CUSTOMTIPS style for that purpose ;)

It is up to you to give me the TBS_CUSTOMTIPS constant value that is not already being used.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 07, 2018, 04:57:34 pm
TBS_CUSTOMTIPS? What's this? :o

Don't your tooltips send TTN_NEEDTEXT notifications like ordinary tooltip controls?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 07, 2018, 05:01:32 pm
TTN_NEEDTEXT, i have never used that one, i must read the MSDN doc on how to use it  ???
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 07, 2018, 05:12:58 pm
They are normally sent to the tooltip owner window proc when the tooltip is about to pop up but hasn't yet appeared on screen. The user can supply custom text for it in real time, rather than display the tooltip's string hardcoded at creation time.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 07, 2018, 05:26:07 pm
Your auto-tooltip fix works well with mouse dragging. But if the thumb position has changed due to keyboard key presses and the tooltip pops up later on mouse hover, it still displays the last "dragged" value it stored when the mouse button was released.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 07, 2018, 05:40:23 pm
Re. TBS_CUSTOMTIPS, the trackbar style largest value used so far is only 0x1000. FWIW we can safely #define TBS_CUSTOMTIPS 0x10000000 and never live long enough to see our custom style conflict with the official MS Windows documentation. :D
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 07, 2018, 05:50:59 pm
to let it work with both mouse and keyboard, move the previous code from SetThumbLocation to GetThumbTrackLocation like this

void GetThumbTrackLocation(IN HWND hWnd, OUT long &tx, OUT long &ty) {
    RECT rc = {0}; float sIncrement = 0.0f; long imgW = 0, imgH = 0, tMin = 0, tMax = 0, tVal = 0, nRange = 0, nWidth = 0, nHeight = 0;

    skGetBitmapSize(g_BtnTrack, imgW, imgH);
    imgW = imgW / 2;
    tMin = (long) SendMessage(hWnd, TBM_GETRANGEMIN, 0, 0);
    tMax = (long) SendMessage(hWnd, TBM_GETRANGEMAX, 0, 0);
    tVal = (long) SendMessage(hWnd, TBM_GETPOS, 0, 0);
    GetClientRect(hWnd, &rc); nWidth = rc.right; nHeight = rc.bottom;
    if (TrackOrientation(hWnd) == TRACK_HORZ) {
        ty = (nHeight - imgW) / 2; if ((nHeight % 2) == 0) { ty += (imgH % 2); }
        nRange = nWidth - imgW;
        sIncrement = (float)((float)(tMax - tMin) / (float) nRange);
        if (sIncrement == 0) { tx = 0; } else { tx = (long)((float)(tVal - tMin) / (float)sIncrement); }
    } else {
        tx = (nWidth - imgW) / 2; if ((nWidth % 2) == 0) { tx += (imgW % 2); }
        nRange = nHeight - imgH;
        sIncrement = (float)(tMax - tMin) / (float)nRange;
        if (sIncrement == 0) { ty = 0; } else { ty = (long) ((float)(tVal - tMin) / (float)sIncrement); }
    }

    if (CheckWindowStyle(hWnd, TBS_TOOLTIPS)) { skSetToolTipText(hWnd, STRL(tVal)); }
}


I shall use  #define TBS_CUSTOMTIPS 0x10000000, and offer a new API much easier to deal with, than the convoluted WM_NOTIFY/TTN_NEEDTEXT
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 07, 2018, 07:34:45 pm
Mike

The new API can be used on the fly.
skSetCustomTipText(GetDlgItem(gP.hMain, IDC_BRIGHT_CONTROL), L"my custom tip");
to use altogether with the new
#define TBS_CUSTOMTIPS 0x10000000
is ready to test.

See the attachment (and make a backup copy first!!!)

Look at the comments // 2018-11-07 for the changes i have done.

Of course you will have to add the new constant and the declaration at the end of OR WinLIFT.h as well.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 07, 2018, 11:24:22 pm
Patrice,

Let's do it one step at a time. TBS_TOOLTIPS comes first, and when we fix it then we'll proceed to TBS_CUSTOMTIPS.

Your moving skSetToolTipText(hWnd, STRL(tVal)); from SetThumbLocation() over to GetThumbTrackLocation() alone in order to sync mouse dragging with keyboard control did not work.

Earlier the tooltip with the current integer value used to automatically pop up when the mouse would hover on top of it, then followed the thumb changing its readings accordingly as I pressed the LMB down and dragged it, and finally faded away when I released the LMB. Everything appeared to be working exactly like in an ordinary unskinned thumbtrack control except the readings didn't update in sync with keyboard key presses (arrow keys/PgUp/PgDn/Home/End) when the tooltip was naturally out of view.

Now the tooltip doesn't appear under the mouse any more, flashes only momentarily when I press the LMB down, and then disappears almost instantly to be never seen while dragging the thumb. :(

I think skSetToolTipText(hWnd, STRL(tVal)); should've stayed where it was but more code to handle key presses and tVal updates in the tooltip should've been added to the TrackProc() callback.

Is my analysis correct, do you think?


(BTW why should the names of SetThumbLocation() and GetThumbTrackLocation() be different?)



[UPD] Patrice, skSetToolTipText(hWnd, STRL(tVal)); should be in both Set and Get thumb location procedures! Then the tooltip's automatic tVal text is in perfect sync between mouse button and keyboard key presses. 8) I think the same applies to TBS_CUSTOMTIPS. Checking...
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 08, 2018, 12:01:01 am
Quote
Is my analysis correct, do you think?
I should have been more prolix, and better explain how to use it.

BTW you can use either TBS_TOOLTIPS or TBS_CUSTOMTIPS (mutually exclusive)
for TBS_TOOLTIPS, you already know how to use it.

For TBS_CUSTOMTIPS, you must call in real time the new API skSetCustomTipText(GetDlgItem(gP.hMain, CtrlID), WCHAR_TIP_TEXT) from any part of the code.
I could enhance it, by sending also a WM_NOTIFY/TTN_NEEDTEXT message, but this is almost the same, in both case you must provide a formatted string with the value to be shown.

Still clear as mud?

GetThumbTrackLocation, must be used for keyboard interaction, while SetThumbLocation() works only with the mouse, but of course we can use the same code in both places.

And for further obscurification i also have zGetThumbLocation and zSetThumbLocation, but it is a pandora box isn't it :)
These are for the native WinLIFT skTrackbar control, rather than subclassing pre-existing controls.

Going to bed right now, Zzzz

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 08, 2018, 12:19:04 am
No, I was smart enough to understand the usage from the very beginning. ;) I'm not that bad, you know... ;D

I just wanted to keep both functionalities but your latest mods broke TBS_TOOLTIPS -- it should have worked exactly as in bare (naked? ;) ) Windows. So I started with fixing it first.

And no, the styles are exclusive because TBS_CUSTOMTIPS overrides all TBS_TOOLTIPS automation, so they shouldn't be applied concurrently IMHO. My fixes change the branching to if/else if.

And no again, I do not see enough grounds to name the two functions differently, sorry. But of course it's your prerogative. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 08, 2018, 12:25:08 am
Quote
so they shouldn't be applied concurrently
I though that, mutually exclusive, had the same meaning  :-[
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 08, 2018, 12:42:05 am
No, not the same: TBS_TOOLTIPS with my fix is now fully automatic without user intervention. OTOH TBS_CUSTOMTIPS requires skSetToolTipText() in both WM_V/HSCROLL and WM_??? handlers in the user window callback.

Still checking TBS_CUSTOMTIPS...
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 08, 2018, 02:43:01 am
BTW frankly, I do not understand why your custom control callbacks (e.g. TrackProc()) use DefWindowProcs rather than subclassing the control's original specialized procs assined to them by Windows, to handle the control-specific messages you aren't handling yourself... Is it a correct approach, do you think? ??? Or are those callbacks meant for some type of controls different from the Windows common controls?

I've never done that in my own skinning engines I developed for use in FBSL... :-\

(Still fighting with TBS_CUSTOMTIP that seems totally non-responsive to arrow key messages and such... :( )
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 08, 2018, 05:28:33 am
No success nor new ideas so far.

Moreover, I've started to get random OR crashes due to memory access violation when the Ctrl toolwindow is on screen in a fancy mode and I try to exit the app. The debug mode lands randomly at various places of OR code but the cause is always the same -- heap memory corruption. A few times the debugger even pointed me to WinLIFT.dll as the offending module. :(

I'm too tired having spent the whole night at my desk. Going to zzzz now...
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 08, 2018, 10:07:05 am
My trackbar control doesn't behave the same, because i want the thumb button to jump directly to the correct mouse location, rather than moving tick by tick from the old location to the new one.

For now, just rem out the latest tooltip trackbar addition, if you think they are causing havoc in the Ctrl toolwindow.

To display trackbar values, i prefer to use something like in the attached screen shot, and keep the tooltip for generic help, like for the other controls.

So far, for the Ctrl toolwindow, i would recommend to switch to unskinned mode and plain toolwindow (no Ctrl popup) until full completion, then i will take on it and create a state of the art "tunning" like interface for the final version.

And about the final version, many of the new commands, will be converted to overlay checkboxes rather than menu options, to be more easy to use.

The important point that has been fixed in WinLIFT is the menu misalignment problem, but i couldn't see how this could have an impact on the toolwindow.
 
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 08, 2018, 10:20:05 am
Good "morning"! :D

1. So I consider TBS_TOOLTIPS fully Windows-compliant and working as expected.

2. The problem with TBS_CUSTOMTIPS still needs further investigation and that's what I'm going to continue right now.

3. The problem with random memory crashes at exit from OR that occur only if the toolwindow has already been created (i.e. the Ctrl button has been pressed at least once) will be the last to try and resolve when item 2 above has been fully fixed.

Thant's gonna be my program for today. :-\

I've read your response while typing this and I think that what you suggest would be somewhat humiliating for my intelligence. I'm sort of a d'Artagnan by my nature: I see a challenge and I attack, rather than retreat in pitiful surrender. And at any rate, there should be no faults in your frameworks otherwise there'll be no value in them when you bequeath them to your heirs and decide to pass away. :D

So I think I can spare yet one more working day trying to resolve the problems cleanly. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 08, 2018, 10:29:47 am
TBS_CUSTOMTIPS is something new (from yesterday) and i am still experiencing with it, to see if it is of real value or not, and if the new style is not causing havoc in Windows itself :o

Added:
I could turn it into property rather than adding a new Windows style, that is a MS prerogative.

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 08, 2018, 10:58:12 am
Quote
... many of the new commands, will be moved to an overlay rather than menu, to be more user friendly.

In my opinion, triple nested popup menus are still user friendly enough (especially in full screen where there's no other way to use many of OR's options) while quadruple nested would be too shaky and cumbersome.

Another one of my ideas of user friendliness is having many of popup menu options duplicated in the main menu for much faster access when windowed.

Yet more user friendliness lies in being able to utilize ESC and TAB keys to the fullest. ObjReader can now ESC from the toolwindow, Z-axis rotation, full screen, and design/fancy render modes directly to the main render mode (in precisely that order) without the help of the menu. Moreover, when in a texture inspection or fancy render mode, the user can now loop through the other modes of the group (bypassing the disabled ones) with the help of TAB key, again without having to resort to the menu.

That's what I call genuine user friendliness of a GUI, my friend. And if at the same time the GUI is also a pleasure to look at, then the entire program's strong wow-factor appeals to the user to the fullest. Not every user is a pure point-and-click guy like us, you know. ::)

Quote
I could turn it into property rather than adding a new Windows style, that is a MS prerogative.

That'll be the best thing to do for all trackbars because the moment the user needs the latest thumb position value, e.g. to handle custom tooltip text for keyboard key presses, currently it isn't yet available to poll from the user code. Or we need a hypothetic skGetThumbPosition() export for genuine Windows trackbars, not only for your custom-drawn mockups. And that export must be 100% guaranteed functional and always freshly updated for trackbar keyboard control as well.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 08, 2018, 11:55:14 am
Mike

Working back on CUSTOMTIP for the new property, i found several mistakes because i have used skChild rather than the new skTip, this is what happens when i am getting too tired…
This could cause the memory allocation error you are experiencing  :-[

I shall post a new pandora with my latest changes for winmerge comparison purpose, as soon as i have got some good food :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 08, 2018, 12:39:35 pm
No problem my friend, we aren't as mighty as we used to be and that's only natural. :)

Take as much time as you need to still feel fun from coding. We're in no hurry and it's our valued privilege at our age. :)

(The toolwindow's latent memory corruption seems so heavy I can't call a ChooseColor common dialog in response to the button press. The dialog crashes OR at dialog show or hide time... :'( )
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 08, 2018, 02:18:21 pm
Mike

Here is the latest pandora, please do a winmerge to see the changes done to the code.

The name of the new property is
skUseCustomTip(IN HWND hWnd)

Note: when used, the TBS_TOOLTIPS style is disabled

Would you like me to send a WM_NOTIFY/TTN_NEEDTEXT from SetThumbLocation and GetThumbTrackLocation, when CustomTip is being used?

Tell me what you think?
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 08, 2018, 04:02:26 pm
DL'ed OK , now starting to merge, then will proceed with testing...

Please don't expect it to be soon. Build some nice little model for us in the meantime. :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 08, 2018, 06:15:44 pm
No Patrice,

The one and only obvious improvement is that now there seem to be no more app crashes due to memory corruption, and that is very very good! :)

SYNOPSIS

While issue #3 is easy to resolve, I'm seeing no progress with issue #2. We still have no means to determine the real current position of the custom-drawn thumb at all times (including WM_H/VSCROLL) by polling WinLIFT directly, rather/other than SendMessage(TBM_GETPOS). It probably goes to the trackbar too early when the thumb hasn't yet reached the new position in response to a key press, or hasn't yet updated its thumb position value.

While this nuance may not be so important for verbal/descriptive custom tooltip texts, it is absolutely essential for the accurate numeric readings of current parameter's real values.

What trackbar are you using to test your mods against? I have a feeling you're modding WinLIFT by ear following my descriptions rather than testing your mods against some real setup. My ToolWindow.h is now heavily modified as compared to what it used to be originally and I wouldn't want to incorporate it in your OR too early without my other mods.

Yet I could probably describe what minimal code you should add to your virgin ToolWindow to have a test bench to reproduce and correct issue #2 on your own machine... ???
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 08, 2018, 06:30:24 pm
My Friend

To say the truth i have got a flu, and was coding most of the last changes with a terrible headache.

After looking again at it, it seems that
UseCustomTip should be renamed skIsCtrlUsingCustomTip and exported from the DLL.
To be able to use it with the WM_VSCROLL and WM_HSCROLL messages

Glad it has solved the memory corruption, sorry for the confusion between skChild and skTip that was my mistake :-[

Added:
Quote
What trackbar are you using to test your mods against?
The vertical straylight one  :(
...
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 08, 2018, 06:42:58 pm
MY FRIEND,

WHY DIDN'T YOU TELL ME EARLIER YOU AREN'T FEELING WELL? :'(

This all can wait till you get better; I have other important things to do with my code, and I can live with inaccurate readings for the time being. When you tell me you're in a good shape again, I'll send you my minimal code for a virgin ToolWindow for us to be as close to the real setup as possible.

Get well soon and sorry for my being so insistent, impatient and perhaps even aggressive in the recent couple of days. :-[

Please accept my sincere apologies!
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 08, 2018, 07:57:01 pm
Mike

The OR WndProc
    case WM_VSCROLL: // ML 02-01-2018: scene brightness
is incomplete, because so far it considers only the SB_THUMBPOSITION,
none of the SB_BOTTOM to SB_TOP flags are handled correctly.
https://docs.microsoft.com/en-us/windows/desktop/controls/wm-vscroll

As you said, being "point and click" guy, we never noticed the wrong value while using the keyboard arrow keys to move the slider.  :-\

Easy to solve when using SendMessage(TBM_GETPOS) rather than HIINT(wParam).

Code: [Select]
    case WM_VSCROLL: // ML 02-01-2018: scene brightness
        //zTrace(STRL(SendMessage(GetDlgItem(hWnd, IDC_BRIGHT_CONTROL), TBM_GETPOS, 0, 0)));

        //gP.rIllumFactor = (HIINT(wParam)) / -100.0f;
        hCtrl = (HWND) lParam;
        if (hCtrl == GetDlgItem(hWnd, IDC_BRIGHT_CONTROL)) {
            gP.rIllumFactor = SendMessage(hCtrl, TBM_GETPOS, 0, 0) / -100.0f;
            SCALEILLUM(0); SCALEILLUM(1); SCALEILLUM(2); SCALEILLUM(3);
            //zTrace(STRF(gP.rIllumFactor));
            if (skIsCtrlUsingCustomTip(hCtrl)) {
                swprintf_s(zTxt, strSize(zTxt), L"brightness %2.0f", gP.rIllumFactor * 100 + 0.001f);
                skSetToolTipText(hCtrl, zTxt);
            }
            gP.redraw = -1; // Redraw the OpenGL scene
        }
        break;
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 08, 2018, 09:54:47 pm
You're dealing with trackbars rather than scrollbars, Patrice. Prefer to use TB_xxx constants here.

And note that HIINT (HIWORD actually) isn't recommended (https://docs.microsoft.com/en-us/windows/desktop/controls/wm-hscroll--trackbar-) by MSDN itself.

Note also that it's exactly SendMessage(TBM_GETPOS) that  falters in WM_HSCROLL when our trackbars have custom text tooltips and the keyboard keys are pressed. :(

Get a good rest and tell me when you're ready for the ToolWindow minimum code to reproduce the glitch.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 08, 2018, 09:59:29 pm
YEs i meant TB_rather than SB_ of course.
So far with the posted code that works well by me, using either the mouse or the keyboard, i got exactly what i want.

Added:
Quote
Get a good rest and tell me when you're ready for the ToolWindow minimum code to reproduce the glitch.
I can start looking at it tomorrow, thanks!
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 09, 2018, 08:44:47 am
OK Patrice,

I hope you're feeling better today. :)

Please overwrite the DetectCtrlKey() function in Main.cpp with the this code:

void DetectCtrlKey(MSG* msg) { // MLL 11-06-2018: hide on [X] button only
    if (msg->wParam == VK_CONTROL) {
        if (msg->message == WM_KEYDOWN) {
            gP.hTool = CreateToolWindow();
        }
    }
}


and do the following:And get well soon! :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 09, 2018, 03:15:01 pm
Problem solved, thank you!

Doing some UI improvements before posting the result...
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 09, 2018, 06:57:39 pm
Mike

About pandora i reverted back to the Quo ante status.

And the trackbar tooltips are shown/used as soon as we are calling skCreateToolTip (no need to use the TBS_TOOLTIPS style first).

I made a few changes into the ToolWindow to better see the current value setting, without having first to click on the track bar.


Here is the WM_HSCROLL used in ToolWindow.h
Code: [Select]
    case WM_HSCROLL:
        hCtrl = (HWND)lParam;
        gMinn.spotCur = SendMessage(hCtrl, TBM_GETPOS, 0, 0) * gMinn.spotStep;
        swprintf_s(zTip, strSize(zTip), L"%2.0f", gMinn.spotCur);
        skSetToolTipText(hCtrl, zTip);
        SetWindowText(GetDlgItem(hWnd, IDT_VALUE02), zTip);
        gP.redraw = -1; // request redraw
        return 0;


Here is the WM_VSCROLL used in Main.cpp
Code: [Select]
    case WM_VSCROLL: // ML 02-01-2018: scene brightness
        hCtrl = (HWND) lParam;
        if (hCtrl == GetDlgItem(hWnd, IDC_BRIGHT_CONTROL)) {
            gP.rIllumFactor = SendMessage(hCtrl, TBM_GETPOS, 0, 0) / -100.0f;
            SCALEILLUM(0); SCALEILLUM(1); SCALEILLUM(2); SCALEILLUM(3);
            swprintf_s(zTxt, strSize(zTxt), L"brightness %2.0f", gP.rIllumFactor * 100 + 0.001f);
            skSetToolTipText(hCtrl, zTxt);

            gP.redraw = -1; // Redraw the OpenGL scene
        }
        break;



Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 09, 2018, 07:48:03 pm
Thank you Patrice,

I'll try out your mods and report back a.s.a.p.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 09, 2018, 09:04:20 pm
OK I got your point Patrice,

So now we have Windows tooltip automation no more... ::)

Never mind, your fix (or rather rollback) is working perfectly fine for me. :)

I just moved the value labels to xOffset = 100 because the parameter names (captions) are going to change dynamically depending on the shader and I want to avoid having to move the labels manually based on the name lengths.

I also made the labels 50 px wide and changed the tooltip and value label formats to %2.3f because those are shader parameters and everything in GLSL has at least half-float (three decimal digits) precision.

You've done a great job and may now "rest in peace" till you get completely well. :)

But don't forget to send me your official WinLIFT VS2010 libs first!

Thank you! :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 10, 2018, 10:14:53 am
What do you mean by static one?

For the ToolWindow, here is what to do to compute the correct xOffset, and display the IDT_VALUExx at the right location, rather than a fixed one.

long stW = 0, stH = 0;
WCHAR zFont[MAX_PATH]; ClearMemory(zFont, sizeof(zFont));
Path_Combine(zFont, skSkinFolder(), L"trebuc.ttf");
WCHAR zTxt[MAX_PATH]; ClearMemory(zTxt, sizeof(zTxt));
GetWindowText(GetDlgItem(hWnd, IDT_CAPTION02), zTxt, strSize(zTxt));
ZD_GetTextBound(zTxt,           // The related string
                zFont,          // The TrueType font name
                14,             // The size of the font being used in pixel
                stW,            // Get the bounding width
                stH,            // Get the bounding height
                ZD_TextHorzUp); // We use horizontal orientation
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 10, 2018, 11:06:06 am
BTW are there any help files for the GDImage and WinLIFT libraries?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 10, 2018, 11:26:51 am
Quote
Isn't that a bit too much for a 3rd-rate feature that will eventually be moved into the existing/additional overlay window?
This was also to let you know, how to use the existing pandora API for that purpose.

I have attached the missing .lib (i thought it was already in the previous zip)

And 2 chm help files for WinLIFT and GDImage (for the 32-bit version, but the 64-bit API names are the same)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 10, 2018, 12:50:36 pm
Thank you ever so much Patrice!

How are you feeling today? We've got 0oC with fog and wind here and 100% humidity but we've seen no snow so far. That's the worst weather possible for my arteries, and I'm aching all over. :(

Quote
... i thought it was already in the previous zip ...

No, the zip contained the DLL only. I guess both libraries are regenerated when a WinLIFT/GDImage build is recompiled, so to keep them ABI compatible we should reinstall both of them after each recompilation.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 10, 2018, 01:08:44 pm
Does your trebuc.ttf in the \Reader subfolder differ from the Trebuchet MS font that's installed under my Win 7 natively?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 10, 2018, 01:20:59 pm
Quote
How are you feeling today?
After an horrible night, i feel a little better now with the help of a "tea tree" fumigation.

Quote
That's the worst weather possible for my arteries, and I'm aching all over.
My friend you have my compassion.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 10, 2018, 01:27:07 pm
Quote
Does your trebuc.ttf in the \Reader subfolder differ from the Trebuchet MS font that's installed under my Win 7 natively?
I couldn't say, but the use of a private font, is the garantie that the look of the interface is always the same from one computer/OS version to another.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 10, 2018, 10:33:53 pm
Re. Mark17:

Contemporary rendering engines usually store grayscale luminance texture maps (AO/cavity, specular/shadow, gloss/roughness/metalness, height/displacement) in individual color/alpha channels of common multipurpose 32-bit textures. This way they improve 4x on both the texture size in VRAM and the time it takes to mipmap huge contemporary 4Kx4K and 8Kx8K texture atlases.

How would you suggest they store your bluish chrome_AO.png in their paradigm? ;)

(What you really need here is effectively called a colored light map -- an opposite to the grayscale AO/shadow map.)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 10, 2018, 10:45:29 pm
Currently, i am doing the best of what i can do, with what is on my disposal ;)

Here is another example of altered AO to produce the attached screen shot...
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 10, 2018, 10:53:53 pm
In Blender, you can bake the AO and/or light map directly into the mesh diffuse texture thus sparing a huge amount of model loading time and video memory.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 11, 2018, 07:51:28 pm
Ok, i found the error, the antialias that was used in skDrawTextToDC is incorrect.

Try with this

void skDrawTextToDC(IN HDC hDC, IN wstring sTxt, RECT rb, IN long nItem, IN LONG_PTR nStrFormat) {
    if (nItem > -1) {
        RECTF rcLayout;
        LONG_PTR nFontToUse = 0, graphics = 0, nFam = 0, nBrush = 0;
        // Create matching font
        nFam = g_Child[nItem].PrivateFont;
        if (nFam == 0) { GdipCreateFontFamilyFromName(g_Child[nItem].fontName, 0, nFam); }
        if (nFam) {
           GdipCreateFont(nFam, g_Child[nItem].fontSize, g_Child[nItem].fontStyle, 2, nFontToUse);
           if (nFontToUse) {
               if (skGetSystemMetrics(SK_OUTER_GLOW)) { BlurTextPlus(hDC, (WCHAR*) sTxt.c_str(), rb, nFontToUse, nStrFormat); }
               if (GdipCreateFromHDC(hDC, graphics) == 0) {
                   rcLayout.left   = (float) rb.left;
                   rcLayout.top    = (float) rb.top;
                   rcLayout.right  = (float) rb.right - rb.left;
                   rcLayout.bottom = (float) rb.bottom - rb.top;
                   //GdipSetTextRenderingHint(graphics, TextRenderingHintAntiAliasGridFit); // wrong antialias
                   GdipSetTextRenderingHint(graphics, TextRenderingHintAntiAlias);
     
                   if (GdipCreateSolidFill(g_Child[nItem].fontColor, nBrush) == 0) {
                       GdipDrawString(graphics, sTxt, (long) sTxt.length(), nFontToUse, rcLayout, nStrFormat, nBrush);
                       GdipDeleteBrush(nBrush);
                   }
                   GdipDeleteGraphics(graphics);
               }
               GdipDeleteFont(nFontToUse); // Delete the font object
           }
           if (g_Child[nItem].PrivateFont == 0) { GdipDeleteFontFamily(nFam); }    // Delete the font family object
        }
    }
}


Check with this change and tell me how it goes.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 11, 2018, 11:24:21 pm
Thanks for the good job, Patrice! :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 12, 2018, 04:23:30 pm
OK Patrice,

I want you to get well sooner, and to this end, I'm going to increase your interest in life.

Here are my mods that add run time controls to the fancy shaders. Now you'll be able to inspect your patients under much higher quality adjustable X-ray light. :)

The code has been refactored a little further to avoid forward declarations, improve functional modularity, and allow conditional compilation. I'm including my MLL_DEV.h but of course you can suppress all my specific code from your compilations by commenting out one single PP directive #define MLL_DEV on line 5 at the top of globals.h.

My next step will be to add:Please inform me of any glitches you may spot as well as of your general impression of the new features I added.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 12, 2018, 06:20:13 pm
Ok, Mike

You can REM OUT all references to SetProcessorAffinity()

testing now...
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 12, 2018, 07:44:15 pm
Everything seems to work fine, thank you!

The new "Smooth shading" option, showed me a small problem on my 3W_HR calandre ;)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 12, 2018, 08:10:10 pm
Thanks for the good news, Patrice! :)

Regretfully I can't yet provide flat shading in every fancy shader as many of them don't use the model's normals or specular lighting at all. But I've made provisions to add them at some future point in time when I figure out how to.

What can you say about our new global "hotkeys" that allow TAB-ing through the fancy and texture inspection modes, and ESC-aping from the tool windows, Z-axis rotation, design and fancy modes, and full screen (precisely in that order of priority)?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 12, 2018, 08:57:27 pm
Huh, i can't popup the toolwindow while pressing the cytl key  ???

Where does GP.bIsFunMode is being fired?

Added
found it ;)
gP.bIsFunMode = gP.bSpecular | gP.bMinnaert | gP.bGooch | gP.bToon | gP.bXray | gP.bMicro;
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 12, 2018, 09:18:41 pm
Probably you missed something while merging?

Don't be in a hurry, check and re-check carefully in WinMerge. There's quite a lot of stuff to mod as compared to what we've had before...
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 12, 2018, 09:45:57 pm
Looking closely at DetectHotKeys, i was able to understand how to use the TAB key.

I think there should be a furtive window to inform the user when he can "Press the TAB key to move to the next design mode"

I have an example of furtive window in the HUD controls project here
http://www.objreader.com/index.php?topic=26.0
(the one that displays the time)
And listen the sound used when the furtive window is open or closed.

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 12, 2018, 10:06:06 pm
Probably yes, but the arrow tab of that window should not stick from the outside into the viewport all the time. The tab (if the window is needed at all) should appear visible only when the cursor is somewhere near the viewport side where the window is supposed to slide in from.

I'd like to see that functionality in the lighting pane too, instead of the current F1 key. This way we could free F1 for its proper function -- to bring the help window on screen. IMHO  OR is already sophisticated enough to be supplied with an appropriate help system. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 12, 2018, 10:08:23 pm
There is also the concept of the toast window explained here:
https://doc.windev.com/?1000019358&name=toastdisplay_function
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 12, 2018, 10:19:58 pm
Yeah, I know this type of message windows. They are used extensively in the Code::Blocks editor that hosts my GCC. They slide up into view above the notification area on the right side of the taskbar and then disappear automatically.

We could have the same in the viewport sliding up into view on Ctrl press in the bottom right corner of the viewport and then sliding down and out of view completely after staying on screen for, say, 15 or 20 seconds.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 13, 2018, 07:58:52 pm
Here is an example of the furtive/toast window i have been working on.

The GDimage compositing build this kind of image on the fly, that can be used as a static window.

We can change everything, there is no limit to what we could put inside of the compositing
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 14, 2018, 03:43:54 am
Hey Patrice,

OR doesn't seem to store the state of scene individual lights (on or off) into the MTL file, just #multilight or not.

Is it a bug or a feature?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 14, 2018, 08:17:27 am
Correct, OR stores the color of the individual lights, and #multilight switch them ALL to On mode.
If we want to store the individual on/off lighting mode, then we should use another #meta, aka #individuallight (for example).

Working on the compositing of the new furtive/toast window, shows me a difference of behaviour between GDImage 32 and 64 that i have fixed, i am also adding a new button to test the toast window.

Because of the changes done to OR, you will have to sync with me once done.

Updated
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 14, 2018, 10:28:28 am
If we want to store the individual on/off lighting mode, then we should use another #meta ...

From my standpoint, there are a few objections to the current syntax of #Light statements:Secondly, it seems weird that on clicking Reset scene lighting, OR currently resets the scene lights to some predefined default values rather than the initial states described in the MTL file. Moreover, Stray light intensity remains unaffected by the reset at all. I think the existing light arrays should include yet one more set that's loaded from the MAT file and used instead of the existing ref arrays to reset the light and light intensity states to. The existing ref arrays should be used to reset the scene lighting only when i) the MAT file has no specific light control section or is missing altogether, and ii) before initial model load and in between model reloads when no MAT file has yet been parsed.

I'd like to know your opinion on my suggestions.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 14, 2018, 11:10:38 am
Yes, i agree with you, as long as it doesn't break the existing .mtl files  8)

I keep working on the toast window, shall send you something to play with later on today, altogether with new pandora and extra resources.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 14, 2018, 08:13:53 pm
Here is what i have done so far…

1 - OR_patch.zip (the changes done to support the new ToastWindow)
2 - pandora.zip (New FontStyle parameter added to ZD_GetTextBound, and ZI_CreateTextObject)
3 - resource.zip (to put into the Reader skin folder)

The Toast button is for test purpose only, so far the code timer has not been yet implemented.

To display a new Toast message just use something like this

WCHAR UseIcon[MAX_PATH] = { 0 }; Path_Combine(UseIcon, skSkinFolder(), L"bulb.png");
ToastWindow(UseIcon, L"Caption", L"first text line.\nsecond text line very long, very very long, i said very long!\netc.");


Of course we can use any other icon, like ICON_info.png or ICON_alert.png

I hope there is nothing missing in the zip(s)  ::)

...
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 14, 2018, 09:13:24 pm
Thank you Patrice!

Need time to play with the new goodies.

See you tomorrow. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 14, 2018, 10:39:54 pm
Here is the OR_patch.zip with the missing files, sorry  ???

The Toast button should show the ToastWindow, as long as you have used first
WCHAR UseIcon[MAX_PATH] = { 0 }; Path_Combine(UseIcon, skSkinFolder(), L"bulb.png");
ToastWindow(UseIcon, L"Caption", L"first text line.\nsecond text line very long, very very long, i said very long!\netc.");
see line 2912 of my Main.cpp

zToast.png is the composited image build from memory, see line 82 of TestWindow.h
and read the CHM documentation

ZI_CreateImageComposited  

Create a GDImage composited image from a ZOBJECT array.

This is powerful feature that allows you to create on the fly a new image composed from any number of overlapping layers.
Each of the object layer being defined first in a ZOBJECT array, using any GDImage object type.
The order of the array will match the z-order of the final composited bitmap, starting from bottom to top.

You have the choice to create a new disk file to save the composited image, or to create a memory bitmap that you can use into a GDImage control or into a provided DC (GDI32).


FUNCTION ZI_CreateImageComposited ( _
zImageDest AS ASCIIZ, _          ' OPTIONAL name to save the resulting composited image to file.
BYVAL xW AS LONG, _              ' Bound Width of the resulting composited image.
BYVAL yH AS LONG, _              ' Bound Height of the resulting composited image.
BYVAL pSprite AS ZOBJECT PTR, _  ' Pointer to the ZOBJECT array structure
BYVAL N AS LONG _                ' The ZOBJECT array count.
) LONG

Return:
A GDI32 bitmap handle if  zImageDest = "", else Null.

Remark:
If you assign the memory bitmap to a GDI32 DC, then it is up to you to delete the bitmap when you don't need it anymore.

 
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 14, 2018, 11:15:36 pm
Thanks for updating the patch, Patrice!

The Toast button should show the ToastWindow, as long as you have used first
WCHAR UseIcon[MAX_PATH] = { 0 }; Path_Combine(UseIcon, skSkinFolder(), L"bulb.png");
ToastWindow(UseIcon, L"Caption", L"first text line.\nsecond text line very long, very very long, i said very long!\netc.");
see line 2912 of my Main.cpp

:o

I'm telling you, until you sent me the updated patch, I was using my arbitrary value for IDC_BTN_TOAST in my constants.h:

#defineIDC_BTN_TOAST 50116

because that was the next free numeric value at the bottom of the file.

Believe it or not, the Toast button click was never fired in WndProc() with that ID! But with a small ID of 126 it does fire now! :o

Is it somehow related to

#define IDC_GRAPHIC_CARD 127 // PAT: 02-17-2018
#define IDC_LAST IDC_GRAPHIC_CARD // PAT: 02-17-2018
  ?

What do we need such a restriction on the ID values for?
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 14, 2018, 11:49:25 pm
The toast window is beautiful! :D

I've just taken the liberty of deleting most of the shadow from under the bulb. It looked pretty much like ordinary borderline smear against dark backgrounds... ???

Do you agree to use my modded image instead?
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 15, 2018, 01:43:38 am
Most of your skinned controls usually have one and the same parent in a common main window. Why wouldn't you use a single call to Begin/EndDeferWindowPos() in response to their parent resize event, instead of numerous individual MoveWindow() actions that cause multiple redraw in the parent window?

Successive MoveWindow() calls make the controls follow the parent visibly one by one while a common Begin/EndDeferWindowPos() call will move all of the included child control windows to their respective new places in just one draw call.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 15, 2018, 09:50:50 am
Mike

1 - When using new ID for button controls, it is very important to use a value lower than the IDC_LAST, for the code used in ToggleFullScreen
aka:
for (K = IDC_FIRST; K <= IDC_LAST; K++) {
    ShowWindow(GetDlgItem(gP.hMain, K), SW_HIDE);
}

Anyway this button was there, just for test purpose, and it will be removed as soon as the test is completed :)

2 - Bulb.png
Do you agree to use my modded image instead? YES ;)

3 - About Begin/EndDeferWindowPos()
Now that we have several control to resize that is worth a try, even if most of the time these related controls are kept hidden.

Here is the one i was using in my old PB's zSkin.inc
Code: [Select]
FUNCTION zBeginDeferWindowPos(BYVAL hWnd AS LONG, BYVAL nWindowCount AS LONG) AS LONG
    CALL LockWindowUpdate(hWnd)
    CALL SendMessage(hWnd, %WM_SETREDRAW, 0, 0)
    IF nWindowCount = < 128 THEN nWindowCount = 128
    FUNCTION = BeginDeferWindowPos(nWindowCount)
END FUNCTION

SUB zEndDeferWindowPos(BYVAL hWnd AS LONG, lRes AS LONG)
    CALL EndDeferWindowPos(lRes)
    CALL SendMessage(hWnd, %WM_SETREDRAW, 1, 0)
    CALL LockWindowUpdate(0)
END SUB

    CASE %WM_SIZE
         IF zComposited() THEN lRes& = zBeginDeferWindowPos(hWnd, 0)
         CALL zDrawBackground()
         CALL EnumChildWindows(hWnd, CODEPTR(AnchorEnum), lRes&)
         IF glRC THEN
            CALL ResizeGLwindow(zGetMainItem(%ID_OpenGL))
            CALL RenderOpenGL(zGetMainItem(%ID_OpenGL))
         END IF
         'CALL zUpdateWindow(hWnd, 0)
         IF zComposited() THEN CALL zEndDeferWindowPos(hWnd, lRes&)
Do you agree with it?
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 15, 2018, 10:25:55 am
1. Got it!

2. Fine! :)

3. That code doesn't reveal the DeferWindowPos() calls proper but logically I'm assuming they reside in the EnumChildWindows() enumeration.

Since you used that code in PB already, I guess everything's all right with the deferrals and the setup works as expected, otherwise the controls simply wouldn't move anywhere. So why not use it in 64 bits as well? That's the best of what WinAPI can offer in the way of handling multiple resizes/moves of the child windows that belong to strictly the same parent window.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 15, 2018, 10:48:12 am
Just one practical objection.

LockWindowUpdate() is redundant in the presence of WM_SETREDRAW/FALSE. The matter is that LockWindowUpdate() is very rough visually when later on it is used with (0) to unlock the updates. It then causes the entire desktop to redraw, and this is irritating to see on every main window resize.

WM_SETREDRAW/FALSE/TRUE with a subsequent UpdateWindow() call should be sufficient and very neat visually. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 15, 2018, 10:56:03 am
Code: [Select]
That's the best of what WinAPI can offer in the way of handling multiple resizes/moves of the child windows that belong to strictly the same parent window.To say the thruth i haven't used it for more than a decade, since it seems to be useless when working in DWM compositing mode.
But if DWM is turned off, that could be handy.

It is my undertsanding than when using DWM compositing, all drawing are sent to the DirectX hidden surface to compose the desktop screen preserving the z-order of all windows as well as their child controls, then bliting everything in one go.

But you can try to use deferwindowpos if you have a way to check it, then there will be probably no harm to use it with DWM?

Did you hear the sound played while poping up the Toast window?

You can easily change the font style, for example at line 73 in ToastWindow.h, we could use this
ZI_CreateTextObject(arrayobj[3], UseCaption, 4 + bmW + 4, 4, CaptionW + 8, CaptionH + 8, ZD_ARGB(255, 255,240,140), zFont, 18, ZS_VISIBLE, 1, StringAlignmentNear, FontStyleUnderline);
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 15, 2018, 12:54:42 pm
... it seems to be useless when working in DWM compositing mode ... when using DWM compositing, all drawing are sent to the DirectX hidden surface to compose the desktop screen preserving the z-order of all windows as well as their child controls, then bliting everything in one go.

There can't be "one go" if you're dealing with atomic MoveWindow() calls. Re-compositing and re-blitting will be done after each move, and if you're attentive enough and there are, say, a dozen child controls to move, then you'll notice all the dozen redraws as Windows moves each control to its new place and/or size one by one, re-compositing and re-blitting the form in the process after each move. Now imagine what it's gonna look like if there are five dozens child controls on the parent form, which isn't a rare case at all in modern professional looking GUIs. ;)

OTOH it is not so with Begin/End/DeferWindowPos(). All resizing/repositioning is recalc'ed on the spot but deferred (i.e. postponed) -- BTW regardless of WM_SETREDRAW -- until the OS sees the EndDeferWindowPos() call, whereby it redraws the parent window immediately with all its child windows in their new places/sizes in just one blitting operation, DWM or no DWM.

Quote
Did you hear the sound played while poping up the Toast window?

Yes, I noticed it, and I think it's a good idea to alert the user to the hint popping up on the screen. Of course there should be an option in the rightmost Help menu to enable/disable the toast window option for beginners or experienced users, respectively.

And thanks for the font hint to customize the toast window's appearance. I'm going to fiddle with it today and try to adjust it to our needs. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 15, 2018, 04:02:29 pm
BTW, the Toast button is not anchored ;)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 15, 2018, 04:22:10 pm
Yours wasn't but mine is. ;D
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 15, 2018, 06:16:43 pm
That's very elegant and so französisch! ;D

But a little too burlesque for our purposes I think. :)

Toast window timing built around the timer func callback fired after 10 secs to close the popup works perfectly fine. I'm currently populating the code with popup help. 8)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 15, 2018, 06:56:16 pm
Some more TODOs pending... (see below)

I think when we fix them all and add FBO for post-processing, we are going to be ready to release OR v3.0. :)

BTW item #2 in this menu's gonna be a very very exciting and advanced thing to implement. Then we'll be able to create and save collages like your DreadRoamer+butterfly (The Beauty & The Beast(c) LOL) directly in OR. 8)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 15, 2018, 08:44:35 pm
Here is the code to add a close button into the ToastWindow

Code: [Select]
LRESULT CALLBACK ToastCallBack(IN HWND hWnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam) {
    LRESULT nRet = FALSE; // Do not stop the event processing in GDImage.

    long nID = ZI_MouseOverObjectID();

    switch (uMsg) {

    case WM_LBUTTONUP:
        if (nID == ID_TOAST_HIDE) { HideToast(); }
        break;
    }
    return nRet;
}

void ToastWindow(IN WCHAR* UseIcon, IN WCHAR* UseCaption, IN WCHAR* UseComment) { //IN HWND hParent, IN HINSTANCE hInstance) {
    if (gP.hToast) { DestroyWindow(gP.hToast); }

    WCHAR zFont[MAX_PATH]; ClearMemory(zFont, sizeof(zFont));
    Path_Combine(zFont, skSkinFolder(), L"trebuc.ttf");

    // We compute the correct size
    long CommentW = 0, CommentH = 0;
    ZD_GetTextBound(UseComment, zFont, 14, CommentW, CommentH, ZD_TextHorzUp, FontStyleRegular); // We use horizontal orientation
    long UseW = CommentW + 4;
    long UseH = CommentH;
    long CaptionW = 0, CaptionH = 0;
    ZD_GetTextBound(UseCaption, zFont, 18, CaptionW, CaptionH, ZD_TextHorzUp, FontStyleRegular); // We use horizontal orientation
    UseW = max(UseW, CaptionW + 4);
    UseH += CaptionH;
    long bmW = 0, bmH = 0;
    HBITMAP hBitmap = ZI_CreateBitmapFromFile(UseIcon, bmW, bmH);
    UseW = 4 + bmW + 4 + UseW + 4;
    UseH = 4 + max(bmH, UseH) + 4 + 4;

    // Here we create the compositing array
    // Note: The z-order composition will match the array order, the lower indice at the bottom, the higher on top.
    const long nCount = 5;
    ZOBJECT arrayobj[nCount]; ClearMemory(&arrayobj[0], sizeof(arrayobj));

    ZI_CreateBitmapObject(arrayobj[2], 4, 4, hBitmap, ZD_ARGB(255, 0,0,0), ZS_VISIBLE);
    ZI_CreateTextObject(arrayobj[3], UseCaption, 4 + bmW + 4, 4, CaptionW + 8, CaptionH + 8, ZD_ARGB(255, 255,240,140), zFont, 18, ZS_VISIBLE, 1, StringAlignmentNear, FontStyleRegular);
    ZI_CreateTextObject(arrayobj[4], UseComment, 4 + bmW + 4, 4 + CaptionH + 4, CommentW + 8, CommentH + 8, ZD_ARGB(255, 255,213,83), zFont, 14, ZS_VISIBLE, 1, StringAlignmentNear, FontStyleRegular);

    ZI_CreateRectangleObject(arrayobj[1], 1, 1, UseW - 3, UseH - 3, ZD_ARGB(255, 255,240,140), 1, ZS_VISIBLE | ZS_DRAFT, ZD_DRAW_OUTLINE, 0);
    ZI_CreateRectangleObject(arrayobj[0], 0, 0, UseW, UseH, ZD_ARGB(128, 128,128,128), 0, ZS_VISIBLE | ZS_DRAFT, ZD_DRAW_FILLED, 0);

    WCHAR zFile[MAX_PATH]; ClearMemory(zFile, sizeof(zFile));
    Path_Combine(zFile, zGetTempPath(), L"zToast.png");
    //Path_Combine(zFile, EXEpath(), L"zToast.png");
    ZI_CreateImageComposited(zFile, UseW, UseH, arrayobj, nCount);

    RECT rw; GetWindowRect(gP.hGL, &rw);
    long x = rw.right - UseW;
    long y = rw.bottom - UseH;
    // This API requires the use of a file name, rather than a bitmap handle. It can create/use a region on the fly.
    HWND hWnd = ZI_CreateWindowFromImage(WS_POPUP, zFile, x, y, gP.hGL, 0, 0, 0);
    if (IsWindow(hWnd)) {
        ZI_DwmEnable(hWnd);
        WCHAR zResource[MAX_PATH]; ClearMemory(zResource, sizeof(zResource));
        Path_Combine(zResource, skSkinFolder(), L"T_Close.png");
        long w = 0, h = 0;
        hBitmap = ZI_CreateBitmapFromFile(zResource, w, h);
        x = UseW - w - 8; y = 8;
        long nID = ID_TOAST_HIDE;
        ZD_DrawBitmapToCtrl(hWnd, x, y, hBitmap, ZD_ColorARGB(255, 0), nID, ZS_VISIBLE);
        ZD_SetObjectLocked(nID, TRUE);
        //MonitorMessages(hWnd, (LONG_PTR) ToastCallBack);
        ZI_EventMessageEx(hWnd, (LONG_PTR) ToastCallBack, WM_LBUTTONUP, TRUE);
        gP.hToast = hWnd;
    }
    zKillFile(zFile);
}

The new close button is attached to this post (to put into the Reader folder).

Add the new constant below line 131 in constants.h
#define ID_LAST                 ID_GAUGE_GPU
#define ID_TOAST_HIDE           ID_LAST + 1

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 15, 2018, 09:18:51 pm
Added:
Here is how it looks with the new close button

Are you in fact teasing me with all those futuristic gadgets and constructs? ;D
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 15, 2018, 09:34:30 pm
Quote
Are you in fact teasing me with all those futuristic gadgets and constructs?
It is my way to teach you what could be done using GDImage memory compositing, with just a few lines of code.  8)

BTW, for the button color i prefer to keep the gray one, to stay in sync with the main skin theme.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 15, 2018, 10:14:31 pm
Re. "futuristic gadgets and constructs":

It is my way to teach you what could be done using GDImage memory compositing, with just a few lines of code.  8)

I'm well past 2D, my friend. You can only stir my feelings with your 3D content. ;)

But while we're at it, can you send me your französisch assets to try out? :)

Quote
BTW, for the button color i prefer to keep the gray one, to stay in sync with the main skin theme.

When something's popping up with a swoosh sound in your viewport, your attention is bound to concentrate on that something rather than on your main window decorations. ;)

I'm going to send you some of my toast window exercises soon.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 15, 2018, 11:47:47 pm
Here it is...

Thanks a lot, Patrice! But how do I make her sit on top of our toast window, please?

If you want to fade the Toast window, you can play with the ZI_SetLayeredAlpha(hWnd, Alpha) API. Using it when the timer has ellapsed the 10 seconds delay, while keeping the current moving down, for the case of the T_Close button.

Good idea Patrice, thank you! Will do in the next patch.

In the mean time, TA-DA-A-A !!! ... And as promised, here comes our brand new Popup Help System! :D
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 17, 2018, 03:44:36 pm
Progress Status Update

Been working on the viewport tool tip (now called "mesh info tip") since morning. A regular WinLIFT tool tip isn't usable for this purpose because the mesh info tip has different logic and behavior.

I'm hoping to be ready to submit the patch this evening. Stay tuned! :)


(In the mean time, what about my question on sitting the französisch creature on top of the toast window?)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 17, 2018, 04:22:00 pm
We can create a custom one, based one the same concept than for the toast window, especially if we want to use fancy shape or multiline(s)...
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 17, 2018, 04:28:28 pm
Quote
In the mean time, what about my question on sitting the französisch creature on top of the toast window
To use the Hajime Sorayama robot, just use the same API than for the T_Close button or the light bulb.

I shall create the bitmap for you, give me just a few minutes…

Added:
Here is the png file, now i shall write a quick code example to show you how to sit her on the top left corner...
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 17, 2018, 06:15:43 pm
Try with this (make first a copy of your ToastWindow)

Code: [Select]
void ToastWindow(IN WCHAR* UseIcon, IN WCHAR* UseCaption, IN WCHAR* UseComment) { //IN HWND hParent, IN HINSTANCE hInstance) {
    if (gP.hToast) { DestroyWindow(gP.hToast); }

    WCHAR zFont[MAX_PATH]; ClearMemory(zFont, sizeof(zFont));
    Path_Combine(zFont, skSkinFolder(), L"trebuc.ttf");

    // We compute the correct size
    long CommentW = 0, CommentH = 0;
    ZD_GetTextBound(UseComment, zFont, 14, CommentW, CommentH, ZD_TextHorzUp, FontStyleRegular); // We use horizontal orientation
    long UseW = CommentW + 4;
    long UseH = CommentH;
    long CaptionW = 0, CaptionH = 0;
    ZD_GetTextBound(UseCaption, zFont, 18, CaptionW, CaptionH, ZD_TextHorzUp, FontStyleRegular); // We use horizontal orientation
    UseW = max(UseW, CaptionW + 4);
    UseH += CaptionH;
    long bmW = 0, bmH = 0;
    HBITMAP hBitmap = ZI_CreateBitmapFromFile(UseIcon, bmW, bmH);
    long xOffset = 0, yOffset = 0;
    WCHAR zResource[MAX_PATH]; ClearMemory(zResource, sizeof(zResource));
    Path_Combine(zResource, skSkinFolder(), L"robot.png");
    if (FileExist(zResource)) {
        xOffset = 22, yOffset = 76;
    }

    UseW = xOffset + 4 + bmW + 4 + UseW + 4;
    UseH = yOffset + 4 + max(bmH, UseH) + 4 + 4;

    // Here we create the compositing array
    // Note: The z-order composition will match the array order, the lower indice at the bottom, the higher on top.
    const long nCount = 7;
    ZOBJECT arrayobj[nCount]; ClearMemory(&arrayobj[0], sizeof(arrayobj));

    if (xOffset) {
        long w = 0, h = 0;
        ZI_CreateBitmapObject(arrayobj[6], 0, 0, ZI_CreateBitmapFromFile(zResource, w, h), ZD_ARGB(255, 0, 0, 0), ZS_VISIBLE);
    }

    ZI_CreateBitmapObject(arrayobj[3], xOffset + 4, yOffset + 4, hBitmap, ZD_ARGB(255, 0, 0, 0), ZS_VISIBLE);
    ZI_CreateTextObject(arrayobj[4], UseCaption, xOffset + 4 + bmW + 4, yOffset + 4, CaptionW + 8, CaptionH + 8, ZD_ARGB(255, 255, 240, 140), zFont, 18, ZS_VISIBLE, 1, StringAlignmentNear, FontStyleRegular);
    ZI_CreateTextObject(arrayobj[5], UseComment, xOffset + 4 + bmW + 4, yOffset + 4 + CaptionH + 4, CommentW + 8, CommentH + 8, ZD_ARGB(255, 255, 213, 83), zFont, 14, ZS_VISIBLE, 1, StringAlignmentNear, FontStyleRegular);

    ZI_CreateRectangleObject(arrayobj[2], xOffset + 1, yOffset + 1, UseW - 3 - xOffset, UseH - 3 - yOffset, ZD_ARGB(255, 255, 240, 140), 1, ZS_VISIBLE | ZS_DRAFT, ZD_DRAW_OUTLINE, 0);
    ZI_CreateRectangleObject(arrayobj[1], xOffset + 0, yOffset + 0, UseW - xOffset, UseH - yOffset, ZD_ARGB(128, 128, 128, 128), 0, ZS_VISIBLE | ZS_DRAFT, ZD_DRAW_FILLED, 0);
    ZI_CreateRectangleObject(arrayobj[0], 0, 0, UseW, UseH, ZD_ARGB(0, 0, 0, 1), 0, ZS_HIDDEN | ZS_DRAFT, ZD_DRAW_FILLED, 0);

    WCHAR zFile[MAX_PATH]; ClearMemory(zFile, sizeof(zFile));
    Path_Combine(zFile, zGetTempPath(), L"zToast.png");
    //Path_Combine(zFile, EXEpath(), L"zToast.png");
    ZI_CreateImageComposited(zFile, UseW, UseH, arrayobj, nCount);

    RECT rw; GetWindowRect(gP.hGL, &rw);
    long x = rw.right - UseW;
    long y = rw.bottom - UseH;
    // This API requires the use of a file name, rather than a bitmap handle. It can create/use a region on the fly.
    HWND hWnd = ZI_CreateWindowFromImage(WS_POPUP, zFile, x, y, gP.hGL, 0, 0, 0);
    if (IsWindow(hWnd)) {
        ZI_DwmEnable(hWnd);
        WCHAR zResource[MAX_PATH]; ClearMemory(zResource, sizeof(zResource));
        Path_Combine(zResource, skSkinFolder(), L"T_Close.png");
        long w = 0, h = 0;
        hBitmap = ZI_CreateBitmapFromFile(zResource, w, h);
        x = UseW - w - 8; y = 8 + yOffset;
        long nID = ID_TOAST_HIDE;
        ZD_DrawBitmapToCtrl(hWnd, x, y, hBitmap, ZD_ColorARGB(255, 0), nID, ZS_VISIBLE);
        ZD_SetObjectLocked(nID, TRUE);
        //MonitorMessages(hWnd, (LONG_PTR) ToastCallBack);
        ZI_EventMessageEx(hWnd, (LONG_PTR)ToastCallBack, WM_LBUTTONUP, TRUE);
        gP.hToast = hWnd;
    }
    zKillFile(zFile);
}
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 17, 2018, 06:25:55 pm
We can create a custom one, based one the same concept than for the toast window, especially if we want to use fancy shape or multiline(s)...

No, I prefer to keep it in your ordinary tool tip style. Either way, there's going to be the need to create a custom window and that's what's the easiest part of it.

What I'm doing now is debugging the shader and proc that are meant to render the scene to an invisible backbuffer to perform color coded mesh selection pass. That's similar to the Z-axis rotation hit test pass but coded in 24-bit color palette. It's supposed to render the entire model, and there may be dozens of thousands meshes there (like in those that you haven't yet optimized), and each one needs coding in its own unique color. Hence the need to use a shader rather than an ordinary draw list -- for speed reasons.

This takes time. I'm marking my mods conservatively with MLL 11-18-2018: but hopefully I'll be able to complete the task tonight. :)

I shall create the bitmap for you, give me just a few minutes…
Added:
Here is the png file, now i shall write a quick code example to show you how to sit her on the top left corner...

Try with this ...

Thanks for your time, my friend! :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 17, 2018, 06:29:06 pm
Mike

Using drag & drop of an obj file, onto the desktop OR icon, doesn't work anymore  :-[
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 17, 2018, 06:41:21 pm
For me, it works just fine when
-- dragging-and-dropping the OBJ file on the ObjReader.exe icon;
-- ditto, on the ObjReader desktop shortcut;
-- from the Windows menu Run... prompt;
-- from the console prompt with absolute pathnames to the EXE and OBJ files.

I've got no idea what might be wrong with your copy...  :-\

(The robot smears the viewport when sliding up into view but never mind, I've got the idea how to use it, thanks!)

Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 17, 2018, 06:51:00 pm
Ok, i found the problem, this occures when space characters are being used in the path name (or file name).
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 17, 2018, 10:25:26 pm
Got it , thanks!
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 18, 2018, 02:38:03 am
Quote
I do not agree with the way the wallpaper is now being resized (stretched), the original aspect is not preserved...
................................
Thank you!

Patrice,

Please pull your horses a little. :) (the red quotation in written English is usually an indication that the conversation is on the verge of becoming a scandal)

If you bother to find all the occurrences of glOrtho(-gP.glRatio, gP.glRatio, ...) pertaining to the wallpaper renders, you'll see that your aspect ratio is preserved throughout the sources as it always has been.

The problem is a direct consequence of your historically uncontrollable wallpaper texture rescaling/gl_wrapping havoc and voodoo in the pandora's formerly closed sources. Remember where

// MLL 02-28-2018: tex generation modes
//1 = Create square texture
//2 = Stretch to memory bitmap
//3 = Accept texture of any size
//4 = MipMapping
//0 or 1 is the same, for historical purpose(OpenGL 1.0 compatibility)
#define TEX_COMPAT  0
#define TEX_SQUARE  1
#define TEX_STRETCH 2
#define TEX_ANYSIZE 3 // clamped, not mipmapped
#define TEX_REPEAT  4 // mipmapped
#define TEX_CLAMP   5 // clamped, mipmapped


came from? The red color denotes direct copy-paste from you forum message. Those were my attempts to GL_CLAMP_TO_BORDER your mipmapped/gl_wrapped wallpapers that kept displaying those notorious wrongly colored scan lines all around the viewport borders, caused effectively by uncontrolled rescaling, mipmapping and illegal gl_wrapping the wallpaper around its quad's edges -- and all this with no access to your closed-source texture loading function you bulldozed me to use. ;) You know very well I'm perfectly able to code my own texture loading procs from scratch in ca. 10 minutes that would be completely devoid of this crap -- but I wasn't allowed to! ::)

I tried to mask off the ugly edges as best I could from outside the function code, but obviously there wasn't much I could really do back at those times.

To cut it short, I know the wallpaper is still not resized nor rendered 100% correctly and I will fix it eventually, but it certainly isn't going to be item #1 on my current top priority list. In the mean time, I'm afraid you'll have to put up with it; just try not to stretch the viewport across multiple monitors to keep its aspect ratio within reasonable limits and preclude visible distortion of the wallpaper ovals.

Oh, and avoid the (O)BLIVION wallpaper castrated by POT rescaling in GDImage.

 :-X


P.S. Will you send me the OR v2.0 sources, please? I'm not keeping an archive of deprecated code -- I've got too many forks of current one to have time or nerve to look back over my shoulder.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 18, 2018, 11:03:21 am
My friend,

Yes, i prefer to see the black borders aside the texture than image distortion.
This is how it works in my old BassBox OpenGL plugins since the first release, and in the original OR 32-bit version as shown on your screen shot.
(ZI_ResizeGLWindow in GDImage)
Indeed this is the same to what i am doing when resizing a video while playing a movie (see MBox64).
This is also the reason why, now i am always using full HD image (1920x1080) to create my wallpaper backgrounds.

And the iconise function that i am using in all my projects to resize an image, while preserving its aspect.

Code: [Select]
void ZI_Iconise (IN long xPicSize, IN long yPicSize, IN long xCell, IN long yCell, OUT long &xPos, OUT long &yPos, OUT long &xSize, OUT long &ySize) { // dllexport
    float rScale = 0.0f;
    if (xPicSize) { rScale = (float) (xCell / (float) xPicSize); }
    if (rScale > 1) { rScale = 1.0f; }
    xSize = (long) (xPicSize * rScale); ySize = (long) (yPicSize * rScale);
    // In case Height > 150 compute new scale factor
    if (ySize > yCell) {
        if (yPicSize) { rScale = (float) (yCell / (float) yPicSize); }
        xSize = (long) (xPicSize * rScale); ySize = (long) (yPicSize * rScale);
    }
    xPos = (long)((xCell - xSize) * 0.5f); yPos = (long)((yCell - ySize) * 0.5f);
}

The code of version 2.00 is attached to this post.


Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 18, 2018, 12:59:21 pm
OK Patrice,

I heard your say.

There's 1024% sure gonna be another #ifndef MLL_DEV block in the code.

Your "wallpaper" (in fact, just another billboard in sight) has always been making me dizzy. It describes how different our attitudes are to the worlds we're trying to create in our viewports. I'm trying to immerse into mine and stay inside looking out while you prefer to stay outside yours looking in. :)

Secondly, 1920x1080 full HD is still too low-res for your algo. ObjReader is unable to run on anything other than pretty advanced HW, and it won't even launch on a typical business-class notebook. OTOH a decent modern desktop setup is usually equipped with at least two monitors (mine uses three of them, all horizontal), and the most advanced would use four in a 2x2 matrix (I'm just too reluctant to drill holes in the walls of my study and suspend the upper two on the wall mounts). So your wallpapers should come in at least 4Kx2K pxs so that ObjReader could look into the scene through its viewport frustum regardless of its size or aspect without the need to shrink or stretch the wallpaper. Then there will never be any margins or distortion in your preferred rendering solution, unless the number of horizontal and/or vertical monitors exceeds two in a row.

Lastly, the wallpapers may stay 1920 pxs high but should be made tilable horizontally (and that imposes certain restrictions on their visual content). Then their textures may be loaded wrappable only horizontally (S clamped to edge and T wrapped), so that another horizontal tile would just slide silently into view on either side of the main image as the respective margin of the main window is dragged in either horizontal direction. That will solve the problem at least partially for the horizontal layout of monitors in the workstation regardless of their actual number in a row (2, 3, or 4).

Do you think your 2D skills can procure us with such tilable wallpaper images? There are descriptions of techniques on the net on how to create tilable images in modern image editors like Photoshop or Gimp.

Thanks for the v2.0 code. I'll see what I can do in the mean time.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 18, 2018, 02:19:26 pm
Quote
Your "wallpaper" (in fact, just another billboard in sight) has always been making me dizzy
This is a point of divergence between you and me, because preserving the aspect of an image has always been my moto.

I want to let it work like in my SkinnedChart or my Mbox64 projects, especially when moving to full screen.

I never understood people watching a cinemascope movie on their TV in stretched mode.

To please both of us, this could become an option ;)

ZI_Iconise computation could be used to clip the texture to match the viewport size on the fly (cell size), then no more black section on the side parts (so far for OpenGL i have choosen to adjust mostly on the height to avoid bluring the image too much).

Note: WinLIFT is also always preserving the background wallpaper aspect, but in this case taking both width and height into consideration, thus we could do the same. See the attached screen shots using the Marilyn wallpaper as a skinned background (see the ue of ComputeAspect).

Code: [Select]
       if (UseStretchMode == 1) { // PAINT_STRETCH_MODE
          skGetBitmapSize(g_CtlBack, bmW, bmH);
          ComputeAspect(bmW, bmH, nWidth, nHeight, xP, yP, xS, yS);
          SelectObject(hDCsrce, g_CtlBack);
          AlphaBlendEx(hDCdest, xP, yP, xS, yS, hDCsrce, 0, 0, bmW, bmH, 2); // 4.70 DWM support
          if (g_nUsingDWM) {
             nLeft   = skGetSystemMetrics(SK_DWM_LEFT);   if (nLeft) { skFillRect(hDCdest, 0, 0, nLeft, nHeight, 0); }
             nTop    = skGetSystemMetrics(SK_DWM_TOP);    if (nTop) { skFillRect(hDCdest, 0, 0, nWidth, nTop, 0); }
             nRight  = skGetSystemMetrics(SK_DWM_RIGHT);  if (nRight) { skFillRect(hDCdest, nWidth - nRight, 0, nRight, nHeight, 0); }
             nBottom = skGetSystemMetrics(SK_DWM_BOTTOM); if (nBottom) { skFillRect(hDCdest, 0, nHeight - nBottom, nWidth, nBottom, 0); }
          }
       } else { // Paint in tile mode
          skTilePaint(hDCdest, g_CtlBack, 0, 0, nWidth, nHeight);
       }

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 18, 2018, 04:59:29 pm
Your Marilyn just proves what I was saying in my 2nd option above. The image must be resized in real time (or preferably manufactured in advance) in a much higher resolution than any viewport configuration (aspect ratio) it may ever be applied to, and clipped by the view frustum rather than stretched to fit it on the fly.

The matter is that OpenGL is much much slower to generate even an unmipmapped texture of such size than GDI+ is capable to stretch-blit its images in memory in each DWM recomposition. We could try and regenerate the wallpaper texture in response to the OR window WM_SIZING events but I'm absolutely sure it will make window corner dragging painfully slow and non-resilient.

As a fourth option to what I've already proposed, I can suggest extending your WM_SIZING min/max watch with a capability to restrict the main window resizes to just the wallpaper aspect ratio, so that when a side or corner is being dragged, all the four sides of the main window extend or shrink proportionately to match and maintain the wallpaper's original aspect ratio automatically -- and consequently, resize it in the OpenGL ortho projection exactly in its own aspect ratio rather than in an arbitrary main window proportions.

This is going to drive me (and people like me) even madder than your black margins but at least everybody would understand sooner or later why it's being done so by the app creators and what for. Contrary to that, the black margins are not going to have any similar sane explanation and purpose no matter what you say in English or French. ;)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 18, 2018, 08:43:07 pm
By all means Patrice,

You're free (and encouraged!) to experiment in whatever way you're most interested, and if such results are aesthetically satisfactory (black border-less and with all the peripheral scan colors intact, in this particular case) then we can use them as optional rendering modes for particular scene content.

However most of the GLSL coolest effects with translucency (like e.g. glass surface specular reflection, or refraction, or diffraction, etc.) are implemented not against simple 2D billboard backgrounds but within a 3D world enclosed in a skybox, skysphere, or at least skydome. OpenGL simple stock transparency isn't used at all. Instead, multiple render passes are run into all sorts of buffers (depth, stencil, lighting, etc.) and their final swap on the screen is deferred till the final PP step. Then all the buffers are sampled against the existing scene geometry and its attributes (including emulated translucency), and decisions are taken as to what objects should be seen directly, and which of them should be rendered first to be "seen" through other "translucent" surfaces and in what order, and how these surfaces should distort and fake reflection/refraction of other objects' 3D and planar geometry including the background.

In other words, the shaders should be immediately aware not only of scene geometry but also of the enclosing background. OTOH there would be no background in the scene at all from OpenGL's standpoint if it has been taken out of the scene and placed in parallel, but still alien, unreachable and incommunicado worlds of GDI+ drawing and DirectX compositing.

I am going to introduce sky boxes and probably sky domes in OR a.s.a.p. after FBO because proper rendering of advanced GLSL 3D effects is impossible against flat 2D backgrounds of our current wallpaper type.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 19, 2018, 12:20:09 pm
Mike

Good news, i have solved my ratio problem, while keeping your genBackgroundList() optimization. :)

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 19, 2018, 12:32:55 pm
Thanks for the good news!

I'm a little busy today with real life issues but I'll be home in the evening. Please post or upload your mods for me to study.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 19, 2018, 01:51:01 pm
Here are my changes.

1 - constants.h
//#define ClientW       1166 + 20 // 1188 //1024 + 164
//#define ClientH       600 + 20 + 73 // PAT: 10-10-2018
//#define ClientWGL     1032 + 20
#define ClientH       672
#define ClientWGL     1042
#define ClientW       ClientWGL + 136
[/color]

2 - case WM_SIZE (line 1381 in Main.cpp)
    case WM_SIZE:
        gP.glWidth = max(LOWORD(lParam), 1);
        gP.glHeight = max(HIWORD(lParam), 1);
        //gP.glRatio = ((float)gP.glWidth / (float)gP.glHeight) * 0.5f; // To preserve wallpaper aspect in glOrtho
        gP.glRatio = ((float)gP.glWidth / (float)gP.glHeight) * 0.54f;  // PAT: 11-19-2018, more accurate ratio computation

        gl_AdjustNearPlane();
        gl_Resize(gP.glWidth, gP.glHeight);

        if (IsWindowVisible(gP.hMain)) { // PAT 11-19-2018
            genBackgroundList();
        }

        gP.redraw = -1; // Redraw the OpenGL scene
        gl_DrawScene();
        break;


For your information, the black borders get visible only when the resized width reaches the limit of the glOrtho(-gP.glRatio, gP.glRatio, -1.0, 1.0, -1.0, 1.0); computation.
But this is the best solution to preserve the correct aspect ratio, and this is what i am using in my other applications.

Note: If you want to use stretching rather than aspect preservation, just rem out genBackgroundList(); in the WM_SIZE above.
And if you make it a new option, please keep the aspect preservation for default.

Added
I did post you a copy of the answer i got from Bob, about your speed DL limitation problem, he says you should see an improvement now :(
 
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 19, 2018, 07:15:58 pm
Patrice,

Thank you for walking an extra mile to resolve my DL problem. Everything's in perfect order now, and I was able to download your recent Construction_ship.zip literally instantly as a test. The image attachments are also working for me again now: the firewall has been so bad on me recently that I couldn't even enlarge the thumbs by clicking on them. ;)

What he says about SSL might be a good idea. The site traffic would then use unbreakable encryption in real time, and a secure https:// address. I'd recommend buying a certificate, of course provided you can afford it materially.

I'm back home now and am going to dive into our code again in about 30 or 40 minutes after a quick bite. :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 19, 2018, 08:16:36 pm
Well,

Your resize code fix works for me. (the black borders I haven't seen for ages are back again in their places ;))

It'll stay as the default but I'll be adding my own #ifdef MLL_DEV variant if I find it more pleasing to my eyes than yours.

I'm still stuck with the selection render pass shader for the mesh info tip. The shader setup is exceptionally simple but the other shaders in the system apparently leave OpenGL in such a weird state that I can't figure out how to reset it ATM.

I can't use a draw list approach here for speed reasons because I need to render all of the model's geometry rather than just four corners of the screen quad like in the wallpaper and ellipse hit test passes. Compiled draw lists are simple to set up (just compile once and forget) but they are perhaps an order of magnitude or two slower than GLSL shaders, especially for complex geometry.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 19, 2018, 10:18:04 pm
I agree that the problem for sky boxes and spheres is something rather different, but for looking at a model from the outside, that is currently 100% of our model collection, preserving the aspect when using a photographic texture is the best solution in my not so humble opinion.  :D
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 19, 2018, 10:42:34 pm
Quote
Windows has a set of stock WinAPI's to handle save/restore to/from editable text .INI files. I see no reason in re-inventing a proprietary configuration system for an open source application.
Nothing proprietary, i just prefer to use Bload/Bsave direct from memory, and this is the same concept to create a binary .ORB version.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 20, 2018, 12:17:05 am
No,

BLOAD/BSAVE are too straight forward for an elegant solution. There's a hellofalot of trickery awaiting us to optimize the binary format dramatically for size, both in memory and on disk. 8)

<nostalgia>

My very early (probably 3 or 4 years ago) experimentation with glass reflection/refraction shading in Objector. :-*

</nostalgia>
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 22, 2018, 01:03:53 pm
I was able to fix the color coding shader. 8)

I also put the main window nVidia/ATi/Intel icons into operation.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 22, 2018, 03:10:39 pm
The Mesh info tip option is fully implemented.

See below how a tiny 64-tris-only mesh named holo_emitter_hull stored at index 16087 in the mesh list is detected at the cursor current position within the viewport that's displaying a 32K mesh model. 8)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 22, 2018, 04:17:15 pm
Here's my patch with the mesh info tip and gfx icon implementation.

Enable/disable the mesh info tip feature in the Design menu as needed.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 22, 2018, 07:00:00 pm
Thanks for the patch !
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 22, 2018, 09:46:36 pm
The new "Mesh info tips" is very handy to inspect a model!
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 23, 2018, 01:42:34 am
Yes Patrice,

Mesh info tips are one of my most favorite features in 3ds Max. It is pixel-perfect and extremely handy when you're inside a complex model in the vertex editing mode surrounded by thousands of vertex points looking all the same to you, and you need just one of them to mark for deletion or drag around to an appropriate place, and there's literally no other means to tell them from one another.

And since it uses 24-bit color coding, the number of meshes in the model can be virtually unlimited. (actually up to 16M of them)

A similar color coding approach may further be used for pixel perfect detection of an unique vertex point under the cursor in the mesh editing mode. 8)

(Yes, I'd like to live long enough to see quite a number of model editing options implemented in ObjReader itself. There's nothing better than to be able to fix the model in real time directly in the renderer you're using to visualize it. :) )
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 23, 2018, 05:44:09 am
Re: Vertex normals shader implementation

Real time visualization of vertex and/or polygon normals is of great help to quickly evaluate the expected quality of normal mapping in a particular model.

But as it happens, drawing something that's not part of model geometry is no easy task for the pixel shader without much of ray tracing mumbo-jumbo. That's where geometry shaders may come to the rescue.

ObjReader is claimed to run under OpenGL 2.0 and higher. OTOH geometry shaders (GS) first appeared as an ARB extension in GLSL v120 alongside OpenGL 2.1.

So, if the user's current OpenGL driver still doesn't support GS and shader compilation fails at app start, I'm going to just disable the vertex normals visualization option in the Design mode popup menu but let ObjReader launch itself for execution anyway.

Is such tactics OK with you?

Note there may be yet some more tricky visualization modes like e.g. shader drawn (rather than draw listed) wireframe overlays that would also require some OpenGL 2+, which I'm going to simply disable as well under similar conditions.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 23, 2018, 07:56:25 am
Code: [Select]
Is such tactics OK with you?Yes, that makes sense to me.  :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 23, 2018, 01:52:16 pm
Oh, and I forgot to mention:

Mesh info tips are one of my most favorite features in 3ds Max.

infotip.h is my own ground-up re-implementation of this 3ds Max functionality first developed in FBSL for a closed source game engine editor dated 2012. I'm hereby covering it with a permissive MIT license for use in open source projects like ObjReader.

A corresponding blurb is added at the top of infotip.h attached below. Please use it instead of the file I sent you in the 11-22-2018 patch.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 23, 2018, 01:58:35 pm
Mike

The tooltip should shows up under the cursor rather than above it (just like for regular tooltip)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 23, 2018, 02:36:59 pm
Patrice,

Firstly, a Windows "regular tooltip" has its own logic to determine where to pop up depending on the space available between itself and the screen margins, pretty much like a Windows regular popup menu window would do, overriding your custom placement commands.

Secondly, a Windows regular cursor icon is 32x32 px large. In the most general case, its visible content's size is unpredictable (i.e. arbitrary, like in an arrow, cross, bar, hand, etc), and the only thing we can determine for sure is the exact location of its hot spot. With this in mind, how would you suggest we place our custom tip with respect to the cursor's visible content so as to neither obscure the cursor or tip text nor make the gap between the cursor and tool tip way too large unless we also provide the window class structure with our custom cursor icon whose visible content size is guaranteed to be known in advance?

And lastly, that said, I see no problem in placing the info tip according to the same rules your WinLIFT "regular custom tooltip" uses to pop up on the screen. I just wanted to stress those rules are not fool proof.

Will do in the next patch. :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 25, 2018, 12:39:56 pm
OK Patrice,

While you're still struggling with the AO jaggies, here's the info tip you wanted to see. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 25, 2018, 03:17:51 pm
GL_GEOMETRY_SHADER is undeclared
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 25, 2018, 04:09:16 pm
Ah yes,

Sorry, my bad. :-[

There were a hellofalotof things undeclared in gl2.h that relate to geometry shaders.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 25, 2018, 05:09:09 pm
Thanks!
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 26, 2018, 09:05:58 am
Awaiting your comments. ;)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 26, 2018, 10:24:02 am
The info tip is now very close to the original (still one pixel offset missing ;) )

Would be very handy if while upon a specific mesh, we could (press on the ALT key for example) to hide all the other meshes for better inspection.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 26, 2018, 12:56:14 pm
The info tip is now very close to the original (still one pixel offset missing ;) )

Which one, horizontal or vertical? Everything's perfectly all right for me under Win 7 empirically, and both offsets are the exact replicas of what I'm seeing in your "custom" tool tips over the ObjReader side panels.

Perhaps there are slight differences between the Win 7 and Win 10 arrow pointer images? (I didn't run any tests in my Win 10 box yet) That's exactly what I was talking about when saying that, in a general sense, we can never be sure about the exact outlines and metrics of system default cursor images, and consequently, about a pixel perfect vertical offset of their respective tool tips.

Quote
Would be very handy if while upon a specific mesh, we could (press on the ALT key for example) to hide all the other meshes for better inspection.

That's a very bright idea! Will do in the next patch for the mesh info tip mode: Alt press will hide the info tip and all other meshes except the one immediately under the cursor, and Alt release will respawn both the info tip and hidden meshes. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 26, 2018, 03:25:23 pm
On the vertical, the tooltip should be 2 pixels lower.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 26, 2018, 04:32:40 pm
Not under Win 7. It shows up exactly where your own custom tool tip pops up.

I'll check it under my Win 8.1 and 10 later during the day.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 26, 2018, 08:28:00 pm
Patrice,

On my Windows 7, 8.1 and 10 machines, the placement of my info tip matches your custom tool tip's initial fade in position exactly, both horizontally (along the left black border of arrow pointer) and vertically (the arrow pointer tail's black bottom line resides on the tip's upper white border).

I don't know what may be wrong with it in your system. :-\
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 26, 2018, 08:45:13 pm
That is really not something important, don't waste your time on this.
I keep working on the Prometheus pod, but there are plainty of small normal errors that i still have to fix.
They were hidden on the previous version because map_bump was not used.

I have found also many small errors in the native .lwo files, that could be detected only when scaling up (x 100) the project into C4D.  ::)

Added:
Sometimes when using the new "mesh info tips" in maximized mode, the menu get frozen, and/or the mesh moving becomes erratic.
The only way to regain control is to restore the window size (looks like there is a kind of topmost conflict with the menu).
To say the truth this occured while i was also playing a Netflix movie on the main display, and OR on the secondary, and the mouse became unresponsive for a few seconds while i was working with the huge Prometheous_pod project.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 27, 2018, 12:15:21 am
You did something I usually don't do.

You had three OpenGL programs running in stressful multi-threaded modes at the same time, not counting DWM compositing that runs in DirectX. I'm sure you were also having your browser open which is a hardware-accelerated multi-threaded OpenGL or DirectX application as well.

Do you think it's something that your video card can, and is supposed to, handle so easily? I think you've been lucky not to freeze your system completely and damage your hard disk(s) in the process.

The info tip has nothing to do with it. In fact it was the easiest task OpenGL was running at that moment. ;)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 27, 2018, 08:18:29 am
The info tip ALT mode patch is ready.

Usage:
Enjoy! :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 27, 2018, 10:04:58 am
Thank you my friend!

That would help me to better check my current work on the Prometheus_pod.

Added:
That works fine, however it would be easier if that could setup the checklist accordingly, then we could just use the "show all" button to restore all meshes visibility, because it is a pain to hold down the ALT key while working in another application at the same time (C4D in my case, is also using the ALT key). Indeed the ALT tip combination should ease the use of the checklist, like when cliking on "Hide all" and selecting just a specific mesh.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 27, 2018, 12:51:48 pm
I have a counter-suggestion: 8)What would you say to this idea?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 27, 2018, 01:11:00 pm
Any solution would be fine to me.

As long as it makes the selection/inspection of a specific mesh easier than checking/unchecking from the listview (especially when long names are used).
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 27, 2018, 01:11:44 pm
Great!

Will do now.

Stay tuned! :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on November 27, 2018, 03:41:57 pm
OK Patrice,

It wasn't easy to get rid of all sorts of transient states but I think I succeeded, more or less.

I found it more convenient to follow this behavior:At any rate it's perfectly usable now, and if we see some annoying oddities in the future, we'll try to correct them there and then.

The main thing is to always wait till the appropriate mesh info tip pops up. I made the timer a little faster to shorten the waiting time.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on November 27, 2018, 05:04:54 pm
That does the job, thank you!
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 07, 2018, 05:37:53 pm
FYI: I'm currently working on emissive and gloss (a.k.a. roughness, a.k.a. map_Ns) texture maps.


(Found a nasty bug, in fact a typo, in height (a.k.a. disp) map rendering. :(

It f*cking broke all my efforts to render parallax and steep parallax correctly all this time. >:(

My bad! :'(  :-[)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 07, 2018, 07:34:22 pm
Emission and gloss (roughness) maps are ready. 8)

Note the normals are looking a little weird in the renders below because the model uses a DirectX object space normal map rather than a tangent space normal map that ObjReader needs. (been too lazy to switch over to another model ;))
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 07, 2018, 07:50:20 pm
Great!
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 08, 2018, 05:35:21 pm
OK, here comes the latest patch.

Again, the model lighting is crooked because the normal maps are for DirectX, not OpenGL. But the main idea should be clear:

No missing Ns'es, no neutral bumps, no FFP, no more fooling around with "I'm an artist, that's how I see it". We've got over half a dozen texture channels, and all of them must be filled with premium quality maps and lit with rich specular lighting. The only worthwhile objective is: minimum polygons, maximum detail.

Note this texture and shader setup still isn't physically based. That's why we're free to use any textures in any slots as is best to produce maximum visible surface detail with minimum possible polygon count.

P.S. Please use the new milder and crisper UV checker map included in the zip, instead of the older one that I copy-pasted directly off the SketchFab screen. It was too acid color-wise and also re-scaled from some arbitrary size.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 08, 2018, 07:33:41 pm
Thank you, thank you, thank you!

Looks like with this new version we will have to divide all the current existing material Ke parameters with a 0.30 factor, other way they are too much bright.

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 08, 2018, 08:38:59 pm
I'm glad you like it! :)

Looks like with this new version we will have to divide all the current existing material Ke parameters with a 0.30 factor, other way they are too much bright.

No Patrice, I don't think it's so bad. The emissive component is calc'ed very early in the pipeline and blended additively rather than multiplicatively with the ambient component. They both are then clamped to within [0,1] and AO-shadowed further along the pipeline.

Next, the emissive materials that aren't controlled with a special map_Ke texture (like our existing flares or car headlights) get through a default programmatic 50% grayscale texture map transparently, which further reduces the emissive component brightness two times. So, I'd estimate the new uncontrolled Ke at approx. 1.5 times brighter than it was before, despite the 6x multiplier used in the shader.

I think it's better to have an overhead that we can suppress, than to be short of emissive brightness that gets lost in the overbright components of a daylight scene. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 08, 2018, 10:03:21 pm
Trying to use the original JetVette material, i couldn't get the correct emissive "newmtl light" to work correctly, all the orange parts are not shown anymore.

Try with the attached "ex_lights.zip" textures.

newmtl light
Ka 0.1 0.1 0.1
#Kd 0.31369999051094 0.06899999827147 0.06899999827147
Kd 0.75 0.75 0.75
Ks 1 1 1
Ke 0.3 0.3 0.3
map_Ka ex_lights_ao.png
map_Kd ex_lights_d.png
map_bump ex_lights_n.png
map_Ks ex_lights_s.png
map_Ke ex_lights_e.png
map_Ns ex_lights_g.png
Ns 225
illum 2
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 08, 2018, 10:42:07 pm
Patrice,

THAT IS EXACTLY WHY I ASKED IF YOU WEREN'T FIDDLING WITH TEXTURES INSTEAD OF SUPPLYING THE ORIGINAL FULL SET OF THEM! I KNEW YOU WERE GOING TO GET US INTO TROUBLE ONE WAY OR ANOTHER! >:(

OK I'll see what I can do with emissive color and texture blending but that will be tomorrow morning. :)

(In fact I got pneumonia last time I went to Poland to visit my friend for a few days. The Polish border guard/CLO gargoyles, all of them of feminine gender, kept me at -12oC and strong NNW wind for nearly two hours at night at the EU border with my doors, hood and trunk open in the area where it was forbidden to turn on my car engine. They had spotted a 0.5l bottle of Camus and two packages of Belarusian cigarettes in my bag extra to what I was supposed to be having on me so as not to blow up the European economy. They gave it all back to me eventually without consequences but my health was ruined and now I hate Polish women, which is a bad thing to do because they are generally renowned as the most beautiful blonds in our part of the world. ;))

In the mean time, have you noticed that on spherical surfaces, our artificial "ambient reflection" UVs are near perfect mirror reflections of the corresponding texture maps? If not then see how your Tron is watching you from different angles when in the "ambient reflection" fancy mode. ;D

And catch yet another patch with usual transparencies added to the fancy shaders besides the X-ray mode. I like it more that way, and hopefully you will too. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 08, 2018, 11:39:20 pm
Quote
THAT IS EXACTLY WHY I ASKED IF YOU WEREN'T FIDDLING WITH TEXTURES INSTEAD OF SUPPLYING THE ORIGINAL FULL SET OF THEM! I KNEW YOU WERE GOING TO GET US INTO TROUBLE ONE WAY OR ANOTHER

Your remark is not fair, because i did the best of what i could do with that model.

Here is the full texture set, however you will have to download the fbx original, because i have reworked the texture to avoid the jagged artefacts visible in the original, as well as several other texture errors.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 09, 2018, 12:06:33 am
i did the best of what i could do with that model.

You job is absolutely wonderful as always. But I, on my behalf, also did my best with the test materials at hand, and I cannot be held responsible if some obscure emissive map that you held back and I hadn't ever seen before doesn't meet your expectations now.

To avoid this in the future, I'll be now testing my patch against other SketchFab models at my option, and when I'm through, you'll have to mod JetVette again to meet ObjReader's final emissive blending as I will have designed it based on my own exhaustive experimentation.

Does this temporary stall suit you, my friend?

This is something i have been using for long, see the ambient reflection of Marylin on the projector lens ;)

Your ambient reflection of Marylin is OpenGL's intrinsic immediate mode while Tron's ambient reflection was hand-coded in my shader through much trial and error to be working with normal maps, AO, specularity and a lot more. :P
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 09, 2018, 07:32:21 am
I'm somewhat nonplussed, my friend.

From what I've been able to see on SketchFab so far, it seems like when an emissive material has an accompanying map_Ke, then there's no additive or other blending of its emissive areas with the diffuse or any other map in the same areas at all. The emissive map just overruns everything else, and its image must be detailed enough to substitute the lack of other images in these areas, if needed.

I do not then understand how it may go along in the same shader with the meshes that are emissive entirely, have no emissive maps and rely only on their emissive color component for mesh coloration. I need more time to search through SketchFab for reliable, even if simple, examples that would preferably contain emissive meshes of both kinds, map_Ke-textured and untextured, to learn the algo they're using.

In the mean time, enjoy yet another patch that allows for a FOV switchable between 20 and 45 degrees using the menu. 45o makes it much easier to explore the interiors of cars, rooms and buildings.

(It seems like I've begun to feel myself definitively better starting 5:00 this morning. I hope my productivity will improve accordingly from now on.)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 09, 2018, 11:20:23 am
My friend, i am converting some Sketchfab models for emissive test purpose.

This one looks promising unfortunatly it didn't come with a .mtl file  >:(
https://sketchfab.com/models/8ca5084b181340e0b19245094788fdff
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 09, 2018, 03:06:48 pm
Here is the Sketchfab "Edison light bulb" .dae model converted to .obj with a custom material file using most of the provided textures.
The original can be found there
https://sketchfab.com/models/abab549e6aa846209e8411cd1e135739

As you will notice, the new "map_Ke" doesn't respect the texture color, i have to explicitly use Ke with a yellow setup to get the wanted color.

Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 09, 2018, 03:48:46 pm
Here is another one.

the original is here:
https://sketchfab.com/models/c40053b034a74789892d1fdfc7764fe7?ref=related
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 09, 2018, 07:02:37 pm
Another one from here
https://sketchfab.com/models/7f65049c5020498b9ade8080a1f7d59c

And my reworked version  ???
(with my own texture set + normal alignment)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 10, 2018, 01:08:38 am
Thank you for those models, Patrice.

They are nice, however somewhat simplistic for what I'm trying to fix. Their meshes are almost fully emissive (and the lamp is without any emissive maps altogether) whereas the case you complained about was small emissive areas where the visual content of map_Ke conflicted with the map_Kd and was never shown in ObjReader. There are no such areas in the models you posted; the LED diffuse and emissive maps are so close in content that I can't tell which map I'm seeing in full light and dark.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 10, 2018, 04:40:09 am
Ok, here is a working example baked from this one:
https://sketchfab.com/models/6b95bca828184242a7746a902a5e6a48

Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 10, 2018, 07:05:53 am
Here is a simplified JetVette model based on the original, using only emissive meshes.

You can see the Ke emissive problem, especially on the light and jet material.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 10, 2018, 08:01:45 am
The dragon is a killer! :D

It seems like I've done a damned good job on emissive maps anyway! 8) ;D

OK Patrice, thanks a lot for your help. I'll see what I can do today. :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 10, 2018, 07:27:50 pm
OK Patrice,

I think you'll like what you'll see. I do. :D

You will probably have to fix an emissive material here and there (e.g. Tron's engines) but overall, the result is excellent and 100% correct. 8)

(I'm in love with your dragon. :) )
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 10, 2018, 09:42:25 pm
Everything looks fine now, and we can again adjust the Ke emissive level. Thank you!

I have attached the wallpaper i am usig with the dragon.
And here is my material setup

Code: [Select]
#wallpaper @wallpaper.png
#multilight
#straylight 50

newmtl body
Ka 0.15 0.15 0.15
Kd 0.75 0.75 0.75
Ks 0.375 0.375 0.375
Ke 0.5 0.5 0.5
map_Kd dragon_d.png
map_bump dragon_n.png
map_Ks dragon_s.png
map_Ke dragon_e.png
Ns 1024
illum 2
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 10, 2018, 10:20:28 pm
Thank you, Patrice.

Are the maps just renamed or different from what they were?

Strictly speaking, the Ns range should fall within [0,1000] according to the Wavefront OBJ specs.

I prefer the following settings:

Ks 0.475 0.275 0.175
Ke 0.75 0.75 0.75

Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 10, 2018, 11:16:14 pm
They have been just renamed.

Take care of yourself my friend!
 
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 12, 2018, 11:40:01 am
OK Patrice,

Just to get you out of your fruitless hibernation, here are some animated lights. 8)

It's almost Christmas time, after all! :D
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 12, 2018, 03:49:59 pm
Mike

Light animation is another great feature, thank you!!!

I am thinking to use something more meaningfull that the button(s) "Render", perhaps like the GDImage FPS on/off used in the overlay control panel.
Or using a couple of overlapped WinLIFT skButtonImage (one for On, another for Off, and playing with the visual state accordingly)
Same as using a "Render On" and "Render Off"; see also my MTC64 project.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 12, 2018, 04:02:13 pm
Actually, I don't find the light balls very spectacular even if we change them to colored light bulbs or flares or anything. They are just a convenient instrument to fine tune the animation speed easily and then IMHO they should be turned off not to distract the user from the scene. :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 12, 2018, 04:36:38 pm
Patrice,

In the meantime, da ya haz teh codez to implement a splitter that would slide from the right-hand gray panel to the left of current viewport dragging the existing gP.hGL border along with it and thus leaving the underlying gP.hMain's areas unobscured?

I'm planning to experiment with a few of texture edit options in ObjReader soon, and I would like you to code such a feature for me, if your WinLIFT/GDImage framework provides such a splitter control preferably skinned to match the existing looks of the main window. 8)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 12, 2018, 08:21:50 pm
Yet one more wish:It won't be reasonable to load them all separately. I want to add them dynamically at model load time to the 4th (alpha) channel of diffuse and specular maps, respectively.

My question is: are there functions in GDImage to load, resize smoothly to the same size if needed, combine the pixel data with the alpha channel, and finally load from memory and mipmap such synthetic textures pretty much like we deal with the texture disk files now?

If yes, can you provide me with hints on such a practical toolchain using your GDImage facilities?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 13, 2018, 10:54:36 am
Yes, we can resize a bitmap on the fly, and/or manipulate the pixels using the GetDIBits either from a bitmap or from a DC.
See also ZI_CreateGLTextureFromFileEx.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 13, 2018, 11:02:04 am
I do not want to create it from the file.

I want to load its pixel data as 32-bit array from the file, add the alpha channel from another grayscale pixel array, and then I want to use this 32-bit pixel data array with the new alpha channel to create a texture in a normal way. But not from the file as in ZI_CreateGLTextureFromFileEx but from the memory data array.

If there is no ready made ZI_CreateGLTextureFromMemoryEx in GDImage then I'm going to write my own texture loading function for this purpose.

Is it all right with you?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 13, 2018, 02:01:12 pm
Yep, there is no ready made ZI_CreateGLTextureFromMemoryEx in GDImage, thus it must be written for this purpose.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 13, 2018, 03:25:32 pm
Thank you, then I'll do that when needed.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 13, 2018, 03:28:31 pm
Patrice,

In the meantime, da ya haz teh codez to implement a splitter that would slide from the right-hand gray panel to the left of current viewport dragging the existing gP.hGL border along with it and thus leaving the underlying gP.hMain's areas unobscured?

I'm planning to experiment with a few of texture edit options in ObjReader soon, and I would like you to code such a feature for me, if your WinLIFT/GDImage framework provides such a splitter control preferably skinned to match the existing looks of the main window. 8)

Patrice,

Any feedback on this message, please?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 13, 2018, 03:52:10 pm
Quote
leaving the underlying gP.hMain's areas unobscured
What do you mean exactly by unobscured?

Should it be a transparent layer (to see the underlaying desktop), and does this new layer should be a GDImage control to draw in?

Added
To create a splitter here is an example of code i am using for a vertical one, and the code is the same for horizontal except for that width and heigh size are inverted.

Code: [Select]
    // =============================================================================
    // TOP SPLITTER control
    Path_Combine(szResource, EXEresource(), L"splith.png");
    skPushButtonImage(gP.hMain, szResource, $NULL, -4, 128, CLIENT_WIDTH + 8, 8, IDC_SPLIT_TOP, 0);

I shall add one in the code, and send you a screen shot for your advice once done.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 13, 2018, 05:17:14 pm
Thank you, Patrice!

Ultimately, I want to have two gP.hGL's side by side in the gP.hMain window. The border between them is to be controlled by a vertical splitter control, so that the hGL windows shrink and stretch as the splitter is dragged in between them from right to left and back.

There's no need for transparency in gP.hMain. It'll still be obscured by two gP.hGL's on top of it.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 14, 2018, 03:49:05 am
Yeah, the red one is what I have in mind, with two gP.hGL's on both sides of it shrinking and stretching as it moves left or right. The minimum width of each gP.hGL should be able to reach 0 so that the splitter could abut snugly the gray panel on the right, and the main window border, on the left. Forget about gP.hGL's aspect ratios for the moment; the main thing now is to let the splitter do its job.

However I wouldn't mind if both splitters are operable with one correction: idc_win2 and idc_win3 should be to the right of the red splitter rather than to the left.

TIA!


(Patrice, if that's too much of a job for you, don't hesitate to tell me and I'll design something simpler. It's just that I thought it would be great to have a skinnable splitter if you don't have one yet...)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 14, 2018, 09:39:45 am
My friend

To say the truth, i would have used something simpler than a splitter, aka a button to switch from one gP.hGL to another (see the attached screen shot).
That would keep the existing code unchanged, and we could display it using an effect like for the control panel overlay when showing/hidding the texture's one.
We just have to change the text of the new button from "<" to ">" to indicate the open or close mode.

BTW there is now a "vector subscript out of range" when trying to run OR in debug mode when loading a model.
See in the new ResetCamera()
Code: [Select]
void ResetCamera() {
//    MobjMesh* pMesh = &gtm_meshes[0]; // MLL 10-18-2018: see below

    if (gP.nObjectLoaded) {
        MobjMesh* pMesh = &gtm_meshes[0]; // PAT: 12-14-2018 avoid the subscript out of range
        gP.rTargetPos[0] = gM.center[0];
        gP.rTargetPos[1] = gM.center[1];
        gP.rTargetPos[2] = gM.center[2];

        gP.rCameraPos[0] = gP.rTargetPos[0];
        gP.rCameraPos[1] = gP.rTargetPos[1];
        gP.rCameraPos[2] = 3.05f;

        gl_AdjustNearPlane();
        gP.rPitch = gP.rYaw = gP.rRoll = 0.0f; // MLL 10-28-2018:

        for (int i = 0; i < gM.numberOfMeshes; i++, pMesh++) // MLL 10-18-2018: reset mesh rotation angles
            pMesh->pMaterial->rotangle = 0.0f;
    }
}

PS: I could however translate the slider code, if you think it would make our life easier.
But then, first try the Visual Studio internal border/splitter they are now using to resize the display of the individual controls to limit the number of redraw messages.

Added:
Tell me if you want the code with the new button, i made also a couple of very minor changes.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 14, 2018, 11:09:10 am
1. Thanks for the code fix!

2. No problem, I will do as I'm doing in the FBSL Eclecta editor: dragging starts on LMB down over the horizontal bar above the edit field. The moving cursor drags a grayscale pixel XOR line similar to how the Windows windows' oulines (hehe) are drawn when resized without repainting their contents. The LMB released, the two edit fields appear delineated with a horizontal bar similar to the one where dragging has started.

I'll do the same but vertically in ObjReader. Just provide me with a nicely skinned narrow vertical bar adjacent snugly to the right side gray panel for me to be able to change the cursor to the splitter shape when hovering above the bar.

3. Are the changes you made effectively hot fixes or just code reformatting?
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 14, 2018, 11:11:43 am
Your "button" is perfect as a bar I was talking about!!! :D
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 14, 2018, 01:02:39 pm
Quote
2. No problem, I will do as I'm doing in the FBSL Eclecta editor: dragging starts on LMB down over the horizontal bar above the edit field. The moving cursor drags a grayscale pixel XOR line similar to how the Windows windows' oulines (hehe) are drawn when resized without repainting their contents. The LMB released, the two edit fields appear delineated with a horizontal bar similar to the one where dragging has started.
See what Microsoft does in Visual Studio, that is very close to what you describe.

Quote
Just provide me with a nicely skinned narrow vertical bar adjacent snugly to the right side gray panel for me to be able to change the cursor to the splitter shape when hovering above the bar
For me, the easiest and more versatile solution is to create another GDImage control just like for the control panel overlay with one multiplle state sprite image to figure the dots or an horizontal arrow, using a callback to monitor mouse interactions.

Quote
Are the changes you made effectively hot fixes or just code reformatting?
As i said, minor code changes, to display the correct verion #, and to clear the main caption when loading a new model from the previous name, and perhaps a few other little things (winmerge will come to rescue to see them)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 14, 2018, 01:35:11 pm
For me, the easiest and more versatile solution is to create another GDImage control just like for the control panel overlay with one multiplle state sprite image to figure the dots or an horizontal arrow, using a callback to monitor mouse interactions.

Whatever -- I just need a nice looking distinct "vertical bar" window with an easy access to its message pump, that can display a splitter cursor as its class cursor, drift freely anywhere within gP.hMain's client area bounds, and serve as a visible border between two gP.hGL's (or gP.hGL to the left of it and any other graphics window that I might need, to the right of it) when in any position other than the rightmost one.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 14, 2018, 02:28:44 pm
Working on the new GDImage Splitter.h  :)


Added:
Please add this into pandora at line 4936
    switch (uMsg) {

    case WM_NCHITTEST: // 12-14-2018
         nResult = ForwardEventMessage(hWnd, uMsg, wParam, lParam);
         if (nResult == HTCAPTION) { return nResult; }
         break;
    case WM_MOVING: // 12-14-2018
         nResult = ForwardEventMessage(hWnd, uMsg, wParam, lParam);
         if (nResult == 1) { return nResult; }
         break;

    case WM_ACTIVATEAPP:
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 14, 2018, 04:45:56 pm
Done.

But I'll still need both the DLL and LIB from the official distro when everything is debugged and working.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 14, 2018, 05:05:53 pm
One more needed to display the WE cursor used by the splitter.
The LIB kept unchanged.

Line 5284
    case WM_SETCURSOR:
         if (LOWORD(lParam) == 0x01) {
            UseThisTool = zGetToolToUse(hWnd);
            if (UseThisTool) {
               return Usetool(hWnd, uMsg, wParam, lParam, UseThisTool);
            }

            if (ForwardEventMessage(hWnd, uMsg, wParam, lParam)) {
               return 1;
            }
            if ((zFlagMouseCapture(0, 0) > -1) || (CursorOverObject > -1)) {
               if (CursorOverObject > -1) {
                  SetCursor(LoadCursor(NULL, IDC_SIZEALL));
               }
               return 1;
            }

            if ((nStaticZoomID) && (hWnd == nStaticZoomCtrl)) {
               SetCursor(LoadCursor(gn_DllInstance, MAKEINTRESOURCE(HAND2)));
               return 1;
            }
         } else if (ForwardEventMessage(hWnd, uMsg, wParam, lParam)) {
             return 1;
         }
         break;
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 14, 2018, 05:11:20 pm
So far the moving of the splitter is constraint within the GL viewport size, and that works well.

Further customization could be done from the SplitterCallback.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 14, 2018, 05:24:31 pm
But it shouldn't be literally constrained to it because the splitter itself is supposed to be moving the right edge of (shrinking the width of) existing GL window, i.e. literally "change the OpenGL viewport size".  ::)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 14, 2018, 06:38:11 pm
OK! Can't wait to see your progress. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 14, 2018, 07:29:51 pm
Mike

Here is the splitter code + LIB and DLL

A you said small is beautiful…

You should easily find your way in, the point you will have to do, is inside MoveOverlay() where an offset should be used on the x location at the time the moving of the OGL controls is performed, you will have to use a new global parameter.

The Splitter callback is the place to use, to process the messages you want to monitor.

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 14, 2018, 07:45:50 pm
Thank you very much, Patrice!

I will study the patch and then I will come back to you if I have any questions or remarks. :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 14, 2018, 08:56:39 pm
How can I make the splitter color exactly the gray right panel color? Is it an RGBA constant or a brush from the \Reader PNG/JPG images? How can I tile it with the CTLBACK.jpg skin? (I do not need translucency; it should be of the exact gray color the right panel uses)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 14, 2018, 09:40:17 pm
Easy

// Create a popup GDImage overlay window
HWND CreateSplitter(IN HINSTANCE hInstance) {
    RECT lpr; GetWindowRect(gP.hGL, &lpr);

    DWORD dwStyle = WS_POPUP | WS_VISIBLE;
    DWORD dwExStyle = WS_EX_TOOLWINDOW;
    HWND hWnd = CreateWindowEx(dwExStyle, GDImageClassName, NULL, dwStyle, lpr.left + Width(lpr), lpr.top, SPLITTER_WIDTH, Height(lpr), gP.hMain, 0, hInstance, NULL);
    if (IsWindow(hWnd)) {

        //Setup the custom color background here
        ZI_SetProperty(hWnd, ZI_GradientTop, ZD_ARGB(128, 0,255,0));
        ZI_SetProperty(hWnd, ZI_GradientBottom, ZD_ARGB(128, 0,255,0));

        ZI_UseWinLIFTbackground(hWnd, TRUE, FALSE);


The beauty of this API is that it would work also with a complex background, if you use it in the Callback WM_MOVING section
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 15, 2018, 04:07:45 am
Awesome, thnx!
Title: Re: Early WIP on v2.55 : A2C Fix
Post by: Michael Lobko-Lobanovsky on December 15, 2018, 05:34:06 pm
Patrice,

One of my recent renderers must have broken the global A2C -- it switches off permanently after 1 frame render.

To fix the problem, please add in renderers.h the following statements at the very end of both main render functions:

drawUsingFixedFuncPipeline()
........
            // Test rotation
            if (doRotate) { glPopMatrix(); }
        }
    }
    if (gP.nAlphaToCoverage) glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
}


drawUsingProgrammablePipeline()
........
            // Test rotation
            if (doRotate) { glPopMatrix(); }
        }
    }
    if (gP.nAlphaToCoverage) glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
    glUseProgram(0);
}
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 15, 2018, 06:45:37 pm
Done, thank you!
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 16, 2018, 07:51:48 am
Patrice,

Just for you to know what I'm currently doing, I'm busy studying and implementing PBR and (possibly) soft shadows in ObjReader.

It's all very intricate stuff and it isn't going to be very fast -- but I am progressing slowly but steadily.

Please also remind me of what Rxx version exactly your Cinema 4D is?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 16, 2018, 07:56:17 am
Currently i am using C4D Prime version R17

I thought you were working on the splitter code, if not, i shall make a few changes  :)

Added
Please change this into constants.h

#define SPLITTER_WIDTH 7
//#define ClientW       1166 + 20 // 1188 //1024 + 164
//#define ClientH       600 + 20 + 73 // PAT: 10-10-2018
//#define ClientWGL     1032 + 20
#define ClientH       672
//#define ClientWGL     1042
//#define ClientW       ClientWGL + 136
#define ClientWGL     1042 - SPLITTER_WIDTH
#define ClientW       ClientWGL + 136 + SPLITTER_WIDTH


and add this at line 289 of globals.h
    long        usePal;        // PAT: 01-03-2018
    long        splitXoffset;  // PAT; 12-16-2018

    DWORD       aniTick;       // PAT: 02-04-2018
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 16, 2018, 11:59:10 am
I actually made a few changes to your splitter code because as it is, it wouldn't respond to the mouse. Because of your constant HTCAPTION test, the mouse thinks it's always in the non-client area. Therefore the mouse events must be made non-client too. Another problem is the non-client mouse wouldn't generate NCxBUTTONUP events (except after an NCxBUTTONDBLCLK) because it's captured by the splitter dragging process, and I have to synthesize NCxBUTTONUPs myself to be able to detect end-of-dragging and resize gP.hGL accordingly. I can send you the code if you wish.

So, editing options are a vast area of activity and I decided to first implement our more immediate needs , which however also implies a substantial learning curve. The worst thing is PBR is relatively new, and there's little practical code available on the net. Nonetheless I was able to find some that we can use but, in its turn, it also requires our camera to be re-written to match the matrices the PBR shaders need.

Thus, there's much to be learnt and experimented on. :)

If you want, you can finish off the splitter yourself in the meantime, so that it would actually reshape gP.hGL reliably in windowed, full screen, and light panel modes. There's no need for a second gP.hGL at this stage because the first editing thing I'm going to add (mesh UV remapping) will use a 2D GDI, rather than OpenGL, window and drawing side by side with the existing gP.hGL.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 16, 2018, 03:15:13 pm
My friend,

This is cool! 8) :)

Actually I wanted gP.hGL to resize while splitting so that the model is always in view. But your scenario can work for us too if we stretch gP.hMain over two monitors for the model to be at least partially seen even when gP.hGL rolls to the left as-is. I'd like the editing operations to be visible in the model on the fly.

Now please make the splitter responsive to WM_NCLBUTTONDBLCLK in such a way that when it is double clicked in its rightmost position, it would snap to the viewport center, otherwise, to its rightmost position. If possible, make it slide smoothly rather than snap, similar to how the lighting panel slides in and out of view.

Why wouldn't you download my code?


(I asked about your C4D version because I suddenly came across an open-source library that loads modern C4D models up to version R20.0 in any viewer/editor without needing an original C4D installation.)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 16, 2018, 04:50:45 pm
I have downloaded your code, but there is not much i could use from it with the changes i have done.  :-[
 
What to do of the splitter control in case of full screen mode?

My opinion is that we must hide it, and display only the main GL control (as it is right now), and use edit mode only in window mode.

Note: You can capture all the mouse messages you need for the splitter in DetectHotKeys bypassing the Windows message cracker.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 16, 2018, 05:54:59 pm
1. No problem, use just what you need or nothing, but please make it respond to a double click as I described.

2. There's no need to intercept anything in DetectHotKeys. Your message listener works OK but there won't be any client mouse messages there or elsewhere as long as you return HTCAPTION alone in your hit test handler; all the messages will be non-client only. So, the double clicks I'm talking about will be non-client as well.

3. I agree to hiding the splitter in full screen but when quitting full screen, the split window configuration should be restored.

4. Lastly, whenever the mouse button is released over the splitter, keyboard focus should be shifted programmatically over to gP.hGL immediately else we can't use ESC or CTRL until we click on gP.hGL. To implement this, you should intercept WM_NCLBUTTONUP (see item 2) but you won't be able to because Windows doesn't generate this message (https://docs.microsoft.com/en-us/windows/desktop/inputdev/wm-nclbuttonup) when the mouse is captured. And it is captured when the splitter is being dragged. So, you will have to synthesize it like I'm doing in my code, and then handle it in its own handler in the message listener as appropriate.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 16, 2018, 06:29:29 pm
No problem sync'ing, just will need a little more time to respond. :D

Why RTF and not a regular CHM?
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 16, 2018, 06:42:57 pm
No, for me the light panel and toast window pop up outside of gP.hMain when I press F1 and/or switch to a fancy mode when the splitter is moved anywhere to the left.

The keyboard focus is not returned to gP.hGL or gP.hMain (either will do) when the splitter is released.

Why do you make the splitter crawl upon the left side border of main window? Let it stop at the border like my splitter does. It's sufficient to shift gP.hGL completely out of view.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 16, 2018, 07:14:00 pm
Quote
Why do you make the splitter crawl upon the left side border of main window? Let it stop at the border like my splitter does. It's sufficient to shift gP.hGL completely out of view.

because we have to give the whole viewport for the next gl control, other we loose the width of the splitter

Also we couldn't compute anymore F1 and the ToastWindow on the size of the OGL control because of the offset used.
I am fixing this right now.

For the toastwindow we must use this at line 122
    RECT rw; GetWindowRect(gP.hGL, &rw);
    long y = rw.bottom - UseH;

    // PAT: 12-16-2018 we must align on main window rather than OGL control, in case we change size
    rw; GetWindowRect(gP.hMain, &rw);
    rw.right -= skGetSystemMetrics(SK_CXFRAMERIGHT) + (ClientW - ClientWGL) + SPLITTER_WIDTH * 2;

    long x = rw.right - UseW;



For MENU_LIGHTSETTING in line 1919 of ProcessMenu
    case MENU_LIGHTSETTING: // PAT: 01-30-2018
        if (IsWindow(gP.hOverlay)) {
            GetWindowRect(gP.hGL, &lpr);
            GetWindowRect(gP.hMain, &rw);
            lpr.left = rw.left + skGetSystemMetrics(SK_CXFRAMELEFT);
            lpr.right = rw.right - (skGetSystemMetrics(SK_CXFRAMELEFT) + skGetSystemMetrics(SK_CXFRAMERIGHT) + ClientW - ClientWGL);
            if (IsWindowVisible(gP.hOverlay)) {


and in line 1496 of ProcessMenu
    RECT rw, lpr;

Quote
The keyboard focus is not returned to gP.hGL or gP.hMain (either will do) when the splitter is released.
This is done in DetectHotKeys at line 2557

    if (gP.useSplitFrame == 2) { // PAT: 12-16-2018
        if (!ZI_IsLButtonDown()) {
            gP.useSplitFrame = 1;
            ZD_SetObjectFrameToUse(ID_SPLITTER_VERT, gP.useSplitFrame, true);
            PutFocusOn(gP.hGL);
        }
    }


I have another solution, using a hidden window just to get the correct anchor resizing of the control, working exactly like the previous OGL window before the splitter code, and using this hidden window just to put everything at the right place as it was before.
And that would probably make our life much easier than having to perform convoluted computation.
This Template window could be created in the gP.hGL creation process.

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 16, 2018, 08:13:26 pm
... other we loose the width of the splitter
I can live with it, my friend. Can't you? :)

Quote
Also we couldn't compute anymore F1 and the ToastWindow on the size of the OGL control because of the offset used.
Compute it relative to the gP.hMain frame rather than gP.hGL.

Quote
This is done in DetectHotKeys at line 2557
    if (gP.useSplitFrame == 2) { // PAT: 12-16-2018
        if (!ZI_IsLButtonDown()) {
            gP.useSplitFrame = 1;
            ZD_SetObjectFrameToUse(ID_SPLITTER_VERT, gP.useSplitFrame, true);
            PutFocusOn(gP.hGL);
        }
    }
Fine!

Quote
I have another solution, using a hidden window ...
That's probably feasible unless it gives us yet more PITA with keyboard focus...
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 16, 2018, 10:33:34 pm
From what I can see immediately:

0. FPS counter gets shifted away together with gP.hGL. I think it should stay in view, i.e. be positioned relative to the gP.hMain frame and lighting panel if it is visible.

1. If the splitter is shifted, then when the toast window is visible and gP.hMain is moved (dragged around), the toast window gets misplaced too far to the left.

2. Splitter/gP.hGL position isn't restored when the main window is restored from maximized to normal (as you said).

3. Double click is intercepted but not yet implemented as intended.

Is that all correct?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 16, 2018, 11:13:39 pm
I shall look at this tomorrow.
Have a good sleep!
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 17, 2018, 08:15:30 am
Could you remind me what the double click must do exactly, i must have removed inadvertently your previous post about this.  :(

I think to remember that the splitter must jump directly to the center of the viewport using a scrolling effect like for the control panel, am i right?

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 17, 2018, 09:37:10 am
Yes, when it's double clicked in its rightmost position, it should scroll quickly to the viewport center. When in any other position, it should scroll to the rightmost position.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 17, 2018, 12:09:51 pm
Here is my patch.

Note: Because the gP.hGL is using ANCHOR_HEIGHT_WIDTH, when switching from maximized to restore the rw.right could become negative, then in this case the splitter is constraint to the left border size.

WM_NCLBUTTONDBLCLK is compatible with light or mesh animation(s).
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 17, 2018, 02:33:59 pm
Thank you, Patrice!

The main glitch I'm seeing is that when the splitter is somewhere midway and the lighting panel is visible, the panel stays OK when the main window is dragged around the screen. But it still jumps to the left (sometimes completely off screen) when the main window is resized rather than dragged.

I increased nStep to 50. The double click is primarily meant as an accelerator rather than eye candy. :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 17, 2018, 02:45:20 pm
Another glitch is when I stretch the main window across 1.5 monitors and bring the splitter closer to the left border, and then resize the window horizontally smaller by dragging its right border to the left, the splitter flies outta the main window and slides to the left of it and away over the screen left border.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 17, 2018, 02:50:58 pm
This way it produces much less smear in the left portion of gP.hGL after the double click:

SplitterCallBack():

........
        if (gP.splitXoffset == 0) { // Move to center
            gP.splitXoffset = (w - SPLITTER_WIDTH) / 2;
            for (x = 0; x <= gP.splitXoffset; x += nStep) {
                MoveWindow(gP.hGL, -x, 0, w, h, TRUE);
                MoveSplitter();
                gP.redraw = -1;  gl_DrawScene();//SendMessage(gP.hMain, WM_SYNC_NOTIFY, 0, 0); // Let the animation play while moving the window
                //Sleep(0);
            }
        } else { // Dock to the right
            for (x = WasXoffset; x >= 0; x -= nStep) {
                MoveWindow(gP.hGL, -x, 0, w, h, TRUE);
                MoveSplitter();
                gP.redraw = -1;  gl_DrawScene();//SendMessage(gP.hMain, WM_SYNC_NOTIFY, 0, 0); // Let the animation play while moving the window
                //Sleep(0);
            }
            gP.splitXoffset = 0;
        }
........
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 17, 2018, 02:57:45 pm
error C3861: 'gl_DrawScene': identifier not found

Where did you put the include file?
(or did you move the procedure gl_Drawscene elsewhere)

I couldn't reproduce the two behaviors you describe in post #326 and #327.

Could you create a quick video with the nVidia utility to show me how to reproduce this?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 17, 2018, 05:19:28 pm
New MoveSplitter for the problem reported in post #327

Code: [Select]
void MoveSplitter() {
    RECT lpr; GetWindowRect(gP.hGL, &lpr);
    RECT rw; GetViewRect(gP.hMain, &rw);
    //zTrace(L"-----");
    //zTrace(STRL(lpr.right));
    //zTrace(STRL(SPLITTER_WIDTH));
    //zTrace(STRL(rw.left));
    if (lpr.right < rw.left) {
        MoveWindow(gP.hSplitter, rw.left, rw.top, SPLITTER_WIDTH, Height(rw), TRUE);
    } else {
        MoveWindow(gP.hSplitter, lpr.right, lpr.top, SPLITTER_WIDTH, Height(rw), TRUE);
    }
}
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 18, 2018, 02:03:11 am
Tonight's handicraft: ;)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 18, 2018, 09:32:56 am
My friend, i know you were kept very busy, and i wonder when you take time to go to sleep  ???

Great work!
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 18, 2018, 09:35:06 am
Here's the patch with my nightly mods. :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 18, 2018, 09:39:35 am
Patrice,

I'm still not feeling well, and my sleep is often broken with difficult breath. So, it's easier to stay awake. :)

BTW does your skinned main menu have any limitations as to the number of elements? My 7th (Help) element won't show up and it seems I can only specify 6 of them... ??? :-[
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 18, 2018, 10:13:54 am
I couldn't reproduce the two behaviors you describe in post #326 and #327.

Could you create a quick video with the nVidia utility to show me how to reproduce this?

Patrice,

We're using different OS'es, video cards, and drivers. My main PC also works simultaneously with 2 nVidia monitors and 1 Intel monitor. All this may cause various glitches, which however may be minimized one way or another.

You're cleaning up the thread often and the message numbers aren't valid any more. Obviously, you spoke about the splitter flying out of the main window and smear near the left border? If yes then you've corrected the splitter behavior, and what concerns the smear, I saw your video that shows smooth gP.hGL scrolling while mine shows smear when gP.hGL has a long way to go to the right. But my suggested fixes cure this problem almost completely, and if you're all right with them under your W10 then let them stay in the code for the sake of my Win7.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 18, 2018, 10:14:49 am
I shall check my code to see what could cause the limitation.

Thank you!
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 18, 2018, 10:35:31 am
SYNC,

Please use the attached constants.h
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 18, 2018, 10:50:00 am
Done!
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 18, 2018, 11:08:18 am
Mike,

I you don't mind, there are a few other things i would like you to SYNC with me as soon as i have complete myself my sync with you. ;)

Added
Here is my sync.zip attachment
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 18, 2018, 11:43:05 am
1. Main.cpp:

            skSetAnchorCtrl(hCtrl, ANCHOR_RIGHT); skCreateToolTip(hCtrl, TipFormat(L"  Animate  "));

            hCtrl = GetDlgItem(gP.hMain, IDC_DEMO_MODE);
            skSetAnchorCtrl(hCtrl, ANCHOR_RIGHT); skCreateToolTip(hCtrl, TipFormat(L"  Demo mode  "));

            hCtrl = GetDlgItem(gP.hMain, IDC_BRIGHT_CONTROL);
            skSetAnchorCtrl(hCtrl, ANCHOR_RIGHT); skCreateToolTip(hCtrl, TipFormat(L"  Stray light intensity  "));


TipFormat() uses a static WCHAR buffer. It stays filled with "Stray light intensity" when it is already required to display "Background" in the info tips. I was (and still am) too lazy to reinitialize it with "Background" here again. ;)

2. Why did you remove the void gl_DrawScene(); forward declaration from Splitter.h? Your compiler has suddenly started to accept this frivolity? ;)


I have sync'ed all the rest with your code. Thanks!
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 18, 2018, 01:27:02 pm
Quote
Why did you remove the void gl_DrawScene(); forward declaration from Splitter.h?
Because we need it elsewhere, see in Mobj.h line 1112.

About the menu, this is due to the font change i did one month ago, there is some kind of clipping, but from a quick test all the menu items are there.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 18, 2018, 05:02:29 pm
Quote
Why did you remove the void gl_DrawScene(); forward declaration from Splitter.h?
Because we need it elsewhere, see in Mobj.h line 1112.

My friend,

I do not understand what you're talking about. If I remove the void gl_DrawScene(); forward declaration from line 44 in Splitter.h, my project won't compile. This has nothing to do with line 1112 in mobj.h which also needs its own declaration because the function appears in Main.cpp, i.e. well below all the include files it is used in...

Try to rebuild (rather than just build) the solution to see if your project would compile without that declaration in Splitter.h. ???
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 18, 2018, 06:24:05 pm
Quote
... from a quick test all the menu items are there
.
I mean all  the name are there when using zTrace, it is just that the last one doesn't display at the right place, but on the line below.

To see what i mean, just put the focus on a menu, then use the left or right arrow to move the popup and see how "Help" is being shown (Under the first item).

I keep trying to understand why Windows doesn't return me the correct location for that one in the ownerdrawn menu section when using
DRAWITEMSTRUCT* lpdis = (DRAWITEMSTRUCT*) lParam;
at the line 2970 of skDrawmenu (in WinLIFT.cpp).

Quote
If I remove the void gl_DrawScene(); forward declaration from line 44 in Splitter.h, my project won't compile.
Obviously we don't use the same Splitter.h code, could you send me yours for comparison purpose.
I made several changes in mine to fix the different misalignments we spoke about.
(Note: i am always using "Rebuild solution")
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 18, 2018, 07:27:33 pm
... use the left or right arrow to move the popup and see how "Help" is being shown (Under the first item).

     :o
;D ;D ;D

Quote
Obviously we don't use the same Splitter.h code ...

I'm using exactly what you've been sending to me as the splitter mods and for sync'ing... ???
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 18, 2018, 07:49:39 pm
I never put void gl_DrawScene(); in the case WM_NCLBUTTONDBLCLK: case section, because i was not aware that this C++ syntax could be used like this inside of a case message cracker.  ::)

You learned me something new about the C++ syntax , thank you!  ;D
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 18, 2018, 09:35:52 pm
I'm glad you liked it! ;D

Yeah, you can put a declaration anywhere you want, but if you put it inside a scope (in between curly braces as inside an if-clause), it just isn't going to be visible anywhere else.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 19, 2018, 12:36:06 am
Thanks for the library, it solves the problem even if temporarily! Hopefully it'll also allow us to add yet more main menu elements as might be necessary in the future. :)

Regarding the new rendering modes,

1. Vertex normals (and even more so, face normals which I haven't yet implemented due to the lack of spare controls on the tool window) help isolate faces that have wrong (flipped) normals. They may be difficult to spot in complex meshes with hundreds of thousands of polies but in simple and symmetrical meshes, the irregularities are easily spotted at a glance.

2. Customized skinned color dialogs would be nice but only if their color selectors are large enough, substantially bigger in size than your usual rainbow strip.

3. Sometimes it is difficult to tell by the looks of normal map alone if it has correct normal Y orientation (the green channel). It should be +Y (upwards) for OpenGL and -Y (downwards) for DirectX. But it becomes immediately prominent when you inspect the white material surface void of the model's diffuse maps. That's the purpose of the new material surface mode.

4. Last but not least, I've put our billboards to useful service. Now they visualize our rotating lights instead of the colored spheres. I hope you noticed the new corona.png texture map in the zip. You're supposed to put it into the \x64\Release\Reader folder alongside the skin and other system maps.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 19, 2018, 11:58:02 am
Quote
I've put our billboards to useful service
I have just checked the new corona billboard, and it looks better than the previous sphere, good work.

Thank you!
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 19, 2018, 12:27:59 pm
I made a copy-paste typo in the ToolProc() function, line 219, ToolWindow.h:

........
        case IDT_CHECK02:
            if (HIWORD(wParam) == BN_CLICKED) {
                if (gP.bTexVertNorms) {
                    gP.bShowNorms[1] = (BOOL)SendMessage(GetDlgItem(gP.hTool, IDT_CHECK02), BM_GETCHECK, 0, 0);
                } else if (gP.bAnimateLights) {
                    gP.bRotateLight[2] = (BOOL)SendMessage(GetDlgItem(gP.hTool, IDT_CHECK02), BM_GETCHECK, 0, 0);
                }
                gP.redraw = -1; // request redraw
            }
            break;

        case IDT_CHECK03:
            if (HIWORD(wParam) == BN_CLICKED) {
                if (gP.bTexVertNorms) {
                    gP.bShowNorms[2] = (BOOL)SendMessage(GetDlgItem(gP.hTool, IDT_CHECK03), BM_GETCHECK, 0, 0);
                } else if (gP.bAnimateLights) {
                    gP.bRotateLight[3] = (BOOL)SendMessage(GetDlgItem(gP.hTool, IDT_CHECK03), BM_GETCHECK, 0, 0);
                }
                gP.redraw = -1; // request redraw
            }
            break;
        }
        break;
........


Please correct it.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 19, 2018, 05:09:47 pm
I found the cause of the menu problem:
That was a wrong size computation of the menu container, because the use of GetTextExtentPoint32 is not reliable with the new font i am using for menu.

The new pandora with the new DLL is attached to this post.

Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 19, 2018, 06:26:23 pm
And here is what could be the ToolWindow with the Pandora's build-in color selector.

Code: [Select]
C_IMPORT HWND      zColorCtrl(IN long x, IN long y, IN long w, IN long h, IN HWND hParent, IN long nID, IN long UseColor);
C_IMPORT long      zGetPickColor(IN long nColor, IN long RW);
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 19, 2018, 08:46:11 pm
Dear friend,

I will respond to your messages a little later; need to have my somewhat late dinner first.

Attached please find my today's work. Added wireframe overlay, bounding boxes, and bounding spheres rendering modes.

BTW the bounding spheres rendering mode revealed that our mesh radius calc is evidently incorrect; the radius seems to be too large. Need to do something about it later on...  :-\
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 19, 2018, 09:33:11 pm
Mike

May i ask you why you remove this code from

BOOL DetectHotKeys(MSG* msg) { // PAT: 10-26-2018 The new tool popup window is now fired here

    if (gP.useSplitFrame == 2) { // PAT: 12-16-2018
        if (!ZI_IsLButtonDown()) {
            gP.useSplitFrame = 1;
            ZD_SetObjectFrameToUse(ID_SPLITTER_VERT, gP.useSplitFrame, true);
            PutFocusOn(gP.hGL);
        }
    }

    if (msg->wParam == VK_MENU) {
        if (GetMenuState(gP.hMnu, MENU_INFOTIP, MF_BYCOMMAND) & MF_CHECKED) { // MLL 11-28-2018: info tip ALT mode support
            static BOOL isVisibilitySaved = FALSE; // ALT key autorepeat suppressor
            size_t nMeshCount = gtm_meshes.size();
            if ((msg->message == WM_SYSKEYDOWN) && (infoTipMeshID > -1) && !isVisibilitySaved) { // only if other than background
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 19, 2018, 09:51:25 pm
May i ask you why you remove this code from ...

Patrice,

I don't know what you're talking about. I have never gotten a Main.cpp from you for sync'ing that would contain such code... :o

Please merge my latest patch with your code and then send me all your main project files for final re-sync'ing.


[UPD] Ah yes, this code fixes the glitch with the green dots staying on the splitter after a double click.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 19, 2018, 10:27:45 pm
You're welcome, my friend, and thank you for the sync zip!

Main.cpp and texture files are identical. What redards Splitter.h, I don't see why we should forward declare the same function twice in 15 lines of code. Please use the following code starting on line 85 in Splitter.h:

........
        void gl_DrawScene();
        if (gP.splitXoffset == 0) { // Move to center
            gP.splitXoffset = (w - SPLITTER_WIDTH) / 2;
            for (x = 0; x <= gP.splitXoffset; x += nStep) {
                MoveWindow(gP.hGL, -x, 0, w, h, TRUE);
                MoveSplitter();
                gP.redraw = -1; gl_DrawScene(); // Let the animation play while moving the window
                //Sleep(0);
            }
        } else { // Dock to the right
            for (x = WasXoffset; x >= 0; x -= nStep) {
                MoveWindow(gP.hGL, -x, 0, w, h, TRUE);
                MoveSplitter();
                gP.redraw = -1; gl_DrawScene(); // Let the animation play while moving the window
                //Sleep(0);
            }
            gP.splitXoffset = 0;
        }
........
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 19, 2018, 10:30:00 pm
Quote
Here's the old DSW converted to a new VS 2013 SLN. It compiles for both x86 and x64 without a single error or warning.

Thank you very much!

That would allow us to display this kind of help file directly inside of OR
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 19, 2018, 10:36:09 pm
:D

Very nice but with one objection: an RTF file is going to be perhaps 10 times larger than a corresponding (zipped) CHM. ;)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 19, 2018, 11:21:57 pm
I would like to have something directly embedded into OR.

About the example you have kindly coverted for me, i didn't know that it was base on MFC.

MFC is a NoNo for me, what i want, is a pure Win32 solution (like the one i am using in my other applications, but so far i can only display plain text without images, because OLE is missing from my code).

Here is the very short Win32 code i am using to display plain text without image.

Code: [Select]
#pragma once
#include <Richedit.h>

DWORD CALLBACK EditStreamCallback(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, LONG* pcb) {
    HANDLE hFile = (HANDLE)dwCookie;
    return !ReadFile(hFile, lpBuff, cb, (DWORD*)pcb, NULL);
}

BOOL LoadRTF(IN HWND hWnd) {
    BOOL fSuccess = FALSE;
    HANDLE fHandle = 0;
    EDITSTREAM es = { 0 };
    WCHAR szFileName[MAX_PATH] = {0};
    Path_Combine(szFileName, skSkinFolder(), L"HELP.rtf");
    if (FileExist(szFileName)) {
        if (zFOpen(szFileName, 0, 2, fHandle) == 0) {
            es.pfnCallback = EditStreamCallback;
            es.dwCookie = (DWORD_PTR) fHandle;
            LRESULT nRet = SendMessage(hWnd, EM_STREAMIN, SF_RTF, (LPARAM) &es);
            zFClose(fHandle); fHandle = 0;
        }
    }
    return fSuccess;
}

void MoveHelp () {
    if (IsWindowVisible(gP.hHelp)) {
        RECT rc = { 0 };
        GetViewRect(gP.hMain, &rc);
        MoveWindow(gP.hHelp, 0, 0, Width(rc), Height(rc), true);
        PutFocusOn(gP.hHelp);
    }
}

// Create help control
HWND CreateHelp(IN HINSTANCE hInstance) {
    RECT lpr; GetViewRect(gP.hGL, &lpr);

    DWORD dwStyle = WS_CHILD | WS_VSCROLL | ES_MULTILINE | ES_READONLY | WS_BORDER;
    DWORD dwExStyle = 0;
    //HWND hWnd = CreateWindowEx(0, L"RichEdit20A", $NULL, dwStyle, 0, 0, 0, 0, gP.hMain, (HMENU) IDC_RICHEDIT, hInstance, NULL);

    HWND hWnd = CreateWindowEx(0, MSFTEDIT_CLASS, L"", dwStyle, 0, 0, Width(lpr), Height(lpr), gP.hMain, NULL, hInstance, NULL);
    //HWND hWnd = CreateWindowEx(0, L"RichEdit20A", $NULL, dwStyle, 100, 0, Width(lpr), Height(lpr), gP.hMain, NULL, hInstance, NULL);
    if (IsWindow(hWnd)) {
        LoadRTF(hWnd);
    }
    return hWnd;
}

and in Main.cpp
Code: [Select]
                    //HMODULE hRichEdit = LoadLibrary(L"RICHED20.DLL");
                    HMODULE hRichEdit = LoadLibrary(L"Msftedit.dll");
                    if (hRichEdit) {
                        gP.hHelp = CreateHelp(hInstance);
                        if (IsWindow(gP.hHelp)) {
                            Path_Combine(gP.mt.FullName, skSkinFolder(), L"BTN_Help.png");
                            hCtrl = skButtonImage(gP.hMain, gP.mt.FullName, ClientW - 127, 664, IDC_USERHELP, 5);
                            skCreateToolTip(hCtrl, TipFormat(L"User help"));
                        }
                    }
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 20, 2018, 12:05:36 am
... so far i can only display plain text without images, because OLE is missing from my code).

Probably if you could copy the RTF file onto the clipboard as RTF_TEXT then you would be able to paste-special it into your rich text control automagically together with the images? I think (but I'm not sure) the clipboard copy-paste operations would use system OLE facilities rather than your literal code... :-\
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 20, 2018, 12:13:14 am
I just checked the new "Bounding volumes".

I can see the sphere problem you have found, but all in one that is a nice addition!
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 20, 2018, 12:37:18 am
Re. sphere problem, that's because we calc the radius as half the distance between literal min and max bounds. But we shoul calc it as half the distance between two diagonally opposing corners of the real AABB whose calc I added to the function. That's gonna generate a shorter diagonal and radius, hence, a tighter bounding sphere. 8)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 20, 2018, 01:43:21 am
Here's the last patch for today. It implements rendering color coded meshes. The bounding sphere radius isn't fixed yet.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 20, 2018, 08:27:24 am
!!! MAKE SURE TO MERGE THE PRECEDING PATCH FIRST !!! (see message #360 above)

Here comes today's first patch: Close all and clear scene implemented. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 20, 2018, 12:14:09 pm
Here is the rudimentary code i came with, for the Help.h

Code: [Select]
#pragma once
#include <Richedit.h>
#include <Richole.h>

BOOL InsertObject(HWND hRichEdit, LPCTSTR pszFileName) {
    HRESULT hr;

    LPRICHEDITOLE pRichEditOle;
    SendMessage(hRichEdit, EM_GETOLEINTERFACE, 0, (LPARAM)&pRichEditOle);
    if (pRichEditOle == NULL) { return FALSE; }

    LPLOCKBYTES pLockBytes = NULL;
    hr = CreateILockBytesOnHGlobal(NULL, TRUE, &pLockBytes);
    if (FAILED(hr)) { return FALSE; }

    LPSTORAGE pStorage;
    hr = StgCreateDocfileOnILockBytes(pLockBytes, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &pStorage);
    if (FAILED(hr)) { return FALSE; }

    FORMATETC formatEtc;
    formatEtc.cfFormat = 0;
    formatEtc.ptd = NULL;
    formatEtc.dwAspect = DVASPECT_CONTENT;
    formatEtc.lindex = -1;
    formatEtc.tymed = TYMED_NULL;

    LPOLECLIENTSITE pClientSite;
    hr = pRichEditOle->GetClientSite(&pClientSite);
    if (FAILED(hr)) { return FALSE; }

    LPUNKNOWN pUnk;
    CLSID clsid = CLSID_NULL;

    hr = OleCreateFromFile(clsid, pszFileName, IID_IUnknown, OLERENDER_DRAW, &formatEtc, pClientSite, pStorage, (void**)&pUnk);
    pClientSite->Release();
    if (FAILED(hr)) { return FALSE; }

    LPOLEOBJECT pObject;
    hr = pUnk->QueryInterface(IID_IOleObject, (void**)&pObject);
    pUnk->Release();
    if (FAILED(hr)) { return FALSE; }

    OleSetContainedObject(pObject, TRUE);
    REOBJECT reobject = { sizeof(REOBJECT)};
    hr = pObject->GetUserClassID(&clsid);
    if (FAILED(hr)) { pObject->Release(); return FALSE; }

    reobject.clsid = clsid;
    reobject.cp = REO_CP_SELECTION;
    reobject.dvaspect = DVASPECT_CONTENT;
    reobject.dwFlags = REO_RESIZABLE | REO_BELOWBASELINE;
    reobject.dwUser = 0;
    reobject.poleobj = pObject;
    reobject.polesite = pClientSite;
    reobject.pstg = pStorage;
    SIZEL sizel = { 0 };
    reobject.sizel = sizel;

    SendMessage(hRichEdit, EM_SETSEL, 0, -1);
    DWORD dwStart, dwEnd;
    SendMessage(hRichEdit, EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd);
    SendMessage(hRichEdit, EM_SETSEL, dwEnd+1, dwEnd+1);
    SendMessage(hRichEdit, EM_REPLACESEL, TRUE, (WPARAM)L"\n");

    hr = pRichEditOle->InsertObject(&reobject);
    pObject->Release();
    pRichEditOle->Release();

    if (FAILED(hr)) { return FALSE; }
   
    return TRUE;
}

BOOL LoadRTF(IN HWND hWnd) {
    BOOL fSuccess = FALSE;
    HANDLE fHandle = 0;
    EDITSTREAM es = { 0 };
    WCHAR szFileName[MAX_PATH] = { 0 };
    Path_Combine(szFileName, skSkinFolder(), L"HELP.rtf");
    if (FileExist(szFileName)) {
        fSuccess = InsertObject(hWnd, szFileName);
    }
    return fSuccess;
}

void MoveHelp () {
    if (IsWindowVisible(gP.hHelp)) {
        RECT rc = { 0 };
        GetViewRect(gP.hMain, &rc);
        MoveWindow(gP.hHelp, SPLITTER_WIDTH, 0, Width(rc) - SPLITTER_WIDTH, Height(rc), true);
        PutFocusOn(gP.hHelp);
    }
}

// Create help control
HWND CreateHelp(IN HINSTANCE hInstance) {
    RECT lpr; GetViewRect(gP.hGL, &lpr);

    DWORD dwStyle = WS_CHILD | WS_VSCROLL | ES_MULTILINE | ES_READONLY;// | WS_BORDER;
    DWORD dwExStyle = 0;
    HWND hWnd = CreateWindowEx(0, MSFTEDIT_CLASS, L"", dwStyle, 0, 0, 0, 0, gP.hMain, NULL, hInstance, NULL);
    if (IsWindow(hWnd)) {
        LoadRTF(hWnd);
    }
    return hWnd;
}
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 20, 2018, 01:22:47 pm
The code seems clear enough to me. :)

Re. custom skinned color dialogs, I think putting them directly on the tool window i) will make the window unnecessarily and disproportionately large, and ii) will leave the three buttons mostly without work though they'll still be needed for other tasks in other shading modes.

So, I'd suggest putting them in a neatly skinned window of their own to show on pressing the buttons instead of the standard color dialogs. I suppose the arrow button that pops up the list of predefined colors can also be skinned to match the general look of the app's other windows?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 20, 2018, 01:41:59 pm
About the custom color control, we can adjust its height size as we want, and we can turn it on or off.
We can also managed the size of the popup window, to put it outside of the viewport when we do not want it, indeed plainty of solutions.

About the custom help, i am thinking that we could even have a list on the left of the control to load and display a specfic rtf topic file ;)
The blue icon on the bottom right is to show or hide the help control.
The provided Windows WordPad is just perfect to create the rtf files.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 20, 2018, 02:33:23 pm
WordPad's markup RTF is nearly 100% compatible with the standard RichEdit20's capabilities. OTOH MS Word's RTF deviates from WordPad and RichEdit20 in many ways and yields weird visuals in too many cases.

I don't think the blue help button should be there where it is now. I think we'd better use a standard [?] button in the top right corner of the caption bar if only WinLIFT supports it.

Re. custom color controls, I agree to putting them at the tool window bottom, hidden. The tool window should grow down to no more than extra 30% of its usual height and should reveal the hidden control in response to the usual Color button press. Then the tool window should also show up another button called Select next to its existing Reset button. The Select button press will fetch the given selected color to the shader and will at the same time close (hide) the color control, shrink the tool window back to its usual size, and hide the Select button itself.

Do you agree to such a scenario? If yes then can we rely on your practical implementation of it soon, i.e. before your RTF help system materializes?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 20, 2018, 03:25:53 pm
Quote
Do you agree to such a scenario? If yes then can we rely on your practical implementation of it soon, i.e. before your RTF help system materializes?
My friend, too late, i am already working on the help system (that's something i wanted to have for long).
But i shall do my best to work on custom color control, as soon as i have sorted out the basic features of richedit.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 20, 2018, 04:08:20 pm
Ok, i have the fundamental of the help system working, now switching back on the color control ;)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 20, 2018, 05:13:36 pm
My friend, too late, i am already working on the help system ...

Gees, am I not familiar with this feeling of excitement and impatience myself when I can't think of anything else before I get me that toy that I've been dreaming of for ages? ;D
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 20, 2018, 06:18:08 pm
Here is my suggestion for the color picker, we coul use a parameter to show or hide it, because the dialog size won't change.

Note: I can't skin the combo on the fly because it is an ownerdrawn control, using subclassing to display the list with an offset to the left.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 20, 2018, 06:28:40 pm
Patrice,

I decided to make gP.redraw a real BOOL = 1 instead of that BASIC-ish funny long = -1. We aren't supporting BASIC any more, and we should abandon its evil practices here and in all other cases.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 20, 2018, 06:40:26 pm
Here is my suggestion for the color picker ...

How do we abandon incorrect choices/cancel the operation without a Select button?

Quote
... we coul use a parameter to show or hide it, because the dialog size won't change.

... show in response to the Color button click but hide in response to what event, may I ask? I suggest pressing an ESC keyboard key.

Quote
Note: I can't skin the combo on the fly because it is an ownerdrawn control, using subclassing to display the list with an offset to the left.

Whose control is that, yours or 3rd party's?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 20, 2018, 07:12:19 pm
This color picker is a GDImage control, we could add an extra button,
I have to check the code you are using with the native Windows control, to better figure what to do

So far i did this (search for if (ShowColorPick) { )

#define IDT_COLORPICK   59999 // PAT: 12-20-2018

Code: [Select]
HWND CreateToolWindow(IN long ShowColorPick = 0) {
    if (!IsWindow(gP.hTool)) {
        HWND hCtrl = NULL, hWnd = NULL;
        WNDCLASSEX wcx = { 0 };
        WCHAR zClass[MAX_PATH]; ClearMemory(zClass, sizeof(zClass));
        wcscopy(zClass, L"ZTOOLW");

        wcx.cbSize = sizeof(wcx);
        long IsInitialized = GetClassInfoEx(gP.hInstance, zClass, &wcx);
        if (!IsInitialized) {
            wcx.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
            wcx.lpfnWndProc = ToolProc;
            wcx.cbClsExtra = 0;
            wcx.cbWndExtra = 0;
            wcx.hInstance = gP.hInstance;
            wcx.hIcon = LoadIcon(wcx.hInstance, L"PROGRAM");
            wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
            wcx.hbrBackground = NULL;
            wcx.lpszMenuName = NULL;
            wcx.lpszClassName = zClass;
            wcx.hIconSm = wcx.hIcon;
            if (RegisterClassEx(&wcx)) { IsInitialized = TRUE; }
        }

        if (IsInitialized) {
            DWORD dwStyle = WS_POPUP | WS_CAPTION; // | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
            DWORD dwExStyle = WS_EX_TOOLWINDOW;
            hWnd = CreateControl(dwExStyle, zClass, L"Controls", dwStyle, 0, -1000, ToolW, ToolH, gP.hMain, 0, gP.hInstance, 0);
            if (IsWindow(hWnd)) {

                Path_Combine(zClass, skSkinFolder(), L"DLG_Info.png");
                skStaticImage(hWnd, zClass, 6, 6, 366, 196, 777);

                wcscopy(zClass, L"button"); dwStyle = WS_CHILD | BS_AUTOCHECKBOX;
                hCtrl = CreateControl(0, zClass, L"", dwStyle, 42, 50, 16, 16, hWnd, IDT_CHECK01, gP.hInstance, 0);
                hCtrl = CreateControl(0, zClass, L"", dwStyle, 42, 96, 16, 16, hWnd, IDT_CHECK02, gP.hInstance, 0);
                hCtrl = CreateControl(0, zClass, L"", dwStyle, 42, 142, 16, 16, hWnd, IDT_CHECK03, gP.hInstance, 0);

                WCHAR zFont[MAX_PATH]; ClearMemory(zFont, sizeof(zFont));
                Path_Combine(zFont, skSkinFolder(), L"trebuc.ttf");

                wcscopy(zClass, L"static"); dwStyle = WS_CHILD;
                hCtrl = CreateControl(0, zClass, L"Cap 1", dwStyle, 85, 29, 164, 20, hWnd, IDT_CAPTION01, gP.hInstance, 0);
                hCtrl = CreateControl(0, zClass, L"Cap 2", dwStyle, 85, 75, 220, 20, hWnd, IDT_CAPTION02, gP.hInstance, 0);
                hCtrl = CreateControl(0, zClass, L"Cap 3", dwStyle, 85, 121, 164, 20, hWnd, IDT_CAPTION03, gP.hInstance, 0);

                long xOffset = 120;
                hCtrl = CreateControl(0, zClass, L"", dwStyle, 85 + xOffset, 29, 50, 20, hWnd, IDT_VALUE01, gP.hInstance, 0);
                hCtrl = CreateControl(0, zClass, L"", dwStyle, 85 + xOffset, 75, 50, 20, hWnd, IDT_VALUE02, gP.hInstance, 0);
                hCtrl = CreateControl(0, zClass, L"", dwStyle, 85 + xOffset, 121, 50, 20, hWnd, IDT_VALUE03, gP.hInstance, 0);

                wcscopy(zClass, TRACKBAR_CLASS); dwStyle = WS_CHILD | TBS_BOTH | TBS_NOTICKS | TBS_TOOLTIPS;
                hCtrl = CreateControl(0, zClass, L"", dwStyle, 85, 50, 166, 16, hWnd, IDT_SLIDE01, gP.hInstance, 0);
                SendMessage(hCtrl, TBM_SETRANGE, TRUE, MAKELONG(0, 100)); SendMessage(hCtrl, TBM_SETPOS, TRUE, 50);
                hCtrl = CreateControl(0, zClass, L"", dwStyle, 85, 96, 166, 16, hWnd, IDT_SLIDE02, gP.hInstance, 0);
                SendMessage(hCtrl, TBM_SETRANGE, TRUE, MAKELONG(0, 100)); SendMessage(hCtrl, TBM_SETPOS, TRUE, 50);
                hCtrl = CreateControl(0, zClass, L"", dwStyle, 85, 142, 166, 16, hWnd, IDT_SLIDE03, gP.hInstance, 0);
                SendMessage(hCtrl, TBM_SETRANGE, TRUE, MAKELONG(0, 100)); SendMessage(hCtrl, TBM_SETPOS, TRUE, 50);

                wcscopy(zClass, L"button"); dwStyle = WS_CHILD | BS_CENTER | BS_VCENTER | BS_NOTIFY;
                hCtrl = CreateControl(0, zClass, L"But 1", dwStyle, 282, 47, 60, 20, hWnd, IDT_BUT01, gP.hInstance, 0);
                hCtrl = CreateControl(0, zClass, L"But 2", dwStyle, 282, 93, 60, 20, hWnd, IDT_BUT02, gP.hInstance, 0);
                hCtrl = CreateControl(0, zClass, L"But 3", dwStyle, 282, 139, 60, 20, hWnd, IDT_BUT03, gP.hInstance, 0);
                dwStyle |= WS_VISIBLE;
                hCtrl = CreateControl(0, zClass, L"Reset", dwStyle, 292, 218, 80, 27, hWnd, IDT_RESET, gP.hInstance, 0);


                skSkinWindow(hWnd, L"");// "Dock|Undock|Minimize|Maximize|Restore|Close");

                // PAT: 12-20-2018
                if (ShowColorPick) {
                    hCtrl = zColorCtrl(6, 220, ToolW - 114, 30, hWnd, IDT_COLORPICK, zGetPickColor(0, 0));
                }

                skCreateToolTip(GetDlgItem(hWnd, IDT_SLIDE01), L"");
                skCreateToolTip(GetDlgItem(hWnd, IDT_SLIDE02), L"");
                skCreateToolTip(GetDlgItem(hWnd, IDT_SLIDE03), L"");

                // We use the new trebuc.ttf private font stored into the Reader resource folder
                skSetLabelFont(GetDlgItem(hWnd, IDT_CAPTION01), zFont, 14, skARGB(255, 255, 255, 255), FontStyleRegular);
                skSetLabelFont(GetDlgItem(hWnd, IDT_CAPTION02), zFont, 14, skARGB(255, 255, 255, 255), FontStyleRegular);
                skSetLabelFont(GetDlgItem(hWnd, IDT_CAPTION03), zFont, 14, skARGB(255, 255, 255, 255), FontStyleRegular);
                skSetLabelFont(GetDlgItem(hWnd, IDT_VALUE01), zFont, 14, skARGB(255, 255, 255, 255), FontStyleRegular);
                skSetLabelFont(GetDlgItem(hWnd, IDT_VALUE02), zFont, 14, skARGB(255, 255, 255, 255), FontStyleRegular);
                skSetLabelFont(GetDlgItem(hWnd, IDT_VALUE03), zFont, 14, skARGB(255, 255, 255, 255), FontStyleRegular);
                skSetLabelFont(GetDlgItem(hWnd, IDT_BUT01), zFont, 14, skARGB(255, 255, 255, 255), FontStyleRegular);
                skSetLabelFont(GetDlgItem(hWnd, IDT_BUT02), zFont, 14, skARGB(255, 255, 255, 255), FontStyleRegular);
                skSetLabelFont(GetDlgItem(hWnd, IDT_BUT03), zFont, 14, skARGB(255, 255, 255, 255), FontStyleRegular);
                skSetLabelFont(GetDlgItem(hWnd, IDT_RESET), zFont, 14, skARGB(255, 255, 255, 255), FontStyleRegular);

                long nWidth, nHeight, w, h, x, y;
                RECT rw; GetWindowRect(gP.hMain, &rw); nWidth = rw.right - rw.left; nHeight = rw.bottom - rw.top;
                RECT rc; GetWindowRect(hWnd, &rc); w = rc.right - rc.left; h = rc.bottom - rc.top;
                x = rw.left + (nWidth - w) / 2;
                y = rw.top + (nHeight - h) / 2;
                MoveWindow(hWnd, x, y, w, h, 0);

                gP.hTool = hWnd;
            }
        }
    }

    if (!IsWindowVisible(gP.hTool)) {
        SetToolwinParams(gP.hTool);
        ShowWindow(gP.hTool, SW_SHOW);
    }

    return gP.hTool;
}

We could put the extra button on the left of the color picker, and reduce the width of the control accordingly.
But i can live with the Windows control for now.

Added
I have checked the SetToolwinParams, and i better understand now what to do   :-[
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 20, 2018, 08:05:19 pm
Thank you for your effort, Patrice!

But please make it HWND CreateToolWindow(IN BOOL bShowColorPick = FALSE), will you? ;)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 20, 2018, 08:08:02 pm
While we're at it, can you make it so that the tool window first pops up not in the center of the screen, but exactly at the bottom left corner of the viewport?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 20, 2018, 09:47:11 pm
Here is how it looks with the [OK] button
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 20, 2018, 11:37:03 pm
Because i am using now a #32770 container for the color picker, i can hide the combo if you want?

The use of a container also allows us to show/hide the whole color picker easiliy.

See the attachment
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 21, 2018, 12:17:17 am
Yes Patrice, thanks for your time!

This one looks much more to my liking if only you can't make the combo size exactly as large as the colored square on the left side of the picker.

If you still can resize it a little larger then let's have it visible and functional too. It's much handier for many simple purposes than the full blown picker. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 21, 2018, 09:44:58 am
There is a conflitc between the toastwindow and toolwindow, when showing the popup.
This is because of the non-cooperative timer effect used in the toastwindow, that must be reworked, the same problem occures when using OGL animations at the time the toastwindow shows up.

For the color picker, the color picker itsel could be resized to any size, however the combo header height must match the size of a single list line (indeed the ownerdrawn color square cell).

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 21, 2018, 10:43:49 am
There is a conflitc between the toastwindow and toolwindow, when showing the popup.

I think all the timed animations and objects in the app should use one and the same timer, SyncTimer()->WM_SYNC_NOTIFY->gl_TimerView(). Then all the animations will be mutually sync'ed, smooth and non-interfering.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 21, 2018, 11:23:57 am
Absolutly, this is the best solution!

Moreover our central timer is working in a specific thread.

I am not sure when to show or hide the color picker, also the "OK" button seems redundent to me with the "Color" button.
Because in case "Color" button is pressed, no need to click first on "OK" we just have to use the color already selected.

Here is the current "ToolWindow.h" code, to check the changes i have done…

WARNING, zGetPickColor is using long rather than COLORREF thus i have added the GetPickColor function for that purpose.

Note: zGetPickColor(ZD_ARGB, 1) is the way to setup the initial color value.

The ColorPicker visibility is setup with ShowColorPicker/HideColorPicker, indeed no need for the bShowColorPick parameter in CreateToolWindow.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 21, 2018, 01:24:39 pm
Add this into ShowToast

void ShowToast() {
    if (!(GetMenuState(gP.hMnu, MENU_HELP_TOAST, MF_BYCOMMAND) & MF_CHECKED)) // MLL 11-15-2018: show only if allowed
        return;
    if (IsWindow(gP.hToast)) {
        ZD_DoEvents();
        if (IsWindowVisible(gP.hToast))
            HideToast(); // MLL 11-15-2018: allow toasts to come in quick succession
        WCHAR zFile[MAX_PATH]; ClearMemory(zFile, sizeof(zFile));
        RECT lpr; GetWindowRect(gP.hToast, &lpr);
        Path_Combine(zFile, skSkinFolder(), L"furtiv.wav");
        if (FileExist(zFile)) { PlaySound(zFile, NULL, SND_FILENAME | SND_ASYNC); }
        MoveWindow(gP.hToast, lpr.left, lpr.top + Height(lpr), Width(lpr), 0, 0);
        ShowWindow(gP.hToast, SW_SHOWNOACTIVATE);
        for (long K = 1; K < Height(lpr); K++) {
            MoveWindow(gP.hToast, lpr.left, lpr.top + Height(lpr) - K, Width(lpr), K, 0);
            ZI_UpdateWindow(gP.hToast, 1);
            //Sleep(1); // ditto
            ZD_DoEvents();
        }
        MoveWindow(gP.hToast, lpr.left, lpr.top, Width(lpr), Height(lpr), 0);
        ZI_UpdateWindow(gP.hToast, 1);
        toastTimerID = SetTimer(gP.hToast, 0xABC, 15000, toastTimerFunc); // MLL 11-15-2018: close this toast in 15 secs
    }
}
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 21, 2018, 01:37:19 pm
Thank you for your work, Patrice!

I'm currently finishing off two more visual enhancements to OR: 3 states of grid opaqueness (solid=100%, glass=50%, ghost=10%) and 1 sec long camera reset animation (linear interpolation between the latest current pos translation/rot angles and zero pos and rot). I'll test, and comment on, your color picker shortly when I'm through with my work. :)

I am not sure when to show or hide the color picker, also the "OK" button seems redundent to me with the "Color" button.
Because in case "Color" button is pressed, no need to click first on "OK" we just have to use the color already selected.

No problem, I'll fix it myself as appropriate.

There's no redundancy in the OK button because the user should have a chance to cancel color selection any time without making a final choice and assigning the new color value. Thus
-- pressing a specific "Color" button will set forward which color exactly the picker is going to control and will also show the picker and OK button;
-- ESC will cancel color selection and will hide the picker and OK button without actually assigning the new color value to the color being selected; and
-- pressing OK will assign the new color value to the color being selected and will hide the picker and OK button.

ShowToast() updated, thanks!
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 21, 2018, 04:52:37 pm
Please change this in Main.cpp at line 3186

                    //hCtrl = skStaticImage(gP.hMain, gP.mt.FullName, /*1041*/ 1065 - skGetSystemMetrics(SK_CXFRAMELEFT), 10 - (skGetSystemMetrics(SK_CYCAPTION) + skGetSystemMetrics(SK_CYMENU)), 34, 32, IDC_GRAPHIC_CARD);
                    GetViewRect(gP.hMain, &rc);
                    hCtrl = skStaticImage(gP.hMain, gP.mt.FullName, skGetSystemMetrics(SK_CXFRAMELEFT) + Width(rc) - SPLITTER_WIDTH, 10 - (skGetSystemMetrics(SK_CYCAPTION) + skGetSystemMetrics(SK_CYMENU)), 34, 32, IDC_GRAPHIC_CARD);
                    skSetAnchorCtrl(hCtrl, ANCHOR_RIGHT);
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 21, 2018, 06:47:25 pm
Hehe, I got many more menu entries than you so for me, this line lies somewhere in the mid-200's. ;)

OK, here's my patch that implements a variable opacity scene grid and model reset animation (active on default).

I'm sending you many files because I have changed all the long=-1 vars that were present in gl_DrawScene() to genuine C BOOLeans throughout the entire solution. So you'll have to do quite a bit of merging before your project compiles. Sorry for that but we should've done it long ago anyway.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 21, 2018, 07:55:54 pm
Really i couldn't see the advantage of boolean over long (the size in memory is the same, and long is more versatile among the different languages i am using).
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 21, 2018, 09:14:17 pm
C is a strictly typed language. BOOL is a data type that can have two values: 1 and 0, TRUE and FALSE, YES and NO. This is what most (but not all) of our gP flags are doing. Thus strategically I was acting in my own right and within the C paradigm.

Do you like the model orientation reset animation? That's how it works in 3ds Max when you click the Home gismo. I like it. :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 21, 2018, 09:22:24 pm
Here is the current "ToolWindow.h" code, to check the changes i have done…

I'm sorry Patrice,

But what you attached there was a ToastWindow, not ToolWindow, file. ???
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 21, 2018, 09:27:32 pm
Oh, no all the time i have spent working on the colorpicker has been lost, i have overwritten my code with yours.  :'(

I made a backup this afternoon, let's see if i can restore it…

Added
Here is my backup with boolean used rtaher than long.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 21, 2018, 09:34:58 pm
Didn't I tell you to merge with, rather than overwrite your own one with, the code I sent you? That's because you stood awake too long last night, my friend. :)

Seriously, I'm sorry about the loss. If you haven't got a workable backup, I can live without the mods for some reasonable length of time.

Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 21, 2018, 09:36:51 pm
see my backup attached to my previous post.




I am not sure when to show or hide the color picker, also the "OK" button seems redundent to me with the "Color" button.
Because in case "Color" button is pressed, no need to click first on "OK" we just have to use the color already selected.

Here is the current "ToolWindow.h" code, to check the changes i have done…

WARNING, zGetPickColor is using long rather than COLORREF thus i have added the GetPickColor function for that purpose.

Note: zGetPickColor(ZD_ARGB, 1) is the way to setup the initial color value.

The ColorPicker visibility is setup with ShowColorPicker/HideColorPicker, indeed no need for the bShowColorPick parameter in CreateToolWindow.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 22, 2018, 05:55:26 am
No Patrice,

Your latest changes to ToastWindow.h don't work correctly for rotating lights. When the light panel is also visible and the lights are rotating, the toast window's sliding animation is so-o-o-o-o-o-o slo-o-o-o-o-w...

I rolled the code (starting on line 41 in ToastWindow.h) back to the following:

........
    if (IsWindow(gP.hToast)) {
        //ZD_DoEvents();
        if (IsWindowVisible(gP.hToast))
            HideToast(); // MLL 11-15-2018: allow toasts to come in quick succession
        WCHAR zFile[MAX_PATH]; ClearMemory(zFile, sizeof(zFile));
        RECT lpr; GetWindowRect(gP.hToast, &lpr);
        Path_Combine(zFile, skSkinFolder(), L"furtiv.wav");
        if (FileExist(zFile)) { PlaySound(zFile, NULL, SND_FILENAME | SND_ASYNC); }
        MoveWindow(gP.hToast, lpr.left, lpr.top + Height(lpr), Width(lpr), 0, 0);
        ShowWindow(gP.hToast, SW_SHOWNOACTIVATE);
        for (long K = 1; K < Height(lpr); K++) {
            MoveWindow(gP.hToast, lpr.left, lpr.top + Height(lpr) - K, Width(lpr), K, 0);
            ZI_UpdateWindow(gP.hToast, 1);
            Sleep(1); // ditto
            //ZD_DoEvents();
        }
        MoveWindow(gP.hToast, lpr.left, lpr.top, Width(lpr), Height(lpr), 0);
        ZI_UpdateWindow(gP.hToast, 1);
        toastTimerID = SetTimer(gP.hToast, 0xABC, 15000, toastTimerFunc); // MLL 11-15-2018: close this toast in 15 secs
    }
........



(Shit happens. ;))
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 22, 2018, 06:12:15 am
OK, I agree to your vision of color picking in the tool windows.

Attached are ToolWindow.h cleaned of bloat, and constants.h with the tool window constants added.

Thanks again for your work!
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 22, 2018, 09:56:23 am
I may have an idea to fire the toastwindow in a more cooperative way, i have to experiment with it first.

Added
The experiment went fine for me.  ;)

Thus for you to try, here is my patch using the new WM_POPUPTOAST (RegisterWindowMessage) to preserve the message flow.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 22, 2018, 03:45:19 pm
Yes Patrice,

Your patch seems to be working fine for me, thanks! :)


(Why aren't you ever commenting in time on my patches? Don't you like what I'm doing? :-[)
Title: Santa
Post by: Patrice Terrier on December 22, 2018, 05:17:30 pm
Quote
Why aren't you ever commenting in time on my patches? Don't you like what I'm doing?
Because i couldn't always test them in time, but i am so delighted of the great work that has been done on OR.
For me you are my most valuable partner, and this is the reason why i sent you pandora to show you my gratitude.

And i am always waiting for your new patches like a boy waiting for Santa  :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 22, 2018, 07:01:23 pm
Here is a screen shot of what i have in mind for the OR help window, indeed it would be based on a listbox (on the left) to select a specific topic.

Each topic would be stored in a distinct .rtf file.

And the first Help menu item, will be used to display the control.

Does that makes sense to you?

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 22, 2018, 08:00:50 pm
AWESOME! 8)

What about adding a very thin "paper" tint to the help pages? Snow white looks a little too high contrast against the OR dark gray background...
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 22, 2018, 10:02:16 pm
Quote
What about adding a very thin "paper" tint to the help pages
I don't know how to change the color of an embedded OLE object (EM_SETBKGNDCOLOR doesn't work with it).

And pure white is better for WYSIWYG if ever we decide to allow the printing of a topic.

I think that the best place to display the help file is to use the full view port (GetViewRect), and above everything else, your thought?

We could use ESC to close the help view (a toast window will inform first the user what to do at the time of the help popup).
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 22, 2018, 10:51:33 pm
I don't know how to change the color of an embedded OLE object (EM_SETBKGNDCOLOR doesn't work with it).

You shouldn't. You should rather change the background color of the original .RTF file when typing it in the RTF editor. :P

Quote
And pure white is better for WYSIWYG if ever we decide to allow the printing of a topic.

Do you wear glasses, my friend? My eyes are crying for mercy after 30 minutes of staring into the white pages of my VS 2013.  :(

And I can hardly imagine anyone these days printing out the help pages on hard paper. ;)

Quote
I think that the best place to display the help file is to use the full view port (GetViewRect), and above everything else, your thought?

No, I think the help file should be displayed against the gP.hMain background with the splitter moved full left. And certainly not above everything else, but below everything else -- the splitter, toast window, etc. The user should be able to drag the splitter and compare immediately what they are seeing in the OGL viewport with what's written and depicted in the help topic.

Quote
We could use ESC to close the help view (a toast window will inform first the user what to do at the time of the help popup).

Exactly!
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 22, 2018, 11:12:45 pm
Quote
You should rather change the background color of the original .RTF file when typing it in the RTF editor.
I do not know how to do it with WordPad from W10  :(
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 22, 2018, 11:20:56 pm
Gimme the RTF file and a PNG sample of the page tint. I'll try to do the rest. :P


And have a good night's sleep. A new patch with a bombastic Model Slicer mod will be waiting for you in the early morning. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 23, 2018, 12:05:46 am
i was able to change the background color with LibreOffice Writer, however when i display a transparent png file, the color doesn't match.

Try with the attached png, and see if you can get it to work, i did try to add an opaque background of the same gray color, but once embedded there is always a small difference with the text background.

The gray color should be RGB(204,204,204)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 23, 2018, 12:47:08 am
Please give me the RTF file with the PNG embedded to see what you're talking about. It is better to see once than to hear one hundred times.

Here comes the promised patch:

-- TODO menu entries hidden for the time being. They are too discouraging to see hundreds of times when debugging. ;)
-- All texture and renderer load errors have been intercepted and handled gracefully.
-- Model Slicer is under View->Geometry Control->Slice model on X,Y,Z axes. Pretty smart to inspect the model's guts. :)

I'm sending many files because I was working on this patch for 48 hours and I forget which ones have been modified by me. Hopefully all of them are there in the zip.

Enjoy!
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 23, 2018, 10:33:39 am
Here is the requested RTF file, showing the problem.

Thanks for the patch i will download it asap!

Added
This is the first time i see such slice feature, so amazing and handy to inspect the inside!

Note: The ESC key should leave the slice mode to switch back to default mode.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 23, 2018, 03:31:43 pm
Except for the flickering, is that what you had in mind to display the help control?

If you agree with this, i shall send you a new patch for sync purpose, even if this Help control is still a work in progress.
I have to figure how to get rid of the richedit flickering  ::)

Added
On this scenario we are unable to use the right scrollbar of the RTF control that becomes only visible when the splitter is moved to the full left side.
Thus i think the best solution is to quickly switch bettween the Help and the GL window (Show/Hide), and that would solve also the flickering problem.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 23, 2018, 05:50:22 pm
Patrice,

It seems flickering is inherent in the RichEdit control due to the CS_HREDRAW | CS_VREDRAW styles. My WordPad is using RichEdit50 and still flickers like hell on resize. I can remember I used to fight a lot with RichEdit flicker probably a dozen years ago when I was developing my FBSL code highlighting control based on RichEdit20 for Eclecta (FBSL stock code editor). I don't remember if I succeeded because later, I used subclassing to totally suppress the control's native drawing and re-implemented my own absolutely flickerless text painting routine on the control's canvas that used the RichEdit metrics but drew everything in it using custom BASIC/C/Asm routines.

MS RichEdit seems to have been written by total lamers judging by its hellish flicker. No wonder every decent language developer around tends to write their own code highlighting controls for their RADs/IDEs. ;)

Since flicker is what I'm seeing in WordPad, I'm intrinsically prepared to see it in OR without much anger or irritation as well. And yes, your video implements my vision of how the OR help system should display regardless. Have you tried to actually resize the RichEdit control while panning the slider, rather than drag it in view from beyond the right border? Resizing will ensure the right scrollbar is always visible. Another palliation is to have a custom vscroll control next to the right gray panel that's always visible and controls the scrolling of the help page instead of the RichEdit original vscroll which always remains under the right-side gray panel or is made disabled and invisible programmatically.

I'm waiting for your OR help sync patch, my friend. I prefer to face the problems  rather than read about them. :)

Re. your OR orb logo, be prepared to use 24-bit RGB illustrations with their backgrounds colored manually to match the page background color exactly, rather than use 32-bit ARGB's and watch the OLE color blending fail to reproduce the sRGB palette of your alpha PNG's correctly. ;)

[ADD] Seems like WordPad's OLE/RTF uses dithering when resizing the embedded PNG objects, hence the unexpected change in colors. For all I know, it may even discard the original PNG format and save the images in some obscure lossy indexed-color BMP format, and that would be exactly what causes dithering/discoloration. I'm going to reboot into XP (that's where my MS Office is installed) and see, if the DOC/DOCX formats are better at preserving the original picture format of embedded image objects...
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 23, 2018, 07:08:16 pm
My friend

Since my previous post, i managed to display the help file, in full view port.
Because we must keep the right side of the splitter to display the future texture editor you spoke me about.
see my comment at line 65 of Splitter.h
 ///////MoveWindow(Futur_DrawingWindow, w - gP.splitXoffset + SPLITTER_WIDTH, 0, gP.splitXoffset, h, false); // PAT: 12-23-2018

To Show/Hide the Help window, click on the top left OR icon.

The patch for syncing purpose is attached to this post.

Added
Forgot to say that you must put the attached HELP.rtf into the \Reader folder for test purpose.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 23, 2018, 08:28:08 pm
Thanks Patrice,

While I'm investigating your patch, please consider the attached HELP_MSWORD.rtf file that has your ARGB OR orb embedded in MS Word. It displays flawlessly in Word regardless of it being in the RTF format, and the PNG is true color transparent with the [198,198,198] background preserved.

However neither WordPad nor RichText can display it correctly (BTW is your Libre Office RTF canvas ARGB-capable as is Word's?). They are obviously trying to convert ARGB to some much lower color bitness smearing the image with moire and dither dots in the process... :(

BTW what about HTML/PDF formats and controls? They are ARGB capable, and MS Word can translate its RTF files with embedded true color transparent objects to both HTML and PDF losslessly.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 23, 2018, 09:03:00 pm
Quote
Do not create the Splitter window with DWORD dwStyle = WS_POPUP | WS_VISIBLE; !
there was no splitter.h is the three latest patches i got from you  :-[

And you are living two days ahead of me  ;D
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 23, 2018, 09:12:01 pm
And you are living two days ahead of me  ;D

I was planning to hold back my mods till Christmas to be able to add saving the configuration file. ;D

But I was so excited about the Model Slicer that I decided to share it with you a.s.a.p. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 23, 2018, 09:22:00 pm
Here is the screenshot done with your HELP_MSWORD.rtf
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 23, 2018, 09:42:50 pm
Formidable!

But still not in my OR. The image sizes are all broken. :'( :'( :'(
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 23, 2018, 09:54:26 pm
Were you using Seven or W10 with your screen shot?

For all image colors except black and white, they are indeed using dithering :(
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 23, 2018, 10:01:25 pm
This is Win 7 which is my main development platform on my workstation, as well as on the workstations of perhaps a billion other human beings on the planet Earth. ;)

This however may be due to the OS differences. Do you want me to switch on my W10 box and check? At any rate, something must be done with it under Win 7 and 8/8.1. Not all of us are so fond of extreme diving as you are, my friend.:)

I don't see my embedded OR orb, it isn't visible at all, so I can't tell you if it's dithered in OR or not for me. Not with this particular file. I'll remove all other images so that I can see the orb at least partially and then I'll tell you if I'm able to see a non-dithered original PNG in OR under Win 7 at all... But I need to go back to XP to re-save the modded file correctly in MS Word.

Stay tuned in the mean time.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 23, 2018, 10:15:42 pm
That's a real pain that it doesn't work the same with Seven, i have no easy solution yet :(
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 23, 2018, 10:36:18 pm
No Patrice,

It's still bad under Win 7; see the attached snapshot.

I've also checked under my W10 and everything's looking perfect as in your own screenshot.

So go on with your help system and I'll be doing ARGB PNG embedding for you in my MS Office. I'll be concurrently thinking about HTML/PDF viewer controls in my spare time, and probably we'll switch over to something that works reliably under both W7 and 10 at some future point in time.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 23, 2018, 11:06:27 pm
Strange behavior when switching textures with MENU_VIEW_MIPMAP
try with the attached model.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 23, 2018, 11:16:14 pm
Quote
I'll be concurrently thinking about HTML/PDF viewer controls in my spare time
embedding a web browser is another solution, but more complex, and i am not speaking of the documentation itself so much easier to write with wordpad.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 23, 2018, 11:45:58 pm
No,

The easiest way will be to use MS Windows' standard HH.exe (.CHM HTML help vewer application), subclass its main window at the moment of creation using a Windows hook, and make it a child window to our custom help window in OR.

This is exactly what the FBSL Eclecta editor does with its numerous help files, also skinning the help windows' non-client areas in the process... ;)

 8)

[ADD] Re. the complexity of writing the text, we just write it in MS Word (or Libre Office) as usual embedding the images as needed, then save it in the HTML format, and then compile a bunch of them to a .CHM file (that's actually the bunch of .HTMs zipped with a custom header) that HH.exe is able to display, using MS Windows HTML Help Workshop or compatible.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 23, 2018, 11:49:25 pm
The cyborg needs further investigation. I'm seeing this glitch for the first time in my life.

(I know of a few more texture glitches in my recent mods but I was too much in a hurry to present the mods to you. Actually I know how to, and I will, fix them all shortly. But they have nothing to do with this mipmapping glitch.)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 24, 2018, 12:13:21 am
Hmm, this RTF-equipped Obj Reader takes some substantially longer time to launch, possibly due to the time it takes the RichEdit control to load and parse this HELP.rtf file...

How long will it take it to parse some few hundred Megs of RTF markup when all the RTF help topics are ready? ;)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 24, 2018, 09:38:35 am
Quote
How long will it take it to parse some few hundred Megs of RTF markup when all the RTF help topics are ready?

For the RTF control, i am using exactly the code shown on MSDN there:
https://docs.microsoft.com/en-us/windows/desktop/controls/using-rich-edit-com#complete-insertobject-example-function
however this code is probably designed to work on the current OS  :-[

I do not see any speed impact on OR at startup on my computer when loading the RTF file.
But for slower computer, the loading could be done only when pressing the help button, just like what i had in mind for switching from one topic to another. Then the only thing that would be done at startup would be to detect the topic files to create the index listbox to select from, and display only a very short Welcome.rtf saying "ObjReader <logo>, please select a topic from the list.".
My idea was also to put all help files into one single dedicated HELP folder.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 24, 2018, 10:32:15 am
My PC is by no means slower than yours, especially at such trivial tasks as parsing and/or disk access; it's a 3.6GHz quad core with 16GB of RAM, after all. ;) It takes this OR version some 2+ secs to load and appear on my screen. As things are, we are going to need a splash screen real soon. ;)

My friend, you can do whatever you see best fit for your help system. What concerns me, I'll be looking for alternatives until I find something equally suitable for, and compatible under, both W7 and W10. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 24, 2018, 11:32:03 am
Mike

With the current version there is definitly a normal/bump problem when we do not use mipmap  textures.
You can try also with the JetVet model, and look at the tire bump texture when switching from one mode to the other.

Quote
until I find something equally suitable for, and compatible under, both W7 and W10.
Unfortunatly, and as you know it already i have no more way to test it on Seven, except asking you ;)
BTW i have used already RTF files with success for help in my PhotoComposer (since more than 10 years), but never with OLE, that seems to be the issue on previous OS.

Added
I reworked the initialisation of the Help process to keep the loading speed of OR unchanged.   ;)
Now it will be fired only the first time than you press the top left Icon.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 24, 2018, 01:22:31 pm
With the current version there is definitly a normal/bump problem when we do not use mipmap  textures.

No Patrice,

This isn't a bug inherent in this version alone. It has a very long history, and I believe it dates back to the times when you were ObjReader's only developer.

See the same glitch all over JetVette under similar conditions in an ObjReader compiled over 2.5 years ago.

Anyway I'm working on it though not very fruitfully yet. It seems like trivial memory corruption somewhere because so far I couldn't spot any invalid handles anywhere... ???
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 24, 2018, 01:51:50 pm
Yes, you are right it has a long history, but this is the first time it is so obvious in a model  :o
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 24, 2018, 05:42:36 pm
Patrice,

I have isolated the cause of mipmapping glitch.

The cause is some moronic 3rd party textures that are made artificially GL_REPEATable for their creator to be able to exceed the normal [0.0f,1.0f] UV range and better see the UV map of a particular mesh against the other UVs in the model by moving the mesh UV map completely out of the texture display in their UV mapping SW. >:(

I'm currently writing a UV verification routine to protect us against such cases by leaving the texture wrappable rather than clamped to the edges. Alas, the texture loading process is going to become longer than it was before.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 24, 2018, 06:32:40 pm
Thank you for the feedback, perhaps this checking could be done only when switching mipmap off?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 24, 2018, 07:31:03 pm
I have completed the help topic selection, would you like to try it?
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 24, 2018, 07:31:35 pm
Thank you for the feedback, perhaps this checking could be done only when switching mipmap off?

Exactly but regardless, it's a doubly nested for-loop.

OK, here's une pilule for your cyborg girl friend and your favorite car: :)

mobj.h
Code: [Select]
// MLL 12-25-2018: sanity check for safe GL_CLAMP_TO_EDGE
BOOL verifyUvsFitIntoZeroOneRange(IN long texID) {
    MobjMesh*    pMesh       = NULL;
    MobjMat*     pMaterial   = NULL;
    MobjVertexT* vertex      = NULL;
    float*       UVs         = NULL;
    BOOL         bNeedVerify = FALSE;
    GLuint       index = 0;

    if (texID == 0) // irrelevant
        return TRUE;
    if (texID == gP.mt.Texture) // wallpaper's always clamped
        return TRUE;
    for (int i = 0; i < gM.numberOfMeshes; ++i) {
        pMesh = &gtm_meshes[i];
        pMaterial = pMesh->pMaterial;
        if (pMaterial->reflMapID) // refl UVs are autogenerated "ad hoc"
            return FALSE;
        bNeedVerify = FALSE;
        if ((pMaterial->colorMapID == texID)
            || (pMaterial->ambiMapID == texID)
            || (pMaterial->bumpMapID == texID)
            || (pMaterial->specMapID == texID)
            || (pMaterial->dispMapID == texID)
            || (pMaterial->emitMapID == texID)
            || (pMaterial->glossMapID == texID)) {
            bNeedVerify = TRUE;
        }
        if (bNeedVerify) {
            index = pMesh->startIndex;
            for (int j = 0; j < pMesh->triangleCount * 3; j++, index++) {
                vertex = &gtm_vertexBuffer[gnm_indexBuffer[index]];
                if (vertex->texCoord[0] < 0.0f)
                    return FALSE;
                if (vertex->texCoord[0] > 1.0f)
                    return FALSE;
                if (vertex->texCoord[1] < 0.0f)
                    return FALSE;
                if (vertex->texCoord[1] > 1.0f)
                    return FALSE;
            }
        }
    }
    return TRUE;
}

void Mobj_makeMultipleTextures(IN ZGLTEXTUREX* mt, IN long mtCount) {
    if (mtCount> 0) {
        long K, OkDelete = 0;
        long* Texture = new long[mtCount];
        memset(Texture, 0, sizeof(long) * mtCount);
        for (K = 0; K < mtCount; K++) {
            Texture[K] = mt[K].Texture; if (Texture[K]) { OkDelete = -1; }
        }
        if (OkDelete) { glDeleteTextures(mtCount, (GLuint*) Texture[0]); }
        glGenTextures(mtCount, (GLuint*) &Texture[0]);
        long nRet = glGetError();
        if (nRet == 0) {
            for (K = 0; K < mtCount; K++) {
                BYTE* lpArray = NULL;
                long xSize = 0, ySize = 0;

                Mobj_texAlpha(0, 1); // 05-10-2015 to detect if we are using an alpha channel
                if (Mobj_createGlTextureFromFileEX(mt[K].FullName, xSize, ySize, lpArray, mt[K].Square)) {
                    mt[K].Texture = Texture[K];
                    mt[K].alpha = Mobj_texAlpha(0, 0); // 05-10-2015 to detect if we are using an alpha channel
                    GL_BindTexture(GL_TEXTURE_2D, Texture[K]); nRet = glGetError();
                    if (nRet == 0) {
                        // MLL 10-18-2018: fix to disallow mipmaps following "Mipmap textures" menu
                        if ((mt[K].Square > TEX_STRETCH) && gP.nEnableMipMap) { // MipMapping in ZI_CreateGLTextureFromFileEX
                            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // MLL 12-25-2018: _MIPMAP_LINEAR can't be used for MAG_FILTER !!!
                            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
                            if (mt[K].Square == TEX_REPEAT) {
                                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
                                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
                            } else if (mt[K].Square == TEX_CLAMP) { // MLL 02-28-2018:
                                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // Avoid BB edge artifacts
                                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // ditto
                            }
                            gluBuild2DMipmaps(GL_TEXTURE_2D, 4, xSize, ySize, GL_RGBA, GL_UNSIGNED_BYTE, lpArray);
                        } else { // TEX_ANYSIZE, NO MIPMAPPING (e.g. wallpaper or do not mipmap at all)
                            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                            // MLL 12-25-2018:  !!! VERIFY that the texture UVs were not generated by a
                            //                  CLINICAL IDIOT that moved them out of [0.0f,1.0f] range
                            //                  and made the texture artificially WRAPPED just to be able
                            //                  to better see these UVs against the other meshes' UVs !!!
                            if (verifyUvsFitIntoZeroOneRange(Texture[K])) {
                                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // Avoid wallpaper bottom line artifacts
                                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // ditto
                            } else {
                                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
                                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
                            }
                            glTexImage2D(GL_TEXTURE_2D, 0, 4, xSize, ySize, 0, GL_RGBA, GL_UNSIGNED_BYTE, lpArray);
                        }
                        nRet = glGetError();
                    }
                    free (lpArray);
                }
            }
        }
        delete[] Texture;
    }
}


Enjoy! :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 24, 2018, 07:34:31 pm
I have completed the help topic selection, would you like to try it?

But of course Patrice,

Why are you asking? :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 24, 2018, 07:45:47 pm
I am asking because you told me that it doesn't work on Seven. ;)

Here is my sync patch, i managed to handle 1000 topics (see the 3 digits number in front of each topic name in the Helper folder), that should be quite enough. The numbers are used to easily sort the topic list order.

See also the use of # in file name to perform indentation in the list ("005#Lighting.rtf").
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 24, 2018, 07:56:03 pm
Thank you!

And here's a more, er, natural rendition of the sanity check function. Please ovewrite the older one with it:

Code: [Select]
// MLL 12-25-2018: sanity check for safe GL_CLAMP_TO_EDGE
BOOL verifyUvsFitIntoZeroOneRange(IN long texID) {
    MobjMesh*    pMesh       = NULL;
    MobjMat*     pMaterial   = NULL;
    float*       UVs         = NULL;
    GLuint       index       = 0;

    if (texID == 0) // irrelevant
        return TRUE;
    if (texID == gP.mt.Texture) // wallpaper's always clamped
        return TRUE;
    for (int i = 0; i < gM.numberOfMeshes; ++i) {
        pMesh = &gtm_meshes[i];
        pMaterial = pMesh->pMaterial;
        if (pMaterial->reflMapID) // refl UVs are autogenerated "ad hoc"
            return FALSE;
        if ((pMaterial->colorMapID == texID)
            || (pMaterial->ambiMapID == texID)
            || (pMaterial->bumpMapID == texID)
            || (pMaterial->specMapID == texID)
            || (pMaterial->dispMapID == texID)
            || (pMaterial->emitMapID == texID)
            || (pMaterial->glossMapID == texID)) {
            index = pMesh->startIndex;
            for (int j = 0; j < pMesh->triangleCount * 3; j++, index++) {
                UVs = &gtm_vertexBuffer[gnm_indexBuffer[index]].texCoord[0];
                if (UVs[0] < 0.0f)
                    return FALSE;
                if (UVs[0] > 1.0f)
                    return FALSE;
                if (UVs[1] < 0.0f)
                    return FALSE;
                if (UVs[1] > 1.0f)
                    return FALSE;
            }
        }
    }
    return TRUE;
}
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 24, 2018, 08:04:26 pm
I am asking because you told me that it doesn't work on Seven. ;)

I want to keep my finger in the broth regardless -- just in case you're going to break something with your help system mods.  ;D
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 24, 2018, 08:09:41 pm
My friend

Your pilule is a very good medicine, that totaly cured the problem, thanks a bunch!
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 24, 2018, 08:27:54 pm
I'm glad I was able to isolate the cause of trouble relatively fast. :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 26, 2018, 03:02:42 am
                  Want some?

(https://i.pinimg.com/236x/f1/6d/e4/f16de4a3a64393f1a8ee893b3aab93a8--symbols-emoticons-smiley-faces.jpg)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 26, 2018, 09:59:07 am
Make sure to put the .HTM+.FILES into your \Help subfolder and use the .EXE instead of your regular ObjReader.

This is your 64-bit HH.exe that's in your C:\Windows folder, made to serve as a thin top-level window wrapper for a COM browser control to display our HTML help pages. 8)

HH.exe can also display .XML files if a matching .XMS style sheet is provided, and of course, which is the most convenient way of all, it can display a precompiled .CHM file that would have the smallest footprint on the disk.

HH.exe's standard toolbar and index/contents tab control have been suppressed because their respective window areas have too much flicker. The total length of code to pop up, trim and resize HH.exe is probably twice shorter than your .RTF stuff.

This demo has no contents list box implemented but it can easily be added to the scene exactly like you do in your RTF help system.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 26, 2018, 10:27:39 am
Your demo using HH.exe doesn't work by me. :(

I had a com browser written long ago in PowerBASIC, in my "zap media lite" freeware, and my "zap image solution" commercial project.

However what i like with .rtf, is that everything is embedded into one single file (like .pdf), and that is what i was looking for.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 26, 2018, 10:52:32 am
What exactly doesn't work for you? I have tested it thoroughly on my W10 box (which has all the latest updates installed) and found no differences with my W7 environment except a better window region management that prevents those annoying grayish flicker on the left of gP.hGL that you can notice in my W7 video.

I implemented the HTML help in a separate HH.h include file that coexists peacefully in the project with your own Help.h due to a few #ifdef MLL_DEV directives. So no problem for the both of us if we don't come to a consensus. ;)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 26, 2018, 11:00:00 am
Quote
What exactly doesn't work for you?
It deosn't show anything, i have checked the Help folder and all the extra files are within the extra "THIS IS A TEST PAGE.files" subfolder.

BTW, please check the attached OleRTF written in PowerBASIC and tell me if it works by you.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 26, 2018, 11:07:31 am
It works but the same as with your OR RTF help system: image dither and hellish flicker on resize.

[ADD] Please check if there's a C:\Windows\hh.exe file on your machine. Also, put this texture into your \Reader subfolder:
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 26, 2018, 11:10:13 am
Ok i have been able to use the version you sent me, after cliking on the top left OR icon.  ;)

The PowerBASIC version doesn't flicker by me, did you embed it changing the parent?
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 26, 2018, 11:15:08 am
AAAAAAAAAAaaaaaaaaaa!!!!!!!!!!!!!!!!!!!!!!!1111
 ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D

Didn't you watch the video? :D :D :D :D :D :D :D
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 26, 2018, 11:26:13 am
... did you embed it changing the parent?

Assuming you're talking about HH.exe rather than your PowerBASIC demo, no, HH.exe isn't "embedded". Its window styles have been changed to remove the decorations (non-client areas) and set gP.hMain as its owner window, and then WS_EX_TOOLWINDOW was added to prevent it from showing an icon in the title bar. Finally, WM_CLOSE was sent to its tool bar to kill it and prevent it from showing the contents/index tab control. All this automatically made the browser control occupy HH's entire client area.

Then all moving/resizing was done using standard MoveWindow() calls.

HH.exe is created/destroyed each time the top left orb is clicked.

The real beauty of it is it's working identically under both W7 and W10 and it doesn't interfere with the gP.hGL display of the model in all modes. 8)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 26, 2018, 11:44:47 am
The .HTM was intentionally made very rich visually using the background image to test the setup under the most stressful conditions. The background image is huge. If it's omitted and a background color is used instead, then the .FILES subfolders will be much much smaller and redraw on resize will be significantly faster.

Last but not least, if there are no images in a particular .HTM then there won't be any accompanying .FILES subfolder to it at all.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 26, 2018, 11:46:34 am
Quote
Also, put this texture into your \Reader subfolder
I couldn't see any difference with the one i already have  ???

I am making some test with the .odt format (much smaller file size)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 26, 2018, 11:59:31 am
I couldn't see any difference with the one i already have  ???

I wasn't sure you had one named 69.png exactly. IIRC the app aborts if it fails to find the FPS texture in its \Reader folder.

My message had been edited to attach the texture before you said you finally tumbled to click the orb. ;)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 26, 2018, 12:03:14 pm
Now, do you want me to send you my sources? ;)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 26, 2018, 12:41:45 pm
Quote
Now, do you want me to send you my sources?
I will need it for sync purpose, but as i told you i want to experiment with the ODT format (1/3 the size of a single RTF file).
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 26, 2018, 12:46:37 pm
Well, well, well... The sides are chosen, aren't they? ;)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 26, 2018, 01:43:44 pm
Nothing build in concrete yet...
but i don't want to bloat OR with too much extra files, and i want to preserve smooth left right scrolling as we have it already when moving only the OGL control with the splitter.

I may have a solution using a backbuffer to suppress the flickering, with my skOFFscreen or zOFFscreen API that i could export from the existing DLL(s), and using WM_PRINT rather than WM_PAINT using subclassing or a superclass.

Added
You know what, ODT is nothing more than a standard ZIP file (xml based)…
all related files being unzipped to the temporary folder, then removed when not needed anymore  :P

That means we could do the same unziping first everything into the temporary folder on the fly, when switching from one topic to another.
Do you think that would work with HH, and what would be the best tool to produce the documentation itself ?
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 26, 2018, 03:39:18 pm
but i don't want to bloat OR with too much extra files

From my perspective, a single file project of such complexity is a nuisance, a rudiment of the PowerBASIC era when its so called RAD wasn't able to cope with multiple files.

And for what it's worth, I may just as well consider the RTF branch of help file system a piece of bloatware based off of technologies of the yesteryear.

Quote
... and i want to preserve smooth left right scrolling as we have it already when moving only the OGL control with the splitter.

And I want to preserve compatibility with the pre-W10 platforms, which in my opinion is a more worthwhile objective.

Quote
I may have a solution using a backbuffer to suppress the flickering, with my skOFFscreen or zOFFscreen API that i could export from the existing DLL(s), and using WM_PRINT rather than WM_PAINT using subclassing or a superclass.

We could probably suppress it with just a careful choice of timely direct gl_DrawScene() calls rather than gP.bRedraw = TRUE requests to repaint the viewport at some unknown later points in time. We can also use SendMessage(WM_SETREDRAW) wisely to update it only when the actual positions of the windows have already stabilized.

Quote
You know what, ODT is nothing more than a standard ZIP file (xml based)…
all related files being unzipped to the temporary folder, then removed when not needed anymore :P
That means we could do the same unziping first everything into the temporary folder on the fly, when switching from one topic to another. Do you think that would work with HH ...

This is what HH.exe does with the .CHM files, and it is damned fast at that doing it directly in memory without dumping anything on disk at all.

Quote
... and what would be the best tool to produce the documentation itself ?

The best tools for the help file system are MS Word and MS HTML Help compiler if you're following my route. If not, you may settle with Libre Office and zlib.dll unless you have your own code to include in the project to compress/decompress ZIPs, JPEGs and PNGs without any 3rd party dependencies. I have used such an include in my FBSL. It added only 8KB to the binary. Then I switched over to the 7-zip algo to yield almost twice deeper compression ratios.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 26, 2018, 06:19:18 pm
Sooner or later i shall have more leave weeks than i want to ;)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 26, 2018, 06:47:47 pm
We are all gonna have them unavoidably, my friend, in our due time and I think it isn't very rewarding to concentrate on such thoughts too deeply. Let's praise the Lord for allowing us to still enjoy ourselves hobbying while too many of our good friends and relatives are long gone...
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 26, 2018, 07:28:20 pm
My friend

What did you do to create the gray background behind the png ObjReader logo?

I managed to change the white background to RGB(192,192,192) as you can see on the screen shot.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 26, 2018, 08:04:53 pm
MS Word allows the embedded image objects to be put behind the text and be sized larger than the page they reside on. If the image is detailed and large enough, then magnification isn't going to impair its visible quality. I own MS Office 2007 but perhaps later version also allow small images to be tiled in the background rather than stretched/magnified? I don't know...

At any rate, such approach isn't very practical in use cases because the large image should then be cloned in every .FILES folder of the .HTMs it is used in. Probably it can be used in the style sheet rather than individual files of other markups like e.g. XML/XMS and thus be applied once to every content file in the bunch but I don't know for sure.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 26, 2018, 10:07:15 pm
Do you know if it is possible to change the text color and background of the selected item in a ListView, without using CUSTOMDRAW ?
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 27, 2018, 08:42:23 am
To the best of my knowledge, not with WinAPI. You've got to use CUSTOMDRAW tricks to return a custom color brush handle to the system. Some modern languages have it hardcoded under the hood, so they expose the Foreground/BackgroundColor properties but inherently they are implemented via the CUSTOMDRAW mechanism.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 27, 2018, 10:34:58 am
Thanks, for the confirmation, then i will go to CUSTOMDRAW  :(
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 27, 2018, 06:35:20 pm
Help has been switched from LISTBOX to CUSTOMDRAW LISTVIEW.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 27, 2018, 07:33:04 pm
Is the control's main background skinned in any way?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 27, 2018, 10:06:50 pm
Screen shot showing the current color, used by the CustomDraw ListView.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 27, 2018, 11:18:33 pm
Looks good under W10, congrats! :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 28, 2018, 11:28:20 am
Thank you Patrice,

FYI I was able to precise the bounding sphere radius calc and am now very heavily (but not very successfully yet) occupied with mesh visibility using both bounding spheres and boxes. I wanted to fix it for a long time, so I thought why not now?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 28, 2018, 11:38:07 am
Thank you for the feedback, i am confident that you will solve the bounding sphere problem sooner or later ;)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 28, 2018, 01:20:23 pm
Sync done, thank you!

Help shouldn't interfer with the full screen mode, see my change in red below.

void ToggleFullScreen() {

    static DWORD savedExStyle, savedStyle, screenWidth, screenHeight;
    static long OverLayVisible, AnimationVisible; // PAT: 02-05-2018
    static RECT rcSaved;
    static HRGN oldRgn = 0, newRgn = 0;
    long K = 0, nLeft = 0, nTop = 0;
    WINDOWPLACEMENT wp = { 0 };

    gP.bIsFullScreen = !gP.bIsFullScreen;

    if (GetWindowPlacement(gP.hMain, &wp)) { // 04-20-2015
        if (wp.showCmd == SW_SHOWMAXIMIZED) {
            //ShowWindow(gP.hMain, SW_RESTORE);
            skRestore(gP.hMain);
        }
    }

    if (gP.bIsFullScreen) { // Moving to full screen mode.
        long wasFPS = gP.bUseFPS; if (gP.bUseFPS) { gP.bUseFPS = FALSE; }

        GetWindowRgn(gP.hMain, oldRgn);

        GetWindowRect(gP.hMain, &rcSaved);

        AnimationVisible = IsWindowVisible(GetDlgItem(gP.hMain, IDC_ANIMATION));

        if (IsWindowVisible(gP.hHelp)) { HideHelp(); } // PAT: 12-28-2018

        for (K = IDC_FIRST; K <= IDC_LAST; K++) {
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 28, 2018, 01:26:11 pm
The fix added under an #ifndef MLL_DEV/#endif condition. ;)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 28, 2018, 02:12:40 pm
I shall experiment using WM_PRINT and a bitmap back buffer to remove flicker from RTF (the same to what i am doing in WinLIFT when skinning ListView).

The RTF PowerBASIC project i sent you, was designed to work on Seven (written in 2016 by José Roca), thus i do not understand why it doesn't work by you  :-[
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 28, 2018, 05:26:20 pm
... (the same to what i am doing in WinLIFT when skinning ListView).

BTW I'm using SendMessage(WM_SETREDRAW FALSE/TRUE) for both ListViews when populating them at model load time. Otherwise their scrollbars flicker like hell unskinned in the process. ;)

The RTF PowerBASIC project i sent you, was designed to work on Seven (written in 2016 by José Roca), thus i do not understand why it doesn't work by you  :-[

It does work for me under W7 but exactly the way any other genuine WordPad pages work: with indexed colors and image dither. If an ARGB PNG is embedded in the page markup manually, then its background (substrate) color is preserved but the foreground colors still get dithered and the image sizes on the page get broken to invisibility.

Evidently José Roca has no authority on my workstation despite all his numerous services to the BASIC Vaterland.  ;D
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 29, 2018, 09:32:17 pm
I have almost completed my new Scrollbar.h to skin any control scrollbar on the fly.
That was a tedious work because i had to remember what i have done in WinLIFT, to add new support for the RICHEDIT control.
I have exported several WinLIFT internal functions to retrieve the bitmap handle of the scrollbar bitmap components.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 29, 2018, 11:30:40 pm
Amazing!

IIRC this is something I can't do yet. :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 30, 2018, 12:12:20 am
Dear Patrice,

I wasn't sure you celebrate Christmas at all (we have two of them as national holidays on both sides of New Year in this country) and that's why I didn't congratulate you with the date.

But the New Year holiday is something that every nation and religion celebrates in one form or another, so

Have a happy coming New Year 2019 and stay healthy and wealthy and cheerful all year round!
 :) :) :)

______________________________________________


The New Year holiday is the date that one usually celebrates at home with the family. But this year my friends and I, all aged ca. 63 to 65, decided to shake off the rust and have it like we hadn't any families at all yet. So, I'm going to be off the air starting December 30 afternoon till January 3 afternoon.

I append a zip with all my files below for sync'ing in the mean time. I wasn't very successful or productive these last few days but I did manage to add some fixes and optimizations, and most importantly, I added ESC to the model slicer. ;)

Visibility isn't going to succeed until I'm able to reliably visualize the current camera frustum on screen and make out what's wrong with its bounds. The code has a few test routines clearly marked as such, and it will be easy for you to safely omit them while merging. When I'm back, I'd like to have your source files too to be able to finalize the merger on both sides.

Take care and see you soon. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on December 30, 2018, 09:50:36 am
Quote
I wasn't sure you celebrate Christmas at all
I do not celebrate any of these, because they are inherited from the old Roman time and the Mitra cult.
Christ is never born on december 25, and new year is a survival of the Janus time.

I shall merge your changes, and will wait for your return, to send you my work and pandora code (with the new exported functions) for sync purpose.

Anyway, enjoy your short holydays my friend!
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on December 30, 2018, 10:53:12 am
Thank you, Patrice!

I do not celebrate any of these, because they are inherited from the old Roman time and the Mitra cult.
Christ is never born on december 25, and new year is a survival of the Janus time.

No, you simply can't be so grim! ;) There must be some holidays that bring you pleasure and delight! :)
Title: Why i am using the current OS
Post by: Patrice Terrier on December 30, 2018, 05:23:24 pm
Here is an example of the reason why i am always using the latest API and the current OS

The compress API is not available on Seven
https://docs.microsoft.com/en-us/windows/desktop/cmpapi/-compression-portal
this is what i wanted to use with my new help system to decrease the size of the .rtf files, and produce a lossless .ztf file that is almost half the size of the original when using embedded images.

Here is the link to the C++ compression/decompression examples to test in W10 console mode.
https://docs.microsoft.com/en-us/windows/desktop/cmpapi/using-the-compression-api-in-buffer-mode
and it is very fast…

Added
12-31-2018
I did several minor changes in OR, that means you will have to sync with me, once you get back from holidays. ;)
I have completed the W10 help support, i am very pleased of the result, and the new skinned scrollbar API works like a charm with it. The rtf compression is not added yet, but it is top on my list, once i have completed the writing of the basic documentation.

01-01-2018
I have fixed an array bug in ResetCamera.
I have written the missing MENU_FILE_REOPEN option.
I have completed the basic help documentation.
I have worked on a new model ;)

01-02-2019
And the whole combination of the new .ztf help files is only 808 Kb with all the embedded images!
Thanks to the W10 COMPRESS_ALGORITHM_XPRESS_HUFF that is amazing both in size and speed.
I have written two console utilities to compress/decompress the help files for the purpose of text edition (zCompress.exe and zDecompress.exe)
The attachment shows the new OR help skinned window on my W10 system (with mouse wheel support), using the new ScrollbarEx API control.

To compress a RTF file with zCompress, use this syntax from a prompt command line:
zCompress text.rtf (create automatically text.ztf into the same folder)

To decompress a ZTF file with zDeCompress, use this syntax from a prompt command line:
zDeCompress text.ztf (create automatically text.rtf into the same folder)

01-03-2019
Sync patch attached to this post…
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 04, 2019, 10:28:41 am
My friend,

To save your time, here is the uncompressed version of the rtf files, i forgot to put them in the previous patch.
They shouldn't be hard to convert to html, to let them work with HH on Seven.

I have also attached WinLIFT64 compiled with VS2010 for smaller binary size.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 04, 2019, 12:57:10 pm
Howdy Patrice,

You did an impressive amount of work these last few days! :)

Thanks for the uncompressed files -- with your permission, I'll use them to generate an equivalent .CHM file for the HH help. I'd also like to have a precompiled ObjReader64.exe to be able to test your help system at all because I can't even compile my own one as it requires a W10 version of Windows SDK -- something that I'm not going to touch until there are still pre-W10 OS'es that Microsoft keeps supporting.

Tell you more, though W8/8.1 can deal with the MS compression API in principle, it still requires an extra non-system Cabinet.dll library to be installed on the user PC.

OTOH I found some open-source Linuxoid code pieces that, apart from other functionality, are claimed to be able to decompress MS XPRESS_HUFF data, and they even claim that it works twice faster than the original. All in all, the code pulls in a lot of Lin/Win dependencies and compiles only with GCC. But I think I can isolate the decompression code, strip it of 3rd party references, make it MS VC friendly, and supply it with a standard MS (de)compression interface to be used literally in place of your W10-only APIs. Then we could have a reasonably small decompression include file to be linked statically in OR to make your system user-friendly on the pre-W10 platforms.

What's your opinion on this possibility?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 04, 2019, 02:32:09 pm
Quote
Thanks for the uncompressed files -- with your permission, I'll use them to generate an equivalent .CHM file for the HH help.
Of course you have my permission, this is the reason why i sent you the uncompressed version.

I have attached the W10 ObjReader64 version compiled with VS2017, to let you try the ztf files in context.

Many of my latest projects (a.k.a. MBox64  and consor) are targeted to work with the latest API, and as much i disliked Windows 8, as much i am pleased of W10, that works very well even on my small ATOM Z8700 Surface (2 Gb RAM) that starts in less than 5 seconds with it!

I plan to test soon VS2019 to check the latest facilities provided by the new environment.

Quote
make it MS VC friendly, and supply it with a standard MS (de)compression interface to be used literally in place of your W10-only APIs
There is another API that could be used for compression/decompression, and it has been used by WinLIFT for years (see skSkiToDib).
And here is a link to the official documentation:
https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntifs/nf-ntifs-rtldecompressbuffer
Note: RtlCompressBuffer seems also to support COMPRESSION_FORMAT_XPRESS_HUFF.

Here is the complete WinLIFT encapsulation, that i could export and it should work on everything ;)
At the time i started to use it, it was a NTAPI undocumented couple of functions, and my code keep linking directly to the core ntdll API, bypassing all other extra encapsulations that have been added since XP.
Code: [Select]
long RtlDecompressBuffer (IN WORD nFormat, OUT CHAR* &szUBUF, IN DWORD nSizeUBUF, IN CHAR* szCBUF, IN DWORD nSizeCBUF, OUT DWORD &FinalSize) {
    long nRet = 0;
    HMODULE hDll = LoadLibrary(L"ntdll.dll");
    if (hDll) {
        long_proc (WORD, CHAR*, DWORD, CHAR*, DWORD, DWORD*);
        zProc hProc = (zProc) GetProcAddress(hDll, "RtlDecompressBuffer");
        if (hProc) { nRet = hProc(nFormat, szUBUF, nSizeUBUF, szCBUF, nSizeCBUF, &FinalSize); }
    }
    return nRet;
}

long RtlGetCompressionWorkSpaceSize (IN USHORT nFormat, OUT DWORD &nSizeCBUF, OUT DWORD &nSizeWorkSpace) {
    long nRet = 0;
    HMODULE hDll = LoadLibrary(L"ntdll.dll");
    if (hDll) {
        long_proc (WORD, DWORD*, DWORD*);
        zProc hProc = (zProc) GetProcAddress(hDll, "RtlGetCompressionWorkSpaceSize");
        if (hProc) { nRet = hProc(nFormat, &nSizeCBUF, &nSizeWorkSpace); }
    }
    return nRet;
}

long RtlCompressBuffer (IN WORD nFormat, IN PUCHAR szUBUF, IN DWORD nSizeUBUF, OUT PUCHAR szCBUF, IN DWORD nSizeCBUF, IN DWORD nSizeChunk,
                        OUT DWORD &FinalSize, IN PVOID WorkSpace) {
    long nRet = 0;
    HMODULE hDll = LoadLibrary(L"ntdll.dll");
    if (hDll) {
        long_proc (WORD, PUCHAR, DWORD, PUCHAR, DWORD, DWORD, DWORD*, PVOID);
        zProc hProc = (zProc) GetProcAddress(hDll, "RtlCompressBuffer");
        if (hProc) { nRet = hProc(nFormat, szUBUF, nSizeUBUF, szCBUF, nSizeCBUF, nSizeChunk, &FinalSize, WorkSpace); }
    }
    return nRet;
}

HBITMAP skSkiToDib (IN WCHAR* szFile, OUT long &nReserved) { // dllexport
    HBITMAP nFunction = 0;
    HDC hIC = 0;
    HBITMAP hDIB = 0;
    if (szFile) {
        if (FileExist(szFile)) {
            HANDLE hFile = 0;
            if (zFOpen(szFile, 0, 2, hFile) == 0) {
                DWORD LenBufIn = zFlof(hFile);
                string sBuffer; sBuffer.assign(LenBufIn, 0);
                zFGet(hFile, sBuffer);
                zFClose(hFile);
                if (LenBufIn > 8) {
                    string sHeader = left$(sBuffer, 8);
                    string sMem;
                    short imgW = 0; sMem = mid$(sHeader, 1, 2); MoveMemory(&imgW, (CHAR*) sMem.c_str(), 2);
                    short imgH = 0; sMem = mid$(sHeader, 3, 2); MoveMemory(&imgH, (CHAR*) sMem.c_str(), 2);
                    nReserved = 0; sMem = mid$(sHeader, 5, 4); MoveMemory(&nReserved, (CHAR*) sMem.c_str(), 4);
       
                    if (g_nUnlocked) { // Detect if (skin are valid
                        char zC[] = {(CHAR) nReserved};
                        g_nUnlocked = instr(0, g_sSkinKey, zC);
                    }
       
                    hIC = skDisplayDC();
                    hDIB = skCreateDIBSection(hIC, imgW, imgH, 32);
                    if (hDIB) {
                        BITMAP bm; GetObject(hDIB, sizeof(bm), &bm);
       
                        LenBufIn -= 8;
                        sBuffer = mid$(sBuffer, 9, LenBufIn);
       
                        // Very important to use the good size for the sBufOut buffer
                        // or we may have a STATUS_BAD_COMPRESSION_BUFFER error!
                        DWORD LenBufOut = bm.bmWidthBytes * bm.bmHeight;
                        //string sBufOut = sBufOut.assign(LenBufOut, 0);
                        char* szBufOut = new char[LenBufOut];
                        memset(szBufOut, 0, LenBufOut);
                        DWORD cBuffSize = 0;
                        long nRet = RtlDecompressBuffer (COMPRESSION_FORMAT_LZNT1, szBufOut, LenBufOut, (CHAR*) sBuffer.c_str(), LenBufIn, cBuffSize);
                        MoveMemory(bm.bmBits, szBufOut, min(LenBufOut, cBuffSize));
                        delete [] szBufOut;
                        if (nRet == 0) { nFunction = hDIB; }
                    }
                    DeleteDC(hIC);
                }
            }
        }
    }
    return nFunction;
}


PS: Tell me if you need the Cabinet.dll
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 04, 2019, 04:25:48 pm
Thanks for the executable!

Quote
Here is the complete WinLIFT encapsulation, that i could export and it should work on everything ;)

Would be useless as-is in this case because the decompressor that we need to re-create directly in ObjReader based on those exports would not support COMPRESSION_FORMAT_XPRESS_HUFF below MS Windows 8, and that's the format you're using in your ZTF help files. You'd have to also change your ZTF format to straight COMPRESSION_FORMAT_XPRESS to be compatible not only with W8/8.1/10 but also W7.

(How can you be so cold blooded and kill your app's compatibility with the potential sub-W10 user base with your own hands anyway? :-\)

Quote
Tell me if you need the Cabinet.dll

No thanks, I'm not planning on testing OR under W8/8.1 at this point in time.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 04, 2019, 05:49:57 pm
Quote
How can you be so cold blooded and kill your app's compatibility with the potential sub-W10 user base with your own hands anyway?
Because here in France most peoples have moved fast to W10, and the private users even faster than the enterprises.
All my friends around me, have moved on, they were reluctant with 8 and 9 (8.1), but 10 has got all the suffrages.
See what ZDnet says about the french market
https://www.zdnet.fr/actualites/chiffres-cles-les-systemes-d-exploitation-sur-pc-39790131.htm

The only other large OS base, used here, is Android and i just bought on Amazon a new 8.4 HUAWEI Mediapad 5, that is a true jewel with its 2K screen.
https://consumer.huawei.com/fr/tablets/mediapad-m5/

IOS is still used by the bobos and the geeks, but the real big market here is W10.

I had the same problem at the time of VISTA, because i moved fast to DWM, while most people were still using XP, but that give me a big boost on my competitors because i learned how to use the new API(s) before all of them, that helped me to make a success of GDImage in the WinDev community.

Quote
Would be useless as-is in this case because the decompressor that we need to re-create directly in ObjReader based on those exports would not support COMPRESSION_FORMAT_XPRESS_HUFF below MS Windows 8,
I could use the same compression that is used in my .ski or my Fly audio files, that is working on XP+, or i could just use the rtf uncompressed as well ;)
I shall make a size comparison of the two compression systems and will let you know the result.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 04, 2019, 06:28:11 pm
Quote
https://www.zdnet.fr/actualites/chiffres-cles-les-systemes-d-exploitation-sur-pc-39790131.htm

But you can see yourself that every 3rd person in France is still using Windows 7! ??? IMHO it is unwise to write them all off your list of potential users...
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 04, 2019, 08:02:46 pm
I wrote a quick compressor project based on NTDLL for comparison purpose

Uncompressed file: 006Lighting.rtf 2150400 bytes

and the result are

with the W10 Cabinet.dll using COMPRESSION_FORMAT_XPRESS_HUFF the file is 184320 bytes

with NTDLL using COMPRESSION_FORMAT_XPRESS the file is 245760 bytes

with NTDLL using COMPRESSION_FORMAT_LZNT1 the file is 425984 bytes (smallest compression ratio, however the fastest)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 04, 2019, 10:08:40 pm
Please let your message stay intact for comparison purposes (do not delete it). I'll see if I can do anything with the Linux code and COMPRESSION_FORMAT_XPRESS_HUFF decompression tomorrow.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 04, 2019, 10:44:34 pm
Just in case, here is the console code i wrote to compress the test file.
As you can see i could easily switch from one to another to select one that give the best result in the old and new Windows paradigm ;)

Tools.h
Code: [Select]
#pragma once
using namespace std;

#define void_proc_c typedef void (__cdecl *zProc)
#define long_proc_c typedef long (__cdecl *zProc)
#define long_proc typedef long (__stdcall *zProc)

WCHAR* wcscopy (IN WCHAR* dst, IN const WCHAR* src) {
    // Warning, there is no check for buffer overflow !
    long nLen = lstrlen(src);
    //for (long K = 0; K < nLen; K++) {
    //    dst[K] = src[K];
    //}
    MoveMemory(dst, src, nLen * sizeof(WCHAR));
    dst[nLen] = L'\0';
    return dst;
}

HMODULE MSVCRT() {
    static HMODULE hModule;
    if (hModule == 0) { hModule = LoadLibrary(L"MSVCRT"); }
    return hModule;
}

void wsplitpath(IN WCHAR* FullPath, OUT WCHAR* Drive, OUT WCHAR* Dir, OUT WCHAR* FileName, OUT WCHAR* Ext) {
    HMODULE hModule = MSVCRT();
    if (hModule) {
        void_proc_c(WCHAR*, WCHAR*, WCHAR*, WCHAR*, WCHAR*);
        zProc hProc = (zProc)GetProcAddress(hModule, "_wsplitpath");
        if (hProc) { hProc(FullPath, Drive, Dir, FileName, Ext); }
    }
}

long Add_Str(OUT WCHAR* dest, IN WCHAR* srce) {
    long nRet = -1; // Error
    HMODULE hModule =  MSVCRT();
    if (hModule) {
        long_proc_c (WCHAR*, WCHAR*, size_t);
        zProc hProc = (zProc)GetProcAddress(hModule, "wcsncat");
        if (hProc) { nRet = hProc(dest, srce, _TRUNCATE); }
    }
    return nRet;
}

HMODULE NTDLL() {
    static HMODULE hModule;
    if (hModule == 0) { hModule = LoadLibrary(L"ntdll"); }
    return hModule;
}

long RtlDecompressBuffer (IN WORD nFormat, OUT CHAR* &szUBUF, IN DWORD nSizeUBUF, IN CHAR* szCBUF, IN DWORD nSizeCBUF, OUT DWORD &FinalSize) {
    long nRet = 0;
    HMODULE hModule =  NTDLL();
    if (hModule) {
        long_proc (WORD, CHAR*, DWORD, CHAR*, DWORD, DWORD*);
        zProc hProc = (zProc) GetProcAddress(hModule, "RtlDecompressBuffer");
        if (hProc) { nRet = hProc(nFormat, szUBUF, nSizeUBUF, szCBUF, nSizeCBUF, &FinalSize); }
    }
    return nRet;
}

long RtlGetCompressionWorkSpaceSize (IN USHORT nFormat, OUT DWORD &nSizeCBUF, OUT DWORD &nSizeWorkSpace) {
    long nRet = 0;
    HMODULE hModule =  NTDLL();
    if (hModule) {
        long_proc (WORD, DWORD*, DWORD*);
        zProc hProc = (zProc) GetProcAddress(hModule, "RtlGetCompressionWorkSpaceSize");
        if (hProc) { nRet = hProc(nFormat, &nSizeCBUF, &nSizeWorkSpace); }
    }
    return nRet;
}

long RtlCompressBuffer (IN WORD nFormat, IN PUCHAR szUBUF, IN DWORD nSizeUBUF, OUT PUCHAR szCBUF, IN DWORD nSizeCBUF, IN DWORD nSizeChunk,
                        OUT DWORD &FinalSize, IN PVOID WorkSpace) {
    long nRet = 0;
    HMODULE hModule =  NTDLL();
    if (hModule) {
        long_proc (WORD, PUCHAR, DWORD, PUCHAR, DWORD, DWORD, DWORD*, PVOID);
        zProc hProc = (zProc) GetProcAddress(hModule, "RtlCompressBuffer");
        if (hProc) { nRet = hProc(nFormat, szUBUF, nSizeUBUF, szCBUF, nSizeCBUF, nSizeChunk, &FinalSize, WorkSpace); }
    }
    return nRet;
}

and wmain
Code: [Select]
// zCompress.cpp : This file contains the 'main' function. Program execution begins and ends there.
#include <iostream>


// Run program: Ctrl + F5 or Debug > Start Without Debugging menu
// Debug program: F5 or Debug > Start Debugging menu

// Tips for Getting Started:
//   1. Use the Solution Explorer window to add/manage files
//   2. Use the Team Explorer window to connect to source control
//   3. Use the Output window to see build output and other messages
//   4. Use the Error List window to view errors
//   5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
//   6. In the future, to open this project again, go to File > Open > Project and select the .sln file
#include <Windows.h>
#include <stdio.h>
#include <compressapi.h>
#include "Tools.h"

// Windows 10, Cabinet.dll version
// Warning, the COMPRESS_ALGORITHM_XPRESS_HUFF is not supported on older OS
//
//void wmain(_In_ int argc, _In_ WCHAR *argv[]) {
//    COMPRESSOR_HANDLE Compressor    = NULL;
//    PBYTE CompressedBuffer          = NULL;
//    PBYTE InputBuffer               = NULL;
//    HANDLE InputFile                = INVALID_HANDLE_VALUE;
//    HANDLE CompressedFile           = INVALID_HANDLE_VALUE;   
//    BOOL DeleteTargetFile           = TRUE;
//    BOOL Success;
//    SIZE_T CompressedDataSize, CompressedBufferSize;
//    DWORD InputFileSize, ByteRead, ByteWritten;
//    LARGE_INTEGER FileSize;   
//    ULONGLONG StartTime, EndTime;
//    double TimeDuration;
//
//    if (argc != 2) {
//        wprintf(L"Usage:\n\t%s <input_file_name>\n", argv[0]);
//        return;
//    }
//
//    WCHAR zFileIn[MAX_PATH] = { 0 }; wcscopy(zFileIn, argv[1]);
//    WCHAR zFileOut[MAX_PATH] = { 0 };
//    WCHAR drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
//    wsplitpath(zFileIn, drive, dir, fname, ext);
//    if (wcsstr(L".rtf", ext) == 0) {
//        wprintf(L"The input file must be a valid .rtf file.\n");
//        goto done;
//    }
//
//    wcscopy(ext, L".ztf");
//    wcscopy(zFileOut, drive); Add_Str(zFileOut, dir); Add_Str(zFileOut, fname); Add_Str(zFileOut, ext);
//
//    //  Open input file for reading, existing file only.
//    InputFile = CreateFile(
//        zFileIn,                  //  Input file name
//        GENERIC_READ,             //  Open for reading
//        FILE_SHARE_READ,          //  Share for read
//        NULL,                     //  Default security
//        OPEN_EXISTING,            //  Existing file only
//        FILE_ATTRIBUTE_NORMAL,    //  Normal file
//        NULL);                    //  No attr. template
//
//    if (InputFile == INVALID_HANDLE_VALUE) {
//        wprintf(L"Cannot open \t%s\n", zFileIn);
//        goto done;
//    }
//
//    //  Get input file size.
//    Success = GetFileSizeEx(InputFile, &FileSize);
//    if ((!Success)||(FileSize.QuadPart > 0xFFFFFFFF)) {
//        wprintf(L"Cannot get input file size or file is larger than 4GB.\n");       
//        goto done;
//    }
//    InputFileSize = FileSize.LowPart;
//
//    //  Allocate memory for file content.
//    InputBuffer = (PBYTE)malloc(InputFileSize);
//    if (!InputBuffer) {
//        wprintf(L"Cannot allocate memory for uncompressed buffer.\n");
//        goto done;
//    }                             
//
//    //  Read input file.
//    Success = ReadFile(InputFile, InputBuffer, InputFileSize, &ByteRead, NULL);
//    if ((!Success)||(ByteRead != InputFileSize)) {
//        wprintf(L"Cannot read from \t%s\n", zFileIn);
//        goto done;
//    }
//
//    //  Open an empty file for writing, if exist, overwrite it.
//    CompressedFile = CreateFile(
//        zFileOut,                 //  Compressed file name
//        GENERIC_WRITE|DELETE,     //  Open for writing; delete if cannot compress
//        0,                        //  Do not share
//        NULL,                     //  Default security
//        CREATE_ALWAYS,            //  Create a new file; if exist, overwrite it
//        FILE_ATTRIBUTE_NORMAL,    //  Normal file
//        NULL);                    //  No template
//
//    if (CompressedFile == INVALID_HANDLE_VALUE) {
//        wprintf(L"Cannot create file \t%s\n", zFileOut);
//        goto done;
//    }
//
//    //  Create an XpressHuff compressor.
//    Success = CreateCompressor(
//        COMPRESS_ALGORITHM_XPRESS_HUFF, //  Compression Algorithm
//        NULL,                           //  Optional allocation routine
//        &Compressor);                   //  Handle
//
//    if (!Success) {
//        wprintf(L"Cannot create a compressor %d.\n", GetLastError());
//        goto done;
//    }
//
//    //  Query compressed buffer size.
//    Success = Compress(
//        Compressor,                  //  Compressor Handle
//        InputBuffer,                 //  Input buffer, Uncompressed data
//        InputFileSize,               //  Uncompressed data size
//        NULL,                        //  Compressed Buffer
//        0,                           //  Compressed Buffer size
//        &CompressedBufferSize);      //  Compressed Data size
//
//    //  Allocate memory for compressed buffer.
//    if (!Success) {
//        DWORD ErrorCode = GetLastError();
//
//        if (ErrorCode != ERROR_INSUFFICIENT_BUFFER)
//        {
//            wprintf(L"Cannot compress data: %d.\n", ErrorCode);
//            goto done;
//        }
//           
//        CompressedBuffer = (PBYTE)malloc(CompressedBufferSize);
//        if (!CompressedBuffer) {
//            wprintf(L"Cannot allocate memory for compressed buffer.\n");
//            goto done;
//        }
//    }
//
//    StartTime = GetTickCount64();
//
//    //  Call Compress() again to do real compression and output the compressed
//    //  data to CompressedBuffer.
//    Success = Compress(
//        Compressor,             //  Compressor Handle
//        InputBuffer,            //  Input buffer, Uncompressed data
//        InputFileSize,          //  Uncompressed data size
//        CompressedBuffer,       //  Compressed Buffer
//        CompressedBufferSize,   //  Compressed Buffer size
//        &CompressedDataSize);   //  Compressed Data size
//
//    if (!Success) {
//        wprintf(L"Cannot compress data: %d\n", GetLastError());
//        goto done;
//    }
//
//    EndTime = GetTickCount64();
//
//    //  Get compression time.
//    TimeDuration = (EndTime - StartTime) / 1000.0;
//
//    //  Write compressed data to output file.
//    Success = WriteFile(
//        CompressedFile,     //  File handle
//        CompressedBuffer,   //  Start of data to write
//        (DWORD)CompressedDataSize, //  Number of byte to write
//        &ByteWritten,       //  Number of byte written
//        NULL);              //  No overlapping structure
//
//    if ((ByteWritten != CompressedDataSize) || (!Success)) {
//        wprintf(L"Cannot write compressed data to file: %d.\n", GetLastError());
//        goto done;
//    }
//
//    wprintf(
//        L"Input file size: %d; Compressed Size: %d\n",
//        InputFileSize,
//        (DWORD)CompressedDataSize);
//    wprintf(L"Compression Time(Exclude I/O): %.2f seconds\n", TimeDuration);
//    wprintf(L"File Compressed.\n");
//
//    DeleteTargetFile = FALSE;
//
//done:
//    if (Compressor != NULL) {
//        CloseCompressor(Compressor);
//    }
//
//    if (CompressedBuffer) {
//        free(CompressedBuffer);
//    }
//
//    if (InputBuffer) {
//        free(InputBuffer);
//    }
//
//    if (InputFile != INVALID_HANDLE_VALUE) {
//        CloseHandle(InputFile);
//    }
//
//    if (CompressedFile != INVALID_HANDLE_VALUE) {
//        //  Compression fails, delete the compressed file.
//        if (DeleteTargetFile)
//        {
//            FILE_DISPOSITION_INFO fdi;
//            fdi.DeleteFile = TRUE;      //  Marking for deletion
//            Success = SetFileInformationByHandle(
//                CompressedFile,
//                FileDispositionInfo,
//                &fdi,
//                sizeof(FILE_DISPOSITION_INFO));   
//            if (!Success) {
//                wprintf(L"Cannot delete corrupted compressed file.\n");
//            }
//        }
//        CloseHandle(CompressedFile);
//    }
//}

// NTDLL version
// This version supports either COMPRESSION_FORMAT_LZNT1 (faster) or COMPRESSION_FORMAT_XPRESS (smaller size)
//
void wmain(_In_ int argc, _In_ WCHAR *argv[]) {
    COMPRESSOR_HANDLE Compressor    = NULL;
    PBYTE CompressedBuffer          = NULL;
    PBYTE InputBuffer               = NULL;
    HANDLE InputFile                = INVALID_HANDLE_VALUE;
    HANDLE CompressedFile           = INVALID_HANDLE_VALUE;   
    BOOL DeleteTargetFile           = TRUE;
    BOOL Success;
    DWORD InputFileSize, ByteRead, ByteWritten;
    LARGE_INTEGER FileSize;   
    ULONGLONG StartTime, EndTime;
    double TimeDuration;

    if (argc != 2) {
        wprintf(L"Usage:\n\t%s <input_file_name>\n", argv[0]);
        return;
    }

    WCHAR zFileIn[MAX_PATH] = { 0 }; wcscopy(zFileIn, argv[1]);
    WCHAR zFileOut[MAX_PATH] = { 0 };
    WCHAR drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
    wsplitpath(zFileIn, drive, dir, fname, ext);

    wcscopy(ext, L".zor");
    wcscopy(zFileOut, drive); Add_Str(zFileOut, dir); Add_Str(zFileOut, fname); Add_Str(zFileOut, ext);

    //  Open input file for reading, existing file only.
    InputFile = CreateFile(zFileIn, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (InputFile == INVALID_HANDLE_VALUE) {
        wprintf(L"Cannot open \t%s\n", zFileIn);
        goto done;
    }

    //  Get input file size.
    Success = GetFileSizeEx(InputFile, &FileSize);
    if ((!Success)||(FileSize.QuadPart > 0xFFFFFFFF)) {
        wprintf(L"Cannot get input file size or file is larger than 4GB.\n");       
        goto done;
    }

    InputFileSize = FileSize.LowPart;

    //  Allocate memory for file content.
    InputBuffer = (PBYTE)malloc(InputFileSize);
    if (!InputBuffer) {
        wprintf(L"Cannot allocate memory for uncompressed buffer.\n");
        goto done;
    } 

    //  Read input file.
    Success = ReadFile(InputFile, InputBuffer, InputFileSize, &ByteRead, NULL);
    if ((!Success) || (ByteRead != InputFileSize)) {
        wprintf(L"Cannot read from \t%s\n", zFileIn);
        goto done;
    }

    //  Open an empty file for writing, if exist, overwrite it.
    CompressedFile = CreateFile(zFileOut, GENERIC_WRITE|DELETE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (CompressedFile == INVALID_HANDLE_VALUE) {
        wprintf(L"Cannot create file \t%s\n", zFileOut);
        goto done;
    }

    DWORD nSizeCBUF = 0, nSizeWorkSpace = 0;
    //RtlGetCompressionWorkSpaceSize(COMPRESSION_FORMAT_LZNT1, nSizeCBUF, nSizeWorkSpace);
    RtlGetCompressionWorkSpaceSize(COMPRESSION_FORMAT_XPRESS, nSizeCBUF, nSizeWorkSpace);
    char* szWorkBuffer =  new char[nSizeCBUF + 1]; memset(szWorkBuffer, 0, nSizeCBUF + 1);
    char* szCBUF = new char[InputFileSize + 1]; memset(szCBUF, 0, InputFileSize + 1);

    StartTime = GetTickCount64();

    DWORD FinalSize = 0;
    long nRet = RtlCompressBuffer (COMPRESSION_FORMAT_XPRESS, (PUCHAR) InputBuffer, InputFileSize, (PUCHAR) szCBUF, InputFileSize, 4096, FinalSize, szWorkBuffer);
    if (nRet == 0) { //  Write compressed data to output file.
        Success = WriteFile(CompressedFile,     //  File handle
                            szCBUF,             //  Start of data to write
                            FinalSize,          //  Number of byte to write
                            &ByteWritten,       //  Number of byte written
                            NULL);              //  No overlapping structure
    }

    delete [] szWorkBuffer;
    delete [] szCBUF;

    if (nRet) {
        wprintf(L"Cannot compress data: %d\n", GetLastError());
        goto done;
    }

    EndTime = GetTickCount64();

    //  Get compression time.
    TimeDuration = (EndTime - StartTime) / 1000.0;

    if ((ByteWritten != FinalSize) || (!Success)) {
        wprintf(L"Cannot write compressed data to file: %d.\n", GetLastError());
        goto done;
    }

    wprintf(L"Input file size: %d; Compressed Size: %d\n", InputFileSize, (DWORD)FinalSize);
    wprintf(L"Compression Time(Exclude I/O): %.2f seconds\n", TimeDuration);
    wprintf(L"File Compressed.\n");

    DeleteTargetFile = FALSE;

done:
    if (InputFile != INVALID_HANDLE_VALUE) {
        CloseHandle(InputFile);
    }

    if (CompressedFile != INVALID_HANDLE_VALUE) {
        //  Compression fails, delete the compressed file.
        if (DeleteTargetFile)  {
            FILE_DISPOSITION_INFO fdi;
            fdi.DeleteFile = TRUE;      //  Marking for deletion
            Success = SetFileInformationByHandle(
                CompressedFile,
                FileDispositionInfo,
                &fdi,
                sizeof(FILE_DISPOSITION_INFO));   
            if (!Success) {
                wprintf(L"Cannot delete corrupted compressed file.\n");
            }
        }
        CloseHandle(CompressedFile);
    }
}
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 05, 2019, 05:23:05 pm
Thanks for your effort to help, Patrice!

But please be patient: the Linuxoid code is heavily macro'ed  and written to an alien C standard. Yet I think I'll crack it to be usable in MS VC for our purposes. ;)

(BTW what's the point in adding a compressor routine to your compressor.h if the only thing ObjReader would ever need is a de-compressor?)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 05, 2019, 06:04:57 pm
The compressor is only needed as an utility, to write new topics or edit an existing one with WordPad.

I have completed the pure ntdll version that would just add a few bytes to the OR code.
And the compression ratio is 2150400 / 245760 = 8.75 that is already a very good value using COMPRESSION_FORMAT_XPRESS.
The compression ratio for COMPRESSION_FORMAT_XPRESS_HUFF is 11.66, but that will produce larger OR code and requires extra dependencies at load time.


If the linux code is too much extra work (we need both compressor/decompressor), i would say that i could live with the 8.75 ratio that is the same on Seven and 10.

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 05, 2019, 07:42:43 pm
I have completed the pure ntdll version ...

OMG Patrice, that's yet another case when, as if competing who turns out to be the smartest of the two in the end, we're working on the same issue in parallel unawares of what the companion is/is not doing... What kept you so long before letting me know you've already decided what your personal preferences are as the project lead? :(

Quote
... that will produce larger OR code ...

That's correct. COMPRESSION_FORMAT_XPRESS_HUFF presupposes that, like any other modern deep lossless compression algo, the code uses extra Huffman hashing, which implies building and maintaining a dynamic dictionary whose physical size determines the final (de)compression ratio. All the maintenance code is implemented as __forceinline functions that are in fact macros expandable in-place throughout the code, which will certainly add much more binary code to the executable than just "a few bytes to the OR code" you developed. But that's a trade-off for an almost 50% deeper compression ratio than the raw XPRESS algo provides.

Quote
... and requires extra dependencies at load time.

But no, unlike the MS stuff you used to advocate, the Linuxoid code doesn't require any dependencies at either load time or afterwards. It is self-sufficient and functionally complete.

Quote
... (we need both compressor/decompressor) ...

No! We do not need a compressor in OR unless you aren't planning to edit its help files directly from its own environment. As things are, ATM your BOOL compressor(IN WCHAR* zFileIn, IN WCHAR* zFileOut) in compressor.h is pretty much dead code that bloats the OR binary because the project doesn't use the VC linker dead code removal option.

You've already implemented compression/decompression routines as standalone console utils that are unlikely to be used by anyone except you -- the author, creator and maintainer of ObjReader's RTF/ZTF help files. So why not keep them the way they are, based on the W10-only MS compression API?

_____________________________________________________

Anyway, if you "could live with the 8.75 ratio that is the same on Seven and 10", I hereby quit porting the Linuxoid code as a pointless, futile and wasteful affair leading knowingly to a dead end. Please send me your final NTDLL help compression code for sync'ing.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 05, 2019, 09:55:26 pm
Mike

There is clearly a misunderstood, the compressor is not intended to be inside of OR.
But i need an external compressor utility to convert the .rtf file or whatever to create the compressed file.

About my code, i already told you that compression based on the ntdll was part of WinLIFT, i just have to export the functions.

Also you told me that the rtf format i was using was not looking good on Seven, thus i thought that you wanted to stay with the HH solution that is chm based.

I have no problem using HH into OR.
And i am looking forward for your linuxoid  HUFF compression, that i will gladly use if it produces smaller and faster binary files.
I see no competition there, but a panel of choices for our finger tips. ;)

As i told you before your holidays, i wanted for long to have my own custom help solution based on RTF, because i always found the creation of .chm files a tedious process, even with the help of Vizaac Helpmaker that i have used for years (they seem to have disappeared now from the net).

Adding compression to rtf, was part of my Help white paper, in order to keep the files small, and to avoid unsolicited edition of the provided documentation.
And to enforce the security i plan to use the same kind of header signature, borrowed to my WinLIFT's ".ski" files to protect the components inside of my commercial skin package collection.
This is also what i am doing with my fly audio files that are an OGG encrypted format, to be played only with FlyWorship.


Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 05, 2019, 11:12:10 pm
Quote
You've already implemented compression/decompression routines as standalone console utils that are unlikely to be used by anyone except you -- the author, creator and maintainer of ObjReader's RTF/ZTF help files. So why not keep them the way they are, based on the W10-only MS compression API?

Anyway, if you "could live with the 8.75 ratio that is the same on Seven and 10", I hereby quit porting the Linuxoid code as a pointless, futile and wasteful affair leading knowingly to a dead end. Please send me your final NTDLL help compression code for sync'ing.

To say the truth, having two distinct help file system this is what looks wasteful to me.

Thus, i cast my vote for the solution that would be the easiest to maintain for both of us.

If HH is needed for backward compatibility, then we can remove all the code from help.h, compress.h, and scrollbar.h, to reduce the code size (because i am using it only there).
And please send me the new chm file with the additions or corrections you may have done.


Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 06, 2019, 05:39:36 am
Patrice,

Quote
To say the truth, having two distinct help file system this is what looks wasteful to me.

We aren't having two distinct help systems. We offer conditional compilation that yields one single help system at the user's option if they want, and are able, to compile the app directly from the sources:And now ask anyone on this forum which system they'd prefer to have in their precompiled ObjReader distros? This isn't a question of which (or whose) system is more compact byte-wise but rather which one is better suited for the variety of user setups that ObjReader is capable of running on. In all other respects, the both systems are nearly equal visually and functionally.

I haven't produced an equivalent CHM yet. I was busy reworking the code to incorporate a platform-independent XPRESS_HUFF decoder in your help system. And I made all the code fixes except one: the MS compression API supplies your ZTF files with a header of unknown format, and I can't yet make out exactly where the compressed data proper starts in a ZTF file. This is the last problem I'll be working on tomorrow. I can read the uncompressed buffer length from the ZTF file directly but the compressed buffer starting address will require some trial and error that's too late to rack my brains about tonight. I will compile the CHM file once I'm through with what I'm doing now -- it's trivial and not challenging at all.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 06, 2019, 05:56:14 am
My friend,

I didn't wanted the help function to become a conditionnal compilation. I want just one same help system for everything, using the same basic files to produce the topic contents. Also we should use only one help GUI for ease of code maintenance, either aside of the slider that seems to have your preference or above the viewport as i have done.

So far, i wanted to go to full completion of what i had in mind, using Wordpad RTF files, compressed with the native API to produce a tiny help system. I succeed on this, and i am pleased with the work done that could be used in my other W10 projects. However i shall revert first to the ntdll compression, except if you succeed with your linux transcription that i would be glad to use with your permission. ;)

In the case of our common OR project, it is very important that both of us could enjoy it with our respective OS of choice, my use of the cabinet.dll was an error because it is is not available on Seven.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 06, 2019, 03:41:35 pm
OK Patrice,

My Linuxoid venture is coming to an end.

I was able to sort of crack empirically the header for this particular layout of single compressed files but I am not satisfied with the results:

1. Under Windows 7, the RichEdit control is pitch black and the text is unreadable. Probably some styles/settings aren't compatible with this OS.

2. Under Windows 10, some text files (not all of them!) are readable and look almost as expected.

3. As soon as it comes to decompressing the embedded pictures, the decoder always fails and fills the output buffer with garbage. Evidently, the internal structure of MS archive buffer is not a simple "solid" (i.e. contiguous throughout) but rather split into chunks each with its own header, and possibly, with its own dictionary. The header that MS adds to such archives is not documented anywhere, and I don't find it particularly entertaining to spend days and nights trying to hack it by trial and error.

I think I should stop with this code here and now. If you're OK with the lower level of compression, we can switch over to your NTDLL implementation and try it out as well but something must be done about the W7 RichEdit unreadable black viewport.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 06, 2019, 04:41:05 pm
Ok, thank you very much for your effort!

I can live with the COMPRESSION_FORMAT_XPRESS ratio of 8.56 that is already very good (and fast).
This is what i will use now in new projects, previously i was using COMPRESSION_FORMAT_LZNT1 for compatibilty purpose with … XP, go figure ;)

About the black background you get running the code on Seven, i have no idea of what could cause this, because i am using exactly the OLE code documented on MSDN here
https://docs.microsoft.com/en-us/windows/desktop/controls/using-rich-edit-com
perhaps this is another W10 specific API, because the documentation date is from May, 30, 2018.

There is an older example of 2005, on CodeProject, here
https://www.codeproject.com/Articles/9541/%2FArticles%2F9541%2FA-Rich-Edit-Control-That-Displays-Bitmaps-and-Othe
However the code style used by the author is too far from the SDK style i am familiar with, to let me use it.

Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 06, 2019, 05:38:50 pm
Mike

Here is the new XPRESS only compressor, based on ntdll.dll.

The Help folder, has both compressed and uncompressed file + 2 console utilities, to convert from one format to another.

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 06, 2019, 06:55:35 pm
I am very sorry to say, my friend, that COMPRESSION_FORMAT_XPRESS was added only in Windows 8.

I'm getting a 0xC000025F == STATUS_UNSUPPORTED_COMPRESSION error. :'(
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 06, 2019, 07:15:12 pm
Oh No!  ::)

with COMPRESSION_FORMAT_LZNT1, the ratio will be only 5.05
with COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM, the ratio will be 5.73(but slower)

5 would be better than nothing  ???
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 06, 2019, 07:24:24 pm
Here are the files compressed with the LZNT1 algo  ::)

Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 06, 2019, 07:46:22 pm
And here are the 2 LZNT1 console applications

Indeed the LZNT1 decompression speed is the fastest all in all…
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 06, 2019, 07:54:54 pm
 :( :( :( :(
 :'( :'( :'( :'(

(disabling your WM_PAINT manipulations to restore the RichEdit background to a readable color...)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 06, 2019, 08:03:36 pm
Patrice,

Maybe I should continue with Linuxoid compression and add a compressor so that we could compress XPRESS_HUFF data with something other than the MS APIs?

Currently the decompressor I ported adds less than 2K binary code to the app as compared to your XPRESS and LZNT1 decompressors but the executable's disk image size remains the same 440KB due to the 4K clusters...

Hopefully the Linuxoid compressor will create solid archives that the matching decompressor can decode flawlessly... :-\
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 06, 2019, 08:47:44 pm
From your Screenshot it looks like the RTF API has also changed, but MSDN doesn't says anything about the OS supported with their example.

Working on the Linuxoid compression is useless if we couldn't display the ztf/rtf correctly on Seven, that should be solved first.




Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 06, 2019, 09:14:27 pm
Working on the Linuxoid compression is useless if we couldn't display the ztf/rtf correctly on Seven, that should be solved first.

I think first and foremost, the images that are embedded in the files should be of W7 acceptable format, probably even converted to high color to avoid uncontrollable dithering and spontaneous resizing. Second, the text fonts should be true MS native TTF's rather than Linuxoid open source surrogates. Finally, formatting options (e.g. like list bullets) should be checked for adequate reproduction in both W7 WordPad and RichEdit.

I'll try to fiddle with all this in the morning based on your uncompressed RTF files. We're going to have the Orthodox Christmas holiday tomorrow, so it's unlikely that something might distract me from my hobbies.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 07, 2019, 06:46:37 pm
... it's unlikely that something might distract me from my hobbies.

If you want to make the god laugh out loud in your face, just let him know about your intentions. ;D

It's been a while since I checked ObjReader last on my 64-bit AMD/ATi W7 box. I did so today only to find that the ATi Radeon version of OpenGL refuses to compile the OR shaders. I had to remove the GL_EXT_gpu_shader4 extension that enabled us to render the model flat shaded in certain modes, and I had also to remove the initialization of shader uniforms in the GLSL code because it isn't supported in ATi's GLSL v1.2 that the shaders were using. nVidia seems to be much more permissive in this regard than its closest competitor.

Yet I found out that this PC is more tolerant to your .RTF help files. Of course 32-bit alpha transparent PNG's are out of the question as they get dithered as badly as on my main workstation, but what regards the sizes and shapes of the fonts, I can read practically any text that's there in the files.

So, it's an indication that the RichEdit distortions I'm seeing are likely to be a W7 video driver issue (both of my PCs have the latest drivers installed from their respective video card vendors), and no one knows how bad or good it may be on yet other people's PCs. I'll be trying to rework the .RTF's in my native W7 WordPad as planned until they look OK on both of my W7 machines.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 07, 2019, 08:07:55 pm
Same problems here with Intel HD Graphics 4000, i can't run OR anymore on my ASUS i5 Transformer.  :-[

The solution could be perhaps to check the graphic card being used, and use these shaders only on nVidia ?
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 07, 2019, 09:32:46 pm
Here's the patch with the shaders and renderers fixed to run on my ATi Radeon. Hopefully it'll suit your 4000. Let me know if it works or not.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 07, 2019, 09:45:23 pm
BTW do you mean to say your ASUS i5 Transformer runs exclusively on Intel HD Graphics 4000 HW and we can now create and test some specific code to add Intel recognition to our options? Can you send me a snapshot of your Transformer's Graphics info... message box if the patch I sent you works well?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 07, 2019, 09:59:25 pm
Yes, this ASUS Transformer has only on an Intel HD 4000, see the attached snapshot.

With your patch, everything seems to work, including the RTF help.
The only problem i have found so far, is when moving the slider, the dot bitmap is left behind and is moved only once i release the mouse button.

Of course there is no speed comparison with my nVidia ASUS Gamer computer.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 07, 2019, 10:05:55 pm
Glad the patch worked for you! :)

Thanks for the Intel HD Graphics panel snapshot but I'd like to see ObjReader's message box as well, that pops up when clicking the video brand icon in the main window caption or choosing the Help->Graphics info... menu, if possible.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 07, 2019, 10:10:00 pm
Ok, here is the dialog.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 07, 2019, 10:16:52 pm
Thnx! And what icon is displayed currently in the OR caption?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 07, 2019, 10:18:53 pm
The icon shown is the Intel one, that's perfectly correct ;)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 07, 2019, 10:23:33 pm
 :D

Of course there is no speed comparison with my nVidia ASUS Gamer computer.

That's most likely because your Transformer has no (or very little, like 256KB only) video memory at all, and there's no profit from using HW VBO's that are emulated transparently in the conventional RAM.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 08, 2019, 11:20:07 am
My friend

zTrace in renderers.h at line 558 and 958  8)

There is a missing mesh display when loading a new model in the latest shaders/renderers.
Try with the attached Samourai project, at startup the face becomes visible only after the model has been moved.

Added:
I am writing the Material topic for the documentation.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 08, 2019, 05:22:26 pm
Dear Patrice,

My renderers.h (including lerpReset()) that I sent you was taken as-is directly from my current WIP on mesh visibility. It bears traces of code that wasn't meant to be used in your OR. Please comment out the following:

1. In lerpReset():

........
    //gluLookAt(gP.rCameraPos[0], gP.rCameraPos[1], gP.rCameraPos[2],
    //    gP.rTargetPos[0], gP.rTargetPos[1], gP.rTargetPos[2],
    //    0.0, 1.0, 0.0);
........


2. In both drawUsingFixedFuncPipeline() and drawUsingProgrammablePipeline():

........
            //// MLL 01-01-2019: !!! TEMPORARILY DISABLED !!!
            //if (!isPointInBox(gP.rCameraPos, pMesh->meshAABB.min, pMesh->meshAABB.max)) {
            //    if (isSphereInFrustum(gM.frustum, pMesh->meshCenter, pMesh->meshRadius)) { // rough/quicker test
            //        //if (!isBoxInFrustum(gM.frustum, pMesh->meshAABB.min, pMesh->meshAABB.max)) // precise/slower test
            //        //    continue;
            //    } else {
            //        continue;
            //    }
            //} // mesh is assumed visible if camera is within its bounding box
            //meshesDrawn++;
........


3. And in both those functions (and everywhere else), everything that pertains to meshesDrawn.

The current camera setup is incapable of creating a usable frustum in real time. I'll have to add some parallel (probably OOP-ed) code that will take care of the necessary modelview and projection matrix transforms as planned to allow us to take advantage of early mesh culling to ease up rendering of high mesh count models. Our recent help system efforts have distracted me from this task I was preoccupied with on the new year's eve. :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 08, 2019, 05:30:26 pm
(The samurai's "pigtail" is gorgeous! :D)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 10, 2019, 03:27:11 pm
I have been thinking of another solution based on GDImage, if ever we couldn't get rid of the RTF oddities, that won't need further compression, because the file will be already using .png format and the compression is vey effective on text based document.

See the attached png that is only 274 Kb, while the original rtf is 776 Kb.




Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 10, 2019, 07:24:44 pm
No Patrice,

This will probably be the smallest possible .PNG file that an ordinary user like me will consider perfect for a help file system. I don't think you'll be able to beat it in size losslessly as far as PNG's go. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 10, 2019, 07:55:20 pm
Your png file is really small.  :o

I did try HH, with a .chm file, and that seems to work well, except that it takes some time to render the full index, and the index is not redrawn correctly when moving the slider, we probably need to force a redraw.

I did download HelpNDoc 5, that seems to work very well, and i was able to import my WinLIFT and GDImage chm help files into it.
That is nice, because HelpMaker, that i have used to create them, doesn't exist anymore.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 10, 2019, 09:01:59 pm
I wasn't planning to use HH's original Index/Contents tab control area as, unlike its browser window, it flickers like hell on HH window resize. That's because the child controls are originally placed inside the HH tab containers -- something I never do in my own apps. You simply can't suppress or override the tab container flicker by subclassing the control, and if you want to get a really flickerless behavior then you should minimize the tab container area to just a couple of pixels below the control's row of tabs, place its "child" controls beneath the tab row, and manipulate their visibility programmatically (possibly via Begin/EndDeferWindowPos if the number of "child" controls is significant) in response to the tab clicks.

HH.exe can open up individual topic files from the common .CHM archive on load if their names are specified in its command line. It is possible to reuse your skinned list view control for surfing the CHM help by restarting HH.exe as needed with a particular help topic while the HH window area redraw is blocked to make the restart unnoticeable and seemingly instantaneous.

I think that, unlike your full sized RichEdit help, it is more reasonable to make the HH window resizable by the splitter because it enables the user to both read the help guides and follow them immediately in the OpenGL viewport without toggling the help window first on and off all the time.

(Have you noticed the size and quality of PNG I appended to my previous post?)

Yes, the file is devoid of all metadata and thumbnail payload a PNG usually carries, and it has its color data reordered, optimized palette-wise and re-compressed at zlib compression level 9 (maximum). IIRC I already made you aware of all sorts of PNG optimizers available on the net. And while we're at it, it seems you can still find lots of sites on the net where you can download your HelpMaker v7.4.4 in case you don't have it installed on your box. As for me, I prefer to use Microsoft's original good old HTML Help Workshop to craft my help files. :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 10, 2019, 09:58:23 pm
Patrice,

Can you add and code a File->Reload->MTL file and File->Reload->Textures (in addition to File->Reload->Model) options to the main menu's File section? It will enable us to edit the material library and textures interactively (through the Edit->MTL file and Edit->Textures menus) in full entirety, not just the MTL light properties section, and thus extend ObjReader's useful capabilities still further?

In general, what's your attitude to extending ObjReader's capabilities from a pure viewer to some sort of an interactive editor?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 10, 2019, 10:06:05 pm
Quote
I think that, unlike your full sized RichEdit help, it is more reasonable to make the HH window resizable by the splitter because it enables the user to both read the help guides and follow them immediately in the OpenGL viewport without toggling the help window first on and off all the time
I shall try, but then we have to use one horizontal and vertical scrollbar, something that i didn't wanted to deal with. :(
Except if we go to a 100% graphic solution, using a GDImage graphic control, but then you will have first to teach me how to produce those tiny png file  :)
 
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 10, 2019, 10:12:03 pm
Quote
In general, what's your attitude to extending ObjReader's capabilities from a pure viewer to some sort of an interactive editor?
If i remember well, that was the initial purpose of the slider, to see the editor asside the GL scene to make interactive changes ;)

But i would like first, to complete OR's help, in one way or another.
If we go to a full graphic help solution (based on tiny png) then we could see the OpenGL scene, just like with the transparent control panel in HUD display mode.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 10, 2019, 10:29:31 pm
I shall try, but then we have to use one horizontal and vertical scrollbar, something that i didn't wanted to deal with. :(

Yeah, I felt it might be a PITA...

Quote
Except if we go to a 100% graphic solution, using a GDImage graphic control ...

I have absolutely no objections, and if it works nicely, I'm ready to give up my HH obsession in favor of the common code. :)

Quote
... but then you will have first to teach me how to produce those tiny png file  :)

No problem, my friend. Catch the attached zip. It contains what I think is the best PNG optimizer around. It is free to use for any purpose though regretfully it comes without the source code. Exhaustive help is included in the zip though in most cases, a simple truepng /o max image.png command line yields the best results without additional headaches, trial and error. :)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 10, 2019, 10:35:58 pm
If i remember well, that was the initial purpose of the slider, to see the editor asside the GL scene to make interactive changes ;)

Excellent! But I think being able to use help alongside the OpenGL viewport alone would be a reason good enough to have introduced the splitter control. :) BTW have you managed to make the dotted button behave well under the Intel HD driver?

Quote
If we go to a full graphic help solution (based on tiny png) then we could see the OpenGL scene, just like with the transparent control panel in HUD display mode.

But on the right side of the main window. :D
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 11, 2019, 07:37:37 am
Thank you very much for TruePNG, that would be very handy for all kind of purpose(s)!

Quote
BTW have you managed to make the dotted button behave well under the Intel HD driver?
No, i haven't, because the intel driver is so slow compared to what i am accustomed to use with OR, and it draws a window border around the slider because it is a popup, probably because the option "move the window content" is disabled, due to the poor performance of the graphic card, and this is also probably the cause of the dotted button problem.

Added:
Yep, when the option "Show window content while dragging" is checked everything works much better in OR, and moving the slider get smooth!
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 11, 2019, 10:51:02 am
You're welcome Patrice,

I'm glad you appreciated the benefits of using a PNG optimizer where necessary to keep the footprint of asset store to a minimum. We can probably reduce our \Resource subfolder to a fraction of its current size even if all its images are true PNGs rather than JPEG junk.

... poor performance of the graphic card ...

Intel HD graphics is not a discrete graphics card but rather a video controller integrated directly on the CPU chip. Due to the chip finite size, allowable power consumption and working temperature limitations, HD graphics has barely enough VRAM (ca. 256MB only IIRC) to support Windows/macOS/Linux aero compositing and standard video apps only thus leaving full featured 3D HW acceleration out of the question.

However Intel is expected to release their first discrete video card some time later this year. If it carries at least 2GB of VRAM and sells at a reasonably low price, I plan on buying myself one for test purposes to support my 3D hobbies. That's why I think it will be reasonable to support Intel graphics in ObjReader specifically despite it being so slow on the current CPU-integrated implementations with a view to their future range of discrete graphics HW.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 11, 2019, 11:17:44 pm
Here are the new PNG help files, to be displayed by a graphic control as a replacement to richedit or HH.

Thank you again for TruePNG!

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 12, 2019, 03:07:16 am
Cool! This is a good start for the help system! 8)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 13, 2019, 11:44:09 am
My friend

I have completed the TruePNG help file to work in standard overlay window mode.

I worked also on the HUD version, but then it defeats the use of TruePNG to create small files, because i have to use blur shadow to enhance the text readability on all kind of wallpaper backgrounds.

However the creation of the topic pages is a rather long process, because i have to create first the RTF text in Wordpad, then take a screenshot to turn it into a variable opacity png file with my GDImage opacity.exe tool. Then import the result into PSD to add shadow and blur effect to finaly save a new png file that is suitable for the HUD display.

I have attached a video to show you the HUD version in action, but i am not sure of what to do, because of the complexity to create the final png materials, and this means also adding more code to OR to process the topic selection (not done yet).


Your thought?
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 13, 2019, 01:26:07 pm
Patrice,

Seriously I think the overall effect is stunning! 8)

And I think it is very well worth the extra effort (and code) put into it. I realize the final size of variable opacity PNGs is going to be much larger than that of the initial RTF-like 24-bit PNGs. But still, I think it is the best of what can be done to preserve the integrity of OR's interface.

And you can use the splitter to drag the topic list alone into view on the right side of the viewport...

I would never regret abandoning HH if I had this help system instead. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 13, 2019, 01:33:06 pm
OK…

Quote
And you can use the splitter to drag the topic list alone into view on the right side of the viewport...
No, i have another idea...
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 13, 2019, 06:41:54 pm
Here are my Help png resources backup, for security purpose ... ::)
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 13, 2019, 09:31:40 pm
You can rely on me keeping them safe and sound. :)
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 14, 2019, 03:29:03 pm
That is going to smell very good  :)

Added:
Ready to test?

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 14, 2019, 08:09:14 pm
Sure! :D
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 14, 2019, 10:12:50 pm
Here is the patch/backup…

There are still a few things i have to work with, but the HUD display is working good, and we can still manipulate the model at the same time the help is shown.

The MouseWheel can be use either with the model when the cursor is in the center of the screen, or to scroll the topic when aside the borders (280 pixels on each side, see case WM_MOUSEWHEEL in Help.h).
You can rotate, drag, zoom the model, popup the contextual menu, and drag and drop .obj file onto the help display.

You can select a topic item with the mouse, and move the selection up or down with the corresponding arrow keys.
But then you have to remove this in the callback in order to keep the keyboard focus (the focus still needs some work).
    case WM_SETFOCUS:
        skRestoreCaption(hWnd, TRUE);
        //SetFocus(gP.hMain);
        nRet = 1;
        break;


Note: I have removed all the HH code from this version.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 15, 2019, 11:31:21 am
Excellent, my friend! :)

I think we'll have to block the lighting panel popping up while the help overlay is on screen, or hide the help if F2 or lighting menu are selected while the help is visible because otherwise the lighting panel remains unusable anyway.

I don't think we absolutely need mouse wheel scrolling the help text. IMHO it is only logical that it zooms the model view rather than scrolls the text since it also pans and rotates the model.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 15, 2019, 12:13:27 pm
A new patch is coming soon to fix a couple of things and capture the keyboard arrow keys from the DetectHotKeys.

Quote
I don't think we absolutely need mouse wheel scrolling the help text. IMHO it is only logical that it zooms the model view rather than scrolls the text since it also pans and rotates the model.
I think that being able to scroll the the help text with the mouse wheel is more handly and intuitive than using the scrollbar on the right, that is also the default processing in a GDImage control when the size of the bitmap background exceed the size of its container.
What i could do is to reduce the mouse section dedicated to the help (currently 280 pixels on each side), and enlarge the section used for 3D.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 15, 2019, 11:52:06 pm
Here is the full_patch, with all the files that have changed since 01-12-2019, in order to support the new graphic help.
In case there was one missing.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 16, 2019, 10:44:52 am
Hi Patrice,

I confirm that commenting out WM_SETFOCUS from GDImageHelpCallBack() makes both W10 and W7 work identically as expected even with also remming out the test block code in WM_MOUSEWHEEL.

Let's consider this glitch fixed. Thanks for co-operation! :)

(I think we can make the 280 pxs wide margins at least twice narrower)


[UPD] Remming out nRet = 1; also works OK under W7. So, which variant do we choose: remming out the whole WM_SETFOCUS or nRet = 1 only?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 16, 2019, 12:08:11 pm
Perhaps we could limit the help scrolling zone to the width of the left index that is 288 pixels large ?
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 16, 2019, 01:23:09 pm
No, I think if the zone exists at all, it should also be detectable in close proximity to the scrollbar. That's how Windows standard controls behave and what the user is accustomed to.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 16, 2019, 02:51:46 pm
Tell me if you prefer the attached help_index.png
using this setting
                PathCombine(gP.mt.FullName, HelpFolder(), L"help_index.png");
                HBITMAP hBitmap = ZI_CreateBitmapFromFile(gP.mt.FullName, w, h);
                if (hBitmap) {
                    nID = IDT_HELPLOGO;
                    x = (288 - w) / 2;
                    y = ClientH - 8 - h;
                    ZD_DrawBitmapToCtrl(hTopic, x, y, hBitmap, ZD_ColorARGB(128, 0), nID, ZS_VISIBLE);
                    ZD_SetObjectAnchorMode(nID, ANCHOR_BOTTOM);
                    ZD_SetObjectHidden(nID, ZS_INACTIVE);
                }
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 16, 2019, 04:41:51 pm
Both are very good Patrice,

Especially knowing your passion towards feminine gender. ;)

Have you tried sitting the android on top of the chevrons?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 17, 2019, 11:36:09 am
I shall complete the help documentation,
do you see anything missing or something new to add ?

I shall also post a step by step tutorial on how to create a topic image (mostly to remember myself how i did it ;) )
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 17, 2019, 12:13:18 pm
When you have all the RTFs ready, just send them to me before creating the PNGs. I'll fix the language issues and probably add a few points for clarification.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 17, 2019, 12:48:34 pm
Here they are.

All text must be always written in pure white hover a full black background (see empty background.rtf)

They must be edited with WordPad, and the font to be used is "Segoe UI symbol".

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 17, 2019, 01:00:42 pm
Got it.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 17, 2019, 08:27:13 pm
While I'm fixing the RTFs, please consider the following.

While the model loads with the splitter moved sideways, the spinner pops up and rolls sideways as well. Do you think it will be reasonable to change its positioning so that it pops up at the center of its top-level parent (the app main window) rather than in the middle of its immediate parent (3D viewport) that may be shifted sideways partially or completely out of view?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 17, 2019, 08:43:07 pm
My opinion is that the splitter should be disabled and kept under the help display for as long as the help is active.
Currently when there is no scrollbar, the splitter could be moved and get hover the help display, while it should stay under it, your thought?

Added:
Oh, i see you were speaking of the spinner, not the splitter ;)
We could use GetViewRect to compute the correct location.

I shall work on the two problems tomorrow.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 17, 2019, 10:58:27 pm
We could use GetViewRect to compute the correct location.

Isn't the spinner part of pandora's control palette? If yes and the spinner popup position is hardcoded there, then perhaps it would be reasonable to make fixes directly in the library code. I guess its popping up in the middle of top level parent (i.e. the app main window) is universal for all possible use cases I can think of.

Quote
I shall work on the two problems tomorrow.

God save us from problems, and we shall deal with issues ourselves. ;D
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 18, 2019, 02:48:44 pm
OK, change all call to ZI_SpinnerInit with gP.hMain rather than gP.hGL

and for the splitter and helper conflict i made these small changes

void ShowHelp() {
    if (IsWindowVisible(gP.hToast)) { HideToast(); }
    if (IsWindowVisible(gP.hOverlay)) { PostMessage(gP.hMain, WM_COMMAND, MAKLNG(MENU_LIGHTSETTING, 0), 0); } // Hide the overlay
    SetWindowPos(gP.hHelp, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    ShowWindow(gP.hHelp, SW_SHOWNOACTIVATE);

    HWND hScroll = GetScrollHandle(GetDlgItem(gP.hHelp, IDT_HELPTOPIC));
    if (hScroll) {
        ScrollBarProc(hScroll, WM_SIZE, 0, 0);
        WindowRedraw(hScroll);
    }
    SetFocus(gP.hMain); // 01-15-2019
}

void HideHelp() {
    if (IsWindowVisible(gP.hHelp)) {
        ShowWindow(gP.hHelp, SW_HIDE);
        SetWindowPos(gP.hHelp, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
        gP.bRedraw = TRUE;
        SetFocus(gP.hMain);
        PutFocusOn(gP.hGL);
    }
}



and add this function at the end of Tools.h

Code: [Select]
BOOL EnableShowDragging(BOOL* activate) {
    BOOL bRet = (FALSE != *activate);
    SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, activate, 0);
    bRet = SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, bRet, 0, 0);
    return bRet;
}

To be used like this in Main.cpp

                    // Force redrawing of the OpenGL control
                    gl_WndProc(gP.hGL, WM_SIZE, 0, MAKLNG(dpi(ClientWGL), dpi(ClientH)));

                    BOOL enable = TRUE;
                    BOOL previousMode = EnableShowDragging(&enable);

                    // Show the main window
                    ShowWindow(gP.hMain, nCmdShow);
                    ShowWindow(gP.hGL, SW_SHOW);
                    ShowWindow(gP.hSplitter, SW_SHOW);              // MLL 12-25-2018: safe to show now
                    SetForegroundWindow(gP.hMain);                  // Slightly Higher Priority
                    SetFocus(gP.hMain);                             // Sets Keyboard Focus To The Window
                    gP.bRedraw = TRUE; // Redraw the OpenGL scene

                    if (lstrlen(lpCmdLine)) { // Check the command line
                        ProccessCommandline(lpCmdLine);
                    }
                    // =================================================================

                    // Disable the taskbar icon flashing
                    FLASHWINFO fi = { 0 };
                    fi.cbSize = sizeof(fi);
                    fi.hwnd = gP.hMain;
                    FlashWindowEx(&fi);

                    // MLL 11-15-2018: enforce OpenGL redraw first
                    gP.bRedraw = TRUE;
                    gl_DrawScene();
                    if (lstrlen(lpCmdLine) == 0) {
                        popupToastWindow(L"Load Model", L"Use the File->Load model... dialog to load the model file, or"
                        L"\ndrag-and-drop the model file icon anywhere in the viewport.");
                    }

                    while (GetMessage(&msg, NULL, 0, 0)) {
                        if (!DetectHotKeys(&msg)) { // MLL 11-12-2018: eat global "hotkey" (ESC, TAB, F1, F2) messages
                            TranslateMessage(&msg);
                            DispatchMessage(&msg);
                        }
                    }

                    if (previousMode) EnableShowDragging(&enable); // set the flag back to the old value

                    // MLL 10-18-2018: free OpenGL resources
                    Cleanup();

                    // PAT: 02-23-2018 (removed, see fpsInit/printFPS)
                    // Delete GLFont.
                    //ZI_DeleteGLFont(gP.glfont);

                    nRet = (long)msg.wParam;
                }


Without window redrawing all fancy stuffs are defeated, i need this for my ASUS Intel based.


To center correctly the Spinner, please use the attached Main.cpp
and look at CenterToViewport(hSpin);
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 18, 2019, 07:07:02 pm
Patrice,

May I freely colorize the ObjReader keywords/metas in your RTF files? The existing white-only color makes the text difficult to visually parse in some densely populated paragraphs.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 18, 2019, 07:24:07 pm
Yes, you can, but i shall have to convert it to full white on black to create the png, with the opacity.exe utility.
Other way the color will be turned into shade of gray. But it can be colored back once imported into PSD before applying the blur effect.

See what i wrote there
http://www.objreader.com/index.php?topic=205.0

Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 18, 2019, 07:29:42 pm
No, then I won't do that. I'll just intersperse the dense paragraphs with more empty lines regardless of yet more work for you to stitch the screenshots into a contiguous image. :P

 ;D
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 18, 2019, 07:40:52 pm
Make sure to sync with the main.cpp attached to post #550
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 18, 2019, 07:46:29 pm
I will. (I'm under W10 currently to be compatible with your RTFs)

OK here are the reviewed RTFs. Hopefully now they look more English than Runglish/Frenglish. :D

I also added some more Notes to describe the options in greater detail, and diluted Material.rtf with CRLFs for better readability.
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 18, 2019, 07:51:57 pm
OK, thank you!
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 18, 2019, 10:56:29 pm
looks like you forgot to download the Main.cpp attachment from post #550.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 18, 2019, 11:13:13 pm
looks like you forgot to download the Main.cpp attachment from post #550.

I never forget anything, my friend, either good or bad. ;)

I'm just sabotaging work. It's friday night, after all. :D And I have a yellow jacket too, if anything... ;D
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 19, 2019, 02:13:53 pm
Another change for Help.h

void ShowHelp() {
    if (IsWindowVisible(gP.hToast)) { HideToast(); }
    if (IsWindowVisible(gP.hOverlay)) { PostMessage(gP.hMain, WM_COMMAND, MAKLNG(MENU_LIGHTSETTING, 0), 0); } // Hide the overlay
    SetWindowPos(gP.hHelp, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    ShowWindow(gP.hHelp, SW_SHOWNOACTIVATE);
    SetWindowPos(gP.hHelp, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

    HWND hScroll = GetScrollHandle(GetDlgItem(gP.hHelp, IDT_HELPTOPIC));
    if (hScroll) {
        ScrollBarProc(hScroll, WM_SIZE, 0, 0);
        WindowRedraw(hScroll);
    }
    SetFocus(gP.hMain); // 01-15-2019
}


Added:
I have attached the new help converted from rtf to png, thank you!
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 19, 2019, 06:21:13 pm
Thanks Patrice,

I'm currently adding your fixes to the code.

Please note that both the 010#Example_of_.mtl_file.rtf and 010#Example_of_.mtl_file.png files contain illegal map_Nx statements where map_Ns should have been.

My bad not spotting those typos while editing the RTFs. :-[
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 19, 2019, 07:51:48 pm
Ok, here is the fixed png file, thank you.
Title: Re: Early WIP on v2.55
Post by: Michael Lobko-Lobanovsky on January 19, 2019, 08:30:29 pm
Thanks!

Now, your immediate code fixes seem to be working for me as expected.

Yet there's one more glitch that needs attention. Suppose I've loaded my monkey and want to texture it. I move the splitter sideways to open my hypothetical UV mapper. Then I open the OR help to read up on how I should proceed. If now I try to orbit or pan my monkey to better view it in gP.hGL through the help text, its rotation and position appears chaotic. OTOH everything works perfectly if I close the help overlay.

Apparently the mouse coords as read from the help overlay are relayed to gP.hGL for processing in their raw form rather than having been previously remapped from the help overlay to gP.hGL screen space.

Do you think it can be fixed without resetting gP.hGL to full view when the help text pops up?
Title: Re: Early WIP on v2.55
Post by: Patrice Terrier on January 19, 2019, 08:51:05 pm
Quote
Do you think it can be fixed without resetting gP.hGL to full view when the help text pops up?

Yes, it is just a matter to apply first an X offset before calling the GL callback.