PDA

View Full Version : New program... parametric surfaces



sblank
19-11-2010, 08:34
Just a new program using some raw OpenGL and Petr's great example code. This program plots a crosscap using 3 parametric equations.

My intention is to add trackball mouse interaction at some point.

n0 is the x function
n1 is the y function
n2 is the z function

Stan

zak
19-11-2010, 10:28
thanks for your example, it is enriching the available examples about using classic OpenGL in thinbasic.
in this link:
http://psch.thinbasic.com/old/tbgl_lesson6.html
download the example "Lesson 6 source code", it is a zip file; and inside it there are 3 code files one of them are interesting; it is Lesson6_TBGL_LightWithMouse.tbasic : whenever you move the mouse pointer (without clicking) the light move toward it. i think it is what needed
the most important functions in the example is TBGL_MouseGetPosX, and TBGL_MouseGetPosY
there is also a less significant example (in the context of your example) called TBGL_Demo19_MouseDemo.tbasic it is in "C:\thinBasic\SampleScripts\TBGL\Basic"
i will try these after recovering from the flu and cold.
best regards

zak
19-11-2010, 13:09
this my rude version adding some mouse code to sblank version
i hope i will not get zero/100 , may be 5 enough, especially i have a cold symptoms ( as if i am better without )
the figure rotate as the mouse pointer move, but can't make it continue rotation like it is intended. and also resorting to
While TBGL_IsWindow(hWnd) ... wend

' Empty GUI script created on 11-16-2010 20:15:22 by (ThinAIR)
Uses "TBGL"
#INCLUDE Once "%APP_INCLUDEPATH%\thinbasic_gl.inc"
#INCLUDE Once "%APP_INCLUDEPATH%\thinbasic_glu.inc"

Global angle As Double
Global dx, dy, theta, Alpha, n0, n1, n2,a,b As Double
Global wd, ht, i, th, ta As Long
Global mouseX, mouseY As Single
wd = 600
ht = 600

Global hWnd As DWord
Global x, y As DWord
Function TBMain()
Local hWnd As DWord
Local FrameRate As Double

' -- Create and show window
hWnd = TBGL_CreateWindowEx("Parametric Plots - press ESC to quit", wd, ht, 32, %TBGL_WS_WINDOWED Or %TBGL_WS_CLOSEBOX)
TBGL_ShowWindow

' -- Initialize lighting
TBGL_UseLighting(%TRUE)
TBGL_UseLightSource(%GL_LIGHT0, %TRUE)
While TBGL_IsWindow(hWnd)
TBGL_ResetKeyState()
mouseX = TBGL_MouseGetPosX
mouseY = TBGL_MouseGetPosY
dx=mouseX: dy=mouseY
funRender()
'dx += 10
'dy += 10
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While
Wend
TBGL_DestroyWindow
End Function
' -- Do any calculations here
Function funIdle( hWnd As DWord, frameRate As Double )

dx += 10
dy += 10

End Function
' -- Handle input here
Function funInput( hWnd As DWord, frameRate As Double )
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then
TBGL_UnBindPeriodicFunction(hWnd)
Exit Function
End If
End Function

Function drawtor()
glBegin(%GL_TRIANGLE_STRIP)
For th = 0 To 360 Step 15
For ta = 0 To 360 Step 15
drawvert(th,ta)
drawvert(th+12,ta)

Next
Next
glEnd
End Function
Function drawvert (ByVal th As Integer, ByVal ta As Integer)
theta = th*0.01745
Alpha = ta*0.01745

a = 1.5
n0 = 0.5*a*Sin(alpha)*Sin(2*theta)
n1 = a*Sin(2*alpha)*Sin(theta)*Sin(theta)
n2 = a*Cos(2*alpha)*Sin(theta)*Sin(theta)

glColor3f(n0,Sin(n1),Cos(n2))
glVertex3f(n0,n1,n2)
End Function

