Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
7ed5116
Android: sync NDK / API / build-tools with apothecary
danoli3 Oct 8, 2026
89c8722
Enable new functionality of GL ES 2/3/3.1 via ifdefs
Sep 6, 2015
404d66a
Android Studio 1.3/1.4 compatibility, and a fix.
Sep 6, 2015
eeb9904
Get an OpenGL ES 3.1 context if possible.
Sep 8, 2015
9f33aec
Fixes.
Sep 8, 2015
5ebc21d
Misc fixes
Sep 12, 2015
b251b07
Minor fixes when using GLES1.
Sep 17, 2015
7a872a1
More consistent API.
Sep 17, 2015
162fd75
Update EGL window class to use new GLES settings class.
Sep 17, 2015
280fd3a
Fixed problem with broken textures.
Sep 18, 2015
41095c9
Smaller fixes
Sep 30, 2015
7993cbd
.
Sep 30, 2015
b160e2d
Remove old android changes
danoli3 Apr 6, 2026
b5054cd
ofImageType
danoli3 Apr 7, 2026
ca31214
ofGLRenderer
danoli3 Apr 7, 2026
1a274a2
ofGLUtils fix
danoli3 Apr 7, 2026
06131c3
Update ofAppEGLWindow.cpp
danoli3 Apr 7, 2026
4036981
OpenGLES 3 changes for ofFbo and ofGLProgrammableRenderer
danoli3 Apr 7, 2026
a1d81d2
Refactor GLES version variables in ofGLESWindowSettings
danoli3 Apr 7, 2026
ddcbae7
OpenGLES 3.0 and Emscripten
danoli3 Apr 7, 2026
fd58215
ofBufferObject OpenGLES 3 fixes
danoli3 Apr 8, 2026
376c70b
ofVbo and ofFbo OpenGLES 3 fixes
danoli3 Apr 8, 2026
a915d4d
ofWindowSettings fix for scope
danoli3 Apr 8, 2026
6f9c643
OpenGLES 3 fixes for ofGLProgrammableRenderer and BaseTypes
danoli3 Apr 8, 2026
011f9ac
OpenGLES 3
danoli3 Apr 8, 2026
d72c343
OpenGLES fixes
danoli3 Apr 8, 2026
d225da3
OpenGLES shader defaults fixed
danoli3 Apr 8, 2026
c037a06
ofMaterial fixes
danoli3 Apr 8, 2026
62afadd
Android Window
danoli3 Apr 8, 2026
95ce6c2
ofAppAndroidWindow Fix
danoli3 Apr 8, 2026
45a2bad
ofAppAndroidWindow
danoli3 Apr 8, 2026
54c70cc
Android Window
danoli3 Apr 8, 2026
49c4579
ofGLUtils Android Fix
danoli3 Apr 8, 2026
faba773
OpenGLES 3.0
danoli3 Aug 11, 2026
f8f860f
ofWindowSettings with hidpi c++ default cpy ctor
danoli3 Apr 9, 2026
2c83b8a
OpenGLES defines with targetable undefs in ofConstants
danoli3 Apr 9, 2026
88cbac0
ofMesh Mode to Triangles on init
danoli3 Apr 9, 2026
2cf731d
ofShader Fix
danoli3 Apr 9, 2026
b40aab5
OpenGL fixes
danoli3 Apr 9, 2026
42c5259
Update Emscripten to 6.0.6
danoli3 Aug 6, 2026
65c85dd
Fix client-side mesh indices on OpenGL ES 2
danoli3 Aug 6, 2026
287ab2c
Restore line topology for ofMesh axis
danoli3 Aug 6, 2026
57e4d94
Guard desktop buffer invalidation on OpenGL ES
danoli3 Aug 6, 2026
fd2d809
Android View null fix
danoli3 Aug 6, 2026
f04d58f
Add Android GLES lifecycle hardware stress test
danoli3 Aug 6, 2026
7ddef8e
Make GL smoke tests safe on ES1, ES2, ES3 and desktop OpenGL
danoli3 Sep 12, 2026
593ebe6
Fix PR compile failures across all CI platforms
danoli3 Sep 28, 2026
c61cc40
Fix GLES regressions found testing ES 1.1 / 2.0 / 3.0 on iOS
danoli3 Oct 6, 2026
9aa7d7b
ofFbo: only accept GL_OES_framebuffer_object for ES 1.1 on iOS
danoli3 Oct 8, 2026
0870ca0
Fix GL_INVALID_ENUM on ES 1 / ES 2 contexts
danoli3 Oct 8, 2026
2f2fbff
Android ES 1.1: OES framebuffer entry points, disabled on the emulator
danoli3 Oct 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/of.yml
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,10 @@ jobs:
TARGET: ${{ matrix.cfg.target }}
ARCH: ${{ matrix.cfg.opt }}
ANDROID_SDK_ROOT: $ANDROID_HOME
ANDROID_NDK_ROOT: $ANDROID_NDK_LATEST_HOME
# keep in sync with apothecary build-android.yml (NDK r29, min API 25);
# cmake.sh resolves $ANDROID_HOME/ndk/$NDK, gradle uses ndkVersion
NDK: "29.0.14206865"
ANDROID_API: "25"

