Android Question [SOLVED]i need help with opengl drawline measurements

Mrjoey

Active Member
Licensed User
Longtime User
hello , im using OpenGl 1.7 , im trying to draw lines but the values of the vertices are float therefore when i draw a line x=0 , y = 1 , the line is different when u draw it using canvas , i mean in opengl 0 is in the center of the screen , but on canvas 0 is the top of the screen , i tried to mess around the camera view but im stuck , i see gl.GL_SHORT but cant see integer option , and how to use it , is there any possible way to fix measurements? my activity.width is 720 , so i want 0 in opengl to be the top left and i want to draw a line from 0 to 720 , so the values have to be in integer , and here s my code :
B4X:
Sub glsv_Draw(gl As GL1)
    ' As this is running on a separate thread exceptions will cause the application to force close
    ' and not report the exception as would happen on the main thread so we use a Try Catch block
    ' to trap any errors
   
        'The view wants to be drawn using the suppllied 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.glTranslatef(-int2float(160*GetDeviceLayoutValues.Scale*1000) ,0,-int2float(SeekBar1.Value))
        'gl.glOrthof(-int2float(Panel1.Width*2),int2float(Panel1.Width) ,-20,20,-1,3)
        'gl.glOrthof(-int2float(SeekBar1.Value),int2float(SeekBar1.Value),-20 ,20,-1,3)
        'gl.glRotatef((eyeangle/(2*3.14159))*360,0,1,0)
        'gl.glRotatef((eyeangle/(2*3.14159))*360,1,0,0)
   
        gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
        gl.glVertexPointerf(2, verts)
        'gl.glColor4f(1,1,1,1)
        gl.glDrawArrays(gl.GL_LINE_STRIP,0,(vn/2))
       
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 ratio As Float
        ratio = width/height
        gl.gluPerspective(45, ratio,1,100)
End Sub
Sub glsv_SurfaceCreated(gl As GL1)
    'Called when the surface is created or recreated.
    'Log("Created")
    'Try
        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)
       
    'Catch
        ' catch and report any exceptions on the rendering thread to the main thread
        ' set the glsv.DebugFlags to DEBUG_CHECK_GL_ERROR to raise an exception immediately on a GL error
        'GLException(gl)   
    'End Try
End Sub

i created a sub that converts integer values to float
B4X:
Sub int2float(In As Int)
Return (In / 65536)
End Sub

can u help me plz?tnx in advance.
 

Informatix

Expert
Licensed User
Longtime User
hello , im using OpenGl 1.7 , im trying to draw lines but the values of the vertices are float therefore when i draw a line x=0 , y = 1 , the line is different when u draw it using canvas , i mean in opengl 0 is in the center of the screen , but on canvas 0 is the top of the screen , i tried to mess around the camera view but im stuck , i see gl.GL_SHORT but cant see integer option , and how to use it , is there any possible way to fix measurements? my activity.width is 720 , so i want 0 in opengl to be the top left and i want to draw a line from 0 to 720 , so the values have to be in integer , and here s my code :
B4X:
Sub glsv_Draw(gl As GL1)
    ' As this is running on a separate thread exceptions will cause the application to force close
    ' and not report the exception as would happen on the main thread so we use a Try Catch block
    ' to trap any errors
  
        'The view wants to be drawn using the suppllied 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.glTranslatef(-int2float(160*GetDeviceLayoutValues.Scale*1000) ,0,-int2float(SeekBar1.Value))
        'gl.glOrthof(-int2float(Panel1.Width*2),int2float(Panel1.Width) ,-20,20,-1,3)
        'gl.glOrthof(-int2float(SeekBar1.Value),int2float(SeekBar1.Value),-20 ,20,-1,3)
        'gl.glRotatef((eyeangle/(2*3.14159))*360,0,1,0)
        'gl.glRotatef((eyeangle/(2*3.14159))*360,1,0,0)
  
        gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
        gl.glVertexPointerf(2, verts)
        'gl.glColor4f(1,1,1,1)
        gl.glDrawArrays(gl.GL_LINE_STRIP,0,(vn/2))
      
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 ratio As Float
        ratio = width/height
        gl.gluPerspective(45, ratio,1,100)
