Skip to content

OpenGLES 3.1 - #8533

Open
danoli3 wants to merge 47 commits into
openframeworks:masterfrom
danoli3:OpenGLES3.1
Open

danoli3 wants to merge 47 commits into
openframeworks:masterfrom
danoli3:OpenGLES3.1

Conversation

@danoli3

@danoli3 danoli3 commented Aug 11, 2026 •

Copy link
Copy Markdown
Member

OpenGLES 3.1

Updated PR to #8512
Merged in @mruegenberg changes and patched them into the core.
Support for openGLES 3.0
Support for openGLES 3.1
Fixed up Emscripten defines to allow for ES3
This feature allows for emulation more easily in Dawn / Emscripten / Metal / Vulkan for Mobile platforms for ES
Merged with Tess2 fixes. Auto Short / Int determination (less defines)

TODO:

  • Review Code changes
  • Smoke Test on iOS / Android / Emscripten
  • OpenGL ES 1 compatibility
  • OpenGL ES 2 compatibility
  • OpenGL compatibility
  • Simulator Test on iOS / Android
  • Device Test on iOS / Android

@danoli3

danoli3 commented Aug 13, 2026

Copy link
Copy Markdown
Member Author

Smoke tests on GL failing will investigate

@danoli3

danoli3 commented Sep 12, 2026

Copy link
Copy Markdown
Member Author

This is almost complete just to do physical device tests

danoli3 added 20 commits October 5, 2026 15:07
# Conflicts:
#	libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp
The shared test always called drawInstanced, which is not in ES1/ES2 or
GL 2.1, and the programmable GLES path never instanced even on ES3
(gated on 3.1, and ofVboMesh ignored primCount). Skip instancing unless
the live context is GL 3.1+ / ES 3.0+, match VBO index type to
ofIndexType on GLES, report WebGL2 as GLES 3, and give the Android
lifecycle test ES2 shaders / an ES1 no-shader path.
- ofGraphics/ofGLRenderer: revert background-gradient relocation that
  used ofVboMesh without its header and dropped the renderer's
  drawBackgroundGradient definition (broke every build + link)
- ofGraphics: revert illegal static_cast to ofBaseGLRenderer in
  ofEnable/DisablePointSprites, virtual dispatch already covers it
- ofAppEGLWindow: rename glesVersion member to glesVersionMajor to
  match ofAppEGLWindow.cpp usage
- ofAppAndroidWindow: drop dead overwrite of glesVersion from legacy
  field so settings getters take effect, init glesVersionMinor
- ofxEmscriptenURLFileLoader: restore lowercase __EMSCRIPTEN_major__/
  __EMSCRIPTEN_minor__ macros (uppercase form is never defined)
- ofTexture: restore GL_TEXTURE_CUBE_MAP mipmap case on desktop,
  align bindAsImage cpp guard with header
- ofConstants: make GLES3 includes live (unconditional on Linux ARM
  and Emscripten, API-gated on Android) so TARGET_OPENGLES_3
  auto-detection actually works
- ofFbo::readToPixels: GLES has no glGetTexImage (ES 1/2/3), so the ES 3
  branch returned empty pixels; read the bound FBO with glReadPixels on all
  GLES again, selecting the attachment with glReadBuffer on ES 3 contexts.
- ofGLProgrammableRenderer::draw(ofMesh) on ES: line modes use the lines
  shader, which needs the line bundle; raw client arrays made
  GL_LINE_STRIP / GL_LINE_LOOP (circle and polyline outlines) collapse to
  nothing. Build the bundle like desktop (ofSetLineWidth works on ES again).
- ofFbo::allocate(w, h, format): keep colour-only on ES; the combined
  depth+stencil renderbuffer was FRAMEBUFFER_INCOMPLETE_ATTACHMENT.
- TARGET_OPENGLES_3 only means the ES 3 headers exist, which is true on iOS
  even for ES 1 / ES 2 contexts. Add ofIsGLES3Context() (headers + live
  context >= 3) and use it for sized RGBA8 / RGB8 internal formats (ES 2
  rejects them with GL_INVALID_OPERATION); ofFbo::checkGLSupport accepts
  GL_OES_framebuffer_object for ES 1.1 contexts.