steps:
- name: checkout openFrameworks
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,14 +273,14 @@ public static void onResume(){
OFAndroid.onStart();
}
}
else if( glView.getRenderer() == null){
else if(glView == null || glView.getRenderer() == null){
Log.w(TAG,"onResume glView is null or not setup");
OFAndroid.setupGL(OFAndroid.eglVersion, true);
if(OFAndroidLifeCycle.coreLibraryLoaded && OFAndroidLifeCycle.appLibraryLoaded) {
OFAndroid.onStart();
}
}
else if( glView != null && glView.getDisplay() == null) {
else if(glView.getDisplay() == null) {
Log.w(TAG,"onResume glView has a null display");
OFAndroid.setupGL(OFAndroid.eglVersion, true);
if(OFAndroidLifeCycle.coreLibraryLoaded && OFAndroidLifeCycle.appLibraryLoaded) {
Expand Down
111 changes: 54 additions & 57 deletions addons/ofxAndroid/src/ofAppAndroidWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,27 @@ ofAppAndroidWindow::ofAppAndroidWindow() {
window = this;
msaaSamples = 1;
glesVersion = 2;

glesVersionMinor = 0;
#ifdef TARGET_PROGRAMMABLE_GL
#ifdef GL_ES_VERSION_3_0
glesVersion = 3;
#ifdef GL_ES_VERSION_3_1
glesVersionMinor = 1;
#endif
#else
glesVersion = 2;
#endif
#else
glesVersion = 1;
#endif
ofGetMainLoop()->setCurrentWindow(this);
}

ofAppAndroidWindow::ofAppAndroidWindow(ofAppBaseWindow & other) {
window = this;
msaaSamples = 1;
glesVersion = 2;
glesVersionMinor = 0;
setMultiWindowMode(other.getWindowMode());
ofGetMainLoop()->setCurrentWindow(this);
}
Expand Down Expand Up @@ -164,47 +177,44 @@ ofAppAndroidWindow::~ofAppAndroidWindow() {
// TODO Auto-generated destructor stub
}


bool ofAppAndroidWindow::isSurfaceDestroyed() {
return surfaceDestroyed;
}

void ofAppAndroidWindow::setup(const ofGLESWindowSettings & settings)
{
glesVersion = settings.getGLESVersionMajor();
glesVersionMinor = settings.getGLESVersionMinor();
setup( (const ofxAndroidWindowSettings &)settings );
}

void ofAppAndroidWindow::setup(const ofxAndroidWindowSettings & settings){

glesVersion = settings.getGLESVersionMajor();
glesVersionMinor = settings.getGLESVersionMinor();
if(window == nullptr) {
ofLogError("ofAppAndroidWindow") << "Setup and Window is nullptr ! Fixing";
setCurrentWindow();
}
glesVersion = settings.glesVersion;
ofLogError("ofAppAndroidWindow") << "Setup OpenGLES:" << glesVersion;
if(glesVersion<2){
currentRenderer = std::make_shared<ofGLRenderer>(this);
}else{
currentRenderer = std::make_shared<ofGLProgrammableRenderer>(this);
}

jclass javaClass = ofGetJNIEnv()->FindClass("cc/openframeworks/OFAndroid");

if(javaClass==nullptr){
ofLogError("ofAppAndroidWindow") << "setupOpenGL(): couldn't find OFAndroid java class";
return;
}

makeCurrent();

jmethodID method = ofGetJNIEnv()->GetStaticMethodID(javaClass,"setupGL","(IZ)V");
if(!method){
ofLogError("ofAppAndroidWindow") << "setupOpenGL(): couldn't find OFAndroid setupGL method";
return;
}

ofGetJNIEnv()->CallStaticVoidMethod(javaClass,method,glesVersion,settings.preserveContextOnPause);


}

void ofAppAndroidWindow::update(){
Expand Down Expand Up @@ -330,6 +340,10 @@ int ofAppAndroidWindow::getGlesVersion()
return glesVersion;
}

int ofAppAndroidWindow::getGlesVersionMinor()
{
return glesVersionMinor;
}

extern "C"{

Expand Down Expand Up @@ -443,57 +457,46 @@ Java_cc_openframeworks_OFAndroid_onSurfaceDestroyed( JNIEnv* env, jclass thiz
}
}


JNIEXPORT void JNICALL
Java_cc_openframeworks_OFAndroid_onSurfaceCreated( JNIEnv* env, jclass thiz ){
if(appSetup){
ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated";
if(!surfaceDestroyed){
ofNotifyEvent(ofxAndroidEvents().unloadGL);
}
ofNotifyEvent(ofxAndroidEvents().reloadGL);
window->renderer()->pushStyle();
window->renderer()->setupGraphicDefaults();
window->renderer()->popStyle();
window->setThreadedEvents(false);
int glesVersion = window->getGlesVersion();
bSetupScreen = true;
if( glesVersion < 2 )
{
ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated OpenGLES 1";
dynamic_cast<ofGLRenderer*>(window->renderer().get())->setup();
}
else
{
ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated OpenGLES 2.0";
dynamic_cast<ofGLProgrammableRenderer*>(window->renderer().get())->setup(glesVersion,0);
}
Java_cc_openframeworks_OFAndroid_onSurfaceCreated( JNIEnv* env, jclass thiz ){
ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated";

}else{
if(window != nullptr) {
int glesVersion = window->getGlesVersion();
bSetupScreen = true;
if (glesVersion < 2) {
ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated OpenGLES 1";
dynamic_cast<ofGLRenderer *>(window->renderer().get())->setup();
} else {
ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated OpenGLES 2.0";
dynamic_cast<ofGLProgrammableRenderer *>(window->renderer().get())->setup(
glesVersion, 0);
}
}
}
if(!surfaceDestroyed && appSetup){
ofNotifyEvent(ofxAndroidEvents().unloadGL);
}
ofNotifyEvent(ofxAndroidEvents().reloadGL);

if(appSetup){
window->renderer()->pushStyle();
window->renderer()->setupGraphicDefaults();
window->renderer()->popStyle();
window->setThreadedEvents(false);
}

bSetupScreen = true;
int glesVersion = window->getGlesVersion();
int glesVersionMinor = window->getGlesVersionMinor();

if(glesVersion < 2){
ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated OpenGLES 1";
dynamic_cast<ofGLRenderer*>(window->renderer().get())->setup();
}else{
ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated OpenGLES 2.0+";
dynamic_cast<ofGLProgrammableRenderer*>(window->renderer().get())->setup(glesVersion, glesVersionMinor);
}

surfaceDestroyed = false;
surfaceDestroyed = false;
}

JNIEXPORT jboolean JNICALL
Java_cc_openframeworks_OFAndroid_isWindowReady( JNIEnv* env, jclass thiz) {

if(window != nullptr && window->renderer() != nullptr) {
return true;
} else {
if(window != nullptr && window->renderer() != nullptr) {
return true;
} else {
return false;
}
}
}

JNIEXPORT void JNICALL
Expand Down Expand Up @@ -554,25 +557,19 @@ Java_cc_openframeworks_OFAndroid_setAssetManager(JNIEnv *env, jclass thiz,
jobject jAssetManager) {

env->NewGlobalRef(jAssetManager);

AAssetManager *aaAssetManager = AAssetManager_fromJava(env, jAssetManager);
if (aaAssetManager == nullptr) {
ofLogError("ofAppAndroidWindow") << "Could not obtain the AAssetManager";
return;
}

assetManager = aaAssetManager;

if(window == nullptr || (window != nullptr && window->renderer() == nullptr)) {
ofLogVerbose("ofAppAndroidWindow") << "setAssetManager window is null";
return;
}

window->setAssetManager(assetManager);




}

/* Call to render the next GL frame */
Expand Down
6 changes: 5 additions & 1 deletion addons/ofxAndroid/src/ofAppAndroidWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,16 +110,20 @@ class ofAppAndroidWindow: public ofAppBaseGLESWindow {


int getGlesVersion();
int getGlesVersionMinor();

AAssetManager& getAssetManager();
void setAssetManager(AAssetManager* assetManager);

int glesVersion;
int glesVersionMinor;



private:
ofCoreEvents coreEvents;
std::shared_ptr<ofBaseRenderer> currentRenderer;
int glesVersion;

int msaaSamples;
AAssetManager* assetManager = nullptr;

Expand Down
51 changes: 25 additions & 26 deletions addons/ofxAndroid/src/ofxAndroidVideoGrabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,35 +132,34 @@ ofxAndroidVideoGrabber::Data::~Data(){
}

void ofxAndroidVideoGrabber::Data::loadTexture(){
ofTextureData td;
GLuint texId[1];
glGenTextures(1, texId);

glEnable(GL_TEXTURE_EXTERNAL_OES);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texId[0]);

glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (!ofIsGLProgrammableRenderer()) {
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
ofTextureData td;
GLuint texId[1];
glGenTextures(1, texId);

glEnable(GL_TEXTURE_EXTERNAL_OES);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texId[0]);

glDisable(GL_TEXTURE_EXTERNAL_OES);
glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

// Set the externally created texture reference
texture.setUseExternalTextureID(texId[0]);
texture.texData.width = width;
texture.texData.height = height;
texture.texData.tex_w = width;
texture.texData.tex_h = height;
texture.texData.tex_t = 1; // Hack!
texture.texData.tex_u = 1;
texture.texData.textureTarget = GL_TEXTURE_EXTERNAL_OES;
texture.texData.glInternalFormat = GL_RGBA;
#ifndef TARGET_PROGRAMMABLE_GL
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
#endif

glDisable(GL_TEXTURE_EXTERNAL_OES);

// Set the externally created texture reference
texture.setUseExternalTextureID(texId[0]);
texture.texData.width = width;
texture.texData.height = height;
texture.texData.tex_w = width;
texture.texData.tex_h = height;
texture.texData.tex_t = 1; // Hack!
texture.texData.tex_u = 1;
texture.texData.textureTarget = GL_TEXTURE_EXTERNAL_OES;
texture.texData.glInternalFormat = GL_RGBA;
}


Expand Down Expand Up @@ -262,7 +261,7 @@ void ofxAndroidVideoGrabber::close(){
} else {
ofLogError("ofxAndroidVideoGrabber") << "close(): couldn't get OFAndroidVideoGrabber close grabber method";
}

data->bGrabberInited = false;
}

Expand Down
2 changes: 2 additions & 0 deletions addons/ofxAndroid/src/ofxAndroidVideoPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ void ofxAndroidVideoPlayer::reloadTexture(){
glTexParameterf(texture.texData.textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(texture.texData.textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(texture.texData.textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#ifndef TARGET_PROGRAMMABLE_GL
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
#endif

glDisable(texture.texData.textureTarget);

Expand Down
10 changes: 8 additions & 2 deletions addons/ofxEmscripten/src/ofxAppEmscriptenWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,18 @@ void ofxAppEmscriptenWindow::setup(const ofGLESWindowSettings & settings){
attrs.alpha = 0;

context = emscripten_webgl_create_context("#canvas", &attrs);
int glesMajor = 3; // WebGL 2 == GLES 3
if (!context) {
attrs.majorVersion = 1;
context = emscripten_webgl_create_context("#canvas", &attrs);
glesMajor = 2; // WebGL 1 == GLES 2
}
assert(context);

makeCurrent();

_renderer = std::make_shared<ofGLProgrammableRenderer>(this);
((ofGLProgrammableRenderer*)_renderer.get())->setup(2,0);
((ofGLProgrammableRenderer*)_renderer.get())->setup(glesMajor, 0);

emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,this,useCapture,&keydown_cb);
emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,this,useCapture,&keyup_cb);
Expand Down Expand Up @@ -359,7 +365,7 @@ EM_BOOL ofxAppEmscriptenWindow::mousedown_cb(int eventType, const EmscriptenMous
return true;
}
EM_BOOL ofxAppEmscriptenWindow::rescale(int* x, int* y) {

return false;
}

//------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions addons/ofxEmscripten/src/ofxEmscriptenURLFileLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ ofHttpResponse ofxEmscriptenURLFileLoader::get(const string & url){

int ofxEmscriptenURLFileLoader::getAsync(const string & url, const string & name){
ofHttpRequest * req = new ofHttpRequest(url,name,false);
#if __EMSCRIPTEN_major__>1 || (__EMSCRIPTEN_major__==1 && __EMSCRIPTEN_minor__>22)
#if __EMSCRIPTEN_major__ > 1 || (__EMSCRIPTEN_major__ == 1 && __EMSCRIPTEN_minor__ > 22)
emscripten_async_wget2_data(url.c_str(), "GET", "", req, true, &onload_cb, &onerror_cb, NULL);
#endif
return req->getId();
Expand All @@ -37,7 +37,7 @@ ofHttpResponse ofxEmscriptenURLFileLoader::saveTo(const string & url, const of::

int ofxEmscriptenURLFileLoader::saveAsync(const string & url, const of::filesystem::path & path){
ofHttpRequest * req = new ofHttpRequest(url,url,true);
#if __EMSCRIPTEN_major__>1 || (__EMSCRIPTEN_major__==1 && __EMSCRIPTEN_minor__>22)
#if __EMSCRIPTEN_major__ > 1 || (__EMSCRIPTEN_major__ == 1 && __EMSCRIPTEN_minor__ > 22)
emscripten_async_wget2(url.c_str(), path.c_str(), "GET", "", req, &onload_file_cb, &onerror_file_cb, NULL);
#endif
return 0;
Expand Down
Empty file removed apps/myApps/.gitignore
Empty file.
Loading
Loading