B4A Library OpenGL library

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.
 

Attachments

  • OpenGL1.7.zip
    51.3 KB · Views: 2,533
Last edited:

agraham

Expert
Licensed User
Longtime User
I think the clue is here
at anywheresoftware.b4a.debug.Debug.PopSubsStack(Debug.java:163)
From comments in the demo
B4X:
' The GLSurfaceView events run on a separate thread to the main thread.
' They therefore must not try to manipulate GUI elements.
' -------------------------------------------------------------------------------------------
' DO NOT ATTEMPT TO PAUSE THE DEBUGGER IN ANY OF SUBS BELOW AS IT MAY HAVE UNEXPECTED RESULTS
' -------------------------------------------------------------------------------------------
' This may be fixed in a future version of Basic4android.
The present implementation of the Basic4android debug code assumes that all Basic4androdi code runs on a single thread. Try compiling in release mode.
 

derez

Expert
Licensed User
Longtime User
I try to run this library in B4J but it gets an error on gl.RenderRequest, not finding the wrapper.
Andrew - is it possible to make it usable in B4J ? thanks.
 

acorrias

Member
Licensed User
Longtime User
Hi
I need to develop a prototipe that opengl to render a semi-transparent texture wrapping a sphere (in order to design a skymap with milky way) with a square that cuts in half the sphere in order to render the horizon. the idea is to rotate the skydome with the skydome with the moon and main stars in order to plan night photograpy.
is it possibile to use textures with alpha channel?
I have seen the nehe demo number 08 (Blending) and I whish to do it with a sphere.

is also possibile to render (other option) the sphere from its inside with the texture wrapping the mesh from its internal?

thanks in advance
alex
 
Last edited:

acorrias

Member
Licensed User
Longtime User
I managed to do it!

this is the code to add to nehe demo (new lines have 'NEW at the end:

Sub glsv_SurfaceCreated(gl As GL1)
gl.glClearDepthf(1.0)
gl.glEnable(gl.GL_DEPTH_TEST)
gl.glDepthFunc(gl.GL_LEQUAL)
gl.glHint(gl.GL_PERSPECTIVE_CORRECTION_HINT,gl.GL_NICEST)
gl.glShadeModel(gl.GL_SMOOTH) 'NEW
gl.glColor4f(1,1,1,0.5) 'NEW
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE) 'NEW

dosetup=True
End Sub

' ===== NEHE 08 - BLENDING =======
Sub Nehe08(gl As GL1)
If dosetup=True Then
ClearStates(gl)
gl.glEnable(gl.GL_TEXTURE_2D) : gl.glEnable(gl.GL_BLEND)
gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY)
' quad
verts2 = Array As Float(-h,-h,-h,h,-h,-h,-h,h,-h,h,h,-h , h,-h,-h,h,-h,h,h,h,-h,h,h,h , h,-h,h,-h,-h,h,h,h,h,-h,h,h , -h,-h,h,-h,-h,-h,-h,h,h,-h,h,-h , -h,h,-h,h,h,-h,-h,h,h,h,h,h , -h,-h,h,h,-h,h,-h,-h,-h,h,-h,-h)
texcoords = Array As Float(0,1,1,1,0,0,1,0 , 0,1,1,1,0,0,1,0 , 0,1,1,1,0,0,1,0 , 0,1,1,1,0,0,1,0 , 0,1,1,1,0,0,1,0 , 0,1,1,1,0,0,1,0)
' texture
bm.Initialize(File.DirAssets,"glass.png")
gl.glGenTextures(1,tex,0)
gl.glBindTexture(gl.GL_TEXTURE_2D,tex(0))
gl.glTexImage2D(gl.GL_TEXTURE_2D,0,bm,0)
gl.glTexParameteri(gl.GL_TEXTURE_2D,gl.GL_TEXTURE_MIN_FILTER,gl.GL_LINEAR)
gl.glTexParameteri(gl.GL_TEXTURE_2D,gl.GL_TEXTURE_MAG_FILTER,gl.GL_LINEAR)
dosetup=False
End If
gl.glClearColor(0.1,0.2,0.4,1)
gl.glClear(Bit.OR(gl.GL_COLOR_BUFFER_BIT, gl.GL_DEPTH_BUFFER_BIT))
gl.glEnable(gl.GL_BLEND) 'NEW
gl.glDisable(gl.GL_DEPTH_TEST) 'NEW

