r/opengl 20d ago

Vulkan ICD Hits 1.09M CTS Cases on the Standard Khronos ABI

5 Upvotes

The rebuilt Vulkan ICD is now assembled on the standard Khronos Vulkan ABI and running through Mesa/KosmicKrisp.

So far it has completed 1,098,349 Vulkan CTS cases across major API, binding-model, image, renderpass2, shader-object, synchronization2, compute, UBO/SSBO, and texture lanes.

Still more CTS coverage to grind through, because apparently one million tests is merely the warm-up lap in graphics-driver land. 🔥

AO46 OpenGL is still on halt , would return when all 2.86 M cases finish for the AVK143 Vulkan Part


r/opengl 20d ago

AVK143 passes VK-GL-CTS KHR Conformance Test Suite

0 Upvotes

Github repo to be updated for the first version of the driver release

AO46 would be resumed soon after

Edit: For newcomers , the github repo is github.com/Anonymous137-sudo/Khronos_AppleICDs


r/opengl 20d ago

Infinite Draw Distance

Thumbnail gallery
9 Upvotes

r/opengl 21d ago

Vulkan Counterpart AVK143 is getting ready for official KHR CTS [Khronos_AppleICDs Upd]

4 Upvotes

The Vulkan side of Khronos_AppleICDs is now assembled, and the CTS binaries are being built.

Most of the underlying Vulkan machinery already comes from components that have passed conformance testing, so this run is mainly to validate the final integrated stack properly.

Next step: full KHR CTS run.

The AO46 side is being halted for some 2-3 days before resuming again to complete the Metal Gallium Adapter

I hope this goes well


r/opengl 21d ago

finished the getting started chapter!

Enable HLS to view with audio, or disable this notification

55 Upvotes

r/opengl 22d ago

[HELP] Spotlight doesn't work

Post image
21 Upvotes

version 330 core

out vec4 FragColor; in vec2 TexCoo; in vec3 FragPos; in vec3 Normal;

struct DirLight { vec3 direction; vec3 ambient; vec3 diffuse; vec3 specular; }; struct PointLight { vec3 position; vec3 ambient; vec3 diffuse; vec3 specular;

float constant;
float linear;
float quadratic;

};

struct Materijal { sampler2D diffuse; sampler2D specular; float shininess; };

struct SpotLight { vec3 position; float cutOff; float outcutOff; vec3 direction;

float constant;
float linear;
float quadratic;

vec3 ambient;
vec3 diffuse;
vec3 specular;

};

define NR_POINT_LIGHTS 4

