Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Renderer Support Info
#1
Save this as "GDK_PC_Info.h" in youre Qb64 folder 

Code: (Select All)
#ifndef GDK_PC_INFO_H
#define GDK_PC_INFO_H
#include <windows.h>
// Function signatures for Dynamic Loading
typedef HRESULT (WINAPI* PFN_D3D11_CREATE_DEVICE)(void*, int, void*, UINT, void*, UINT, UINT, void**, void*, void**);
typedef HRESULT (WINAPI* PFN_D3D12_CREATE_DEVICE)(void*, int, const GUID&, void**);
typedef const unsigned char* (WINAPI* PFN_GL_GET_STRING)(unsigned int);
#define DLLEXPORT extern "C" __declspec(dllexport)
static int g_modes[10];
static int g_versions[10];
// Internal helper for OpenGL
void CheckOpenGL(int* major, int* minor) {
    HMODULE hGL = LoadLibraryA("opengl32.dll");
    if (!hGL) return;
    auto pglGetString = (PFN_GL_GET_STRING)GetProcAddress(hGL, "glGetString");
    auto pwglCreateContext = (void* (WINAPI*)(void*))GetProcAddress(hGL, "wglCreateContext");
    auto pwglMakeCurrent = (int (WINAPI*)(void*, void*))GetProcAddress(hGL, "wglMakeCurrent");
    auto pwglDeleteContext = (int (WINAPI*)(void*))GetProcAddress(hGL, "wglDeleteContext");
    // Create a dummy window to initialize a context
    HWND dummyW = CreateWindowA("STATIC", "GDK_GL_PROBE", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
    HDC hdc = GetDC(dummyW);
    PIXELFORMATDESCRIPTOR pfd = { sizeof(pfd), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 32 };
    SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
    void* hrc = pwglCreateContext(hdc);
    if (hrc) {
        pwglMakeCurrent(hdc, hrc);
        const char* verStr = (const char*)pglGetString(0x1F02); // 0x1F02 = GL_VERSION
        if (verStr) {
            sscanf(verStr, "%d.%d", major, minor);
        }
        pwglMakeCurrent(NULL, NULL);
        pwglDeleteContext(hrc);
    }
    ReleaseDC(dummyW, hdc);
    DestroyWindow(dummyW);
    FreeLibrary(hGL);
}
DLLEXPORT void GDK_Scan_System() {
    for(int i=0; i<10; i++) { g_modes[i] = 0; g_versions[i] = 0; }
    // --- Index 0: OpenGL ---
    int glMaj = 0, glMin = 0;
    CheckOpenGL(&glMaj, &glMin);
    if (glMaj > 0) {
        g_modes[0] = 1;
        g_versions[0] = (glMaj * 100) + (glMin * 10); // e.g., 4.6 becomes 460
    }
    // --- Index 1: DX11 ---
    HMODULE hD3D11 = LoadLibraryA("d3d11.dll");
    if (hD3D11) {
        auto pD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(hD3D11, "D3D11CreateDevice");
        void* device = nullptr; int fl = 0;
        if (pD3D11CreateDevice && SUCCEEDED(pD3D11CreateDevice(NULL, 1, NULL, 0, NULL, 0, 7, &device, &fl, NULL))) {
            g_modes[1] = 1;
            g_versions[1] = fl;
        }
        FreeLibrary(hD3D11);
    }
    // --- Index 2: DX12 ---
    HMODULE hD3D12 = LoadLibraryA("d3d12.dll");
    if (hD3D12) {
        auto pD3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)GetProcAddress(hD3D12, "D3D12CreateDevice");
        void* device = nullptr;
        GUID iid_dx12 = {0x189819f1, 0x1db6, 0x4b5e, {0x85, 0x46, 0x7b, 0x8d, 0x1d, 0x6e, 0x8a, 0x1f}};
        if (pD3D12CreateDevice && SUCCEEDED(pD3D12CreateDevice(NULL, 0x3000, iid_dx12, &device))) {
            g_modes[2] = 1;
        }
        FreeLibrary(hD3D12);
    }
    // --- Index 3: Vulkan ---
    HMODULE hVK = LoadLibraryA("vulkan-1.dll");
    if (hVK) { g_modes[3] = 1; FreeLibrary(hVK); }
}
DLLEXPORT int GDK_Get_Mode_Supported(int index) {
    return (index >= 0 && index < 10) ? g_modes[index] : 0;
}
DLLEXPORT int GDK_Get_Version_Data(int index) {
    return (index >= 0 && index < 10) ? g_versions[index] : 0;
}
#endif

and then run this to see what (and to what degree) your system supports GL/Dx/Vulkan

Code: (Select All)
' Note the casing matches the file on disk exactly
DECLARE LIBRARY "GDK_PC_Info"
  SUB GDK_Scan_System ()
  FUNCTION GDK_Get_Mode_Supported% (BYVAL index AS LONG)
  FUNCTION GDK_Get_Version_Data% (BYVAL index AS LONG)
