View Full Version : glDrawElements and related opengl functions
Hi, i am confused by the way we use glDrawElements in thinbasic and how to call its parameters, i know it depicts the points which are referred to by indices array, the points are stored previously using glVertexPointer and colored with glColorPointer
when using this:
glDrawElements(%GL_POINTS ,2*Nb*Nb*2,%GL_UNSIGNED_BYTE, VarPtr(indices(1)))
--in fact i want this: glDrawElements(%GL_LINES ,2*Nb*Nb*2,%GL_UNSIGNED_INT, VarPtr(indices(1)))--
it works but erroneous, even it gives a clue to what the shape is.
what we should use is %GL_UNSIGNED_INT or %GL_UNSIGNED_SHORT
but here we have an error message thinbasic encountered a problem
the example is a modified and simplified from https://en.wikibooks.org/wiki/OpenGL_Programming/Scientific_OpenGL_Tutorial_04 i put in my consideration that thinbasic arrays begins with index 1
the function i want to draw can be seen in http://www.wolframalpha.com/ using this sentence: plot Sin(10*(x^2+z^2))/5
i can't run it using MingW on windows, too many errors, the examples are downloadable from the bottom of that page. i find thinbasic easier to use with classic opengl . the referred example use a shader for texturing the curve but that another problem.
i saw the function glVertexPointer in one thinbasic examples, but the example are extremely complex even it is interesting. what i seek is the shortest example which show the usage essence of the classic opengl functions in thinbasic. i have used some tbgl function to rotate the shape. it is interesting to mix the functions from the two worlds
thanks
Uses "tbgl"
#INCLUDE "%app_includepath%\thinbasic_gl.inc"
#INCLUDE "%app_includepath%\thinbasic_glu.inc"
Dim hwnd As DWord
hwnd = TBGL_CreateWindowEx("glDrawElements example - esc to exit", 600, 600, 32, 0)
TBGL_ShowWindow
TBGL_ResetKeyState()
glPointSize( 3.0 ) ' just to show the curve in bold
'init
While TBGL_IsWindow(hwnd)
TBGL_ClearFrame
init
display
TBGL_DrawFrame
If TBGL_GetWindowKeyState( hwnd, %VK_ESCAPE) Then Exit While
Wend
TBGL_DestroyWindow
Sub init()
glMatrixMode(%GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, 800/600, 1.0, 60.0)
glMatrixMode(%GL_MODELVIEW)
glTranslatef(0, 1, -5)
glShadeModel(%GL_SMOOTH)
glEnable(%GL_DEPTH_TEST)
Type Point3D
x As Single
y As Single
z As Single
red As Single
green As Single
blue As Single
End Type
Global Nb As Integer =40
Dim a,b As Integer
'Sizee = (Nb+1)*(Nb+1)
Global Vertex(Nb,Nb) As Point3D
Dim xMin, yMin, zMin, xMax, yMax, zMax, range, step1, x, y, z As Single
xMin = -1 : yMin = -1: zMin = -1: xMax = 1: yMax = 1: zMax = 1
'xMin = -0.5 : zMin = -0.5 : xMax = 0.5: zMax = 0.5
range = xMax - xMin
step1 = range / Nb
x = xMin: z = zMin : y = yMin
For b=1 To Nb
For a=1 To Nb
y = Sin(10*(x^2+z^2))/5
Vertex(a,b).x = x
Vertex(a,b).y = y
Vertex(a,b).z = z
If y>=0 Then
Vertex(a,b).red = 1.0 :Vertex(a,b).green = 0.0 :Vertex(a,b).blue = 0
Else
Vertex(a,b).red = 1.0 :Vertex(a,b).green = 0.0 :Vertex(a,b).blue = 0
EndIf
x = x + step1
Next a
x = xMin
z = z + step1
Next b
'=================================================================================
Dim i As Integer
Global indices(2 * Nb * (Nb+1) * 2)
Dim yy,xx As Integer
i = 1
'Horizontal grid lines
For yy = 1 To Nb
For xx = 1 To Nb-2
indices(i) = yy * (Nb+1) + xx
i = i+1
indices(i) = yy * (Nb+1) + xx + 1
i = i+1
Next
Next
'i=1
' Vertical grid lines
For xx = 1 To Nb
For yy = 1 To Nb-2
indices(i) = yy * (Nb+1) + xx
i=i+1
indices(i) = (yy + 1) * (Nb+1) + xx
i=i+1
Next
Next
glScalef(2,2,2) ' amplify the graphics Size by 2
'position camera at 0,1.5,1 __ object position 0,1,0___0,1,0 direction
gluLookAt( 0, 1.5, 1,
0, 1, 0,
0, 1, 0 )
End Sub
Sub display()
glclear(%gl_color_buffer_bit)
TBGL_Rotate GetTickCount/10,0,1,0
'glRotatef(1, 0, 1, 0)' -- 0,1,0 rotate around Y
glClear(%GL_COLOR_BUFFER_BIT Or %GL_DEPTH_BUFFER_BIT)
glClearColor(1, 1, 1, 1)
glEnableClientState(%GL_VERTEX_ARRAY )
glEnableClientState(%GL_COLOR_ARRAY)
glVertexPointer(3, %GL_FLOAT,SizeOf(Point3D),VarPtr(Vertex(1,1)))
glColorPointer(3, %GL_FLOAT, SizeOf(Point3D), VarPtr(Vertex(1,1).red))
'glDrawElements(mode,count,Type, indices Address)
'glDrawElements(%GL_LINES ,2*Nb*Nb*2,%GL_UNSIGNED_INT, VarPtr(indices(1)))
glDrawElements(%GL_POINTS ,2*Nb*Nb*2,%GL_UNSIGNED_BYTE, VarPtr(indices(1)))
glDisableClientState(%GL_VERTEX_ARRAY)
glDisableClientState(%GL_COLOR_ARRAY)
End Sub
Petr Schreiber
10-11-2015, 20:00
Hi Primo,
thanks for your question!
Actually, I think the problem is in fact you don't declare type. Instead of:
Global indices(2 * Nb * (Nb+1) * 2)
...change to:
Global indices(2 * Nb * (Nb+1) * 2) As DWord ' Can be also specified as UInt32
...then, you can use:
glDrawElements(%GL_POINTS , CountOf(indices), %GL_UNSIGNED_INT, VarPtr(indices(1)))
If you don't mind, there is also managed and maybe more user friendly way to render geometry from array - GBuffers. It is a bit different, but maybe you can try as well...
Uses "TBGL"
Function TBMAIN()
Local hWnd As DWord
Local FrameRate As Double
' -- Create and show window
hWnd = TBGL_CreateWindowEx("GBuffers with triangles - press ESC to quit", 640, 480, 32, %TBGL_WS_WINDOWED Or %TBGL_WS_CLOSEBOX)
TBGL_ShowWindow
TBGL_BackColor 255,255,255
' -- Create 3D triangle buffer
Dim gbTriangle As DWord = TBGL_GBufferCreate(%TBGL_Triangles, %TBGL_3D)
' -- Define data for it
Dim VertexA(3) As TBGL_tVector3F
Dim ColorA(3) As TBGL_tRGB
' -- Vertices
VertexA(1).x = -1
VertexA(1).y = -1
VertexA(1).z = 0
VertexA(2).x = 1
VertexA(2).y = -1
VertexA(2).z = 0
VertexA(3).x = 0
VertexA(3).y = 1
VertexA(3).z = 0
' -- Colors
ColorA(1).r = 255
ColorA(1).g = 128
ColorA(1).b = 64
ColorA(2).r = 0
ColorA(2).g = 255
ColorA(2).b = 0
ColorA(3).r = 0
ColorA(3).g = 0
ColorA(3).b = 255
' -- Create buffer dynamically linked to the arrays above
TBGL_GBufferDefineFromArray(gbTriangle, %TBGL_Dynamic, CountOf(VertexA), VertexA(1), ColorA(1))
' -- Resets status of all keys
TBGL_ResetKeyState()
' -- Main loop
While TBGL_IsWindow(hWnd)
FrameRate = TBGL_GetFrameRate
TBGL_ClearFrame
TBGL_Camera(0, 0, 5, 0, 0, 0)
' -- Turn triangle
TBGL_Rotate GetTickCount/100, 0, 1, 0
' -- Render it
tbgl_GBufferRender(gbTriangle)
' -- Modify the colors
ColorA(1).r = 128+Sin(GetTickCount/100)*127
ColorA(2).g = 128+Sin(GetTickCount/100+1)*127
ColorA(3).b = 128+Sin(GetTickCount/100+2)*127
TBGL_DrawFrame
' -- ESCAPE key to exit application
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While
Wend
' -- Destroying the buffer is not necessary,
' -- the garbage collector will take care of it
' -- Destroy window
TBGL_DestroyWindow
End Function
Petr
Thanks Petr for the solution which will guide me also in other codes, i have attached the modified code below since my previous one somehow was not copied correctly from the ide to the forum using chrome, will try again but after copying the ide content to notepad then again to the forum. so the code problem is solved and only my duty is to think how to weave the indices array correctly .
and also thanks for the beautifull, lucid and short example for using GBUFFER
i will post in the future any example i find interesting and short
thanks
Uses "tbgl"
#INCLUDE "%app_includepath%\thinbasic_gl.inc"
#INCLUDE "%app_includepath%\thinbasic_glu.inc"
Dim hwnd As DWord
hwnd = TBGL_CreateWindowEx("glDrawElements example - esc to exit", 600, 600, 32, 0)
TBGL_ShowWindow
TBGL_ResetKeyState()
glPointSize( 2.0 ) ' just to show the curve in bold
'init
While TBGL_IsWindow(hwnd)
TBGL_ClearFrame
init
display
TBGL_DrawFrame
If TBGL_GetWindowKeyState( hwnd, %VK_ESCAPE) Then Exit While
Wend
TBGL_DestroyWindow
Sub init()
glMatrixMode(%GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, 800/600, 1.0, 60.0)
glMatrixMode(%GL_MODELVIEW)
glTranslatef(0, 1, -5)
glShadeModel(%GL_SMOOTH)
glEnable(%GL_DEPTH_TEST)
Type Point3D
x As Single
y As Single
z As Single
red As Single
green As Single
blue As Single
End Type
Global Nb As Integer =40
Dim a,b As Integer
'Sizee = (Nb+1)*(Nb+1)
Global Vertex(Nb,Nb) As Point3D
Dim xMin, yMin, zMin, xMax, yMax, zMax, range, step1, x, y, z As Single
xMin = -1 : yMin = -1: zMin = -1: xMax = 1: yMax = 1: zMax = 1
'xMin = -0.5 : zMin = -0.5 : xMax = 0.5: zMax = 0.5
range = xMax - xMin
step1 = range / Nb
x = xMin: z = zMin : y = yMin
For b=1 To Nb
For a=1 To Nb
y = Sin(10*(x^2+z^2))/5
Vertex(a,b).x = x
Vertex(a,b).y = y
Vertex(a,b).z = z
If y>=0 Then
Vertex(a,b).red = 1.0 :Vertex(a,b).green = 0.0 :Vertex(a,b).blue = 0
Else
Vertex(a,b).red = 1.0 :Vertex(a,b).green = 0.0 :Vertex(a,b).blue = 0
EndIf
x = x + step1
Next a
x = xMin
z = z + step1
Next b
'=================================================================================
Dim i As Integer
'Global indices(2 * Nb * (Nb+1) * 2)
Global indices(2 * Nb * (Nb+1) * 2) As DWord ' Can be also specified as UInt32
Dim yy,xx As Integer
i = 1
'Horizontal grid lines
For yy = 1 To Nb
For xx = 1 To Nb-2
indices(i) = yy * (Nb+1) + xx
i = i+1
indices(i) = yy * (Nb+1) + xx + 1
i = i+1
Next
Next
'i=1
' Vertical grid lines
For xx = 1 To Nb
For yy = 1 To Nb-2
indices(i) = yy * (Nb+1) + xx
i=i+1
indices(i) = (yy + 1) * (Nb+1) + xx
i=i+1
Next
Next
glScalef(2,2,2) ' amplify the graphics Size by 2
'position camera at 0,1.5,1 __ object position 0,1,0___0,1,0 direction
gluLookAt( 0, 1.5, 1,
0, 1, 0,
0, 1, 0 )
End Sub
Sub display()
glclear(%gl_color_buffer_bit)
TBGL_Rotate GetTickCount/10,0,1,0
'glRotatef(1, 0, 1, 0)' -- 0,1,0 rotate around Y
glClear(%GL_COLOR_BUFFER_BIT Or %GL_DEPTH_BUFFER_BIT)
glClearColor(1, 1, 1, 1)
glEnableClientState(%GL_VERTEX_ARRAY )
glEnableClientState(%GL_COLOR_ARRAY)
glVertexPointer(3, %GL_FLOAT,SizeOf(Point3D),VarPtr(Vertex(1,1)))
glColorPointer(3, %GL_FLOAT, SizeOf(Point3D), VarPtr(Vertex(1,1).red))
'glDrawElements(mode,count,Type, indices Address)
'glDrawElements(%GL_LINES ,2*Nb*Nb*2,%GL_UNSIGNED_INT, VarPtr(indices(1)))
'glDrawElements(%GL_POINTS ,2*Nb*Nb*2,%GL_UNSIGNED_BYTE, VarPtr(indices(1)))
glDrawElements(%GL_POINTS , CountOf(indices), %GL_UNSIGNED_INT, VarPtr(indices(1)))
glDisableClientState(%GL_VERTEX_ARRAY)
glDisableClientState(%GL_COLOR_ARRAY)
End Sub
ErosOlmi
10-11-2015, 21:35
This post remember me an old script made by ... I do not remember, sorry.
Anyhow it plots some 3D functions choosing from a predefined set of functions.
i am trying to configure why the grid does not display correctly, at last i find that index(1) refer to Vertex 0 even we dimension Vertex array from 1,1 it is considered by opengl as vertex 0 if plotted first. if we plot the second vertex as vertex(100,100) it will be considered by opengl as vertex 1 and so on.
some changes from the previous example is that the arrays are filled with data before entering the main loop: While TBGL_IsWindow(hwnd)
notes:
if you want to see the dots at the crossings of the grid lines uncomment line 133
glDrawElements(%GL_POINTS, CountOf(indices), %GL_UNSIGNED_INT, VarPtr(indices(1)))
and uncomment line 23
glPointSize( 3.5 )
change the size of the grid from line 16: Dim Nb As DWord =60, and to do research change it to 3 or 2
9360
Uses "tbgl"
#INCLUDE "%app_includepath%\thinbasic_gl.inc"
#INCLUDE "%app_includepath%\thinbasic_glu.inc"
Type Point3D
x As Single
y As Single
z As Single
red As Single
green As Single
blue As Single
End Type
Dim hwnd As DWord
Dim Nb As DWord =60 ' number of vertexes at each Horzontal line and Vertical line
Dim Vertex(Nb,Nb) As Point3D
Dim indices(2 * Nb * Nb * 2) As DWord ' Can be also specified as UInt32
hwnd = TBGL_CreateWindowEx("glDrawElements example with Grid - esc to exit", 600, 600, 32, 0)
TBGL_ShowWindow
TBGL_ResetKeyState()
glPointSize( 3.5 )
init
While TBGL_IsWindow(hwnd)
TBGL_ClearFrame
display
TBGL_DrawFrame
If TBGL_GetWindowKeyState( hwnd, %VK_ESCAPE) Then Exit While
Wend
TBGL_DestroyWindow
Sub init()
Dim a,b As DWord
Dim xMin, yMin, zMin, xMax, yMax, zMax, range, step1, x, y, z As Single
xMin = -1 : yMin = -1: zMin = -1: xMax = 1: yMax = 1: zMax = 1
'xMin = -0.5 : zMin = -0.5 : xMax = 0.5: zMax = 0.5
range = xMax - xMin
step1 = range / Nb
x = xMin: z = zMin : y = yMin
For b=1 To Nb
For a=1 To Nb
y = Sin(10*(x^2+z^2))/10
'y = 0
Vertex(a,b).x = x
Vertex(a,b).y = y
Vertex(a,b).z = z
If y>=0 Then
Vertex(a,b).red = 1.0 :Vertex(a,b).green = 0.0 :Vertex(a,b).blue = 0
Else
Vertex(a,b).red = 0.0 :Vertex(a,b).green = 0.5 :Vertex(a,b).blue = 0.2
EndIf
x = x + step1
Next a
x = xMin
z = z + step1
Next b
'=================================================================================
Dim i As DWord = 1
Dim yy,xx As DWord
'Grid Horizontal lines
For yy = 1 To Nb
For xx = 1 To Nb-1
indices(i) = (yy-1) * Nb + xx -1
i+1
indices(i) = (yy-1) * Nb + xx
i+1
Next
Next
'Grid vertical lines
For xx = 1 To Nb
For yy = 1 To Nb-1
indices(i) = (yy-1) * Nb + xx -1
i=i+1
indices(i) = (yy) * Nb + xx -1
i+1
Next
Next
glScalef(2,2,2) ' amplify the graphics Size by 2
'position camera at 0,1.5,1 __ object position 0,1,0___0,1,0 direction
gluLookAt( 0, 1.5, 0,
0, 0, 0,
0, 1, 0 )
End Sub
'--------------------------------------------------------
'--------------------------------------------------------
Sub display()
glMatrixMode(%GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, 800/600, 1.0, 60.0)
glMatrixMode(%GL_MODELVIEW)
glTranslatef(0, 1, -2)
glShadeModel(%GL_SMOOTH)
glEnable(%GL_DEPTH_TEST)
gluLookAt( 0, 2.0, 2.3,
0, 1, 0,
0, 1, 0 )
glclear(%gl_color_buffer_bit)
TBGL_Rotate GetTickCount/30,0,1,0 '*************************
'glRotatef(1, 0, 1, 0)' -- 0,1,0 rotate around Y
glScalef(2,2,2) ' amplify the graphics Size by 2
glClear(%GL_COLOR_BUFFER_BIT Or %GL_DEPTH_BUFFER_BIT)
glClearColor(1, 1, 1, 1)
glEnableClientState(%GL_VERTEX_ARRAY )
glEnableClientState(%GL_COLOR_ARRAY)
glVertexPointer(3, %GL_FLOAT,SizeOf(Point3D),VarPtr(Vertex(1,1)))
glColorPointer(3, %GL_FLOAT, SizeOf(Point3D), VarPtr(Vertex(1,1).red))
'glDrawElements(%GL_POINTS, CountOf(indices), %GL_UNSIGNED_INT, VarPtr(indices(1)))
glDrawElements(%GL_LINES , CountOf(indices), %GL_UNSIGNED_INT, VarPtr(indices(1)))
glDisableClientState(%GL_VERTEX_ARRAY)
glDisableClientState(%GL_COLOR_ARRAY)
End Sub
Petr Schreiber
16-11-2015, 21:56
Hi Primo,
I am unable to see what exactly is the problem, sadly.
The thing could be that the handling of multi dimensional arrays differs between BASIC and C.
In thinBasic, I think the arrays are column-major ordered. That means for case:
Long myArray(3,2)
...the first element in memory is (1, 1), then (2, 1), (3, 1), (2, 1), (2, 2) and finally (3, 2).
In C, I think, it is row first, which can complicate things a bit in your case, right? That would mean you presumed (1, 1), (2, 1), (1, 2), (2, 2), (3, 1), (3, 2) order, right?
Or maybe it is something different - my apologies then, as I said, I cannot see the problem :)
Petr
Petr Schreiber
16-11-2015, 22:03
Little trick which comes handy - if you need to access data sometimes in 2D way, and sometimes in 1D:
Long MyData2D(3, 2)
Long MyData1D(6) At VarPtr(MyData2D(1, 1))
CountOf
' -- Another cool feature of ThinBASIC, assignment from index 1 and forth in one line...
MyData1D(1) = 1, 2, 3, 4, 5, 6
' -- This is the same, but who would do it this way, right :D?
MyData1D(1) = 1
MyData1D(2) = 2
MyData1D(3) = 3
MyData1D(4) = 4
MyData1D(5) = 5
MyData1D(6) = 6
' -- Alternative...
MyData1D(1) = 1, 2, 3
MyData1D(4) = 4, 5, 6
MsgBox 0, MyData2D(1, 1) + $CRLF + MyData2D(2, 1) + $CRLF + MyData2D(3, 1), %MB_OK, "First column"
MsgBox 0, MyData2D(1, 2) + $CRLF + MyData2D(2, 2) + $CRLF + MyData2D(3, 2), %MB_OK, "Second column"
Petr
Hi Petr
yes i have confused when adapting the above wikibook example to thinbasic, but mainly i was troubled with line 80 indices(i) = (yy-1) * ..., in the above glDrawElements_with_grid.tbasic demo but now solved as the above example are successfull, at first of my trials i have managed the equation wrongly to give : indices(1) = 1 but this begins the Lines plotting from the second vertex # #-----# and not from the first one, so when changing the equation to indices(i) = (yy-1) * Nb + xx - 1 now for yy=1, xx=1 : indices(1) = 0 so it begins the Lines plotting from vertex0 : #----# # which is in my example Vertex(1,1) , this mixing my brain, but now it works.
yes accessing data in 2D or 1D can be usefull i will try it, thank you.
i have heard there is a Next Generation OpenGL http://www.anandtech.com/show/8363/khronos-announces-next-generation-opengl-initiative
i have not approached more than version 2 , i have tried modern opengl but i find it not tasty at all, this is the opinion of many users not only the beginners. they have deleted all math functions such as rotation and others and let it the responsibly of the user who in most cases will do it wrongly, so another math lib (i forget its name) come from the back door to help the modern opengl programmers, so it is useless they have deleted the math functions, and and that math Lib is usable only in C/C++ and not for other languages. fortunately the vga cards are still supporting the classic opengl, can't imagine the case when they release that next generation edition. so i should buy a few old vga card before the advent of that opengl apocalypse era
Petr Schreiber
17-11-2015, 15:03
Hi Primo,
don't be scared from the so called "next gen" OpenGL. The specification is already out, and they call it Vulkan API (https://www.khronos.org/vulkan). It has a bit of different target, I don't see it as OpenGL replacement.
Have a look at Win32 - so many times called dead, and I still use it as backend for Windows version of TBGL without need to change anything in code to make it run from Windows 95 to Windows 10.
I try to keep a reasonable level of abstraction in TBGL, to layer users from such a problems in case something really radical happens.
I, personally, do not like the direction the graphic APIs are taking currently - they basically kill the original idea, to help you write graphic code easily, without need to know all those technical details - it returns us back to 90's when you had to know all the math to draw... rotating triangle :) It kills the joy and can be appreciated just by the true geeks. I do enjoy it, sometimes, too, but mostly when I am in challenge mood. Not when I need to get things done in limited time scope.
I guess the authors of Vulkan API expect they will provide something really low level and the community will take care of "user friendly" middleware. It is possible direction, we will see.
Petr
I watched many videos about Vulkan, like you said too low level. I guess the console game programmers were hammering on having low level access. Vulkan grew out of AMD's Mantel. The professional AAA game programming professionals are happy. Especially Sony and PSx coders, they were the most vocal from what I read about needing the direct access.
Like you said again Petr, I am sure we as hobby programmers will have engines like Unity and other engines provide us with easier mid level access.
Petr Schreiber
12-05-2017, 09:02
I bought the "Official guide to Learning Vulkan" - the book itself is written in very shy way, like the authors are not very confident about what they created.
My feelings about this API are mixed - power on one side, but very suspicious design in places. I am very careful about using this tech so far.
Petr