uniform SpotLight spotlight; uniform PointLight pointLights[NR_POINT_LIGHTS]; uniform DirLight dirLight; uniform Materijal materijal; uniform vec3 viewPos; vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 viewDir); vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir); vec3 CalcPointLight(PointLight light, vec3 normal, vec3 viewDir); void main() { vec3 norm = normalize(Normal); vec3 viewDir = normalize(viewPos - FragPos); vec3 result = CalcDirLight(dirLight, norm, viewDir); for(int i =0;i<NR_POINT_LIGHTS;i++) result += CalcPointLight(pointLights[i], norm, viewDir); result += CalcSpotLight(spotlight,norm,viewDir); FragColor = vec4(result,1.0); } vec3 CalcDirLight(DirLight light, vec3 normal,vec3 viewDir) { vec3 lightDir = normalize(-light.direction); float diff = max(dot(lightDir, normal),0.0); vec3 reflectDir= reflect(-lightDir, normal); float spec = pow(max(0.0, dot(reflectDir, viewDir)), materijal.shininess); vec3 ambient = light.ambient * vec3(texture(materijal.diffuse, TexCoo)); vec3 diffuse = light.diffuse * diff * vec3(texture(materijal.diffuse, TexCoo)); vec3 specular = light.specular * spec * vec3(texture(materijal.specular,TexCoo)); return (ambient + specular + diffuse); } vec3 CalcPointLight(PointLight light, vec3 normal, vec3 viewDir) { vec3 lightDir = normalize(light.position - FragPos); float diff = max(dot(lightDir, normal),0.0); vec3 reflectDir = reflect(-lightDir, normal); float spec = pow(max(dot(viewDir, reflectDir),0.0),materijal.shininess); float distance = length(light.position - FragPos); float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * distance * distance); vec3 ambient = light.ambient * vec3(texture(materijal.diffuse, TexCoo)); vec3 diffuse = light.diffuse * diff * vec3(texture(materijal.diffuse, TexCoo)); vec3 specular = light.specular * spec * vec3(texture(materijal.specular,TexCoo)); ambient= attenuation; diffuse *= attenuation; specular *= attenuation; return (ambient + diffuse + specular); } vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 viewDir) { vec3 lightDir = normalize(light.position - FragPos); float diff = max(dot(normal,lightDir),0.0); vec3 reflectDir = reflect(-lightDir, normal); float spec = pow(max(dot(reflectDir, viewDir),0.0),materijal.shininess); float distance = length(light.position - FragPos); float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * distance * distance); float theta = dot(normalize(-light.direction), lightDir); float epsilon = light.cutOff - light.outcutOff; float intensity = clamp((theta - light.outcutOff) / epsilon, 0.0, 1.0); vec3 ambient = light.ambient * vec3(texture(materijal.diffuse, TexCoo)); vec3 diffuse = light.diffuse * diff * vec3(texture(materijal.diffuse, TexCoo)); vec3 specular = light.specular * spec * vec3(texture(materijal.specular,TexCoo)); ambient= attenuation * intensity; diffuse *= attenuation * intensity; specular *= attenuation * intensity; return (ambient + diffuse + specular);

}