End Sub
Sub glsv_SurfaceCreated(gl As GL1)
    'Called when the surface is created or recreated.
    'Log("Created")
    'Try
        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)
      
    'Catch
        ' catch and report any exceptions on the rendering thread to the main thread
        ' set the glsv.DebugFlags to DEBUG_CHECK_GL_ERROR to raise an exception immediately on a GL error
        'GLException(gl)  
    'End Try
End Sub

i created a sub that converts integer values to float
B4X:
Sub int2float(In As Int)
Return (In / 65536)
End Sub

can u help me plz?tnx in advance.
Did you notice the libGDX library? It's a lot easier to use OpenGL with it.
 
Upvote 0

Mrjoey

Active Member
Licensed User
Longtime User
Did you notice the libGDX library? It's a lot easier to use OpenGL with it.
Well yes i did , thank u for ur hardwork , this library can draws points , lines ? if yes can u post a simple example about drawing plz? cz i found that this library is more for bitmaps not for drawing right? tnx :)
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
Well yes i did , thank u for ur hardwork , this library can draws points , lines ? if yes can u post a simple example about drawing plz? cz i found that this library is more for bitmaps not for drawing right? tnx :)
OpenGL doesn't use bitmaps. And the ShapeRenderer class is especially made to draw all kinds of figures (triangles, rectangles, circles, cones, ellipses, X lines, etc.), filled or not. There's an example provided with the library.
 
Upvote 0

Mrjoey

Active Member
Licensed User
Longtime User
OpenGL doesn't use bitmaps. And the ShapeRenderer class is especially made to draw all kinds of figures (triangles, rectangles, circles, cones, ellipses, X lines, etc.), filled or not. There's an example provided with the library.
Biiiiggggg wow man , amazing , ur really a legend , i just dowloaded it and i opend and tested all the examples , im impressed , and ur right u can substitue opengl with this amzing library and use few codes , i will replace opengl with it , and start spending time on experiment , u deserve the best and i can promise u that i will make a donate , and for sure i already followed u , btw im using also the inputslider lib of urs , best regards to u , keep stunning us man and keep forward , thnx man , appreciate ur work :)
 
Upvote 0

John D.

Member
Licensed User
Longtime User
OpenGL doesn't use bitmaps. And the ShapeRenderer class is especially made to draw all kinds of figures (triangles, rectangles, circles, cones, ellipses, X lines, etc.), filled or not. There's an example provided with the library.

It's an excellent library but ShapeRenderer doesn't use VBO's. (What I want to do is to render lots of (2d) lines using VBO's, and be able to zoom and pan. I utterly failed in the attempt using OpenGL2, and after looking at the game libraries it looks like I'm going to have to make the attempt using OpenGL1.)

P.S. -- A beer for you, hope you enjoy.
 
Last edited:
Upvote 0

Informatix

Expert
Licensed User
Longtime User
I agree that ShapeRenderer is not made for intensive graphics. I did not try but maybe you could use a texture to draw a line, using the Sprite batcher instead of the Shape renderer (with always the same texture of course to avoid multiple bindings). You should see a performance improvement.

EDIT: Concerning VBO, libGDX uses them if they are available.
 
Last edited:
Upvote 0

Informatix

Expert
Licensed User
Longtime User
I did a test with SpriteBatch instead of ShapeRenderer to render thousands of rectangles (I used a white texture 2x2 that I colored before rendering to get exactly the same visual result). I confirm the performance improvement. On a Kindle Fire, I get 22 FPS with sR and 28 FPS with sB for 4210 rect. On a Nexus 7 2012, I get 20 FPS with sR and 25 FPS with sB for 5006 rect.

EDIT: these numbers could seem a bit weak (a Nexus 7 is able to render a lot more rectangles at 60fps). In fact, in my test there's a performance throttler to ensure a constant rate of the values to draw, so I can measure the raw performance of drawing.
 
Last edited:
Upvote 0

John D.