Function funRender()
Dim hWnd As DWord = TBGL_CallingWindow
Dim FrameRate As Double

frameRate = TBGL_GetFrameRate

' -- Process input
funIdle( hWnd, FrameRate)

' -- Process calculations
funInput( hWnd, FrameRate )

FrameRate = TBGL_GetFrameRate
TBGL_ClearFrame
TBGL_Camera(3, 3, 3, 0, 0, 0)
TBGL_GetWindowClient( hWnd, x, y )

TBGL_Rotate(dx,0.0, 1.0, 0.0)
TBGL_Rotate(dy, 1.0, 0.0, 0.0)

TBGL_SetLightParameter(%GL_LIGHT0, %TBGL_LIGHT_POSITION, 100, 100, 100, 1)

drawtor()
TBGL_DrawFrame
End Function

sblank
20-11-2010, 05:44
That's a great addition Zak... thanks!

I'll give you an "A" for the example :D

I can use your mouse code I think. What I want to do is develop a trackball movement with inertia... continuous rotation in the direction of the mouse pointer. I'll keep working on it.

Thanks again... I appreciate the feedback and the example!

Stan

Petr Schreiber
20-11-2010, 10:14
Very nice examples,

thanks a lot for them :)


Petr

sblank
20-11-2010, 18:39
Hi Petr!

This is fun... thinBasic runs the graphic very smoothly (using your TBGL module, of course :D). Once I get the mouse tracking working as I want, then I'll try to optimize a bit.

Stan


Very nice examples,

thanks a lot for them :)


Petr

sblank
21-11-2010, 09:56
Some progress... the mouse moves the crosscap and inertia exists, however this is not trackball rotation yet.

Zak gave me some good ideas (thanks Zak!). I tweaked his mouse statements a bit.

Still working on it... take a look if anyone is interested!

Stan

zak
21-11-2010, 17:30
yes it is a big improvment, i have looked at your original freebasic code and noticed that there is function:
glutPassiveMotionFunc @mousemotion
in the doc http://www.opengl.org/documentation/specs/glut/spec3/node51.html
it is said: "The passive motion callback for a window is called when the mouse moves within the window while no mouse buttons are pressed".
by luck i found that there is %WM_MOUSEMOVE in thinbasic fired only when the mouse move without click, something like:
Case %WM_MOUSEMOVE
mouseX = TBGL_MouseGetPosX
mouseY = TBGL_MouseGetPosY
so this resembles the freebasic GL code:
glutPassiveMotionFunc @mousemotion
sub mousemotion CDECL(byval x as integer, byval y as integer)
mouseX = x
mouseY = y
end sub
but %WM_MOUSEMOVE needs a UI module (i think so), and for luck Eros and Petr have cooked UI with TBGL together so we can use TBGL in a canvas or in a Label. this is good since we may need to control the figure with sliders, buttons, etc.
i have stripped down Petr example:
http://www.thinbasic.com/community/showthread.php?10825-getting-console-like-keyboard-input-in-windowed-mode
to show just the skeleton we need, here is the skeleton: and after that i will proceed to sblank example: look at the coordinated x,y in the TextBox when the mouse moves:


Uses "UI", "TBGL"
#INCLUDE Once "%APP_INCLUDEPATH%\thinbasic_gl.inc"
#INCLUDE Once "%APP_INCLUDEPATH%\thinbasic_glu.inc"