' quad - textured
Reset(gl)
gl.glTranslatef(0.0,0.0,-6.0)
gl.glRotatef(rot,-1.8,1.5,1) ' rotate on all axes
gl.glBindTexture(gl.GL_TEXTURE_2D,tex(0))
gl.glVertexPointerf(3,verts2)
gl.glTexCoordPointerf(2,0,texcoords)
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,0,4)
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,4,4)
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,8,4)
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,12,4)
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,16,4)
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,20,4)
End Sub
 

Johan Schoeman

Expert
Licensed User
Longtime User
I know that this is a very old thread. But it was very educational working through all of this thread.

Some serious great work by especially @agraham and @Jim Brown (and some others that contributed to this thread). Really very impressive work!

So, last post was by @acorrias in Feb 2015 where he posted code in post #146 for the Glass cube. I have added the code to one of @Jim Brown earlier samples in this thread - so, I am posting an updated sample project that includes the "Nehe Lesson 8: Blending" Glass Cube.

Watch out - it sometimes fool the eyes while rotating and the cube looks out of proportion. But it is not - it is the depth perception that fools the eyes.

Thanks @agraham and @Jim Brown for this great work!



glass.png
 

Attachments

  • b4aAddedGlass.zip
    87.7 KB · Views: 240
Last edited:

luke2012

Well-Known Member
Licensed User
Longtime User
I know that this is a very old thread. But it was very educational working through all of this thread.

Some serious great work by especially @agraham and @Jim Brown (and some others that contributed to this thread). Really very impressive work!

So, last post was by @acorrias in Feb 2015 where he posted code in post #146 for the Glass cube. I have added the code to one of @Jim Brown earlier samples in this thread - so, I am posting an updated sample project that includes the "Nehe Lesson 8: Blending" Glass Cube.

Watch out - it sometimes fool the eyes while rotating and the cube looks out of proportion. But it is not - it is the depth perception that fools the eyes.

Thanks @agraham and @Jim Brown for this great work!



View attachment 123740

Very cool :) This is only for Android or there is a iOS version / porting ?
 

agraham

Expert
Licensed User
Longtime User
there is a iOS version / porting ?
No. It use the OpenGL libraries native to and included in the Android operating system so a direct port is not possible. I do not know if a similar library could be made for iOS as I know nothing about Apple products - and it will stay that way!
 

Johan Schoeman

Expert
Licensed User
Longtime User
Attached a sample project for the Nehe Photo-Cube making use of @agraham library in post #1 of this thread. Not sure it is "picture perfect" but seems to do what I would expect it to do. Change it to your liking. Download the lib files from post #1 of this thread and save it to your B4A additional libs folder.

It took a while to figure it out.....


1.png

Sample Code:
B4X:
#Region Module Attributes
    #FullScreen: False
    #IncludeTitle: True
    #ApplicationLabel: PhotoCube
    #VersionCode: 1
    #VersionName:
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region


Sub Process_Globals
    
    Dim Timer1 As Timer

End Sub

Sub Globals
    Dim glsv As GLSurfaceView
    Dim verts2() As Float
    Dim texcoords() As Float
    Dim tex(6) As Int
    Dim bm(6) As Bitmap

    Dim rot As Float
    Dim dosetup As Boolean
End Sub

Sub Activity_Create(FirstTime As Boolean)
    ' OpenGL display setup
    glsv.Initialize(glsv.RENDERMODE_WHEN_DIRTY, "glsv")
    Activity.Initialize("")
    Activity.Color=Colors.RGB(140,100,90)
    Activity.AddView(glsv,10,10,Activity.Width-20,78%y)
    ' listview setup

    dosetup=True

End Sub

Sub Activity_Resume
    glsv.Resume
    Timer1.Initialize("Timer1", 40)
    Timer1.Enabled = True
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    glsv.Pause
    Timer1.Enabled = False
End Sub

Sub Timer1_Tick
    rot = rot + 1.5
    glsv.RequestRender
End Sub

Sub glsv_Draw(gl As GL1)

    Nehe06(gl)
    
End Sub   