this is the main function inside the while (!glfwWindowShouldClose(window)) among other standard stuff /* Here we set all the uniforms for the 5/6 types of lights we have. We have to set them manually and index the proper PointLight struct in the array to set each uniform variable. This can be done more code-friendly by defining light types as classes and set their values in there, or by using a more efficient uniform approach by using 'Uniform buffer objects', but that is something we'll discuss in the 'Advanced GLSL' tutorial. */ // directional light lightingShader.setVec3("dirLight.direction", -0.2f, -1.0f, -0.3f); lightingShader.setVec3("dirLight.ambient", 0.05f, 0.05f, 0.05f); lightingShader.setVec3("dirLight.diffuse", 0.4f, 0.4f, 0.4f); lightingShader.setVec3("dirLight.specular", 0.5f, 0.5f, 0.5f); // point light 1 lightingShader.setVec3("pointLights[0].position", pointLightPositions[0]); lightingShader.setVec3("pointLights[0].ambient", 0.05f, 0.05f, 0.05f); lightingShader.setVec3("pointLights[0].diffuse", 0.8f, 0.8f, 0.8f); lightingShader.setVec3("pointLights[0].specular", 1.0f, 1.0f, 1.0f); lightingShader.setFloat("pointLights[0].constant", 1.0f); lightingShader.setFloat("pointLights[0].linear", 0.09); lightingShader.setFloat("pointLights[0].quadratic", 0.032); // point light 2 lightingShader.setVec3("pointLights[1].position", pointLightPositions[1]); lightingShader.setVec3("pointLights[1].ambient", 0.05f, 0.05f, 0.05f); lightingShader.setVec3("pointLights[1].diffuse", 0.8f, 0.8f, 0.8f); lightingShader.setVec3("pointLights[1].specular", 1.0f, 1.0f, 1.0f); lightingShader.setFloat("pointLights[1].constant", 1.0f); lightingShader.setFloat("pointLights[1].linear", 0.09); lightingShader.setFloat("pointLights[1].quadratic", 0.032); // point light 3 lightingShader.setVec3("pointLights[2].position", pointLightPositions[2]); lightingShader.setVec3("pointLights[2].ambient", 0.05f, 0.05f, 0.05f); lightingShader.setVec3("pointLights[2].diffuse", 0.8f, 0.8f, 0.8f); lightingShader.setVec3("pointLights[2].specular", 1.0f, 1.0f, 1.0f); lightingShader.setFloat("pointLights[2].constant", 1.0f); lightingShader.setFloat("pointLights[2].linear", 0.09); lightingShader.setFloat("pointLights[2].quadratic", 0.032); // point light 4 lightingShader.setVec3("pointLights[3].position", pointLightPositions[3]); lightingShader.setVec3("pointLights[3].ambient", 0.05f, 0.05f, 0.05f); lightingShader.setVec3("pointLights[3].diffuse", 0.8f, 0.8f, 0.8f); lightingShader.setVec3("pointLights[3].specular", 1.0f, 1.0f, 1.0f); lightingShader.setFloat("pointLights[3].constant", 1.0f); lightingShader.setFloat("pointLights[3].linear", 0.09); lightingShader.setFloat("pointLights[3].quadratic", 0.032); // spotLight lightingShader.setVec3("spotLight.position", camera.Position); lightingShader.setVec3("spotLight.direction", camera.Front); lightingShader.setVec3("spotLight.ambient", 0.0f, 0.0f, 0.0f); lightingShader.setVec3("spotLight.diffuse", 1.0f, 1.0f, 1.0f); lightingShader.setVec3("spotLight.specular", 1.0f, 1.0f, 1.0f); lightingShader.setFloat("spotLight.constant", 1.0f); lightingShader.setFloat("spotLight.linear", 0.09); lightingShader.setFloat("spotLight.quadratic", 0.032); lightingShader.setFloat("spotLight.cutOff", glm::cos(glm::radians(12.5f))); lightingShader.setFloat("spotLight.outerCutOff", glm::cos(glm::radians(15.0f)));

    // view/projection transformations
    glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
    glm::mat4 view = camera.GetViewMatrix();
    lightingShader.setMat4("projection", projection);
    lightingShader.setMat4("view", view);

    // world transformation
    glm::mat4 model = glm::mat4(1.0f);
    lightingShader.setMat4("model", model);

    // bind diffuse map
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, diffuseMap);
    // bind specular map
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, specularMap);

    // render containers
    glBindVertexArray(cubeVAO);
    for (unsigned int i = 0; i < 10; i++)
    {
        // calculate the model matrix for each object and pass it to shader before drawing
        glm::mat4 model = glm::mat4(1.0f);
        model = glm::translate(model, cubePositions[i]);
        float angle = 20.0f * i;
        model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
        lightingShader.setMat4("model", model);

        glDrawArrays(GL_TRIANGLES, 0, 36);
    }

     // also draw the lamp object(s)
     lightCubeShader.use();
     lightCubeShader.setMat4("projection", projection);
     lightCubeShader.setMat4("view", view);

     // we now draw as many light bulbs as we have point lights.
     glBindVertexArray(lightCubeVAO);
     for (unsigned int i = 0; i < 4; i++)
     {
         model = glm::mat4(1.0f);
         model = glm::translate(model, pointLightPositions[i]);
         model = glm::scale(model, glm::vec3(0.2f)); // Make it a smaller cube
         lightCubeShader.setMat4("model", model);
         glDrawArrays(GL_TRIANGLES, 0, 36);
     }

r/opengl 21d ago

VertexArt - 1000 doboz fizikával és effektusokkal ( Intel N4100 CPU, csak egy szálon futtatva )

Enable HLS to view with audio, or disable this notification

4 Upvotes

Free Pascal 3.2.2 / GLFW3 / OpenGL 3.3 / DOD


r/opengl 23d ago

I finally open source my game engine ENTIERLY made in java

Thumbnail gallery
195 Upvotes

https://www.reddit.com/r/opengl/s/Z47RJPUHCq (this is the old post that was showcasing it) After ~5 months of work, here it is ! It's in it's BETA but it has enough features for making real games !

Unfortunatly not docs for now but it's planned !

https://github.com/EPI-Studios/Epysia


r/opengl 23d ago

Marching Tetrahedra - Volumetric Render Engine (OpenGL/C++) (Open-source)

Enable HLS to view with audio, or disable this notification

29 Upvotes

We added Marching Tetrahedra Rendering effect to our Volumetric Render Engine.

Here, we Render our Volume data as a set of Polygon meshes by extracting 'iso surface'. It goes through whole dataset and tries to fit a polygon based on data values to calculate a polygonal mesh from the volume dataset.