Global angle As Double
Global dx, dy, theta, Alpha, n0, n1, n2,a,b As Double
Global wd, ht, i, th, ta As Long
Global x, y, mouseX, mouseY As Single
wd = 600
ht = 600
' -- ID numbers of controls
Begin Const
%lCanvas = %WM_USER + 1
%tbOutput
%bClose = %IDCANCEL
%myTimer
%timeOut = 20 ' -- Determines graphics refresh rate in milliseconds
End Const
Function TBMain()
Local hDlg As DWord
Local height As Long
Dialog New 0, "Please type in text",-1,-1, 320, 320, _
%WS_POPUP Or %WS_VISIBLE Or _
%WS_CLIPCHILDREN Or %WS_CAPTION Or _
%WS_SYSMENU Or %WS_MINIMIZEBOX, 0 To hDlg
' -- Place controls here
' -- This will be used as render surface
Control Add Label, hDlg, %lCanvas, "", 0, 0, 320, 250
Control Set Color hDlg, %lCanvas, %BLACK, %BLACK
Control Set Resize hDlg, %lCanvas, 1, 1, 1, 1
Control Add Textbox, hDlg, %tbOutput, "", 5, 250, 60, 14, %ES_AUTOHSCROLL Or %ES_AUTOVSCROLL Or %ES_LEFT Or %WS_BORDER Or %WS_TABSTOP Or %ES_MULTILINE Or %ES_WANTRETURN
Control Set Resize hDlg, %tbOutput, 0, 1, 0, 1
Control Add Button, hDlg, %bClose, "Close", 255, 250, 60, 14
Control Set Resize hDlg, %bClose, 0, 1, 0, 1
Control Set Focus hDlg, %tbOutput
Dialog Show Modal hDlg, Call dlgCallback
End Function
CallBack Function dlgCallback()
Static hCtrl As DWord
Select Case CBMSG
Case %WM_INITDIALOG
Dialog Set Timer CBHNDL, %myTimer, %timeOut, %NULL
Control Handle CBHNDL, %lCanvas To hCtrl
' -- Init OpenGL
TBGL_BindCanvas(hCtrl)
Case %WM_SIZE, %WM_SIZING
TBGL_UpdateCanvasProportions(hCtrl)
RenderMyImage(hCtrl, CBHNDL)
Case %WM_TIMER
RenderMyImage(hCtrl, CBHNDL)
Case %WM_MOUSEMOVE
x = TBGL_MouseGetPosX
y = TBGL_MouseGetPosY
Control Set Text CBHNDL, %tbOutput, Str$(x)+", "+Str$(y)

Case %WM_CLOSE
TBGL_ReleaseCanvas(hCtrl)
Dialog Kill Timer CBHNDL, %myTimer
Case %WM_COMMAND
Select Case CBCTL
Case %bClose
If CBCTLMSG = %BN_CLICKED Then Dialog End CBHNDL
End Select
End Select
End Function
Function RenderMyImage( hCtrl As DWord, hDlg As DWord )
Static FrameRate As Double
Static row As Long
If TBGL_CanvasBound(hCtrl) Then
FrameRate = TBGL_GetFrameRate
TBGL_ClearFrame
' -- Render some image to prove we really draw in 3D
TBGL_RenderMatrix3D
TBGL_Translate 0, 0, -5
TBGL_Rotate GetTickCount/10,1,1,1
TBGL_BeginPoly %GL_TRIANGLES
TBGL_Color 255, 0, 0
TBGL_Vertex -1, -1, 0
TBGL_Color 0, 255, 0
TBGL_Vertex 1, -1, 0
TBGL_Color 0, 0, 255
TBGL_Vertex 0, 1, 0
TBGL_EndPoly
TBGL_DrawFrame
End If
End Function



now for the sblank example, his Function funRender is replaced by Function RenderMyImage, almost i copied his example in the file crosscap.tbasic above. it is working exactly like the non windows example but without the strips, may be it is a problem with lighting, i will keep trying, the picture of the example:
http://img12.imageshack.us/img12/8495/openglw.png


Uses "UI", "TBGL"
#INCLUDE Once "%APP_INCLUDEPATH%\thinbasic_gl.inc"
#INCLUDE Once "%APP_INCLUDEPATH%\thinbasic_glu.inc"