' ===== NEHE 06 - BLENDING =======
Sub Nehe06(gl As GL1)
    If dosetup=True Then
        
        bm(0).Initialize(File.DirAssets,"pluto.jpg")
        bm(1).Initialize(File.DirAssets,"glass.png")
        bm(2).Initialize(File.DirAssets,"aacube1.png")
        bm(3).Initialize(File.DirAssets,"stitch.jpg")
        bm(4).Initialize(File.DirAssets,"woodcrate128.png")
        bm(5).Initialize(File.DirAssets,"b4x.jpg")
        
        Dim imgWidth As Int = bm(0).Width
        Dim imgHeight As Int = bm(0).Height
        Dim faceWidth As Float = 2.0f
        Dim faceHeight As Float = 2.0f
        If imgWidth > imgHeight Then
            faceHeight = faceHeight * imgHeight / imgWidth
        Else
            faceWidth = faceWidth * imgWidth / imgHeight   
        End If
        
        Dim faceLeft As Float = -1* faceWidth / 2
        Dim faceRight As Float = -1 * faceLeft
        Dim faceTop As Float = faceHeight / 2
        Dim faceBottom As Float = -1 * faceTop
        
        
        verts2 = Array As Float(faceLeft, faceBottom, 0.0f , faceRight, faceBottom, 0.0f, faceLeft, faceTop, 0.0f, faceRight, faceTop, 0.0f, _
                                faceLeft, faceBottom, 0.0f , faceRight, faceBottom, 0.0f, faceLeft, faceTop, 0.0f, faceRight, faceTop, 0.0f, _
                                faceLeft, faceBottom, 0.0f , faceRight, faceBottom, 0.0f, faceLeft, faceTop, 0.0f, faceRight, faceTop, 0.0f, _
                                faceLeft, faceBottom, 0.0f , faceRight, faceBottom, 0.0f, faceLeft, faceTop, 0.0f, faceRight, faceTop, 0.0f, _
                                faceLeft, faceBottom, 0.0f , faceRight, faceBottom, 0.0f, faceLeft, faceTop, 0.0f, faceRight, faceTop, 0.0f, _
                                faceLeft, faceBottom, 0.0f , faceRight, faceBottom, 0.0f, faceLeft, faceTop, 0.0f, faceRight, faceTop, 0.0f )
                                
        texcoords = Array As Float(0.0f,1.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f ,  _
                                   0.0f,1.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f ,  _
                                   0.0f,1.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f ,  _
                                   0.0f,1.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f ,  _
                                   0.0f,1.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f ,  _
                                   0.0f,1.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f)

        gl.glGenTextures(6,tex,0)
        For i = 0 To 5
            tex(i) = i
            gl.glBindTexture(gl.GL_TEXTURE_2D,tex(i))
            gl.glTexImage2D(gl.GL_TEXTURE_2D,0,bm(i),0)
            gl.glTexParameteri(gl.GL_TEXTURE_2D,gl.GL_TEXTURE_MIN_FILTER,gl.GL_LINEAR)
        Next
        dosetup=False
    End If
    
    gl.glClear(Bit.Or(gl.GL_COLOR_BUFFER_BIT, gl.GL_DEPTH_BUFFER_BIT))
    gl.glLoadIdentity
    gl.glTranslatef(0.0,0.0,-6.0)
    gl.glRotatef(rot,1.0,1.0,1.0) ' rotate on all axes
    
    gl.glFrontFace(gl.GL_CCW)
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
    gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY)
    gl.glVertexPointerf(3, verts2)
    gl.glTexCoordPointerf(2, 0,texcoords)
    
    
    gl.glPushMatrix
    gl.glTranslatef(0.0f, 0.0f, 1.05f)
    gl.glBindTexture(gl.GL_TEXTURE_2D,tex(0))
    gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,0,4)
    gl.glPopMatrix
    
    gl.glPushMatrix
    gl.glRotatef(270.0f, 0.0f, 1.0f, 0.0f)
    gl.glTranslatef(0.0f, 0.0f, 1.05f)
    gl.glBindTexture(gl.GL_TEXTURE_2D,tex(1))
    gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,4,4)
    gl.glPopMatrix
    
    gl.glPushMatrix
    gl.glRotatef(180.0f, 0.0f, 1.0f, 0.0f)
    gl.glTranslatef(0.0f, 0.0f, 1.05f)
    gl.glBindTexture(gl.GL_TEXTURE_2D,tex(2))
    gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,8,4)
    gl.glPopMatrix
    
    gl.glPushMatrix
    gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f)
    gl.glTranslatef(0.0f, 0.0f, 1.05f)
    gl.glBindTexture(gl.GL_TEXTURE_2D,tex(3))
    gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,12,4)
    gl.glPopMatrix
    
    gl.glPushMatrix
    gl.glRotatef(270.0f, 1.0f, 0.0f, 0.0f)
    gl.glTranslatef(0.0f, 0.0f, 1.05f)
    gl.glBindTexture(gl.GL_TEXTURE_2D,tex(4))
    gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,16,4)
    gl.glPopMatrix
    
    gl.glPushMatrix
    gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f)
    gl.glTranslatef(0.0f, 0.0f, 1.05f)
    gl.glBindTexture(gl.GL_TEXTURE_2D,tex(5))
    gl.glDrawArrays(gl.GL_TRIANGLE_STRIP,20,4)
    gl.glPopMatrix
    
    gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
    gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY)