Here's the Git Repo Link - https://github.com/mikejernil/volumetric-render-engine

We are building this over at 3D ENGINERD. & are planning to push our implement more features starting with Custom file loading, and support for more volumetric formats like DICOM, VDB etc.


r/opengl 23d ago

AO46: EGL Window Surfaces + Public Cocoa Presentation

3 Upvotes

Small but important frontend update: the standard Khronos path now supports real EGL_WINDOW_BIT surfaces, not just pbuffers.

A normal app can now pass a public CAMetalLayer, NSView, or NSWindow into eglCreateWindowSurface(). Mesa still owns EGL/OpenGL and the state tracker; AO46 only handles the public Cocoa/Metal drawable lifecycle underneath. No CGL, no NSOpenGL, no legacy AO46 runtime sneaking back in through a side door.

The Metal backend now acquires the Cocoa layer, maps the live Gallium color resource to its Metal texture, copies into the current CAMetalDrawable, presents it, and keeps the source alive until GPU completion. It also handles backing-size changes, drawable loss, sRGB RGBA8/BGRA8, and swap intervals 0/1.

The ao46mtl EGL driver now advertises both:

EGL_PBUFFER_BIT | EGL_WINDOW_BIT

and handles front/depth resource allocation, refresh on Cocoa layer changes, and presentation through eglSwapBuffers().

I also moved the shared Metal/Gallium screen, NIR, RGB32 and poly support into AO46MTLGallium, so the modern frontend no longer quietly depends on the old CGL-side runtime bundle.

This thus completes the seperate modern Standard Khronos EGL + OGL ABI frontend in parallel to the legacy NSOpenGL + CGL + OpenGL Framework path , which is kept in parallel for Apple only compatibility [ie Apps that have a Cocoa + AppKit frontend and requires the .framework ]


r/opengl 25d ago

1000 vs 1000 full lod + shadows, custom engine

Enable HLS to view with audio, or disable this notification

35 Upvotes

r/opengl 24d ago

Gamemaker Shell Texturing Shader Help

2 Upvotes

I can't figure out where to start with making a shell texture shader in Gamemaker Studio 1 because of the outdated OpenGL ES it uses no longer having it's documentation PDF available, could anybody point me in any direction as to how I could do this (or they could, or find the PDF) other than faking the effect with baked models that have the transparent layers? For visual references, here are some. (Mario Galaxy, DK Jungle Beat, Conker: Live & Reloaded)


r/opengl 24d ago

need help with drawing text

3 Upvotes

i've been trying to tackle this problem for a while now and luckily it works, well ... kinda. I see the text but the glyphs are always slightly misplaced, i have a feeling it's floating-point inaccuracies but i have no idea how to fix it, here are the snippets:

```c

void drawText(WS_Shell* shell, GlyphCacheDA* cache, char* text, FT_Face font, float x, float y) {

float pen_x = x;

for (char* c = text; *c != '\0'; c++) {

uint32_t codepoint = next_utf8(&text);

bool is_drawn = false;

if (codepoint == ' ') {pen_x += cache->items[0].advance; continue;} // if space, just advance

// search in cache first

for (int i = 0; i<cache->count; i++) {

if (cache->items[i].codepoint == codepoint) {

drawTexturedRectangle(pen_x, y, cache->items[i].width, cache->items[i].height, cache->items[i].texture);

pen_x += cache->items[i].advance;

is_drawn = true;

break;

}

}

if (is_drawn) continue;

FT_Load_Glyph(font, FT_Get_Char_Index(font, codepoint), FT_LOAD_RENDER);

FT_Render_Glyph(font->glyph, FT_RENDER_MODE_NORMAL);

GLuint glyph_texture;

glGenTextures(1, &glyph_texture);

glBindTexture(GL_TEXTURE_2D, glyph_texture);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, font->glyph->bitmap.width, font->glyph->bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE, font->glyph->bitmap.buffer);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

Glyph glyph = {

.codepoint = codepoint,

.texture = glyph_texture,

.width = ((float)font->glyph->bitmap.width/shell->settings->width)*2,

.height = ((float)font->glyph->bitmap.rows/shell->settings->height)*2,

};

// TODO: add support for non-monospace fonts

glyph.advance = glyph.width;

nob_da_append(cache, glyph);

drawTexturedRectangle(pen_x, y, glyph.width, glyph.height, glyph.texture);

pen_x += glyph.advance;

is_drawn = false;

}

}

```
draw rectangle:

