v11 beta: Android - polygons rendered in wrong order and glDrawElements issue

Previous topic - Next topic

dreamerman

This problem applies to Android platform with latest 11.322 GLB version, on v10 (and Android) or Win32 (either v10 or v11) there is no such problem.
In simple words, some polygons that are further are rendered over the closer ones, as if the depth function was set wrong or some z buffer parameter was incorrect. This applies to X_Drawobj and inline glDrawArrays, I tried to use glDepthFunc(GL_LESS) and with GL_LEQUAL parameter but that doesn't help, so problem is probably in some init functions.

Example:
Code (glbasic) Select

SYSTEMPOINTER FALSE
SETCURRENTDIR("Media") // seperate media and binaries?

// Create a Pyramid
X_OBJSTART 5
X_OBJADDVERTEX -50, 0, -50, 0,0,RGB(0,0,255)
X_OBJADDVERTEX 50, 0, -50, 0,0,RGB(0,0,255)
X_OBJADDVERTEX 0, 100, 0, 0,0,RGB(255,255,255) // Peak
X_OBJADDVERTEX 50, 0, 50, 0,0,RGB(0,0,255)
X_OBJADDVERTEX -50, 0, 50, 0,0,RGB(0,0,255)
X_OBJNEWGROUP
X_OBJADDVERTEX -50, 0, -50, 0,0,RGB(0,0,255)
X_OBJADDVERTEX 0, 100, 0, 0,0,RGB(255,255,255)
X_OBJADDVERTEX -50, 0, 50, 0,0,RGB(0,0,255)
X_OBJEND

WHILE TRUE
X_MAKE3D 1, 500, 45 // Viewport 3D
X_CAMERA 150, 50, -200, 0, 30, 0
//glDepthFunc(GL_LESS)
X_DRAWOBJ 5, 0
SHOWSCREEN
WEND
END

SUB GLB_ON_LOOP:
ENDSUB


Another issue is glDrawElements, that doesn't work on Android, I have no idea why, no error with glGetError (returns 0), same code works on windows but not on my tablet :> Apart from that, there is an error in 'Samples\Common\gl.bas' file wrapping that function, currently it's:
Code (glbasic) Select
FUNCTION glDrawElements: mode, count, typ, indices[]
typ = GL_INT;
INLINE
GLint* pi=new GLint[(int)count];
for(int i=0; i<count; ++i) pi[i]=indices(i);
OGL glDrawElements(mode, count, typ, pi);
delete[] pi;
ENDINLINE
ENDFUNCTION

But 'typ' => 'type' parameter for that function can only have values: GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, or GL_UNSIGNED_INT. So it should look like this:
Code (glbasic) Select
FUNCTION glDrawElements: mode, count, typ, indices%[]
typ = GL_UNSIGNED_INT;
INLINE
//GLuint* pi=new GLuint[(unsigned int)count];
// for(unsigned int i=0; i<count; ++i) pi[i]=indices(i);
// OGL glDrawElements(mode, count, typ, pi);
// delete[] pi;
OGL glDrawElements(mode, count, typ, &indices(0));
ENDINLINE
ENDFUNCTION

And if 'indices' will be DGIntArray - % type as above there is no need to convert indices[] to GLuint, it's working without it.


polygons order attached image: left = v10, right = v11 - Android
Check my source code editor for GLBasic - link Update: 20.04.2020

mentalthink

Perhaps some problem whit XCullmode?¿, I look in the second image, like the normals are inverted...
Try whit XCull perhaps solve the problem... I never touch nothing about native OpenGL...

bigsofty

Looks like a invalid type problem.

In OpenGL the"type" param for glDrawElements() can be GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT but in OpenGLES it can only be GL_UNSIGNED_BYTE or GL_UNSIGNED_SHORT.

There is an improved GL.GBAS here http://www.glbasic.com/forum/index.php?topic=7801.msg66675#msg66675 for Android/GLES but some functions still need to be checked for GLES compatibility sometimes.

BTW: I don't have that beta installed but it looks like an "inverted normals" problem. Try reversing the triangle vertex order or messing with autonormals (or whatever it's called).
Cheers,

Ian.

"It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration."
(E. W. Dijkstra)

dreamerman

@mentalthink:
X_Cullmode doesn't really help as rendering order is wrong... in that not rotating pyramid example it will mask the problem, but in more complex project that problem still will be visible, and with use of native OpenGL calls, passing additional array of normals isn't a solution - it will slow down rendering process.

@bigsofty:
This improved 'gl.bas' is same as that one included in beta so wont help. But I overlooked that detail about OpenGLES types, so for mobile devices glDrawElements should look like this:
Code (glbasic) Select
FUNCTION glDrawElements: mode, count, typ, indices%[]
typ = GL_UNSIGNED_SHORT;
INLINE
GLushort* pi=new GLushort[(int)count];
for(int i=0; i<count; ++i) pi[i]=indices(i);
OGL glDrawElements(mode, count, typ, pi);
delete[] pi;
ENDINLINE
ENDFUNCTION

And this is working correctly :-)

Still remains first problem with rendering order, as I understand changing normals will not help, because even if all polygons are rendered (either back or front face) the further ones are drawed over those closer ones.
Check my source code editor for GLBasic - link Update: 20.04.2020

bigsofty

I would try altering the winding order all the same, as your 'at fault' picture is what I would expect with reversed normals. That is, inverse normals, the reverse side of triangles showing while the front faces ones not. Not really a rendering order problem more of a face culling problem.

I am sorry I can't try with Android, so this is just an educated guess.
Cheers,

Ian.

"It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration."
(E. W. Dijkstra)

SnooPI

It' s a problem with the z-buffer on android (glbasic v11 beta)
        
We also see this bug on win32 with transparent and textured polygons (glbasic v10 and v11 beta)

:(

Kitty Hello

in your java file, find:
EGL10.EGL_DEPTH_SIZE,   16,

and uncomment it.

Use glDrawArrays instead of glDrawElements. Does it work?

dreamerman

Didn't read your post, and I already downloaded latest beta 11.556, and this z-order bug seems to be fixed  :good:

Next thing, I was checking what would be faster drawArrays or drawElements but still long way before this will be needed truely, but to get glDrawArrays working on Android and other OpenGL ES devices little change to wrapper is needed, as bigsofty mentioned:
Quote from: bigsoftyIn OpenGL the"type" param for glDrawElements() can be GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT but in OpenGLES it can only be GL_UNSIGNED_BYTE or GL_UNSIGNED_SHORT.
so glDrawElements for OpenGL ES should look like this:
Code (glbasic) Select
FUNCTION glDrawElements: mode, count, typ, indices%[]
typ = GL_UNSIGNED_SHORT;
INLINE
GLushort* pi=new GLushort[(int)count];
for(int i=0; i<count; ++i) pi[i]=indices(i);
OGL glDrawElements(mode, count, typ, pi);
delete[] pi;
ENDINLINE
ENDFUNCTION

and it's working properly now :-)
Check my source code editor for GLBasic - link Update: 20.04.2020