End Sub

'this is the code in the sample RENDERER
Sub glsv_SurfaceCreated(gl As GL1)
    gl.glClearColor(0.5f,0.0f,1.0f,0.0f)                                'set the background color of the surface view
    gl.glClearDepthf(1.0)                                           'set the depth's clear-value to farthest
    gl.glEnable(gl.GL_DEPTH_TEST)                                   'enable depth-buffer for hidden surface removal
    gl.glDepthFunc(gl.GL_LEQUAL)                                    'the type of depth testing to do
    gl.glHint(gl.GL_PERSPECTIVE_CORRECTION_HINT,gl.GL_NICEST)       'nice perspective view
    gl.glShadeModel(gl.GL_SMOOTH)                                     'enable smooth shading of color
    gl.glDisable(gl.GL_DITHER)                                        'disable dithering for better performance
    gl.glEnable(gl.GL_TEXTURE_2D)
    dosetup=True
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.0,ratio,0.5,100.0)
    gl.glMatrixMode(gl.GL_MODELVIEW)
    dosetup=True
End Sub
 

Attachments

  • PhotoCube.zip
    172 KB · Views: 209

Johan Schoeman

Expert
Licensed User
Longtime User
Drawing a 3D colored pyramid making use of gl.glDrawElements in place of gl.glDrawArrays:


1.png


B4A:
#Region Module Attributes
    #FullScreen: False
    #IncludeTitle: True
    #ApplicationLabel: OpenGLIndicesPyramid
    #VersionCode: 1
    #VersionName:
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

'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 dosetup As Boolean = False
    Dim vertices() As Float
    Dim indices() As Short
    Dim color() As Float
    Dim lightAmbient() As Float
    Dim lightDiffuse() As Float
    Dim lightPosition() As Float
    Dim lightDirection() As Float
    
    Dim rot As Float = 0.0f
End Sub

Sub Timer1_Tick
'    eyeangle=eyeangle+0.1
'    If eyeangle>(2*3.14159) Then eyeangle=eyeangle-(2*3.14159)
    glsv.RequestRender
    rot = rot + 1.0f
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", 20)
    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 GL1)
    'The view wants to be drawn using the suppllied GL10
    If dosetup = True Then
        
        ClearStates(gl)

        'define cube vertices, indices, colors
                vertices = Array As Float( 0.0f,  0.0f, -2.0f, _
                                           1.0f,  1.0f,  0.0f, _
                                          -1.0f,  1.0f,  0.0f, _
                                          -1.0f, -1.0f,  0.0f, _
                                           1.0f, -1.0f,  0.0f, _
                                           1.0f,  1.0f,  0.0f)
                                  
        indices = Array As Short(3, 2, 5, _
                                 4, 3, 5, _
                                 0, 1, 2, _
                                 0, 2, 3, _
                                 0, 3, 4, _
                                 0, 4, 1)
                                
        color = Array As Float(0.0f, 1.0f, 1.0f, 1.0f, _
                               1.0f, 0.0f, 0.0f, 1.0f, _
                               1.0f, 1.0f, 0.0f, 1.0f, _
                               0.0f, 1.0f, 0.0f, 1.0f, _
                               0.0f, 0.0f, 1.0f, 1.0f, _
                               1.0f, 0.0f, 1.0f, 1.0f, _
                               1.0f, 1.0f, 1.0f, 1.0f, _
                               0.0f, 1.0f, 1.0f, 1.0f)                                 
                                
        lightAmbient = Array As Float(0.1f, 0.3f, 0.3f, 0.1f)
        lightDiffuse = Array As Float(0.7f, 0.7f, 0.7f, 1.0f)
        lightPosition = Array As Float(1.0f, 2.0f, 0.5f, 2.0f)
        lightDirection = Array As Float(0.0f, 1.0f, 0.5f)
        
        dosetup = False
    End If
    
    gl.glFrontFace(gl.GL_CCW)
    gl.glClearColor(0.0f, 0.0f, 0.3f, 0.0f)
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
    gl.glEnableClientState(gl.GL_COLOR_ARRAY)
    gl.glClear(Bit.Or(gl.GL_COLOR_BUFFER_BIT, gl.GL_DEPTH_BUFFER_BIT))

    Reset(gl)
    gl.glTranslatef(0.0f,0.0f,-12.0)
    gl.glRotatef(rot, 1.0f, 0.4f, 0.5f)

    gl.glVertexPointerf(3,vertices)
    gl.glColorPointerf(4, 0, color)

    gl.glDrawElements(gl.GL_TRIANGLES,indices.Length,indices)
        
    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, lightPosition, 0)
    gl.glLightfv(gl.GL_LIGHT0, gl.GL_SPOT_DIRECTION, lightDirection, 0)

    gl.glMaterialf(gl.GL_FRONT, gl.GL_SHININESS, 180)
    gl.glMaterialf(gl.GL_BACK, gl.GL_SHININESS, 90)
    gl.glMaterialf(gl.GL_FRONT_AND_BACK, gl.GL_SHININESS, 45)
    
    gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
    gl.glDisableClientState(gl.GL_COLOR_ARRAY)