Member
Licensed User
Longtime User
Thank you for that, it looks like an excellent performer. But I will be plotting lines using incoming data samples to generate the coordinates in a sort of graphing application. There will be possibly thousands of points spread over perhaps a dozen polylines. Other solutions that people have kindly put up either use the canvas or don't use vbo 's and on reading questions from users it appears they get bogged down when the data points start to get large. Therefore my plan was to get the data into gpu memory and use the shaders to zoom and pan after my data stream is finished. Perhaps I am taking the wrong approach, and any advice you can offer is very much appreciated. Is it feasible to draw arbitrary lines into a texture? My intensive reading on the subject made me think not, but documentation is always for something someone else needs, and I always want to do something nobody ever wrote about. :)
 
Upvote 0

Mrjoey

Active Member
Licensed User
Longtime User
Thank you for that, it looks like an excellent performer. But I will be plotting lines using incoming data samples to generate the coordinates in a sort of graphing application. There will be possibly thousands of points spread over perhaps a dozen polylines. Other solutions that people have kindly put up either use the canvas or don't use vbo 's and on reading questions from users it appears they get bogged down when the data points start to get large. Therefore my plan was to get the data into gpu memory and use the shaders to zoom and pan after my data stream is finished. Perhaps I am taking the wrong approach, and any advice you can offer is very much appreciated. Is it feasible to draw arbitrary lines into a texture? My intensive reading on the subject made me think not, but documentation is always for something someone else needs, and I always want to do something nobody ever wrote about. :)
Well it seems ur drawing waveforms of a song right? i did it using vertex array , it succeded for short songs , shorts i mean about 9 minutes is fine but i tried to draw a song about 120 mins it failed , i thought maybe the buffer is overloaded altough im using an array buffer not VBO's , i deprecated it a while , and im focusing on otherthings , so i can share u some codes to findout how to draw waveforms of a song and if ur goal is drawing song waveforms what library r u using?
B4X:
Dim vn As long
Dim verts(vn)  As Float

B4X:
Sub Drawvl(x1 As Float , y1 As Float, x2 As Float , y2 As Float,index As Long)
Dim mu As Long
    mu = (index * 4)

    verts(mu) = x1

    verts(mu+1) = y1
  
    verts(mu+2) = x2
  
    verts(mu+3) = y2
   
End Sub
Sub drawp(x As Float , y As Float , i As Long )
Dim numb As Long
numb = i * 2
verts(numb) = x
verts(numb+1) = y

End Sub

if u want to draw 1 line , u dim vn = 1 and verts(vn*4) cz 1 line has 4 vertices
if u want to draw 1 point u dim vn = 1 and verts(vn*2) cz 1 point has 2 vertices

so
B4X:
drawvl(0,0,1,1,0)
drawp(0,0,0)

works fine for oscilloscpoe drawing aswell and waveform drawing but my issue was when i vn exceeds the long datatype range it will fail so thats why i deprecated it to learn more about vbo , hope it will help u :)
 
Upvote 0

Mrjoey

Active Member
Licensed User
Longtime User
I did a test with SpriteBatch instead of ShapeRenderer to render thousands of rectangles (I used a white texture 2x2 that I colored before rendering to get exactly the same visual result). I confirm the performance improvement. On a Kindle Fire, I get 22 FPS with sR and 28 FPS with sB for 4210 rect. On a Nexus 7 2012, I get 20 FPS with sR and 25 FPS with sB for 5006 rect.

EDIT: these numbers could seem a bit weak (a Nexus 7 is able to render a lot more rectangles at 60fps). In fact, in my test there's a performance throttler to ensure a constant rate of the values to draw, so I can measure the raw performance of drawing.
i have almost the same idea of John , i want to draw a waveform of a song , ur lib can handle this using spritebatch? i did it using my subs but failed for large data , and i unsure that i wont using opengl anymore i liked ur lib and i found it more powerfull hope it does what i need , althought there is a complimentary course on youtube about opengl , they replace old commands with new ones , heres the link : , but i wont spent my time watching it , btw is there an option for lines like line_strip ? instead of using lines(x,y,x,x,y) i can use point (x,y) and it will link those points to make a line , its more efficient for buffers and memory i think , anyway lets hear ur opinion and see what is best to do for drawing that kind of data , tnx :)
 
Upvote 0

John D.