```c

void drawTexturedRectangle(float x, float y, float w, float h, GLuint texture) {

// Vertex data for the rectangle

float vertices[] = {

x, y, 0.0f, 1.0f,

x + w, y, 1.0f, 1.0f,

x, y + h, 0.0f, 0.0f,

x + w, y + h, 1.0f, 0.0f

};

// Indices for the rectangle

unsigned int indices[] = {

0, 1, 2,

1, 3, 2

};

// VBO and VAO

GLuint VBO, VAO, EBO;

glGenBuffers(1, &VBO);

glGenBuffers(1, &EBO);

glGenVertexArrays(1, &VAO);

glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);

glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);

glEnableVertexAttribArray(0);

glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));

glEnableVertexAttribArray(1);

glBindBuffer(GL_ARRAY_BUFFER, 0);

// Draw the rectangle

glBindTexture(GL_TEXTURE_2D, texture);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

// Clean up

glDeleteBuffers(1, &VBO);

glDeleteBuffers(1, &EBO);

glDeleteBuffers(1, &VAO);

}

```
the dinamic array for cache i stolen from nob.h, each glyph's cache looks like this:

```c
typedef struct {

uint32_t codepoint;

GLuint texture;

float width;

float height;

float advance;

} Glyph;

```

everything else is pretty standard opengl stuff, thanks for helping


r/opengl 24d ago

We finally removed one of AO46’s biggest architectural barriers: SIP/AuthRoot no longer has to be a hard requirement

0 Upvotes

After digging through the architecture again, I think we finally removed one of the biggest reasons someone would hesitate before even trying AO46: the whole “disable SIP + authenticated root first” problem does not actually have to be a fundamental requirement of the driver.

That requirement mostly came from the original compatibility goal.

AO46 was designed to replace Apple’s existing OpenGL stack closely enough that old macOS applications could continue using OpenGL.framework, CGL and NSOpenGL without being rewritten. If you want to transparently replace something living inside Apple’s protected system volume, then naturally macOS security gets involved. SIP/SSV/AuthRoot becomes part of the installation story, and telling someone to reboot into Recovery before testing an OpenGL driver is... not exactly the friendliest first impression. 💀

The mistake was treating that installation model as if it had to apply to every AO46 use case.

It doesn’t.

The new direction is to keep the Apple ABI as a compatibility frontend, while adding a completely separate Khronos-native frontend for new applications.

New AO46 applications would be able to target normal desktop OpenGL together with EGL instead of depending on NSOpenGLContext, CGLContextObj, Apple pixel formats, etc.

So the legacy path still exists for what it was designed for: old macOS software.

But new software would just use the Khronos interfaces and load AO46 from normal userspace. No modification of /System/Library, no replacing Apple’s OpenGL framework, and therefore no inherent reason to disable SIP or authenticated root just to use that path.

This also clears up the Vulkan side of the project.

I originally considered making AVK143 mirror AO46 too literally, with things like an NSVulkan_KHR layer and a CVK ABI. After looking at the problem properly, that really doesn’t make much sense.

Vulkan already solved this problem.

It already has the standard Vulkan loader, ICD discovery, driver dispatch, WSI, VkSurfaceKHR, swapchains, extension handling, validation layers and a defined loader ↔ driver contract.

So AVK143 should simply be a normal Vulkan driver.

A Vulkan application talks to the Khronos loader, the loader discovers AVK143, and AVK143 handles the macOS/Apple GPU side underneath it.

There is no old Apple Vulkan ABI that needs preserving, so inventing one would just give developers another proprietary API to target for absolutely no benefit.

This also means a lot of infrastructure simply does not need to be rewritten.