@danoli3

danoli3 commented Oct 6, 2026

Copy link
Copy Markdown
Member Author

Rebased on master + GLES fixes + GL / GLES test matrix

Rebased onto current master (46 commits, no conflicts; emsdk stays 6.0.11). The previous msys2 failures were the CI mirror/fail-fast issue fixed on master (#8566 / #8568), not this PR.

New commit b226140 — fixes for regressions found while testing ES 1.1 / 2.0 / 3.0 on the iOS Simulator (before it, every iOS ES version failed and unfilled circles/polylines were invisible on ES):

# Problem Fix
1 ofFbo::readToPixels returned no pixels on ES 3: it called ofTexture::readToPixels, which is compiled out on GLES (no glGetTexImage in any ES) glReadPixels on all GLES again (as on master), with glReadBuffer for the attachment on ES 3 contexts
2 Circle / polyline outlines missing on ES: line modes use the lines shader, but the new ES client-array path never built the line bundle, so GL_LINE_STRIP / GL_LINE_LOOP collapsed to nothing ES line modes build the bundle like desktop (also brings back ofSetLineWidth on ES)
3 ofFbo::allocate(w, h, fmt) defaulted to depth+stencil on ES → FRAMEBUFFER_INCOMPLETE_ATTACHMENT colour-only default on ES, as on master (ofFboSettings still requests depth/stencil)
4 TARGET_OPENGLES_3 is a compile-time header check, true on iOS even for ES 1 / ES 2 contexts → ES 2 textures got GL_RGBA8 (GL_INVALID_OPERATION), ES 1.1 FBOs reported "not supported" new ofIsGLES3Context() (headers and live context ≥ 3) for the sized internal formats; ofFbo::checkGLSupport also accepts GL_OES_framebuffer_object

Note: the remaining ~75 TARGET_OPENGLES_3 compile-time branches (ofFbo MSAA/draw buffers, ofShader, ofBufferObject, …) have the same ES1/ES2-runtime caveat; I only switched the ones the tests hit. Worth a follow-up pass with ofIsGLES3Context().

Test matrix

Test app = graphicsExample's scene + the PR's GLSmokeTestCore + extra checks, version picked at launch. Built against the latest Apothecary libraries (macOS / iOS / emscripten / Android downloaded fresh).

Checks: context (renderer set up at the requested version) · texture upload → draw into FBO → readback colour · shader compile/link/draw → readback (programmable only) · smoke (indexed ofVboMesh, tess2 ofPath, FBO readback, instancing where available) · screen readback of graphicsExample's circle · tess2 star (index type matches ofIndexType + star arm pixels) · no GL errors

Platform Requested Context reported Renderer Context Texture Shader Smoke Screen tess2 star GL errors Result
macOS (M1 Max) GL 2.1 2.1 Metal - 90.5 ofGLRenderer (fixed) ✅ ✅ n/a ✅ ✅ ✅ ✅ PASS
macOS GL 3.2 core 4.1 Metal - 90.5 ofGLProgrammableRenderer ✅ ✅ ✅ ✅ ✅ ✅ ✅ PASS
macOS GL 3.3 core 4.1 Metal - 90.5 ofGLProgrammableRenderer ✅ ✅ ✅ ✅ ✅ ✅ ✅ PASS
macOS GL 4.0 core 4.1 Metal - 90.5 ofGLProgrammableRenderer ✅ ✅ ✅ ✅ ✅ ✅ ✅ PASS
macOS GL 4.1 core 4.1 Metal - 90.5 ofGLProgrammableRenderer ✅ ✅ ✅ ✅ ✅ ✅ ✅ PASS
iOS 26.5 Sim (iPhone 17 Pro) ES 1.1 OpenGL ES-CM 1.1 APPLE-23.1.1 ofGLRenderer (fixed) ✅ ✅ n/a ✅ ✅ ✅ ✅ PASS
iOS 26.5 Sim ES 2.0 OpenGL ES 2.0 APPLE-23.1.1 ofGLProgrammableRenderer ✅ ✅ ✅ ✅ ✅ ✅ ✅ PASS
iOS 26.5 Sim ES 3.0 OpenGL ES 3.0 APPLE-23.1.1 ofGLProgrammableRenderer ✅ ✅ ✅ ✅ ✅ ✅ ✅ PASS

macOS tops out at GL 4.1 (any 3.2+ core request returns 4.1); GL 4.2+ needs Linux/Windows. Android emulator (ES 1.1 / 2.0 / 3.0 / 3.1) and emscripten (WebGL 1 / 2) runs to follow.

Also found: with older downloaded libs, ofPath fills drew a single triangle on macOS — tess2's tesselator.h used defined(TARGET_OS_IPHONE) (true on macOS), so oF read tess2's 32-bit indices as 16-bit. Current Apothecary latest already fixes the header; the new tess2 star check catches it.

Screenshots

macOS — GL 2.1 (fixed function)
macOS GL 2.1

macOS — GL 3.2 core
macOS GL 3.2

macOS — GL 3.3 / 4.0 / 4.1 core

macOS GL 3.3
macOS GL 4.0
macOS GL 4.1

iOS Simulator — ES 1.1 (fixed function)
iOS ES 1.1

iOS Simulator — ES 2.0
iOS ES 2.0

iOS Simulator — ES 3.0
iOS ES 3.0

@danoli3

danoli3 commented Oct 6, 2026

Copy link
Copy Markdown
Member Author

This is looking great! Getting Qwen 3.8 local ai to test and analyse everything and doing test qa passes

danoli3 added a commit to danoli3/openFrameworks that referenced this pull request Oct 6, 2026
@danoli3

danoli3 commented Oct 6, 2026

Copy link
Copy Markdown
Member Author

Emscripten results (WebGL 1 / WebGL 2)

Same test app (graphicsExample scene + GLSmokeTestCore + extra checks) built with emsdk 6.0.11 (matches CI) against the latest Apothecary emscripten libs, at b226140. No further code changes were needed — both pass with the fixes already in this PR.

Run in headless Chrome on the real GPU (--use-angle=metal), driven over CDP; the result line is read from the page and the browser's own WebGL context type / renderer are recorded as a cross-check.

Platform Requested Context reported (oF) Browser context GPU Context Texture Shader Smoke Screen tess2 star GL errors Result
Chrome / emscripten WebGL 2 (ES 3.0) OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) webgl2 ANGLE Metal, Apple M1 Max ✅ ✅ ✅ ✅ ✅ ✅ ✅ PASS
Chrome / emscripten, --disable-webgl2 WebGL 1 (ES 2.0) OpenGL ES 2.0 (WebGL 1.0 (OpenGL ES 2.0 Chromium)) webgl1 ANGLE Metal, Apple M1 Max ✅ ✅ ✅ ✅ ✅ ✅ ✅ PASS

Note: ofxAppEmscriptenWindow::setup ignores settings.glesVersion — it always tries WebGL 2 and falls back to WebGL 1 if that fails. So WebGL 1 was tested through that fallback (WebGL 2 disabled in the browser), which is what users without WebGL 2 get. Honouring an explicit setGLESVersion(2) would be possible, but the ofGLESWindowSettings default is glesVersion = 1, so it would need a "not set" state first.

Running total: macOS GL 2.1 / 3.2 / 3.3 / 4.0 / 4.1, iOS Simulator ES 1.1 / 2.0 / 3.0, emscripten WebGL 1 / 2 — all PASS. Android emulator (ES 1.1 / 2.0 / 3.0 / 3.1) next.

Screenshots

Emscripten — WebGL 2 (ES 3.0)
emscripten WebGL 2

Emscripten — WebGL 1 (ES 2.0, fallback)
emscripten WebGL 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

1 participant