Global angle As Double
Global dx, dy, theta, Alpha, n0, n1, n2,a,b As Double
Global wd, ht, i, th, ta As Long
Global mouseX, mouseY As Single
wd = 500
ht = 300
' -- ID numbers of controls
Begin Const
%lCanvas = %WM_USER + 1
%tbOutput
%bClose = %IDCANCEL
%myTimer
%timeOut = 20 ' -- Determines graphics refresh rate in milliseconds
End Const
Function TBMain()
Local hDlg As DWord
Local height As Long
Dialog New 0, "experiments ...",-1,-1, 500, 320, _
%WS_POPUP Or %WS_VISIBLE Or _
%WS_CLIPCHILDREN Or %WS_CAPTION Or _
%WS_SYSMENU Or %WS_MINIMIZEBOX, 0 To hDlg
' -- Place controls here
' -- This will be used as render surface
Control Add Label, hDlg, %lCanvas, "", 0, 0, wd, ht
Control Set Color hDlg, %lCanvas, %BLACK, %BLACK
Control Set Resize hDlg, %lCanvas, 1, 1, 1, 1
Control Add Textbox, hDlg, %tbOutput, "", 5, 300, 60, 17, %ES_AUTOHSCROLL Or %ES_AUTOVSCROLL Or %ES_LEFT Or %WS_BORDER Or %WS_TABSTOP Or %ES_MULTILINE Or %ES_WANTRETURN
Control Set Resize hDlg, %tbOutput, 0, 1, 0, 1
Control Add Button, hDlg, %bClose, "Close", 400, 300, 60, 20
Control Set Resize hDlg, %bClose, 0, 1, 0, 1
Control Set Focus hDlg, %tbOutput
Dialog Show Modal hDlg, Call dlgCallback
End Function
CallBack Function dlgCallback()
Static hCtrl As DWord
Select Case CBMSG
Case %WM_INITDIALOG
Dialog Set Timer CBHNDL, %myTimer, %timeOut, %NULL
Control Handle CBHNDL, %lCanvas To hCtrl
' -- Init OpenGL
TBGL_BindCanvas(hCtrl)
Case %WM_SIZE, %WM_SIZING
TBGL_UpdateCanvasProportions(hCtrl)
RenderMyImage(hCtrl, CBHNDL)
Case %WM_TIMER
RenderMyImage(hCtrl, CBHNDL)
Case %WM_MOUSEMOVE
mouseX = TBGL_MouseGetPosX
mouseY = TBGL_MouseGetPosY
Control Set Text CBHNDL, %tbOutput, Str$(mouseX)+", "+Str$(mouseY)

Case %WM_CLOSE
TBGL_ReleaseCanvas(hCtrl)
Dialog Kill Timer CBHNDL, %myTimer
Case %WM_COMMAND
Select Case CBCTL
Case %bClose
If CBCTLMSG = %BN_CLICKED Then Dialog End CBHNDL
End Select
End Select
End Function
' -- Do any calculations here
Function funIdle( hWnd As DWord, frameRate As Double )
'..................

End Function
' -- Handle input here
Function funInput( hWnd As DWord, frameRate As Double )
' ............
End Function
Function drawtor()
glBegin(%GL_TRIANGLE_STRIP)
For th = 0 To 360 Step 15
For ta = 0 To 360 Step 15
drawvert(th,ta)
drawvert(th+12,ta)

Next
Next
glEnd
End Function
Function drawvert (ByVal th As Integer, ByVal ta As Integer)
theta = th*0.01745
Alpha = ta*0.01745

a = 1.5
n0 = 0.5*a*Sin(alpha)*Sin(2*theta)
n1 = a*Sin(2*alpha)*Sin(theta)*Sin(theta)
n2 = a*Cos(2*alpha)*Sin(theta)*Sin(theta)