Member
Licensed User
Longtime User
Mrjoey,

I am not trying to graph the waveform for a song but otherwise what I need to do is quite similar. I have some instrumentation and will be measuring things and reading in values off that using an IOIO board or arduino.

I can probably help you with getting VBO's working. I managed to figure out how to get them set up in Opengl ES 2, but then of course I ran into a few stoppers and after wasting weeks on this I've decided I am going to implement it in the older version, Opengl ES 1. There just isn't enough documentation out there on the new version, and I am not practiced enough to be able to figure out why all my attempts at translating tutorials aimed at getting zoom and pan capability fail to render. I figure by the time they deprecate the older version then we might have a few working examples in B4A for Opengl ES 2. (As in, draw a line, then zoom and pan.)

I was just hoping for a quick cheat on how you used gl.glOrthof.

I'm not sure how many data points there are in a 120 minute music file, but you might eventually run into a memory limitation, and I'm not sure how to discover what that limitation is on different devices. When setting up the VBO you do have to declare its size beforehand. How exactly are you intending to display your waveform? The whole thing all at once, or ??

You didn't say what kind of failure you ran into, but ... vertex arrays in main memory have to be read into the GPU on every draw, and that slows things down.

For drawing line strips, you can use the GL_LINE_STRIP mode not described here:
http://www.opengl.org/sdk/docs/man2/xhtml/glDrawArrays.xml
Draws connected lines on screen. Every vertex specified after first two are connected.

When I get my VBO test program translated over to use Opengl 1, I'll post it here if you like. There are some hoops you have to jump through. :)

--John--
 
Upvote 0

John D.

Member
Licensed User
Longtime User
I agree that ShapeRenderer is not made for intensive graphics. I did not try but maybe you could use a texture to draw a line, using the Sprite batcher instead of the Shape renderer (with always the same texture of course to avoid multiple bindings). You should see a performance improvement.

EDIT: Concerning VBO, libGDX uses them if they are available.

I experimented with the library and found it to be very good. I did ask the developer if ShapeRenderer used VBO's, and his answer was no (I already knew that from looking at the source, but he confirmed it.)

With its excellent abstraction of a camera class, I was able to implement pan and zoom with ease. But I could not figure out any way to hack it to use VBO's for its polyline function. If I could, I would be a happy man. So it looks like I'm going to have to use the Opengl 1 library in B4A to implement the VBO's, then hack together my own zoom and pan functions.

Also, I've been thinking about using SpriteRenderer to make 'pretend' lines. Seems it would require some interesting manipulations to control the image when zooming and panning, no? Is this just a limitation of my imagination?

Thanks for any tips you can lend,

--John--
 
Upvote 0

Mrjoey

Active Member
Licensed User
Longtime User
Mrjoey,

I am not trying to graph the waveform for a song but otherwise what I need to do is quite similar. I have some instrumentation and will be measuring things and reading in values off that using an IOIO board or arduino.

I can probably help you with getting VBO's working. I managed to figure out how to get them set up in Opengl ES 2, but then of course I ran into a few stoppers and after wasting weeks on this I've decided I am going to implement it in the older version, Opengl ES 1. There just isn't enough documentation out there on the new version, and I am not practiced enough to be able to figure out why all my attempts at translating tutorials aimed at getting zoom and pan capability fail to render. I figure by the time they deprecate the older version then we might have a few working examples in B4A for Opengl ES 2. (As in, draw a line, then zoom and pan.)

I was just hoping for a quick cheat on how you used gl.glOrthof.

I'm not sure how many data points there are in a 120 minute music file, but you might eventually run into a memory limitation, and I'm not sure how to discover what that limitation is on different devices. When setting up the VBO you do have to declare its size beforehand. How exactly are you intending to display your waveform? The whole thing all at once, or ??

You didn't say what kind of failure you ran into, but ... vertex arrays in main memory have to be read into the GPU on every draw, and that slows things down.

For drawing line strips, you can use the GL_LINE_STRIP mode not described here:
http://www.opengl.org/sdk/docs/man2/xhtml/glDrawArrays.xml
Draws connected lines on screen. Every vertex specified after first two are connected.