End Sub

Sub glsv_SurfaceChanged(gl As GL1, width As Int, height As Int)
    'Called when the surface has changed size.
    gl.glViewport(0, 0, width, height)
    gl.glMatrixMode(gl.GL_PROJECTION)
    gl.glLoadIdentity
    Dim aspect As Float = width/height                            'the width / height is propotional to the width and height of the GLSURFACEVIEW
    gl.gluPerspective(45.0f, aspect, 0.1f, 100.0f)                'this will make the square look square rather than rectangular should SV width and height not be the same
    gl.glMatrixMode(gl.GL_MODELVIEW)
    dosetup = True

End Sub

Sub glsv_SurfaceCreated(gl As GL1)
    'Called when the surface is created or recreated.
    gl.glClearDepthf(1.0f)
    gl.glEnable(gl.GL_DEPTH_TEST)
    gl.glDepthFunc(gl.GL_LEQUAL)
    gl.glHint(gl.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_NICEST)
    gl.glShadeModel(gl.GL_SMOOTH)
    gl.glDisable(gl.GL_DITHER)
    dosetup = True
    
End Sub

Sub Reset(gl As GL1)
    gl.glLoadIdentity
    gl.glScalef(0.5,0.5,0.5)
End Sub

Sub ClearStates(gl As GL1)
    
    gl.glDisable(gl.GL_TEXTURE_2D)
    gl.glDisable(gl.GL_BLEND)
    gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
    gl.glDisableClientState(gl.GL_COLOR_ARRAY)
    gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY)
    gl.glDisableClientState(gl.GL_NORMAL_ARRAY)
End Sub
 

Attachments

  • OpenGLIndicesPyramid.zip
    8.4 KB · Views: 214

Johan Schoeman

Expert
Licensed User
Longtime User
A colorful spinning Hexagon using gl.glDrawElements in place of gl.glDrawArrays:



1.png


B4A:
#Region Module Attributes
    #FullScreen: False
    #IncludeTitle: True
    #ApplicationLabel: OpenGlIndicesHexagon
    #VersionCode: 1
    #VersionName:
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

'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 dosetup As Boolean = False
    Dim vertices() As Float
    Dim indices() As Short
    Dim color() As Float
    Dim rot As Float = 0.0f
End Sub