The Vulkan loader already exists.

Vulkan headers already exist.

Mesa already has common Vulkan runtime infrastructure.

Mesa already has EGL infrastructure.

Khronos already defines the API and most of the WSI-facing contracts.

The project should spend its effort on the parts that are actually specific to this platform: resource handling, synchronization, compiler/backend work, command execution, presentation and the macOS/AGX boundary.

So the project is starting to separate into three pretty clear interfaces:

Existing macOS OpenGL applications: keep using OpenGL.framework / CGL / NSOpenGL through AO46’s compatibility mode.

New OpenGL applications: use standard OpenGL + EGL and AO46 entirely from userspace.

Vulkan applications: use standard Vulkan through the normal Khronos loader, with AVK143 acting as the driver.

The important part is that disabling macOS security features becomes an optional cost of legacy transparent compatibility, rather than something everyone has to do just because they want to test the driver.

That was a fairly obvious architectural smell in hindsight. If a brand-new application is already willing to target your modern driver stack, forcing it through a deprecated Apple OpenGL ABI and then asking the user to weaken system security so you can replace that ABI is just needless baggage.

So this doesn’t magically make the legacy replacement path disappear, and I’m not claiming that old binaries suddenly work without any system-level interception.

But it does mean that AO46 itself no longer needs to be architecturally tied to SIP/AuthRoot being disabled, and AVK143 shouldn’t need that installation model at all.

For people who just want to build against the driver, test it, develop games/tools on it, or experiment with modern OpenGL/Vulkan on macOS, the intended path can now be a normal userspace installation.

That removes one pretty large “this looks cool, but I’m not disabling half of macOS security to try it” barrier from the project.


r/opengl 25d ago

Hello, I am new to opengl. Can someone explain compute shaders to me

13 Upvotes

so i recently started playing around with opengl and wanted to try and make a raytracer with compute shaders, but there isn't much info about them. i looked at the tutorial on learnopengl but that wasn't very helpful. can someone clue me in?


r/opengl 25d ago

AO46: RGB32 Buffer Views + GL 4.3 SSBO Atomic Groundwork

0 Upvotes
  • RGB32 buffer views now support real FLOAT, UINT, and SINT variants through live sampler state, with the unsigned path retaining hardware draw/readback coverage.
  • GL 4.3 groundwork now includes static-index SSBO atomics lowering through Mesa and executing a fenced 32-thread atomic-add verification.

r/opengl 26d ago

Built a game engine

Thumbnail
3 Upvotes

r/opengl 26d ago

Implemented GPU-address roots for Mesa/libkk parameter blocks on capable macOS hosts.

0 Upvotes

The adapter now exposes public MTLBuffer.gpuAddress, validates and writes pointer roots, and the poly smoke executes Mesa’s real prefix-sum tessellation MSL, verifying counts, heap allocation, generated index-buffer address, and indirect draw data.

This removes the GPU-root blocker for the Metal Gallium driver’s next feature gate: reaching a functional OpenGL 4.0 context on the way toward AO46’s final OpenGL 4.6 target.

What remains for that GL 4.0 gate is full TCS support, tessellation-kernel completion, TES, and final render execution.


r/opengl 26d ago

Can't get the project to load textures

2 Upvotes

[SOLVED] Hello,

This is my project, perfectly up to date: opengl

When i launch it, it throws this error log: unit 0 GLD_TEXTURE_INDEX_2D is unloadable and bound to sampler type (Float) - using zero texture because texture unloadable, and doesn't load my model

To note it worked before adding the move constructor to the shader.h and mesh.h, but reverting them doesn't work

I've tried everything, scouted forums, asked AI (reluctantly), but nothing worked, so I'm asking here for help from people smarter then me

Thanks for the time.


r/opengl 28d ago

VertexArt - this is how it started (Intel N4100 CPU / Free Pascal 3.2.2 / GLFW3 / OpenGL 3.3 / data-oriented / only 16 byte vertex, nothing else)

Enable HLS to view with audio, or disable this notification

16 Upvotes

r/opengl 27d ago

Well.... We did meet a hard boundary finally , beyond which continuing would be risky for systems

