Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
GL_Screen
#1
Implementing a custom GL_Screen command that uses QB64’s existing internal variables while setting up a modern OpenGL context is the most efficient way to "bridge" your engine with the language. This allows you to keep QB64’s logic flow while taking full control of the rendering pipeline.

To do this, you need to "tap into" the internal state variables that QB64 already maintains.
1. Identify the Internal Global Variables
To make your GL_Screen command compatible, you must link it to these core C++ variables in the QB64 source (found in internal/c/qbx.cpp or internal/c/parts/video/gl_common.cpp):
hdc_global: The Windows Device Context handle for the current screen.
hglrc_global: The OpenGL Rendering Context handle.
canvas_w / canvas_h: Internal variables that track the virtual screen size.
window_w / window_h: Variables tracking the physical window size.
img_handle: QB64’s reference to the current active image (screen is usually handle 0).
2. The "Hack" Implementation
You can create a custom C++ function to serve as your GL_Screen command. Instead of using SCREEN 13, you would call this from your BASIC code.
C++ Source Injection (Add to a new header or qbx.cpp):
cpp

// This function mimics the internal 'sub_screen' but forces your modern context
__declspec(dllexport) void GL_Screen_New(int w, int h) {
    // 1. Let QB64 handle the window creation first so all variables are populated
    // We call the internal screen setup with a dummy mode
    static_sub_screen(w, h, 32);

    // 2. Now, hijack the context it just made
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(hglrc_global); // Destroy the 1.1 legacy context

    // 3. Create your modern compatibility context using your engine logic
    int attribs[] = {
        WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
        WGL_CONTEXT_MINOR_VERSION_ARB, 3,
        WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
        0
    };
    hglrc_global = wglCreateContextAttribsARB(hdc_global, 0, attribs);
    wglMakeCurrent(hdc_global, hglrc_global);

    // 4. Update the glewExperimental bit
    glewExperimental = GL_TRUE;
    glewInit();
    glGetError(); // Clear the mandatory error

    // 5. Sync your engine's Sys variables with QB64's internal canvas
    Sys.Scrn.wh.x = (float)w;
    Sys.Scrn.wh.y = (float)h;
}

3. Usage in BASIC
Once you have modified the source and rebuilt QB64, you can call it directly:
qbasic
DECLARE LIBRARY "engine_hack" ' Point to your modified internal lib
    SUB GL_Screen_New (BYVAL w AS LONG, BYVAL h AS LONG)
END DECLARE

' Instead of SCREEN 13, use your command:
GL_Screen_New 800, 600

' Because you linked to hdc_global/hglrc_global,
' some built-in logic might still work, but you now have:
' - OpenGL 3.3 Compatibility Profile
' - Working std::vectors in your C++ backend
' - Vulkan/DX ready context if you swap the wgl logic


4. Why this approach is better:
State Persistence: By updating hdc_global, you ensure that _DISPLAY and other windowing events (like resizing) still function correctly.
Legacy Fallback: Using the COMPATIBILITY_PROFILE_BIT_ARB allows you to still use glBegin/glEnd for simple debug shapes while using Shaders and VBOs for your main engine.
Variable Sync: Because you call static_sub_screen first, all of QB64's internal pointers for mouse tracking and keyboard input stay active. You are simply "swapping the engine" under the hood.
This is the exact method professional developers use to transfer OpenGL contexts to different window handles or hardware configurations in 2025.


SOOOOO...PLEASE MAKE IT HAPPEN GUYS or at least think about it or give me the nod and ill try though ive never actually modded the source!

John
Reply


Messages In This Thread
GL_Screen - by Unseen Machine - 12-21-2025, 06:48 AM
RE: GL_Screen - by SMcNeill - 12-21-2025, 09:22 AM
RE: GL_Screen - by Unseen Machine - 12-23-2025, 01:01 AM

Forum Jump:


Users browsing this thread: 1 Guest(s)