Sub Timer1_Tick
'    eyeangle=eyeangle+0.1
'    If eyeangle>(2*3.14159) Then eyeangle=eyeangle-(2*3.14159)
    glsv.RequestRender
    rot = rot + 1.0f
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", 20)
    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 GL1)
    'The view wants to be drawn using the suppllied GL10
    If dosetup = True Then
        
        ClearStates(gl)

        'define cube vertices, indices, colors
        vertices = Array As Float(0.0f,   0.0f, 0.0f, _       'center
                                 -0.5f,   1.0f, 0.0f, _       'left top
                                  0.5f,   1.0f, 0.0f, _       'right top
                                  1.0f,   0.0f, 0.0f, _       'right
                                  0.5f,  -1.0f, 0.0f, _       'right bottom (notice sign)
                                 -0.5f,  -1.0f, 0.0f, _       'left bottom
                                 -1.0f,   0.0f, 0.0f)         'left
                                  
        indices = Array As Short(0, 1, 2, 3, 4, 5, 6, 1) 
                                
        color = Array As Float(0.0f, 1.0f, 1.0f, 1.0f, _
                               1.0f, 0.0f, 0.0f, 1.0f, _
                               1.0f, 1.0f, 0.0f, 1.0f, _
                               0.0f, 1.0f, 0.0f, 1.0f, _
                               0.0f, 0.0f, 1.0f, 1.0f, _
                               1.0f, 0.0f, 1.0f, 1.0f, _
                               1.0f, 1.0f, 1.0f, 1.0f, _
                               0.0f, 1.0f, 1.0f, 1.0f)
        
        dosetup = False
    End If
    
    gl.glFrontFace(gl.GL_CCW)
    gl.glClearColor(0.0f, 0.0f, 0.3f, 0.0f)
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
    gl.glEnableClientState(gl.GL_COLOR_ARRAY)
    gl.glClear(Bit.Or(gl.GL_COLOR_BUFFER_BIT, gl.GL_DEPTH_BUFFER_BIT))

    Reset(gl)
    gl.glTranslatef(0.0f,0.0f,-12.0)
    gl.glRotatef(rot, 0.7f, 1.0f, 0.5f)
    gl.glVertexPointerf(3,vertices)
    gl.glColorPointerf(4, 0, color)
'    gl.glDrawArrays(gl.GL_TRIANGLES,0,3)
    gl.glDrawElements(gl.GL_TRIANGLE_FAN,indices.Length,indices)
    
    gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
    gl.glDisableClientState(gl.GL_COLOR_ARRAY)

End Sub

Sub glsv_SurfaceChanged(gl As GL1, width As Int, height As Int)
    'Called when the surface has changed size.
    gl.glViewport(0, 0, width, height)
    gl.glMatrixMode(gl.GL_PROJECTION)
    gl.glLoadIdentity
    Dim aspect As Float = width/height                            'the width / height is propotional to the width and height of the GLSURFACEVIEW
    gl.gluPerspective(45.0f, aspect, 0.1f, 100.0f)                'this will make the square look square rather than rectangular should SV width and height not be the same
    gl.glMatrixMode(gl.GL_MODELVIEW)
    dosetup = True

End Sub

Sub glsv_SurfaceCreated(gl As GL1)
    'Called when the surface is created or recreated.
    gl.glClearDepthf(1.0f)
    gl.glEnable(gl.GL_DEPTH_TEST)
    gl.glDepthFunc(gl.GL_LEQUAL)
    gl.glHint(gl.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_NICEST)
    gl.glShadeModel(gl.GL_SMOOTH)
    gl.glDisable(gl.GL_DITHER)
    dosetup = True
    
End Sub

Sub Reset(gl As GL1)
    gl.glLoadIdentity
    gl.glScalef(0.5,0.5,0.5)
End Sub

Sub ClearStates(gl As GL1)
    
    gl.glDisable(gl.GL_TEXTURE_2D)
    gl.glDisable(gl.GL_BLEND)
    gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
    gl.glDisableClientState(gl.GL_COLOR_ARRAY)
    gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY)
    gl.glDisableClientState(gl.GL_NORMAL_ARRAY)
End Sub
 

Attachments

  • OpenGLIndicesHexagon.zip
    8.3 KB · Views: 182

Johan Schoeman

Expert
Licensed User
Longtime User
A colorful spinning cube using gl.glDrawElements in place of gl.glDrawArrays:

1.png


B4A:
#Region Module Attributes
    #FullScreen: False
    #IncludeTitle: True
    #ApplicationLabel: OpenGlIndicesCube
    #VersionCode: 1
    #VersionName:
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

'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 dosetup As Boolean = False
    Dim vertices() As Float
    Dim indices() As Short
    Dim color() As Float
    Dim h As Float = 1.0f
    Dim rot As Float = 0.0f
End Sub