glColor3f(n0,Sin(n1),Cos(n2))
glVertex3f(n0,n1,n2)
End Function
Function RenderMyImage( hCtrl As DWord, hDlg As DWord )
Static FrameRate As Double
If TBGL_CanvasBound(hCtrl) Then
FrameRate = TBGL_GetFrameRate
dx+=(mouseX-wd/2)/128: dy+=(mouseY-ht/2)/128
TBGL_ClearFrame
' -- Render some image to prove we really draw in 3D
TBGL_RenderMatrix3D
'TBGL_Translate 0, 0, -5
'TBGL_Rotate GetTickCount/10,1,1,1
Dim hWnd As DWord = TBGL_CallingWindow
'Dim FrameRate As Double

frameRate = TBGL_GetFrameRate

' -- Process input
'funIdle( hWnd, FrameRate)

' -- Process calculations
funInput( hWnd, FrameRate )

FrameRate = TBGL_GetFrameRate
TBGL_ClearFrame
TBGL_Camera(3, 3, 3, 0, 0, 0)
'TBGL_GetWindowClient( hWnd, x, y )

TBGL_Rotate(dx,0.0, 1.0, 0.0)
TBGL_Rotate(dy, 1.0, 0.0, 0.0)

TBGL_SetLightParameter(%GL_LIGHT0, %TBGL_LIGHT_POSITION, 100, 100, 100, 1)

drawtor()
TBGL_DrawFrame
End If
End Function

zak
21-11-2010, 19:44
yes it is the lighting, i forgot to add after Case %WM_TIMER
TBGL_UseLighting(%TRUE)
TBGL_UseLightSource(%GL_LIGHT0, %TRUE)


http://img694.imageshack.us/img694/7516/tbglui.png

below is the modified code, now it is the physics and inertia problem.
indeed big thanks for Eros and Petr for their marvelous creations. and the facilities available in thinbasic, which are used in this sblank program.

PS: to use 2D graphics with the above skeleton just delete TBGL_RenderMatrix3D and add
TBGL_RenderMatrix2D
in the doc: TBGL_RenderMatrix2D[( leftX, bottomY, rightX, topY )]
TBGL_RenderMatrix2D resembeles the gluOrtho2D(..... )
wich allows to define the virtual window; in wich it will projected to real opengl frame dimensions
note: the order of gluOrtho2D( left , right , bottom , top ) in C are different from TBGL_RenderMatrix2D , in TBGL_RenderMatrix2D it is more natural leftX, bottomY, rightX, topY )

sblank
22-11-2010, 18:31
Thanks Zak... I appreciate the added features of the UI...

I've attached the latest of my non-UI efforts. I now have rotation with inertia AND a well-behaved motion when the mouse pointer is outside the window.

What I do NOT yet have is trackball rotation. At the moment, mouse rotations are specific to the frame of reference of the model (the crosscap). I want the frame of reference to be specific to the viewer so the mathematical objects ALWAYS rotates in the direction of the mouse point... in other words, rotates toward the mouse point.

In the freebasic example code, this was accomplished by the chaptrack() function and the matrix commands prior to the actual rendering. I have been unable to figure this rotation scheme out for thinBasic.

Can this be done without resorting to quaternions?

Petr?

Thanks,

Stan

Petr Schreiber
22-11-2010, 20:03
Hi Stan,

my apologies but till 26th (http://www.thinbasic.com/community/showthread.php?10917-Petr-false-till-26th) I am not able to dive in to the problem, but I remember in classic OpenGL the glRotatef rotations are always around "global axes", which is not usually what we want, that is why entity system has rotations around local axes, and I for sure did not used quaternions, but the transformations are custom made.


Petr

sblank
22-11-2010, 20:37
Hi Petr,

No worries at all... I understand!

I'll look at the entity system and see what I can find. I'm very close to having this problem figured out.

Cheers... and thanks!

Stan


Hi Stan,

my apologies but till 26th (http://www.thinbasic.com/community/showthread.php?10917-Petr-false-till-26th) I am not able to dive in to the problem, but I remember in classic OpenGL the glRotatef rotations are always around "global axes", which is not usually what we want, that is why entity system has rotations around local axes, and I for sure did not used quaternions, but the transformations are custom made.


Petr