1. Download the free trial version

Library OpenGL library

Discussion in 'Additional libraries, classes and official updates' started by agraham, May 8, 2011.

  1. agraham

    agraham Expert Licensed User

    Here is a first stab at implementing an OpenGL library. The implementation is a subset of the full Android API but the actual functionality is pretty complete (I think!) as the omitted functions are mainly those that used scaled integer working, I have only implemented the equivalents that use floats.

    However it is almost totally untested. I have got it to the point where it can draw a triangle on the screen but my total ignorance of OpenGL makes further progress challenging and I'm not really interested in doing graphics. As it can now draw on-screen most of the further functionality should be OK as it is a very thin wrapper of the OpenGL API. The hard part of integrating the GLSurfaceView with Basic4android and drawing on it is done.

    The reason for posting it therefore is to see if there is any interest in it before I waste more time on it, and to see if there is an OpenGL expert out there who would collaborate on testing and debugging it - assuming anyone wants to use it at all!

    As an aside I believe that the GLSurfaceView, being based on a standard View, can also be drawn on using the same methods as other Views as well as by the OpenGL renderer but I haven't tried that.

    Note that the "demo" needs my Threading library.

    EDIT :- Version 1.1 posted. See post #5 for details.

    EDIT :- Version 1.2 posted. See post #10 for details.

    EDIT :- Version 1.3 posted. See post #16 for details.

    EDIT :- Version 1.4 posted. See post #21 for details.

    EDIT :- Version 1.5 posted. See post #25 for details.

    EDIT :- Version 1.6 posted. See post #35 for details.
    EDIT :- Version 1.6 reposted with correct version number. See post #38 for details.

    EDIT :- Version 1.7 posted. See post #39 for details.
     

    Attached Files:

    Last edited: May 20, 2011
  2. Steven Sparrow

    Steven Sparrow Member Licensed User

    OpenGL Testing

    We use openGL extensively in a number of projects and as we are migrating code to the Android and iPhone platforms, one of the biggest stumbling blocks was the lack of a 3D engine in basic4android.

    We had already starting an openGL implementation of our own, but after seeing your past contributions to basic4andoid I'm sure your implementaiton is likely to be cleaner and more functional.

    Will give it a try and get back to you with our findings.

    Keep up the great work !
    Steve
     
  3. Erel

    Erel Administrator Staff Member Licensed User

  4. JogiDroid

    JogiDroid Member Licensed User

    Wow, that's nice, one big feature/lib I have been missing in B4A... I have some experience with OpenGL and lot of intrest for 3d gfx so I'm going to test this feature soon... (week or so..)
    Thanks!!!
     
  5. agraham

    agraham Expert Licensed User

    Version 1.1 now posted has support for all the Android OpenGL Interfaces, namely GL10, GL10Ext, GL11, GL11Ext and GL11ExtensionPack. The constants and functions supported may be found in the Android documentation GL10 - Android SDK | Android Developers. Note the clickable list of Interfaces in the lower left panel.

    Many functions have equivalents taking either an array or an Android native Buffer. As Basic4android doesn handle Buffers I have omitted those functions using them. However there are a few functions that exist that only accept a Buffer parameter, for example GL10.glVertexPointer. For those functions I have synthesised an alternative using a float array. Alternatives using int or other types of array are possible if required.

    Some functions exist in two forms using the same name but different parameter lists. Basic4android does not suppport this so the figure "2" has been appended to the later version name to allow Basic4android to distinguish them. I think I've found them all but if a particular expected version is not visible that is probably the reason for it.

    There may be stupid mistakes and typos but I am pretty sure we can overcome those as they arise and hopefully end up with a working OpenGL implementation for Basic4android.
     
    Last edited: May 10, 2011
  6. Cor

    Cor Active Member Licensed User

    Thanks agraham,

    for your nice and hard work :sign0098:
     
  7. gorelshv

    gorelshv Member Licensed User

    hey Andrew, could you post a sample code? just something basic like making a cube and putting a texture on it. thanks.
     
  8. agraham

    agraham Expert Licensed User

    No. I'm a Systems Engineer, not a graphics programmer and I know nothing about actually using OpenGL for graphics work. That is why I asked for collaboration to test the library. I knew some people wanted OpenGL so I have done the work to expose it to Basic4android. I now need feedback and examples of failure from people who know what they are doing so that we can debug the library.
     
    Jmu5667 likes this.
  9. geocomputing

    geocomputing Member Licensed User

    Andrew,

    In answer to your question of whether anyone wants a gl library I can personally say that I definitely do and I've got lots of uses for it. Having gl is something I've been hoping for and makes b4a an amazing product. Thank you very much for providing it, I'll post any bugs I find.

    Many thanks,

    Andrew.

    :sign0060: :sign0098: :sign0060:
     
  10. agraham

    agraham Expert Licensed User

    Hmm! I didn't think this library would grow like this :(

    Version 1.2 now posted.

    GL10 Object name changed to GL1 to reflect that it might support either OpenGL ES 1.0 or 1.1.

    Various GL1.xxxPointer functions refined as I now better appreciate what they do.

    Added Int as well as Float versions of many functions to improve the orthogonality of what's available. This may need revisiting when someone who really knows what they are doing plays with this library.

    Added Matrix and Visibility support objects.

    Added GLSurfaceView.RunOnGuiThread so that rendering code can run stuff on the GUI thread.

    Improved the demo, not in the graphics but in the structure to show error handling on the rendering thread which would otherwise force close the application as exceptions not on the main thread are not trapped and reported by Basic4android.
     
    Last edited: May 11, 2011
  11. geocomputing

    geocomputing Member Licensed User

    Andrew,

    I think I've found a little bug. I adapted your demo to make a rotating 3d cube. On a wildfire it works properly, but on a galaxy tab it doesn't clear the view each time it redraws (i.e. each update it doesn't remove the previous triangle drawings). Also, it doesn't seem to properly sort triangles by depth, but that may just need me to add another flag. I've put my code below in case it helps.

    Best wishes,

    Andrew.

    'Activity module
    Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim Timer1 As Timer
    End Sub

    Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim glsv As GLSurfaceView
    Dim eyex,eyey,eyez,eyeradius,eyeangle As Float
    eyex=0
    eyey=0
    eyez=0
    eyeradius=5
    eyeangle=3.14159
    End Sub

    Sub Timer1_Tick
    eyeangle=eyeangle+0.1
    If eyeangle>(2*3.14159) Then eyeangle=eyeangle-(2*3.14159)
    glsv.RequestRender
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
    glsv.Initialize(glsv.RENDERMODE_WHEN_DIRTY, "glsv")
    Activity.AddView(glsv,0,0,Activity.Width,Activity.Height)
    End Sub

    Sub Activity_Resume
    'glsv.DebugFlags = glsv.DEBUG_CHECK_GL_ERROR + glsv.DEBUG_LOG_GL_CALLS ' Can set debug flags here if required
    glsv.Resume ' Must call GLSurfaceView.Resume to restart the rendering thread
    Timer1.Initialize("Timer1", 100)
    Timer1.Enabled = True
    End Sub

    Sub Activity_Pause (UserClosed As Boolean)
    glsv.Pause ' Must call GLSurfaceView.Pause to halt the rendering thread
    Timer1.Enabled = False
    End Sub



    ' The GLSurfaceView events run on a separate thread to the main thread.
    ' They therefore must not try to manipulate GUI elements.
    ' The OpenGL library does not allow the debugger to halt at code within these event Subs.

    Sub glsv_Draw(gl As GL10)
    'The view wants to be drawn using the suppllied GL10
    gl.glDisable(gl.GL_DITHER)
    gl.glClear(gl.GL_COLOR_BUFFER_BIT + gl.GL_DEPTH_BITS)
    gl.glMatrixMode(gl.GL_MODELVIEW)
    gl.glLoadIdentity
    eyex=eyeradius*Sin(eyeangle)
    eyez=eyeradius*Cos(eyeangle)
    gl.gluLookAt(eyex,eyey,eyez, 0,0,0, 0,1,0)
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
    Dim coords(0) As Float
    coords = Array As Float(-0.5,1,-1, 0.5,1,-1, 0.5,-1,-1, -0.5,-1,-1, -0.5,1,1, 0.5,1,1, 0.5,-1,1, -0.5,-1,1)
    Dim indeces(0) As Short
    indeces = Array As Short(0,1,2, 2,3,0, 4,5,6, 6,7,4, 4,5,1, 1,0,4, 7,6,2, 2,3,7)
    gl.glColor4f(1, 0, 0, 1)
    gl.glVertexPointer(3, coords)
    gl.glDrawElements(gl.GL_TRIANGLES, 24, indeces)
    indeces = Array As Short(5,1,6, 1,2,6)
    gl.glColor4f(0, 0, 1, 1)
    ' gl.glVertexPointer(3, coords)
    gl.glDrawElements(gl.GL_TRIANGLES, 6, indeces)
    End Sub

    Sub glsv_SurfaceChanged(gl As GL10, width As Int, height As Int)
    'Called when the surface has changed size.
    gl.glViewport(0, 0, width, height)
    gl.glMatrixMode(gl.GL_PROJECTION)
    Dim ratio As Float
    ratio = width/height
    gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7)
    End Sub

    Sub glsv_SurfaceCreated(gl As GL10)
    'Called when the surface is created or recreated.
    gl.glDisable(gl.GL_DITHER)
    gl.glHint(gl.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_FASTEST)
    gl.glShadeModel(gl.GL_SMOOTH)
    gl.glEnable(gl.GL_DEPTH_TEST)
    gl.glClearColor(0.5, 0.5, 0.5, 1)
    End Sub
     
  12. agraham

    agraham Expert Licensed User

    On my ZTE Blade it works fine except that two of the faces seem transparent which I presume is the depth problem you allude to.

    However my Motorola Xoom also does not clear the old view each time. Checking gl.gluErrorString(gl.glGetError) there is an "invalid value" error on the Xoom after

    gl.glClear(gl.GL_COLOR_BUFFER_BIT + gl.GL_DEPTH_BITS)

    replacing it with

    gl.glClear(gl.GL_COLOR_BUFFER_BIT)

    and it works fine - except for the depth problem which I don't think can be down to the library as most of the method calls are a direct exposure of the API call with no intermediate processing.

    Note that calling GL1.glGetError resets the error value to "no error" so the call return may need to be assigned immediately if wanted for further use.
     
  13. geocomputing

    geocomputing Member Licensed User

    Hi Andrew,

    Many thanks for that, it now works on my galaxy tab properly. Not clearing the depth buffer can lead to some strange antics so I did it this way instead:

    gl.glClear(gl.GL_COLOR_BUFFER_BIT)
    gl.glClear(gl.GL_DEPTH_BUFFER_BIT)

    I'm a bit worried by what you say, as I made four red sides so the 3D effect was more obvious with simple lighting. However, I also added a blue back face and from what you say you didn't see it on your device. In fact it's the back face which shows the depth sorting problem, and I think it may be due to the two calls to glDrawElements.

    I had a look and I couldn't see any immediately obvious reasons why the depth order is wrong. I even set the depth mode to GL_LEQUAL just in case, which didn't help. I'll try to find time to play/read a bit more to find out what's the matter.

    By the way, this is a brilliant B4A library, so thank you very much indeed :)

    Best wishes,

    Andrew.
     
  14. derez

    derez Well-Known Member Licensed User

    Andrew, have mercy !
    I have read already 40 pages of the 453 page openGL tutorial .....

    Thank you for that library :sign0060:
     
  15. agraham

    agraham Expert Licensed User

    Yes, I can see the blue back face, it looks the same on both the devices that I have tried it on. It is the red front face and the edge face coming towards you that seem invisible.

    Tomorrow I'll look at improving the error handling. I've an idea that might make finding the line where an error occurs a bit easier.
     
  16. agraham

    agraham Expert Licensed User

    Version 1.3 has a minor internal change to the library not visible externally. The demo has improved error reporting using the ExceptionEx object from my Threading library.

    Placing glsv.DebugFlags = glsv.DEBUG_CHECK_GL_ERROR in Activity_Resume causes an exception as soon as an error occurs and the exception handler will show the line number in the Java source where the problem arose. You can then check the source in a line numbering editor, like Programmers Notepad or Notepad++, to find the actual method.

    If you look carefully at posts 12 and 13 you will see that I had, due to the perils of Intellisense, used gl.GL_DEPTH_BITS instead of gl.GL_DEPTH_BUFFER_BIT which was the reason for the problem. You corrected it without noticing.

    Both
    gl.glClear(gl.GL_COLOR_BUFFER_BIT + gl.GL_DEPTH_BUFFER_BIT)
    and
    gl.glClear( Bit.Or(gl.GL_COLOR_BUFFER_BIT, gl.GL_DEPTH_BUFFER_BIT))
    do in fact work OK
     
  17. geocomputing

    geocomputing Member Licensed User

    Hi,

    I've been playing more (now using v1.3 of your library). The triangles aren't disappearing, they're just being drawn over by triangles behind. I didn't want to make the mistake of thinking I knew what I was doing, especially as I wasn't setting specific surface normals, so I've taken an example from the Hello Android book by Ed Burnette, and translated it into B4A. It's a spinning cube and I know it should work as I've tried it in Eclipse and it worked perfectly. However, on B4A it doesn't seem to be correctly z-buffering.

    I've put the code below in case it helps, and maybe it's useful for anyone who needs a GL example.

    Thanks,

    Andrew.


    <textarea cols="80" rows="30">

    'Activity module
    Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim Timer1 As Timer
    End Sub

    Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim glsv As GLSurfaceView
    Dim eyeangle As Float
    Dim coords(0) As Float
    eyeangle=0
    End Sub

    Sub Timer1_Tick
    eyeangle=eyeangle+0.1
    If eyeangle>(2*3.14159) Then eyeangle=eyeangle-(2*3.14159)
    glsv.RequestRender
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
    glsv.Initialize(glsv.RENDERMODE_WHEN_DIRTY, "glsv")
    Activity.AddView(glsv,0,0,Activity.Width,Activity.Height)
    End Sub

    Sub Activity_Resume
    glsv.Resume ' Must call GLSurfaceView.Resume to restart the rendering thread
    Timer1.Initialize("Timer1", 100)
    Timer1.Enabled = True
    Dim half As Float
    half=0.5
    coords = Array As Float(-half,-half,half,half,-half,half,-half,half,half,half,half,half,-half,-half,-half,-half,half,-half,half,-half,-half,half,half,-half,-half,-half,half,-half,half,half,-half,-half,-half,-half,half,-half,half,-half,-half,half,half,-half,half,-half,half,half,half,half,-half,half,half,half,half,half,-half,half,-half,half,half,-half,-half,-half,half,-half,-half,-half,half,-half,half,half,-half,-half)
    End Sub

    Sub Activity_Pause (UserClosed As Boolean)
    glsv.Pause ' Must call GLSurfaceView.Pause to halt the rendering thread
    Timer1.Enabled = False
    End Sub

    Sub glsv_Draw(gl As GL1)
    gl.glClear(Bit.Or(gl.GL_COLOR_BUFFER_BIT, gl.GL_DEPTH_BUFFER_BIT))
    gl.glMatrixMode(gl.GL_MODELVIEW)
    gl.glLoadIdentity
    gl.gluLookAt(0,0,5, 0,0,0, 0,1,0)
    gl.glRotatef((eyeangle/(2*3.14159))*360,0,1,0)
    gl.glRotatef((eyeangle/(2*3.14159))*360,1,0,0)
    gl.glVertexPointerf(3, coords)
    gl.glColor4f(1,1,1,1)
    gl.glNormal3f(0,0,1)
    gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,0,4)
    gl.glNormal3f(0,0,-1)
    gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,4,4)
    gl.glNormal3f(-1,0,0)
    gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,8,4)
    gl.glNormal3f(1,0,0)
    gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,12,4)
    gl.glNormal3f(0,1,0)
    gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,16,4)
    gl.glNormal3f(0,-1,0)
    gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,20,4)
    End Sub

    Sub glsv_SurfaceChanged(gl As GL1, width As Int, height As Int)
    gl.glViewport(0, 0, width, height)
    gl.glMatrixMode(gl.GL_PROJECTION)
    gl.glLoadIdentity
    Dim ratio As Float
    ratio = width/height
    gl.gluPerspective(45,ratio,1,100)
    End Sub

    Sub glsv_SurfaceCreated(gl As GL1)
    gl.glEnable(gl.GL_DEPTH_TEST)
    gl.glDepthFunc(gl.GL_LESS)
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
    Dim lightAmbient(0),lightDiffuse(0),lightPos(0) As Float
    lightAmbient=Array As Float(0.2,0.2,0.2,1)
    lightDiffuse=Array As Float(1,1,1,1)
    lightPos=Array As Float(1,1,1,1)
    gl.glEnable(gl.GL_LIGHTING)
    gl.glEnable(gl.GL_LIGHT0)
    gl.glLightfv(gl.GL_LIGHT0,gl.GL_AMBIENT,lightAmbient,0)
    gl.glLightfv(gl.GL_LIGHT0,gl.GL_DIFFUSE,lightDiffuse,0)
    gl.glLightfv(gl.GL_LIGHT0,gl.GL_POSITION,lightPos,0)
    Dim matAmbient(0),matDiffuse(0) As Float
    matAmbient=Array As Float(1,1,1,1)
    matDiffuse=Array As Float(1,1,1,1)
    gl.glMaterialfv(gl.GL_FRONT_AND_BACK,gl.GL_AMBIENT,matAmbient,0)
    gl.glMaterialfv(gl.GL_FRONT_AND_BACK,gl.GL_DIFFUSE,matDiffuse,0)
    End Sub

    </textarea>
     
  18. agraham

    agraham Expert Licensed User

    How about posting the actual project to make it easier?
     
  19. agraham

    agraham Expert Licensed User

    I enabled glsv.DebugFlags = glsv.DEBUG_CHECK_GL_ERROR and found that gl.glLightfv was erroring as it was calling the wrong method. Attached zip corrects that.

    I've been through the OpenGL calls and they all seem to be be being passed through correctly so I can't at the moment see why the same code in Eclipse would be different. Can you post the Java from the Eclipse project for comparison?

    EDIT :- Superseded attachment removed to avoid future confusion.
     
    Last edited: May 12, 2011
  20. agraham

    agraham Expert Licensed User

    If I comment out all glNormal3f calls it looks better - but still wrong when I look closely :(
     
    Last edited: May 12, 2011

Share This Page

Loading...