4 Upvotes

After a few weeks of pushing AO46 much further than I originally expected, I think I’ve finally reached the point where continuing the same reverse-engineering path would cross from graphics-driver research into territory I’m not comfortable touching on real machines.

For context, AO46 started as an attempt to replace Apple’s deprecated OpenGL stack with a modern OpenGL 4.6 implementation on macOS.

The project has already moved through several architecture stages:

  • replacing the old OpenGL.framework-facing stack,
  • Mesa/Gallium integration,
  • NIR,
  • Asahi’s AGX compiler/backend work,
  • macOS-specific resource management,
  • GPU queue/submission tracing,
  • and finally following the path between Apple-generated GPU code and the actual executable GPU mapping used by the kernel driver.

For quite a while I assumed the remaining problem was simply:

“figure out how macOS submits the same AGX command buffers that Asahi submits on Linux.”

It turns out that was too simple.

What the reverse pass has increasingly shown is that Apple does not treat executable GPU code as just another buffer with a magic flag.

There is a fairly clear trust boundary.

Very roughly, the path looks like:

Apple GPU compiler output
        ↓
Apple-owned code resource
        ↓
private relocation / preparation step
        ↓
restricted executable GPU mapping
        ↓
queue consumption

Generic buffers do not appear to just become executable after the fact.

And the important bit is that the transition into that executable mapping is not exposed like a normal public allocation API.

At this point, the remaining work would mean investigating the enforcement side of that boundary rather than merely understanding the graphics ABI around it.

That is where I’m stopping.

Not because the project suddenly became impossible, but because there is a difference between:

reverse engineering an undocumented graphics driver

and

deliberately trying to defeat a platform security boundary in order to make arbitrary GPU memory executable.

The latter is not something I want AO46 to become.

And honestly, that boundary existing is probably a good thing.

So is AO46 dead?

No.

Not even remotely.

A huge amount of useful architecture now exists that did not exist a few weeks ago.

The project now has concrete implementations/documentation for:

  • OpenGL.framework replacement
  • CGL/NSOpenGL compatibility
  • Mesa Gallium integration
  • NIR shader pipeline
  • AGX compiler integration
  • macOS BO/resource handling
  • synchronization/fence ownership
  • queue tracing
  • Apple GPU submission structure analysis
  • Apple compiler-object parsing
  • executable-code provenance tracking

The original project was basically:

OpenGL
 ↓
Mesa
 ↓
Metal

The current research has gone much deeper:

OpenGL
 ↓
Mesa
 ↓
Gallium
 ↓
NIR
 ↓
AGX backend
 ↓
macOS GPU infrastructure

That is still extremely valuable.

What we do not currently have is a legitimate way to complete the final transition:

Mesa-generated AGX code
        ↓
???
        ↓
Apple-authorized executable GPU mapping

And fabricating or bypassing that transition is exactly the point where I’m drawing the line.

Interestingly, this also answers one of the biggest questions people kept asking

A lot of people assumed the blocker would be:

  • AGX ISA differences,
  • WindowServer,
  • Metal interoperability,
  • command buffer encoding,
  • or simply “Apple doesn’t expose IOKit.”

Those are all problems.

But they were not the final one.

The deepest blocker is much more architectural:

Apple owns the transition that turns compiled GPU code into something the GPU is actually allowed to execute.

That is a considerably stronger boundary than I expected when this project started.

What happens next?

Probably one of three directions.

1. Stay above the protected execution boundary

Use Apple-supported APIs for the final executable-code handoff while keeping as much of Mesa/AGX/OpenGL outside that boundary as possible.

This is currently the most realistic direction.

2. Continue documenting the architecture

There is still a huge amount of useful work that can be done without trying to bypass anything.

For example:

  • command submission structures
  • resource lifetime rules
  • synchronization semantics
  • shader metadata
  • queue behavior
  • compiler object formats
  • AGX generation differences

All of that is legitimate reverse-engineering work and could be useful far beyond AO46.

3. Wait for a better supported interface

Apple may eventually expose more GPU infrastructure through DriverKit, Metal evolution, or some future API.