When I get my VBO test program translated over to use Opengl 1, I'll post it here if you like. There are some hoops you have to jump through. :)

--John--

B4X:
Sub glsv_Draw(Gl As GL1)
    ' As this is running on a separate thread exceptions will cause the application to force close
    ' and not report the exception as would happen on the main thread so we use a Try Catch block
    ' to trap any errors
   
        'The view wants to be drawn using the suppllied GL1
       
        Gl.glClear(Bit.OR(Gl.GL_COLOR_BUFFER_BIT, Gl.GL_DEPTH_BUFFER_BIT))
        Gl.glMatrixMode(Gl.GL_PROJECTION)
        Gl.glClearColor(0,0,0,0)
        Gl.glLoadIdentity
       
        Gl.glOrthof(0, Panel1.width/2, Panel1.height, -Panel1.height, -1, 1)
   
        Gl.glVertexPointerf(2, verts)
        Gl.glDrawArrays(Gl.GL_LINE_STRIP,0,(vn/2))
       
End Sub

look at glorthof , i added the glsv to the panel , assigned its size to the panel , so when u draw a point , the x start from the top left of the panel and the y starts from the top of the panel like any canvas do , if u draw a waveform it will stretch it to the panel size , this is how i fixed it .
for the buffer overload , i mean im getting overload from the declaration of "vn" vn is a long , 64 bits , so u can assign millions points but when i declare it for a big song i think it exceeds the 64bits , therefore i maybe have to use bytebuffer instead of buffer array and then send it to the vbo , that s my idea if im not wrong .
i recommend u this library
GraphView Library
 
Upvote 0

John D.

Member
Licensed User
Longtime User
B4X:
Sub glsv_Draw(Gl As GL1)
    ' As this is running on a separate thread exceptions will cause the application to force close
    ' and not report the exception as would happen on the main thread so we use a Try Catch block
    ' to trap any errors

        'The view wants to be drawn using the suppllied GL1
  
        Gl.glClear(Bit.OR(Gl.GL_COLOR_BUFFER_BIT, Gl.GL_DEPTH_BUFFER_BIT))
        Gl.glMatrixMode(Gl.GL_PROJECTION)
        Gl.glClearColor(0,0,0,0)
        Gl.glLoadIdentity
  
        Gl.glOrthof(0, Panel1.width/2, Panel1.height, -Panel1.height, -1, 1)

        Gl.glVertexPointerf(2, verts)
        Gl.glDrawArrays(Gl.GL_LINE_STRIP,0,(vn/2))
  
End Sub

look at glorthof , i added the glsv to the panel , assigned its size to the panel , so when u draw a point , the x start from the top left of the panel and the y starts from the top of the panel like any canvas do , if u draw a waveform it will stretch it to the panel size , this is how i fixed it .
for the buffer overload , i mean im getting overload from the declaration of "vn" vn is a long , 64 bits , so u can assign millions points but when i declare it for a big song i think it exceeds the 64bits , therefore i maybe have to use bytebuffer instead of buffer array and then send it to the vbo , that s my idea if im not wrong .
i recommend u this library
GraphView Library

Thanks for showing how you used glOrthof.

I've looked at the GraphView library, thanks. (Nice, but uses canvas.)

the declaration of "vn" vn is a long , 64 bits , so u can assign millions points but when i declare it for a big song i think it exceeds the 64bits

I assume "vn" is the length of your array. If you look at Opengl datatypes here --
http://opengl.czweb.org/ch03/031-034.html
you can see that Opengl doesn't recognize a 64 bit Int.

If you look at the specification for glDrawArrays, you will see that the length is defined as GLsizei. This is a 32 bit Int. Whatever number you throw at it is getting interpreted as a 32 bit int. So if it is bigger than 2,147,483,647, then it will choke.

I don't know exactly what you need to portray on the screen with this, but if you need to display the whole thing you are probably going to have to do some dithering or 'fudging'. Or display it in chunks.

Edit: if you really want to punish the hardware, you can just use more arrays and draw them in sequence. Opengl will do the dithering for you if there are more points to draw than there are physical pixels to draw to, I guess.

--John--
 
Last edited:
Upvote 0
Top