Who's Online
52 user(s) are online (
39 user(s) are browsing
Forums )
Members: 0
Guests: 52
more...
Headlines
libflac.lha - development/library/audio
Jul 16, 2026
plants_vs_zombies.lha - game/action
Jul 16, 2026
unreal.lha - game/fps
Jul 16, 2026
tgamiga.lha - network/chat
Jul 16, 2026
llad_info.lha - audio/misc
Jul 14, 2026
hwp_httpstreamer.lha - library/hollywood
Jul 14, 2026
vasmm68k_mot.lha - development/cross
Jul 12, 2026
vasmm68k_std.lha - development/cross
Jul 12, 2026
vasmppc_std.lha - development/cross
Jul 12, 2026
amibookreader.lha - office/misc
Jul 12, 2026
Topic options
View mode
Newest First
Re: The OpenGL ES 2.0 thread
Posted on:
2025/2/2 8:22
#161
Just can't stay away
Joined: 2007/7/14 20:30Last Login
: Today 18:31
From Lothric
Group:
Registered Users
@elfpipe What kind of problems? Is there some GL error or anything if you run glSnoop?
Re: The OpenGL ES 2.0 thread
Posted on:
2025/2/2 12:03
#162
Just can't stay away
Joined: 2009/10/7 0:11Last Login
: 3/3 20:57
From Odense
Group:
Registered Users
@Capehill
glCompileShader returns a GL_COMPILE_STATUS of 0, when the call is made in the new thread. glGetShaderInfoLog in this case returns nothing.
glSnoop does an enormous amount of logging. It also interestingly removes the compile error. I get this in the log:
Quote:
[262.857543] Shell Process 'threadedqopenglwidget': W3DN_DrawArrays: <- Result 22 (W3DNEC_NOSHADERPIPELINE) [262.866984] Shell Process 'threadedqopenglwidget': Warning: unsuccessful operation detected [262.875127] Shell Process 'threadedqopenglwidget': GL error 1286 (GL_INVALID_FRAMEBUFFER_OPERATION) detected after DrawArrays EDIT: It could be an issue with context sharing. Maybe I have some wiggle room. EDIT: Probably not, though.
Edited by elfpipe on 2025/2/2 12:27:57 Edited by elfpipe on 2025/2/2 14:05:08 Edited by elfpipe on 2025/2/3 8:53:37
Re: The OpenGL ES 2.0 thread
Posted on:
7/6 16:10
#163
Home away from home
Joined: 2007/9/11 11:31Last Login
: Today 12:38
From Russia
Group:
Registered Users
@All
Do not know if it worth to report anymore, due to all known "dunno if anything will be released" , but seems i found another bug in ogles2 (at least i think so): glBindTexture(GL_TEXTURE_2D, 0) leak memory for no reasson and on exit not free it as well.
That call should just unbind the currently bound 2D texture and restore texture unit 0’s binding to the GLES default object. It should not allocate anything per call. And on x86/etc that it. But seems on our ogles2 realisation this eat memory a lot with no reasson.
I.e:
- Binding real texture IDs does not leak.
- Cycling between real texture IDs does not leak.
- glActiveTexture(GL_TEXTURE0) alone does not leak.
- glBindTexture(GL_TEXTURE_2D, 0) leaks heavily.
It looks like OGLES2 internal bug is: when texture ID 0 is bound, the library creates or realizes some internal “default/no texture” Nova-side object/state each time,
but does not reuse or free it. Or it triggers a state/submit path that appends retained objects for texture 0.
There is SDL2 based test case if anyone need it:
#include <SDL.h>
#include <SDL_opengles2.h>
#include <stdio.h>
static GLuint create_texture ( void )
{
static const unsigned char pixel [ 4 ] = { 255U , 255U , 255U , 255U };
GLuint texture ;
texture = 0U ;
glGenTextures ( 1 , & texture );
glBindTexture ( GL_TEXTURE_2D , texture );
glPixelStorei ( GL_UNPACK_ALIGNMENT , 1 );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE );
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA , 1 , 1 , 0 , GL_RGBA , GL_UNSIGNED_BYTE , pixel );
return texture ;
}
int main ( int argc , char ** argv )
{
SDL_Window * window ;
SDL_GLContext context ;
GLuint texture ;
unsigned int start_ms ;
unsigned int last_ms ;
unsigned long frames ;
unsigned long binds ;
( void ) argc ;
( void ) argv ;
if ( SDL_Init ( SDL_INIT_VIDEO | SDL_INIT_TIMER ) != 0 ) {
return 1 ;
}
( void ) SDL_GL_SetAttribute ( SDL_GL_CONTEXT_PROFILE_MASK , SDL_GL_CONTEXT_PROFILE_ES );
( void ) SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MAJOR_VERSION , 2 );
( void ) SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MINOR_VERSION , 0 );
( void ) SDL_GL_SetAttribute ( SDL_GL_DOUBLEBUFFER , 1 );
window = SDL_CreateWindow (
"glBindTexture 0 leak" ,
SDL_WINDOWPOS_CENTERED ,
SDL_WINDOWPOS_CENTERED ,
320 ,
240 ,
SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN );
if ( window == NULL ) {
SDL_Quit ();
return 1 ;
}
context = SDL_GL_CreateContext ( window );
if ( context == NULL ) {
SDL_DestroyWindow ( window );
SDL_Quit ();
return 1 ;
}
if ( SDL_GL_MakeCurrent ( window , context ) != 0 ) {
SDL_GL_DeleteContext ( context );
SDL_DestroyWindow ( window );
SDL_Quit ();
return 1 ;
}
texture = create_texture ();
if ( texture == 0U || glGetError () != GL_NO_ERROR ) {
SDL_GL_DeleteContext ( context );
SDL_DestroyWindow ( window );
SDL_Quit ();
return 1 ;
}
frames = 0UL ;
binds = 0UL ;
start_ms = SDL_GetTicks ();
last_ms = start_ms ;
for (;;) {
SDL_Event event ;
unsigned int now_ms ;
int i ;
while ( SDL_PollEvent (& event )) {
if ( event . type == SDL_QUIT ||
( event . type == SDL_KEYDOWN && event . key . keysym . sym == SDLK_ESCAPE )) {
goto done ;
}
}
for ( i = 0 ; i < 64 ; ++ i ) {
glBindTexture ( GL_TEXTURE_2D , 0 );
++ binds ;
}
SDL_GL_SwapWindow ( window );
SDL_Delay ( 1 );
++ frames ;
now_ms = SDL_GetTicks ();
if ( now_ms - last_ms >= 1000U ) {
printf ( "t=%u frames=%lu binds=%lu\n" , ( now_ms - start_ms ) / 1000U , frames , binds );
fflush ( stdout );
last_ms = now_ms ;
}
if ( now_ms - start_ms >= 20000U ) {
break;
}
}
done :
glDeleteTextures ( 1 , & texture );
( void ) SDL_GL_MakeCurrent ( window , NULL );
SDL_GL_DeleteContext ( context );
SDL_DestroyWindow ( window );
SDL_Quit ();
return 0 ;
}
It can be build for x86 too if need it (and there it will have no issues, of course).
Edited by kas1e on 2026/7/6 16:25:37 Edited by kas1e on 2026/7/6 16:31:37
Re: The OpenGL ES 2.0 thread
Amigans Defender
Joined: 2006/12/2 13:27Last Login
: Today 20:30
From Taranto, Italy
Group:
Staff members Moderators Registered Users
I think I've found the same issue but I don't think it will be never fixed anymore..
i'm really tired...
Re: The OpenGL ES 2.0 thread
Posted on:
7/7 10:49
#165
Just can't stay away
Joined: 2007/7/14 20:30Last Login
: Today 18:31
From Lothric
Group:
Registered Users
@kas1e glBindTexture(GL_TEXTURE_2D, 0) creates a new texture sampler each time and sets its parameters. So yes, it looks like a bug.
Re: The OpenGL ES 2.0 thread
Posted on:
7/11 13:38
#166
Just can't stay away
Joined: 2023/4/7 5:13Last Login
: Today 17:09
From Deutschland
Group:
Registered Users
Hi @kas1e, @Capehill, just had to post this - I spent basically all day today chasing a memory leak in my Unreal (1998) AmigaOS4 port and this thread is the reason I finally cracked it. Thank you both. Quick version: RAM kept draining while playing, even standing completely still, worst in scenes with animated textures. Ruled out literally everything in my own code before finding this thread - sound, render options, pixel format, you name it, none of it made a difference. Then I saw kas1e's post about glBindTexture(GL_TEXTURE_2D, 0) and went "...wait." Checked my code, and yep - I was calling exactly that, via a ResetTexture() helper, once per visible surface, up to 3 times each. In a normal scene that's easily hundreds of calls a frame. Explains everything. Swapped it for binding a dummy 1x1 texture instead of 0, and the leak is just... gone. Tested standing still for 10 minutes, memory didn't budge. So yeah - this is 100% a real bug that bites real applications, not just a synthetic test case. Really glad you found and reported it, would've been banging my head against this for a lot longer otherwise. Cheers!
MacStudio ARM M1 Max Qemu//Pegasos2 AmigaOs4.1 FE / AmigaOne x5000/40 AmigaOs4.1 FE
Re: The OpenGL ES 2.0 thread
Posted on:
Yesterday 12:14
#167
Home away from home
Joined: 2007/9/11 11:31Last Login
: Today 12:38
From Russia
Group:
Registered Users
@All
As there _maybe_ can be bug-fix release of ogles2 someday, i think it still worth to report another bug i found, even if i have workaround for already:
The currently public ogles2 3.3 appears to have a culling-state query bug:
If we sets:
glEnable(GL_CULL_FACE);
glFrontFace(GL_CW);
glCullFace(GL_BACK);
And then queries the same state:
GLint front_face;
GLint cull_face_mode;
glGetIntegerv(GL_FRONT_FACE, &front_face);
glGetIntegerv(GL_CULL_FACE_MODE, &cull_face_mode);
Expected results, also returned by Mesa GLES2 on WSL2/Linux:
front_face = GL_CW (0x0900)
cull_face_mode = GL_BACK (0x0405)
But on ogles2 3.3 / Warp3DNova 54.17:
front_face = GL_CCW (0x0901)
cull_face_mode = GL_FRONT_AND_BACK (0x0408)
glGetError() = GL_NO_ERROR
This causes a serious state save/restore problems then: A renderer may query and save the current culling state, temporarily change it,
and then restore the queried values. Restoring GL_FRONT_AND_BACK legally culls every polygon, so subsequent geometry disappears without
producing a GL error.
In the game I am working on, this caused geometry rendered after a culling-state save/restore sequence to simple disappear.
There minimal SDL2/GLES2 to reproduce:
#include <SDL.h>
#include <SDL_opengles2.h>
#include <stdio.h>
int main ( int argc , char ** argv )
{
SDL_Window * window ;
SDL_GLContext context ;
GLint queried_front_face ;
GLint queried_cull_face_mode ;
GLenum error ;
int reproduced ;
int result ;
( void ) argc ;
( void ) argv ;
window = NULL ;
context = NULL ;
result = 2 ;
if ( SDL_Init ( SDL_INIT_VIDEO ) != 0 ) {
fprintf ( stderr , "SDL_Init failed: %s\n" , SDL_GetError ());
return result ;
}
if ( SDL_GL_SetAttribute (
SDL_GL_CONTEXT_PROFILE_MASK , SDL_GL_CONTEXT_PROFILE_ES ) != 0 ||
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MAJOR_VERSION , 2 ) != 0 ||
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MINOR_VERSION , 0 ) != 0 ) {
fprintf ( stderr , "SDL_GL_SetAttribute failed: %s\n" , SDL_GetError ());
goto done ;
}
window = SDL_CreateWindow (
"OGLES2 cull state query" ,
SDL_WINDOWPOS_CENTERED ,
SDL_WINDOWPOS_CENTERED ,
160 ,
120 ,
SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN );
if ( window == NULL ) {
fprintf ( stderr , "SDL_CreateWindow failed: %s\n" , SDL_GetError ());
goto done ;
}
context = SDL_GL_CreateContext ( window );
if ( context == NULL ) {
fprintf ( stderr , "SDL_GL_CreateContext failed: %s\n" , SDL_GetError ());
goto done ;
}
if ( SDL_GL_MakeCurrent ( window , context ) != 0 ) {
fprintf ( stderr , "SDL_GL_MakeCurrent failed: %s\n" , SDL_GetError ());
goto done ;
}
( void ) glGetError ();
glEnable ( GL_CULL_FACE );
glFrontFace ( GL_CW );
glCullFace ( GL_BACK );
queried_front_face = 0 ;
queried_cull_face_mode = 0 ;
glGetIntegerv ( GL_FRONT_FACE , & queried_front_face );
glGetIntegerv ( GL_CULL_FACE_MODE , & queried_cull_face_mode );
error = glGetError ();
reproduced =
queried_front_face != ( GLint ) GL_CW ||
queried_cull_face_mode != ( GLint ) GL_BACK ||
error != GL_NO_ERROR ;
printf (
"requested: cull_enabled=1 front_face=0x%x cull_face_mode=0x%x\n" ,
( unsigned int ) GL_CW ,
( unsigned int ) GL_BACK );
printf (
"queried: front_face=0x%x cull_face_mode=0x%x error=0x%x\n" ,
( unsigned int ) queried_front_face ,
( unsigned int ) queried_cull_face_mode ,
( unsigned int ) error );
printf ( "reproduced=%d\n" , reproduced );
fflush ( stdout );
result = reproduced ;
done :
if ( context != NULL ) {
( void ) SDL_GL_MakeCurrent ( window , NULL );
SDL_GL_DeleteContext ( context );
}
if ( window != NULL ) {
SDL_DestroyWindow ( window );
}
SDL_Quit ();
return result ;
}
It requires no shaders, geometry, textures, game data, or draw calls. It only creates a GLES2 context, sets the two states, queries them,
and reports whether the bug was reproduced.
So on OS4 we have:
requested: cull_enabled=1 front_face=0x900 cull_face_mode=0x405
queried: front_face=0x901 cull_face_mode=0x408 error=0x0
reproduced=1
And for example on WSL2/Linux Mesa output:
requested: cull_enabled=1 front_face=0x900 cull_face_mode=0x405
queried: front_face=0x900 cull_face_mode=0x405 error=0x0
reproduced=0
Re: The OpenGL ES 2.0 thread
Posted on:
Today 12:18
#168
Home away from home
Joined: 2007/9/11 11:31Last Login
: Today 12:38
From Russia
Group:
Registered Users
@All
And another one in v3.3 : packed D24S8 texture FBO is complete, but sampler2D always returns 0.0. Details:
While we do have GL_OES_packed_depth_stencil advertised (and changelog for ogles2.library states that packed depth/stencil textures are supported), when
GL_DEPTH_STENCIL_OES / GL_UNSIGNED_INT_24_8_OES texture allocates without GL error, attaches to GL_DEPTH_ATTACHMENT and GL_STENCIL_ATTACHMENT without GL error,
produces GL_FRAMEBUFFER_COMPLETE and accepts a depth-writing draw without GL error , then test draw covering triangle at NDC Z = -0.5 (so the expected sampled depth as 0.25)
cause sampling the texture through sampler2D returns 0.0 (RGBA readback 0,0,0,255), while should be 0.25. GL_DEPTH_COMPONENT/GL_FLOAT behaves same:
the FBO is complete and drawing report no error, but samping return 0.0
There is small test case which reproduce it easy:
#include <SDL.h>
#include <SDL_opengles2.h>
#include <stdio.h>
#include <string.h>
#ifndef GL_DEPTH_STENCIL_OES
#define GL_DEPTH_STENCIL_OES 0x84F9
#endif
#ifndef GL_UNSIGNED_INT_24_8_OES
#define GL_UNSIGNED_INT_24_8_OES 0x84FA
#endif
static int has_extension (const char * extensions , const char * name )
{
const size_t length = strlen ( name );
const char * match = extensions ;
if ( extensions == NULL ) {
return 0 ;
}
while (( match = strstr ( match , name )) != NULL ) {
if (( match == extensions || match [- 1 ] == ' ' ) &&
( match [ length ] == '\0' || match [ length ] == ' ' )) {
return 1 ;
}
match += length ;
}
return 0 ;
}
static void clear_errors ( void )
{
while ( glGetError () != GL_NO_ERROR ) {
}
}
static GLuint compile_shader ( GLenum type , const char * source )
{
GLuint shader = glCreateShader ( type );
GLint compiled = GL_FALSE ;
glShaderSource ( shader , 1 , & source , NULL );
glCompileShader ( shader );
glGetShaderiv ( shader , GL_COMPILE_STATUS , & compiled );
if ( compiled == GL_FALSE ) {
char log [ 512 ];
GLsizei length = 0 ;
glGetShaderInfoLog ( shader , ( GLsizei ) sizeof ( log ), & length , log );
fprintf ( stderr , "shader compile failed: %.*s\n" , (int) length , log );
glDeleteShader ( shader );
return 0 ;
}
return shader ;
}
static GLuint create_program (const char * vertex_source ,
const char * fragment_source )
{
GLuint vertex = compile_shader ( GL_VERTEX_SHADER , vertex_source );
GLuint fragment = compile_shader ( GL_FRAGMENT_SHADER , fragment_source );
GLuint program = 0 ;
GLint linked = GL_FALSE ;
if ( vertex != 0 && fragment != 0 ) {
program = glCreateProgram ();
glAttachShader ( program , vertex );
glAttachShader ( program , fragment );
glBindAttribLocation ( program , 0 , "position" );
glLinkProgram ( program );
glGetProgramiv ( program , GL_LINK_STATUS , & linked );
if ( linked == GL_FALSE ) {
char log [ 512 ];
GLsizei length = 0 ;
glGetProgramInfoLog ( program , ( GLsizei ) sizeof ( log ), & length , log );
fprintf ( stderr , "program link failed: %.*s\n" , (int) length , log );
glDeleteProgram ( program );
program = 0 ;
}
}
if ( vertex != 0 ) {
glDeleteShader ( vertex );
}
if ( fragment != 0 ) {
glDeleteShader ( fragment );
}
return program ;
}
static int probe_depth_type (const char * label ,
GLenum depth_format ,
GLenum depth_type ,
int packed ,
GLuint write_program ,
GLuint sample_program )
{
static const GLfloat triangle [] = {- 1.0f , - 1.0f , 3.0f , - 1.0f , - 1.0f , 3.0f };
GLuint color = 0 ;
GLuint depth = 0 ;
GLuint framebuffer = 0 ;
GLenum allocation_error ;
GLenum attachment_error ;
GLenum write_error = GL_NO_ERROR ;
GLenum sample_error = GL_NO_ERROR ;
GLenum status = 0 ;
unsigned char pixel [ 4 ] = { 0 , 0 , 0 , 0 };
int pass = 0 ;
clear_errors ();
glGenTextures ( 1 , & color );
glBindTexture ( GL_TEXTURE_2D , color );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE );
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA , 4 , 4 , 0 ,
GL_RGBA , GL_UNSIGNED_BYTE , NULL );
glGenTextures ( 1 , & depth );
glBindTexture ( GL_TEXTURE_2D , depth );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE );
glTexImage2D ( GL_TEXTURE_2D , 0 , depth_format , 4 , 4 , 0 ,
depth_format , depth_type , NULL );
allocation_error = glGetError ();
clear_errors ();
glGenFramebuffers ( 1 , & framebuffer );
glBindFramebuffer ( GL_FRAMEBUFFER , framebuffer );
glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 ,
GL_TEXTURE_2D , color , 0 );
glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_DEPTH_ATTACHMENT ,
GL_TEXTURE_2D , depth , 0 );
if ( packed ) {
glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_STENCIL_ATTACHMENT ,
GL_TEXTURE_2D , depth , 0 );
}
attachment_error = glGetError ();
status = glCheckFramebufferStatus ( GL_FRAMEBUFFER );
if ( allocation_error == GL_NO_ERROR &&
attachment_error == GL_NO_ERROR &&
status == GL_FRAMEBUFFER_COMPLETE ) {
clear_errors ();
glViewport ( 0 , 0 , 4 , 4 );
glDisable ( GL_BLEND );
glDisable ( GL_CULL_FACE );
glDisable ( GL_DITHER );
glEnable ( GL_DEPTH_TEST );
glDepthFunc ( GL_ALWAYS );
glDepthMask ( GL_TRUE );
glDepthRangef ( 0.0f , 1.0f );
glClearDepthf ( 1.0f );
glClearStencil ( 0 );
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
( packed ? GL_STENCIL_BUFFER_BIT : 0 ));
glUseProgram ( write_program );
glVertexAttribPointer ( 0 , 2 , GL_FLOAT , GL_FALSE , 0 , triangle );
glEnableVertexAttribArray ( 0 );
glDrawArrays ( GL_TRIANGLES , 0 , 3 );
glFinish ();
write_error = glGetError ();
glBindFramebuffer ( GL_FRAMEBUFFER , 0 );
glViewport ( 0 , 0 , 160 , 120 );
glDisable ( GL_BLEND );
glDisable ( GL_CULL_FACE );
glDisable ( GL_DEPTH_TEST );
glDisable ( GL_DITHER );
glClearColor ( 0.0f , 0.0f , 0.0f , 1.0f );
glClear ( GL_COLOR_BUFFER_BIT );
glUseProgram ( sample_program );
glActiveTexture ( GL_TEXTURE0 );
glBindTexture ( GL_TEXTURE_2D , depth );
glUniform1i ( glGetUniformLocation ( sample_program , "depthTexture" ), 0 );
glVertexAttribPointer ( 0 , 2 , GL_FLOAT , GL_FALSE , 0 , triangle );
glEnableVertexAttribArray ( 0 );
glDrawArrays ( GL_TRIANGLES , 0 , 3 );
glReadPixels ( 80 , 60 , 1 , 1 , GL_RGBA , GL_UNSIGNED_BYTE , pixel );
sample_error = glGetError ();
pass = write_error == GL_NO_ERROR && sample_error == GL_NO_ERROR &&
pixel [ 0 ] >= 56 && pixel [ 0 ] <= 72 &&
pixel [ 1 ] >= 56 && pixel [ 1 ] <= 72 &&
pixel [ 2 ] >= 56 && pixel [ 2 ] <= 72 ;
}
printf ( "depth/%s alloc=0x%04x attach=0x%04x fbo=0x%04x "
"write=0x%04x sample=0x%04x pixel=%u,%u,%u,%u pass=%d\n" ,
label , ( unsigned int ) allocation_error ,
( unsigned int ) attachment_error , ( unsigned int ) status ,
( unsigned int ) write_error , ( unsigned int ) sample_error ,
( unsigned int ) pixel [ 0 ], ( unsigned int ) pixel [ 1 ],
( unsigned int ) pixel [ 2 ], ( unsigned int ) pixel [ 3 ], pass );
glBindFramebuffer ( GL_FRAMEBUFFER , 0 );
glBindTexture ( GL_TEXTURE_2D , 0 );
glDeleteFramebuffers ( 1 , & framebuffer );
glDeleteTextures ( 1 , & depth );
glDeleteTextures ( 1 , & color );
return pass ;
}
int main ( int argc , char ** argv )
{
SDL_Window * window = NULL ;
SDL_GLContext context = NULL ;
GLuint write_program = 0 ;
GLuint sample_program = 0 ;
int uint_pass ;
int ushort_pass ;
int float_pass ;
int packed_pass ;
int result = 2 ;
( void ) argc ;
( void ) argv ;
#if !defined(__amigaos4__)
if ( SDL_getenv ( "MESA_GLES_VERSION_OVERRIDE" ) == NULL ) {
SDL_setenv ( "MESA_GLES_VERSION_OVERRIDE" , "2.0" , 0 );
}
#endif
if ( SDL_Init ( SDL_INIT_VIDEO ) != 0 ) {
fprintf ( stderr , "SDL_Init failed: %s\n" , SDL_GetError ());
return result ;
}
( void ) SDL_GL_SetAttribute ( SDL_GL_CONTEXT_PROFILE_MASK ,
SDL_GL_CONTEXT_PROFILE_ES );
( void ) SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MAJOR_VERSION , 2 );
( void ) SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MINOR_VERSION , 0 );
window = SDL_CreateWindow ( "OGLES2 sampled depth probe" ,
SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED ,
160 , 120 ,
SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN );
if ( window == NULL ) {
fprintf ( stderr , "SDL_CreateWindow failed: %s\n" , SDL_GetError ());
goto done ;
}
context = SDL_GL_CreateContext ( window );
if ( context == NULL || SDL_GL_MakeCurrent ( window , context ) != 0 ) {
fprintf ( stderr , "SDL GLES2 context failed: %s\n" , SDL_GetError ());
goto done ;
}
write_program = create_program (
"attribute vec2 position;"
"void main(){gl_Position=vec4(position,-0.5,1.0);}" ,
"precision mediump float;"
"void main(){gl_FragColor=vec4(0.0);}" );
sample_program = create_program (
"attribute vec2 position;"
"void main(){gl_Position=vec4(position,0.0,1.0);}" ,
"precision mediump float;"
"uniform sampler2D depthTexture;"
"void main(){float d=texture2D(depthTexture,vec2(0.5)).r;"
"gl_FragColor=vec4(d,d,d,1.0);}" );
if ( write_program == 0 || sample_program == 0 ) {
goto done ;
}
printf ( "renderer=%s\n" , (const char *) glGetString ( GL_RENDERER ));
printf ( "version=%s\n" , (const char *) glGetString ( GL_VERSION ));
printf ( "GL_OES_depth_texture advertised=%d\n" ,
has_extension ((const char *) glGetString ( GL_EXTENSIONS ),
"GL_OES_depth_texture" ));
printf ( "GL_OES_packed_depth_stencil advertised=%d\n" ,
has_extension ((const char *) glGetString ( GL_EXTENSIONS ),
"GL_OES_packed_depth_stencil" ));
uint_pass = probe_depth_type ( "UINT" , GL_DEPTH_COMPONENT ,
GL_UNSIGNED_INT , 0 ,
write_program , sample_program );
ushort_pass = probe_depth_type ( "USHORT" , GL_DEPTH_COMPONENT ,
GL_UNSIGNED_SHORT , 0 ,
write_program , sample_program );
float_pass = probe_depth_type ( "FLOAT" , GL_DEPTH_COMPONENT ,
GL_FLOAT , 0 ,
write_program , sample_program );
packed_pass = probe_depth_type ( "D24S8" , GL_DEPTH_STENCIL_OES ,
GL_UNSIGNED_INT_24_8_OES , 1 ,
write_program , sample_program );
printf ( "required_uint=%s ushort=%s float=%s packed=%s\n" ,
uint_pass ? "PASS" : "FAIL" , ushort_pass ? "PASS" : "FAIL" ,
float_pass ? "PASS" : "FAIL" ,
packed_pass ? "PASS" : "FAIL" );
fflush ( stdout );
result = uint_pass ? 0 : 1 ;
done :
if ( sample_program != 0 ) {
glDeleteProgram ( sample_program );
}
if ( write_program != 0 ) {
glDeleteProgram ( write_program );
}
if ( context != NULL ) {
( void ) SDL_GL_MakeCurrent ( window , NULL );
SDL_GL_DeleteContext ( context );
}
if ( window != NULL ) {
SDL_DestroyWindow ( window );
}
SDL_Quit ();
return result ;
}
And while we at it, will be also good to implement GL_OES_depth_texture (woth all GL_DEPTH_COMPMENTS textures with short/int/etc, fbo attached, depth write and sampler2 sampling).
Sampled depth textures is needed for GLES2 effects such as volumetric lighting, water intersection depth and bilateral depth filtering.
Currently Active Users Viewing This Thread:
1
(
0 members
and 1 Anonymous Users
)