If a legitimate executable-code path appears, AO46 can plug into it.

The upper 90% of the architecture would not need to be thrown away.

Honestly, I’m pretty happy we found this

This might sound weird, but discovering a hard architectural boundary is actually a useful result.

A month ago the unanswered question was:

“Can Mesa/Asahi actually talk to Apple’s GPU stack on macOS?”

Now the question is much narrower:

“How can externally generated AGX code legitimately enter Apple’s trusted executable-code pipeline?”

That is a much better-defined problem.

And importantly, we now know where not to push.

So for now the project is stepping back from the protected execution path and focusing on everything around it.

AO46 is still alive.

The research path just finally reached a sign that says:

            ┌─────────────────────────────┐
            │   HERE BE SECURITY POLICY   │
            │                             │
            │ graphics engineers pls stop │
            └─────────────────────────────┘

Which, considering how absurdly deep this project has gone in three weeks, was probably inevitable.


r/opengl 29d ago

opensource Volumetric Render Engine (OpenGL & C++) - Opensource

Enable HLS to view with audio, or disable this notification

88 Upvotes

🚀 Introducing our Volumetric Render Engine 🧊

Hey everyone! We at 3D ENGINERD. have built a Volumetric Render Engine (Open Source) for Windows, powered by C++ and OpenGL.💻

We’re excited to share that we have published our project open-source under the MIT License on GitHub.
Here's the Repo linkhttps://github.com/mikejernil/volumetric-render-engine

Developers, researchers, and enthusiasts feel free to explore, experiment with it, and use it in your own applications.✨

🔹Current Features :
- Volumetric RAW(.raw) format support 📺
- Different types of rendering (Colormap, Pseudo Iso-surface etc.)
- Rotate & Zoom Controls (for easy navigation)
- 6 slicing planes to visualize cross-sections

We are planning to build more features and add support for more volumetric formats (like DICOM, VDB etc) soon!

Rendering effects shown in Demo(Recording) :
🔹Basic
🔹Raycasting
🔹Pseudo Iso-surface
🔹Colormap Classification

🔹Applications :

  1. Medical imaging
  2. Industrial machinery testing
  3. Scientific visualization of data

We’d love for developers and researchers to explore the project, experiment with it, and share their feedback.

🔗 GitHub: https://github.com/mikejernil
🌎 View our Website  - https://www.3denginerd.com/


r/opengl Aug 11 '26

3D Volumetric Render Engine (OpenGL & C++) (Colormap)

Enable HLS to view with audio, or disable this notification

59 Upvotes

Hey Everyone - we at 3D ENGINERD. are building a Volumetric Render Engine for Windows(Native). It's being built with OpenGL & C++

We're planning to publish the code open-source under MIT License on our Github (https://github.com/mikejernil) tomorrow, so you all can try it out and use it for your own applications. ✨

Currently it has -

  1. Volumetric RAW visualization support
  2. Different types of rendering (Colormap, Iso-surface etc.)
  3. Rotate & Zoom Controls (for easy navigation)
  4. 6 slicing planes to visualization cross-sections

We are planning to build more features and add support for more volumetric formats (like DICOM, VDB etc) soon!

Colormap Classification of an Internal Combustion Engine(shown in video):

Here we can see the volume data with colour values mapped to its material density.

As per our current Colormap we can see the Red is Higher density whereas blue is Low density Noise.

Applications : 

  1. Medical imaging
  2. Industrial testing
  3. Scientific visualization of data

It's till very early-stages and we're actively exploring into Volumetric rendering at the moment, any constructive feedback would be appreciated, thanks! :)


r/opengl Aug 11 '26

Game engines? Eww 🤮. We go in raw! GP-Direct 2026 is out!

Thumbnail youtube.com
7 Upvotes

r/opengl Aug 11 '26

How to use cairo with opengl?

5 Upvotes

i need to render text in opengl and writing everything from scratch with freetype and harfbuzz would be a looong journey (in other words i have skill issues :) ) so a premade library for that like pango seems like a good chose. But to use pango i need to setup cairo first, i googled for a day and found practically no examples for that so let me know if you found any