Sub Timer1_Tick
'    eyeangle=eyeangle+0.1
'    If eyeangle>(2*3.14159) Then eyeangle=eyeangle-(2*3.14159)
    glsv.RequestRender
    rot = rot + 1.0f
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", 20)
    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 GL1)
    'The view wants to be drawn using the suppllied GL10
    If dosetup = True Then
        
        ClearStates(gl)

        'define cube vertices, indices, colors
        vertices = Array As Float(-h, -h, -h, _
                                   h, -h, -h, _
                                   h,  h, -h, _
                                  -h,  h, -h, _
                                  -h, -h,  h, _
                                   h, -h,  h, _
                                   h,  h,  h, _
                                  -h,  h,  h)
                                  
        indices = Array As Short(0, 1, 3, 3, 1, 2, _  ' Front face.
                                 0, 1, 4, 4, 5, 1, _  ' Bottom face.
                                 1, 2, 5, 5, 6, 2, _  ' Right face.
                                 2, 3, 6, 6, 7, 3, _  ' Top face.
                                 3, 7, 4, 4, 3, 0, _  ' Left face.
                                 4, 5, 7, 7, 6, 5)    ' Rear face.)
                                
        color = Array As Float(0.0f, 1.0f, 1.0f, 1.0f, _
                               1.0f, 0.0f, 0.0f, 1.0f, _
                               1.0f, 1.0f, 0.0f, 1.0f, _
                               0.0f, 1.0f, 0.0f, 1.0f, _
                               0.0f, 0.0f, 1.0f, 1.0f, _
                               1.0f, 0.0f, 1.0f, 1.0f, _
                               1.0f, 1.0f, 1.0f, 1.0f, _
                               0.0f, 1.0f, 1.0f, 1.0f)
        
        dosetup = False
    End If
    
    gl.glFrontFace(gl.GL_CCW)
    gl.glClearColor(0.0f, 0.0f, 0.3f, 0.0f)
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
    gl.glEnableClientState(gl.GL_COLOR_ARRAY)
    gl.glClear(Bit.Or(gl.GL_COLOR_BUFFER_BIT, gl.GL_DEPTH_BUFFER_BIT))

    Reset(gl)
    gl.glTranslatef(0.0f,0.0f,-12.0)
    gl.glRotatef(rot, 0.7f, 1.0f, 0.5f)
    gl.glVertexPointerf(3,vertices)
    gl.glColorPointerf(4, 0, color)
'    gl.glDrawArrays(gl.GL_TRIANGLES,0,3)
    gl.glDrawElements(gl.GL_TRIANGLES,indices.Length,indices)
    
    gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
    gl.glDisableClientState(gl.GL_COLOR_ARRAY)

End Sub

Sub glsv_SurfaceChanged(gl As GL1, width As Int, height As Int)
    'Called when the surface has changed size.
    gl.glViewport(0, 0, width, height)
    gl.glMatrixMode(gl.GL_PROJECTION)
    gl.glLoadIdentity
    Dim aspect As Float = width/height                            'the width / height is propotional to the width and height of the GLSURFACEVIEW
    gl.gluPerspective(45.0f, aspect, 0.1f, 100.0f)                'this will make the square look square rather than rectangular should SV width and height not be the same
    gl.glMatrixMode(gl.GL_MODELVIEW)
    dosetup = True

End Sub

Sub glsv_SurfaceCreated(gl As GL1)
    'Called when the surface is created or recreated.
    gl.glClearDepthf(1.0f)
    gl.glEnable(gl.GL_DEPTH_TEST)
    gl.glDepthFunc(gl.GL_LEQUAL)
    gl.glHint(gl.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_NICEST)
    gl.glShadeModel(gl.GL_SMOOTH)
    gl.glDisable(gl.GL_DITHER)
    dosetup = True
    
End Sub

Sub Reset(gl As GL1)
    gl.glLoadIdentity
    gl.glScalef(0.5,0.5,0.5)
End Sub

Sub ClearStates(gl As GL1)
    
    gl.glDisable(gl.GL_TEXTURE_2D)
    gl.glDisable(gl.GL_BLEND)
    gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
    gl.glDisableClientState(gl.GL_COLOR_ARRAY)
    gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY)
    gl.glDisableClientState(gl.GL_NORMAL_ARRAY)
End Sub
 

Attachments

  • OpenGLIndicesCube.zip
    8.4 KB · Views: 209
Top