END DECLARE

CLS
PRINT "Scanning ATI/AMD Hardware..."
GDK_Scan_System

' Display Results

IF GDK_Get_Mode_Supported%(0) THEN
  PRINT "OpenGL: Supported (Version Data: "; GDK_Get_Version_Data%(0); ")"
END IF

IF GDK_Get_Mode_Supported%(1) THEN PRINT "DirectX 11: Supported"
IF GDK_Get_Mode_Supported%(2) THEN PRINT "DirectX 12: Supported"
IF GDK_Get_Mode_Supported%(5) THEN PRINT " -> Hardware RayTracing: ENABLED"
IF GDK_Get_Mode_Supported%(3) THEN PRINT "Vulkan: Supported (Driver Found)"

PRINT: PRINT "Scan Complete."

This is a "Dumbed down" rendition of how GDK gets the info to set it rendering mode.

Unseen
Reply
#2
Ok I try to follow you...
I copy and save the GDK_PC_Info.h in QB64pe43 folder
and then I make a subfolder Unseen and in this I save the second codebox with the name Test_Graphic_demo.bas.
And i got this error C++ compilation failed (check ./internal/temp/compilelog.txt)
and TADA here it is! 
but I am not able to understand why an internal header file can cause this error?

Code: (Select All)
g++  -no-pie -std=gnu++20 -fno-strict-aliasing -Wno-conversion-null -DFREEGLUT_STATIC -I./internal/c/libqb/include -I./internal/c/parts/core/freeglut/include -I./internal/c/parts/core/glew/include -DDEPENDENCY_NO_SOCKETS -DDEPENDENCY_NO_PRINTER -DDEPENDENCY_NO_ICON -DDEPENDENCY_NO_SCREENIMAGE internal/c/qbx.cpp -c -o internal/c/qbx.o
In file included from internal/c/../temp/regsf.txt:1,
                 from internal/c/qbx.cpp:592:
internal/c/../temp/../../GDK_PC_Info.h:3:10: fatal error: windows.h: No such file or directory
    3 | #include <windows.h>
      |          ^~~~~~~~~~~
compilation terminated.
make: *** [Makefile:421: internal/c/qbx.o] Error 1
maybe it can be useful as test of new version 4.3
Reply
#3
Because you are Linux user? Or not?


Reply
#4
Doesnt need the subfolder, just put the .h straight in to your qb64 folder. But as Petr says...if your on linux, this aint gonna work as it uses the windows API to get the information.

Thanks

John
Reply
#5
OK I have tried also without a folder... the same result.

Yeah thanks for replying on my procedure mistake!
I have assumed that the code was for all the OSes and not esclusive of Windows of Microsoft.
In my mind I have thought that windows.h was the header for a library of a windowing system, and not for Windows of Microsoft. LOL now I can say that C++ compiling error is a good result, here we are in DebianLinux.
.... only two things to add to this my post:

1. Thanks for replying @Petr, @Unseen

2. putting in the point of view of a BASIC coder, is there anywhere a library not relying on OS and getting the same results?

OpenGl and Vulkan are OS indipendent...
Reply
#6
@TempodiBasic

The main issue is whether the library was designed from the start with multi-platform support in mind.
On Windows, libraries (DLLs) typically depend on Windows internals and the Windows API, and they link against Windows system DLLs. On Linux, shared objects (.so) usually depend on other packages and system components that must be installed on the target system (often via the package manager). Each OS has its own runtime environment and binary formats, and they are not mutually compatible.
On top of that, there are 32-bit and 64-bit builds. That can affect things like structure layout/alignment, pointer sizes, and calling conventions / ABI details. So if the C/C++ code was written with these differences in mind (using proper abstraction layers, conditional compilation, and a stable API/ABI boundary), then yes: you can have one C/C++ codebase and build different binaries from it — e.g. a 32-bit DLL and a 64-bit DLL on Windows, and a 64-bit .so on Linux (32-bit Linux is largely being phased out today, so many projects no longer target it).
That said, for clarity and maintainability, platform-specific parts usually end up separated (at least in different source files), even if the project is “one library”.
Example why a single binary can’t just be “OS independent”: you want a graphics program. If it creates and manages a window on Windows, you call the Windows API. If it creates a window under Linux/X11, there is no Windows API — you use X11 (or Wayland, SDL, GLFW, etc.). Same OpenGL rendering on top, but the window/context creation layer is OS-specific.


Reply
#7
Hi
thanks Petr for the time and the patience for showing me where OS and Graphic card system (OpenGL or Vulkan ) meet to work together.
In the used way the QB64pe works via C/C++ fundaments and so it goes down towards the hardware and the way of managing it (specific OS features ).
I make a mistake to think of QB64pe like a ship over the sea (as other languages first Java), instead it must be thought as a submarine that must take front of all those things that are under the hood.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)