Depth texture for OpenGL ES

Hello,
I am trying to create a depth buffer that is supported for OpenGL ES, including Emscripten and iOS.
I am a bit lost in all of the possible combinations. Is there a way to tell if WebGL is being used and what version? I have been testing on OSX 12.6 M1 and using Empscripten 3.1.28.
Below is the test code that I have been using to test support in Chrome. Both the glTexImage2D GL_FLOAT and GL_UNSIGNED_INT functions succeed, but unsure how to test for support of float and depth textures.

int main( ){

#ifdef TARGET_OPENGLES
	ofGLESWindowSettings settings;
	settings.glesVersion = 3;
#else
	
	//Use ofGLFWWindowSettings for more options like multi-monitor fullscreen
	ofGLWindowSettings settings;
	settings.setSize(1200, 768);
	// shadows only work with programmable renderer
	// point lights work in 3.3, but is limited to 1
	//	settings.setGLVersion(3,3);
	// multiple point lights only work with OpenGL 4+
	settings.setGLVersion(4,1);
#endif
	
	settings.windowMode = OF_WINDOW; //can also be OF_FULLSCREEN
	auto window = ofCreateWindow(settings);
	
	ofRunApp(window, make_shared<ofApp>());
	ofRunMainLoop();

}

#define GL_CHECK() { \
GLenum glError = glGetError();  \
if(glError != GL_NO_ERROR) { \
printf("glGetError() = %i (%#.8x) in ofShadow.cpp at line: %i\n", glError, glError, __LINE__); \
} \
}\
//--------------------------------------------------------------
void ofApp::setup(){
	ofSetLogLevel(OF_LOG_VERBOSE);
	
	vector<string> depthExts = {
		"GL_OES_depth_texture",
		"OES_depth_texture",
		"WEBGL_depth_texture"
	};
	
	for( int i = 0; i < depthExts.size(); i++ ) {
		ofLogVerbose( depthExts[i] ) << " - " << ofGLCheckExtension(depthExts[i]);
	}
	
	if( ofIsGLProgrammableRenderer() ) {
		auto renderer = static_cast<ofGLProgrammableRenderer*>(ofGetCurrentRenderer().get());
		if( renderer ) {
			ofLogVerbose( "GL RENDERER " ) << renderer->getGLVersionMajor();
		}
	}
	
	vector<string> floatExts = {
		"EXT_color_buffer_float",
		"OES_texture_float",
		"OES_texture_float_linear",
		"WEBGL_color_buffer_float"
	};
	
	for( int i = 0; i < floatExts.size(); i++ ) {
		ofLogVerbose( floatExts[i] ) << " - " << ofGLCheckExtension(floatExts[i]);
	}
	
#ifdef GL_DEPTH_COMPONENT32
	ofLogVerbose("GL_DEPTH_COMPONENT32 is defined");
#endif
#ifdef GL_DEPTH_COMPONENT24
	ofLogVerbose("GL_DEPTH_COMPONENT24 is defined");
#endif
	
	GLuint fboId;
	GLuint texId;
	
	glGenFramebuffers(1, &fboId);
	glGenTextures(1, &texId);
	
	GLenum Status = GL_FRAMEBUFFER_UNSUPPORTED;
	
	GLuint textureTarget = GL_TEXTURE_2D;
	glBindTexture(textureTarget, texId );
	GL_CHECK();
	
//#if defined(TARGET_OPENGLES)
//	glTexImage2D(textureTarget, 0, GL_DEPTH_COMPONENT32, 512, 512, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
//	glTexImage2D(textureTarget, 0, GL_DEPTH_COMPONENT24, 512, 512, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
// this works 
//	glTexImage2D(
//				 textureTarget,
//				  0,
//				 GL_DEPTH_COMPONENT24,//GL_DEPTH_COMPONENT32,
//				  512,
//				  512,
//				  0,
//				 GL_DEPTH_COMPONENT,
//				 GL_UNSIGNED_INT,
//				  NULL
//				 );
	
// this also works 
	glTexImage2D(
				 textureTarget,
				 0,
				 GL_DEPTH_COMPONENT32F,//GL_DEPTH_COMPONENT32,
				 512,
				 512,
				 0,
				 GL_DEPTH_COMPONENT,
				 GL_FLOAT,
				 NULL
				 );

	
//#endif
	//		glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT24, getDepthMapWidth(), getDepthMapHeight());
	GL_CHECK();
	
	glBindTexture(textureTarget, 0);
	GL_CHECK();
	
	// Create the fbo
	glBindFramebuffer(GL_FRAMEBUFFER, fboId );
#if defined(TARGET_OPENGLES)
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, textureTarget, texId, 0);
#else
	glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, texId, 0);
#endif
	
	Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
	
	
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	
	if (Status != GL_FRAMEBUFFER_COMPLETE) {
		ofLogError("ofApp :: _allocateFbo : Frame buffer error, status") << Status;
	}
}

This is the output

[verbose] GL_OES_depth_texture:  - 0
[verbose] OES_depth_texture:  - 0
[verbose] WEBGL_depth_texture:  - 0
[verbose] GL RENDERER : 2
[verbose] EXT_color_buffer_float:  - 1
[verbose] OES_texture_float:  - 0
[verbose] OES_texture_float_linear:  - 1
[verbose] WEBGL_color_buffer_float:  - 0
[verbose] GL_DEPTH_COMPONENT32 is defined: 
[verbose] GL_DEPTH_COMPONENT24 is defined:

@NickHardeman not sure if I am doing something wrong, but with:

The glInfoExample works with Emscripten (and maybe with GLES in general).
So maybe you just need to add:
#import <GL/glew.h> to ofConstants.h

1 Like

@Jona thank you.
I am assuming that Emscripten uses WebGL? So if I test for TARGET_EMSCRIPTEN and renderer->getGLVersionMajor(); then it would show me the WebGL version?

@NickHardeman yes, it uses webGL. Not sure, if you can get the version with: renderer->getGLVersionMajor();.
Here is something: Emscripten: how do I detect webgl context version in runtime? - Stack Overflow
And this way you can call it with Emscripten: emscripten_webgl_get_current_context()
The attributes are set in ofxAppEmscriptenWindow.cpp (meanwhile I tend to set alpha to true):

    EmscriptenWebGLContextAttributes attrs;
    emscripten_webgl_init_context_attributes(&attrs);

/// when setting explicitSwapControl to 0 it is emscripten that is in charge of swapping on each render call.
    attrs.explicitSwapControl = 0;
    attrs.depth = 1;
    attrs.stencil = 1;
    attrs.antialias = 1;
    attrs.majorVersion = 2;
    attrs.minorVersion = 0;
    attrs.alpha = 0;

    context = emscripten_webgl_create_context("#canvas", &attrs);
1 Like

@Jona thank you for pointing me to this. It looks like it sets up the programmable renderer in the same function you referenced with major version 2 and minor of 0. When I query renderer->getGLVersionMajor();, it returns 2.

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

Ah, it’s a little confusing to me because the GL version is set to 2 on the programmable renderer because it’s WebGL 2, which apparently uses OpenGL ES 3.0 and WebGL 1.0 looks like it uses OpenGL ES 2.0.

@NickHardeman in addition you can set wegGL related flags in config.emscripten.default.mk
Currently it is:
-s MAX_WEBGL_VERSION=2
For some cases I also need:
-s WEBGL2_BACKWARDS_COMPATIBILITY_EMULATION=1

Here are the options:
https://emscripten.org/docs/porting/multimedia_and_graphics/OpenGL-support.html

And yes, GLES 2 seems to use webGL 1 and GLES 3 seems to use webGL 2.

1 Like