Very cool example! Would you like some help with calculating proper normals?
Petr
Mobius strip is a paper strip in which A connect to D and B connect to C.
A------------------------C
........................
B------------------------D
it is a strange entity , we can't determine its up or down so it is causing confusion, look its lighting on the following demos which are the same demos but done in 2 ways
the first demo depends on lesson 4
http://psch.thinbasic.com/old/tbgl_lesson4.html
the second demo is using the GBufferUses "TBGL" Uses "UI" Uses "math" DIM hWnd as dword Dim x, y, z, u, v As Single Dim wireframe As Long ' We will initialize OpenGL and internal buffers ' Function also returns window handle hWnd = TBGL_CreateWindowEx("Mobius Strip - press 'W' for wire/solid frame...... press ESC to quit", 640, 480, 32, %TBGL_WS_WINDOWED ) tbgl_ShowWindow ' This will display the window on the screen TBGL_BackColor 255,255,255 TBGL_UseLighting(%TRUE) TBGL_UseLightSource(%GL_LIGHT0, %TRUE) TBGL_GetAsyncKeyState(-1) ' Reset status of the all keys to prevent immediate quit 'TBGL_PolygonLook %GL_LINE while TBGL_IsWindow(hWnd) ' While window exists, we will draw and check for ESCAPE If TBGL_GetWindowKeyOnce( hWnd, %VK_W) Then 'display wireFrame or solid frame If wireframe = 0 Then TBGL_PolygonLook %GL_LINE wireframe = 1 Else TBGL_PolygonLook %GL_FILL wireframe = 0 End If End If tbgl_ClearFrame ' This clears the frame and prepares it for drawing TBGL_Camera 0,2,4,0,0,0 ' We will look from point 0,0,10 to 0,0,0 ( origin of coordinates ) TBGL_Color 0, 255, 0 TBGL_PushMatrix TBGL_Rotate 90, 1, 0, 0 TBGL_Rotate GetTickCount/50, 0, 0, 1 DrawQuads tbgl_PopMatrix tbgl_DrawFrame ' This will display the scene ' When ESCAPE is pressed, we will leave the main loop IF TBGL_GetWindowKeyState( hWnd, %VK_ESCAPE ) THEN EXIT while Wend tbgl_DestroyWindow ' This will destroy the window Sub DrawQuads( ) u=0 TBGL_BeginPoly %GL_QUAD_STRIP While u <= 2*Pi v = -0.5 While v<= 0.5 x = Cos(u) * ( 1 + (v/2 * Cos(u/2)) ) y = Sin(u) * ( 1 + (v/2 * Cos(u/2)) ) z = v/2 * Sin(u/2) TBGL_Vertex x,y,z v+1 Wend v = -0.5 u + 0.1 Wend 'connect the last 2 points to the first 2 points in reverse v = 0.5 :u=0 While v>= -0.5 x = Cos(u) * ( 1 + (v/2 * Cos(u/2)) ) y = Sin(u) * ( 1 + (v/2 * Cos(u/2)) ) z = v/2 * Sin(u/2) TBGL_Vertex x,y,z v-1 Wend TBGL_EndPoly end sub
mobius.PNGUses "TBGL" Uses "math" Function TBMain() Local hWnd As DWord Local i,wireframe As Long Local FrameRate As Double ' -- Create and show window hWnd = TBGL_CreateWindowEx("Mobius strip using GBuffers - press 'W' for wire/solid Frame,...press ESC to quit", 600, 600, 32, %TBGL_WS_WINDOWED Or %TBGL_WS_CLOSEBOX) TBGL_ShowWindow TBGL_BackColor 255,255,255 'TBGL_PolygonLook %GL_LINE ' -- Create 3D points buffer Dim gbQuad As DWord = TBGL_GBufferCreate(%TBGL_QUADSTRIP, %TBGL_3D) Global Nb As DWord = 128 ' -- Define data for it Global VertexA(Nb) As TBGL_TVECTOR3F Global ColorA(Nb) As TBGL_TRGB Global NormalA(Nb) As TBGL_TVECTOR3F FillArrays ' call the sub to fill VertexA , ColorA arrays For i = 1 To Nb ColorA(i).r = Rnd(128, 255)'0 ColorA(i).g = Rnd(128, 255)'255 ColorA(i).b = Rnd(128, 255)'0 Next For i = 1 To Nb NormalA(i).x = 0 NormalA(i).y = 1 NormalA(i).z = 0 Next ' -- Create buffer dynamically linked to the arrays above TBGL_GBufferDefineFromArray(gbQuad, %TBGL_DYNAMIC, CountOf(VertexA), VertexA(1), ColorA(1), NormalA(1)) TBGL_UseLighting(%TRUE) TBGL_UseLightSource(%GL_LIGHT0, %TRUE) ' -- Resets status of all keys TBGL_ResetKeyState() ' -- Main loop While TBGL_IsWindow(hWnd) If TBGL_GetWindowKeyOnce( hWnd, %VK_W) Then If wireframe = 0 Then TBGL_PolygonLook %GL_LINE wireframe = 1 Else TBGL_PolygonLook %GL_FILL wireframe = 0 End If End If 'init FrameRate = TBGL_GetFrameRate TBGL_ClearFrame TBGL_Camera(0, 10, 20, 0, 0, 0) TBGL_Rotate 90, 1, 0, 0 TBGL_Rotate GetTickCount/50, 0, 0, 1 ' -- Render it TBGL_GBufferRender(gbQuad) TBGL_DrawFrame ' -- ESCAPE key to exit application If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While Wend ' -- Destroy window TBGL_DestroyWindow End Function Sub FillArrays() Dim x, y, z, u, v As Single v = -0.5 Dim N As DWord = 1 While u <= 2*Pi v = -0.5 While v<= 0.5 x = Cos(u) * ( 1 + (v/2 * Cos(u/2)) ) y = Sin(u) * ( 1 + (v/2 * Cos(u/2)) ) z = v/2 * Sin(u/2) VertexA(N).x = x*6 VertexA(N).y = y*6 VertexA(N).z = z*6 v+1 : N + 1 Wend v = -0.5 u + 0.1 Wend VertexA(N).x = VertexA(2).x VertexA(N).y = VertexA(2).y VertexA(N).z = VertexA(2).z N+1 VertexA(N).x = VertexA(1).x VertexA(N).y = VertexA(1).y VertexA(N).z = VertexA(1).z End Sub
Last edited by primo; 14-08-2016 at 10:55.
Very cool example! Would you like some help with calculating proper normals?
Petr
Learn 3D graphics with ThinBASIC, learn TBGL!
Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB
Yes Petr of course i need help for better Normals and lighting for all parts of Mobius strip, i thought first it is not possible.
the lighting of this kind of shapes cause confusion, it is suitable as a question in computer Lab exam .
i have tried it again and the best result i can get is this (in the second demo)
For i = 1 To Nb
NormalA(i).x = Rnd(-1,1)
NormalA(i).y = Rnd(-1,1)
NormalA(i).z = Rnd(-1,1)
Next
at least the strip will not darken totaly for some moments while rotating
The normal calculation should be deterministic, I will dive into it this weekend
Stay tuned,
Petr
Learn 3D graphics with ThinBASIC, learn TBGL!
Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB
One of the possible approaches, based on: http://psch.thinbasic.com/old/tbgl_lesson6.html
PetrUses "TBGL", "math" Function TBMain() long i, wireframe double FrameRate ' -- Create and show window dword hWnd = TBGL_CreateWindowEx("Mobius strip using GBuffers - press 'W' for wire/solid Frame,...press ESC to quit", 600, 600, 32, %TBGL_WS_WINDOWED Or %TBGL_WS_CLOSEBOX) TBGL_ShowWindow TBGL_BackColor 255,255,255 ' -- Create 3D points buffer Dword gbQuad = TBGL_GBufferCreate(%TBGL_QUADSTRIP, %TBGL_3D) single detail = 0.01 dword Nb = CalculateBufferSize(detail) ' -- Define data for it dim VertexA(Nb) As TBGL_TVECTOR3F dim ColorA(Nb) As TBGL_TRGB dim NormalA(Nb) As TBGL_TVECTOR3F BuildGeometry(vertexA, detail) CalculateNormals(vertexA, normalA) PaintGeometry(colorA) ' -- Create buffer dynamically linked to the arrays above TBGL_GBufferDefineFromArray(gbQuad, %TBGL_DYNAMIC, CountOf(VertexA), VertexA(1), ColorA(1), NormalA(1)) TBGL_UseLighting(%TRUE) TBGL_UseLightSource(%GL_LIGHT0, %TRUE) ' -- Resets status of all keys TBGL_ResetKeyState() single time ' -- Main loop While TBGL_IsWindow(hWnd) If TBGL_GetWindowKeyOnce( hWnd, %VK_W) Then If wireframe = 0 Then TBGL_PolygonLook %GL_LINE wireframe = 1 Else TBGL_PolygonLook %GL_FILL wireframe = 0 End If End If FrameRate = TBGL_GetFrameRate TBGL_ClearFrame TBGL_Camera(0, 10, 20, 0, 0, 0) TBGL_Rotate 90, 1, 0, 0 TBGL_Rotate time/50, 0, 0, 1 ' -- Render it TBGL_GBufferRender(gbQuad) TBGL_DrawFrame ' -- ESCAPE key to exit application If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While time+= 1/FrameRate*1000 Wend ' -- Destroy window TBGL_DestroyWindow End Function function CalculateBufferSize(detail as single) as long single u, v dword N = 1 While u <= 2 * Pi v = -0.5 While v <= 0.5 v+1 : N + 1 Wend u + detail Wend return n+1 end function Sub BuildGeometry(byref vertexA() As tbgl_tVector3F, detail as single) single x, y, z, u, v dword N = 1 While u <= 2 * Pi v = -0.5 While v <= 0.5 x = Cos(u) * ( 1 + (v/2 * Cos(u/2)) ) y = Sin(u) * ( 1 + (v/2 * Cos(u/2)) ) z = v/2 * Sin(u/2) vertexA(N).x = x*6 vertexA(N).y = y*6 vertexA(N).z = z*6 v+1 : N + 1 Wend u + detail Wend VertexA(N).x = VertexA(2).x VertexA(N).y = VertexA(2).y VertexA(N).z = VertexA(2).z N+1 VertexA(N).x = VertexA(1).x VertexA(N).y = VertexA(1).y VertexA(N).z = VertexA(1).z End Sub sub CalculateNormals(byref vertexA() as tbgl_tVector3F, byref normalA() as tbgl_tVector3F) single ux, uy, uz, vx, vy, vz, nx, ny, nz long i, j For i = 1 To countOf(NormalA)-3 step 4 ux = vertexA(i+1).x - vertexA(i).x uy = vertexA(i+1).y - vertexA(i).y uz = vertexA(i+1).z - vertexA(i).z vx = vertexA(i+2).x - vertexA(i).x vy = vertexA(i+2).y - vertexA(i).y vz = vertexA(i+2).z - vertexA(i).z nx = uy * vz - uz * vy ny = -(ux * vz - uz * vx) nz = ux * vy - uy * vx for j = 0 to 3 NormalA(i+j).x = nx NormalA(i+j).y = ny NormalA(i+j).z = nz next Next end sub sub PaintGeometry(byref colorA() as tbgl_tRGB) long i For i = 1 To countOf(ColorA) ColorA(i).r = 255 ColorA(i).g = 128 ColorA(i).b = 64 Next end sub
Last edited by Petr Schreiber; 21-08-2016 at 11:49.
Learn 3D graphics with ThinBASIC, learn TBGL!
Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB
Thanks Petr for this impressive example, also the lesson 6 is very useful.
i though first that you will use a continuous calculations of Normals while the strip rotating but you have used a fixed values and it works.
a very little talk in the web about the normals of not orientable objects, so this adds more to the available literature .
Bookmarks