PDA

View Full Version : insert new tbgl objects into existing scene?



Lionheart008
15-01-2011, 13:50
hi all.

its possible to insert tbgl objects like pyramid or cube in an "existing tbgl scene" ?

I think it`s possible if I kill or replace first scene, but that isn`t my idea. I only want to know if there is a way to include a sphere or cube into an existing scene via button click. I found no way.
there are 3d modelling software they can do that and I wondered how they did such functions? my dummy function was to delete old scene and replace it with new scene, but that couldn`t final solution. any idea or help about this topic would be nice.


see my dummy example:)


'--------------------> insert objects like pyramid, cube, sphere in existing tbgl possible ?
'--------------------> demo dummy by lionheart, 14.01.2010

#MINVERSION 1.7.0.0

USES "UI", "TBGL"

DIM hDlg AS DWORD
' Rotation Variable
Dim angle As Single

' Timing Variables
Dim FrameRate As Number

' -- ID numbers of controls
Begin Const
%lblCanvas = 1000
%btnClose
%btnInfo
%myTimer
%timeOut = 10
%btnPyramid
%btnPyramid_Entity
%sScene = 1
%eCamera
%eLight
%eArrow
%eTarget
End Const

'----------------------> my dummy idea ! for replacing scene or insertion objects :)
Type TAddress
Start As Long
Length As Long
End Type

Function GetAddressLast(Address As TAddress) As Long
Function = Address.Start - 1 + Address.Length
End Function


Sub ClearScene(ByVal SceneIgnore As Long)
Dim A As Long
For A = GetAddressLast(EntityScene.Pyramids) To EntityScene.Pyramids.Start Step -1
If A <> SceneIgnore Then Call RemoveScene(A)
Next
End Sub
'----------------------> my dummy idea ! for replacing scene or insertion objects :)


Dialog New 0, "pyramid insertion test question:)",-1,-1, 320, 230, _
%WS_POPUP Or %WS_VISIBLE Or _
%WS_CLIPCHILDREN Or %WS_CAPTION OR _
%WS_SYSMENU Or %WS_MINIMIZEBOX or %WS_THICKFRAME, 0 To hDlg
dialog set color hDlg, rgb(224,224,224), rgb(224,224,224)

' -- Place controls here
CONTROL ADD label, hDlg, %lblCanvas, "", 5, 5, 310, 200
control set color hDlg, %lblCanvas, rgb(224,224,224), rgb(224,224,224)
control set resize hDlg, %lblCanvas, 1, 1, 1, 1

CONTROL ADD BUTTON, hDlg, %btnInfo, "Info", 5, 210, 60, 14
control set resize hDlg, %btnInfo, 1, 0, 0, 1

Control Add Button, hDlg, %btnPyramid, "Pyramid", 105, 210, 60, 14
Control Set Resize hDlg, %btnPyramid, 1, 0, 0, 1

Control Add Button, hDlg, %btnPyramid_Entity, "Pyramid_Entity", 175, 210, 60, 14
Control Set Resize hDlg, %btnPyramid_Entity, 1, 0, 0, 1

CONTROL ADD BUTTON, hDlg, %btnClose, "Close", 255, 210, 60, 14
control set resize hDlg, %btnClose, 0, 1, 0, 1

dialog set minsize hDlg, 320, 230
DIALOG SHOW MODal hDlg, call dlgCallback


CALLBACK FUNCTION dlgCallback()
static hCtrl as dword
local texInfo AS TBGL_tTexturingInfo

SELECT CASE CBMSG

CASE %WM_INITDIALOG
DIALOG SET TIMER CBHNDL, %myTimer, %timeOut, %NULL
Control Handle CBHNDL, %lblCanvas To hCtrl

' -- Init OpenGL
TBGL_BindCanvas(hCtrl)
TBGL_BackColor 224,224,224

' -- Prepare scene
TBGL_SceneCreate(%sScene)

TBGL_EntityCreateCamera(%sScene, %eCamera)
TBGL_EntitySetPos(%sScene, %eCamera, 0, 0, 15)
TBGL_EntitySetTargetPos(%sScene, %eCamera, 0, 0, 0)

TBGL_EntityCreateLight(%sScene, %eLight)
TBGL_EntitySetPos(%sScene, %eLight, 0, 0, 5)

TBGL_NewList 1
TBGL_BeginPoly %GL_TRIANGLES
TBGL_Normal 0, 0, 1
TBGL_Vertex -1, 0.5
TBGL_Vertex -1, -0.5
TBGL_Vertex 1, 0
TBGL_EndPoly
TBGL_EndList

TBGL_EntityCreateDLSlot(%sScene, %eArrow, 0, 1)
TBGL_EntitySetPos(%sScene, %eArrow, 1, 1, 0)
TBGL_EntitySetColor(%sScene, %eArrow, 255, 0, 0)

TBGL_EntityCreateSphere(%sScene, %eTarget, 0, 0.5)


CASE %WM_SIZE, %WM_SIZING
TBGL_UpdateCanvasProportions(hCtrl)
RenderMyImage(hCtrl)

CASE %WM_TIMER
RenderMyImage(hCtrl)

CASE %WM_CLOSE
TBGL_ReleaseCanvas(hCtrl)
DIALOG KILL TIMER CBHNDL, %myTimer

case %WM_COMMAND
select case cbctl
case %btnClose
If CBCTLMSG = %BN_CLICKED Then Dialog End hDlg

'--------------------------------------------------------------------------->
Case %btnPyramid
MsgBox 0, "hello, how to insert via buttonclick a Pyramid?"
'drawpyramid()
drawpyramid2()

Case %btnPyramid_ENTITY
MsgBox 0, "hello, how to insert via buttonclick an Entity Pyramid?"
drawpyramid_Entity()
'--------------------------------------------------------------------------->

case %btnInfo
if CBCTLMSG = %BN_CLICKED THEN
' Get info on texturing subsystem
TBGL_TexturingQuery(texInfo)

' Get some more
msgbox cbhndl, "Did you know your card supports textures as big as"+ _
STR$(texInfo.maxWidth)+" x"+STR$(texInfo.maxHeight)+"?"+$CRLF+ _
IIF$(texInfo.NPOTSupport, "You can use NPOT textures as well", "But your HW sadly does not support NPOT textures") + $CRLF(2) + _
IIF$(TBGL_oglVersionSupport(2, 0), "You have support for OpenGL 2.0 at least, no need to upgrade soon", "No support for OpenGL 2.0") +$CRLF+ _
IIF$(TBGL_oglExtensionSupport("GL_ARB_fragment_program GL_ARB_vertex_program"), "Support for some form of shaders", "No support for shaders, good TBGL does not require it :)"), _
%MB_ICONINFORMATION, _
"Info"
end if
end select

END SELECT
END FUNCTION

'-----------------------------------------> RENDER IMAGE --------------->
function RenderMyImage( hCtrl as dword )
static FrameRate as double
local angle as double

if TBGL_CanvasBound(hCtrl) then

FrameRate = TBGL_GetFrameRate
tbgl_ClearFrame

' Move target
TBGL_EntitySetColor(%sScene, %eTarget, 128+sin(GetTickCount/1000)*127,128+sin(GetTickCount/1000+1)*127,128+sin(GetTickCount/1000+2)*127)
TBGL_EntitySetpos(%sScene, %eTarget, sin(GetTickCount/1000)*5, cos(GetTickCount/2000)*5,0)

' Get angle hunter-target
angle = TBGL_EntityGetAngleXY(%sScene, %eArrow, %eTarget, %TBGL_X)

' Slowly turn towards target
TBGL_EntityTurn(%sScene, %eArrow, 0, 0, 5*angle/FrameRate )

' Move towards the target, with speed proportional to the distance
TBGL_EntityPush(%sScene, %eArrow, TBGL_EntityGetDistance(%sScene, %eArrow, %eTarget)/FrameRate, 0, 0 )

' Render it please
TBGL_SceneRender(%sScene)

TBGL_Translate 0, 0, -4 ' Move Pyramid to Centre of Screen
TBGL_Rotate angle, 0.0, 1.0, 0.0 ' Rotation Setup

'--HOW TO INSERT PYRAMID BY BUTTON CLICK ?------------------------>
'drawPyramid()
'drawPyramid2()
'--HOW TO INSERT PYRAMID BY BUTTON CLICK ?------------------------>

tbgl_DrawFrame
angle += 180.0/FrameRate
If TBGL_GetAsyncKeyState(%VK_ESCAPE) Then Exit While
end if
end function


'-----------PYRAMID 2 INSERT ? ---------------------------------------->
Sub drawPyramid2()
FrameRate = TBGL_GetFrameRate
TBGL_Rotate angle, 0.0, 1.0, 0.0 ' Rotation Setup

Local nwidth, nheight As Long

TBGL_BeginPoly %GL_TRIANGLE_FAN
TBGL_Color 0, 128, 255 : TBGL_Vertex 0.0, 1.0, 0.0
TBGL_Color 255, 0, 0 : TBGL_Vertex -1.0, -1.0, 1.0
TBGL_Color 255, 255, 255 : TBGL_Vertex 1.0, -1.0, 1.0
TBGL_Color 0, 0, 255 : TBGL_Vertex 1.0, -1.0, -1.0
TBGL_Color 0, 255, 0 : TBGL_Vertex -1.0, -1.0, -1.0
TBGL_Color 255, 0, 0 : TBGL_Vertex -1.0, -1.0, 1.0
TBGL_EndPoly

TBGL_BeginPoly %GL_QUADS ' // Begin Drawing A Single Quad
TBGL_Translate 8.0 ,-2.0 ,-14.0
TBGL_TexCoord2D 1.0 , 0.0 : TBGL_Vertex nwidth/4, 0
TBGL_TexCoord2D 0.0 , 0.0 : TBGL_Vertex 0, 0
TBGL_TexCoord2D 0.0 , 1.0 : TBGL_Vertex 0, nheight/4
TBGL_TexCoord2D 1.0 , 1.0 : TBGL_Vertex nwidth/4, nheight/4
TBGL_EndPoly ' // Done Drawing The Textured Quad

TBGL_DrawFrame ' Swap the Drawing Buffers

angle += 180.0/FrameRate

End Sub

'-----------PYRAMID 1 INSERT ? ---------------------------------------->
Sub drawPyramid()

FrameRate = TBGL_GetFrameRate
TBGL_ClearFrame ' Clear Screen
TBGL_ResetMatrix ' Reset the Current Matrix
TBGL_Camera 0, 0, 1, 0, 0, 0 ' Default Camera Position

TBGL_Translate 4, 0, -4 ' Move Pyramid to Centre of Screen
TBGL_Rotate angle, 0.0, 1.0, 0.0 ' Rotation Setup

Local nwidth, nheight As Long

TBGL_BeginPoly %GL_TRIANGLE_FAN
TBGL_Color 0, 128, 255 : TBGL_Vertex 0.0, 1.0, 0.0
TBGL_Color 255, 0, 0 : TBGL_Vertex -1.0, -1.0, 1.0
TBGL_Color 255, 255, 255 : TBGL_Vertex 1.0, -1.0, 1.0
TBGL_Color 0, 0, 255 : TBGL_Vertex 1.0, -1.0, -1.0
TBGL_Color 0, 255, 0 : TBGL_Vertex -1.0, -1.0, -1.0
TBGL_Color 255, 0, 0 : TBGL_Vertex -1.0, -1.0, 1.0
TBGL_EndPoly

TBGL_BeginPoly %GL_QUADS ' // Begin Drawing A Single Quad
TBGL_Translate 8.0 ,-2.0 ,-14.0
TBGL_TexCoord2D 1.0 , 0.0 : TBGL_Vertex nwidth/4, 0
TBGL_TexCoord2D 0.0 , 0.0 : TBGL_Vertex 0, 0
TBGL_TexCoord2D 0.0 , 1.0 : TBGL_Vertex 0, nheight/4
TBGL_TexCoord2D 1.0 , 1.0 : TBGL_Vertex nwidth/4, nheight/4
TBGL_EndPoly ' // Done Drawing The Textured Quad

TBGL_DrawFrame ' Swap the Drawing Buffers

angle += 180.0/FrameRate

End Sub

'-----------PYRAMID ENTITY INSERT ? ---------------------------------------->
Sub drawPyramid_Entity()
Static hCtrl As DWord
Local texInfo As TBGL_tTexturingInfo

' -- Init OpenGL
TBGL_BindCanvas(hCtrl)
TBGL_BackColor 224,224,224

' -- Prepare scene
TBGL_SceneCreate(%sScene)

TBGL_EntityCreateCamera(%sScene, %eCamera)
TBGL_EntitySetPos(%sScene, %eCamera, 0, 0, 15)
TBGL_EntitySetTargetPos(%sScene, %eCamera, 0, 0, 0)

TBGL_EntityCreateLight(%sScene, %eLight)
TBGL_EntitySetPos(%sScene, %eLight, 0, 0, 5)

TBGL_NewList 2
TBGL_Translate 3, 0, -4
TBGL_BeginPoly %GL_TRIANGLES
TBGL_Normal 0, 0, 1
TBGL_Vertex -1, 0.5
TBGL_Vertex -1, -0.5
TBGL_Vertex 1, 0
TBGL_EndPoly
TBGL_EndList

TBGL_EntityCreateDLSlot(%sScene, %eArrow, 0, 1)
TBGL_EntitySetPos(%sScene, %eArrow, 1, 1, 0)
TBGL_EntitySetColor(%sScene, %eArrow, 255, 0, 0)

TBGL_EntityCreateSphere(%sScene, %eTarget, 0, 0.5)

End Sub thanks frank

Petr Schreiber
15-01-2011, 14:42
Hi Frank,

there is no difference between adding object during first scene definition or anytime later. It is the same.

What is an geometric entity? It is an encapsulated object you can manipulate using TBGL_Entity* commands.

How to define custom entity? Please see the article:
TBGL user defined entities (http://www.thinbasic.com/community/content.php?19-tbgl-user-defined-entities)

You do some interesting stunts in your code with some kind of address, but there is more simple way - using TBGL_EntityGetFreeID to get new id for entity. To delete elements in scene, just destroy the scene using TBGL_SceneDestroy and recreate it.

You do lot of unnecessary actions in your drawPyramid_Entity:


you don't need to bind the control again, it is bound since the program start
you don't need to recreate whole scene just to add one object

So, to start you up, here is sample code (but please read first the article linked above for deeper understanding):


' -- Custom function to create pyramid, based on func slot general purpose entity
Function Pyramid_Create(sScene As Long, x As Single, y As Single, z As Single)
' -- Get new ID
Dim id As Long = TBGL_EntityGetFreeID(sScene)

TBGL_EntityCreateFuncSlot(%sScene, id, 0, "Pyramid_Render")
TBGL_EntitySetPos(%sScene, id, x, y, z)

' -- Just in case we need it later
Return id

End Function

Function Pyramid_Render()

' -- Retrieve entity identifier
Dim element As TBGL_tEntityIdentifier At TBGL_CallingEntity

' -- Draw it
TBGL_BeginPoly %GL_TRIANGLE_FAN
TBGL_Color 0, 128, 255
TBGL_Vertex 0.0, 1.0, 0.0

TBGL_Color 255, 0, 0
TBGL_Vertex -1.0, -1.0, 1.0

TBGL_Color 255, 255, 255
TBGL_Vertex 1.0, -1.0, 1.0

TBGL_Color 0, 0, 255
TBGL_Vertex 1.0, -1.0, -1.0

TBGL_Color 0, 255, 0
TBGL_Vertex -1.0, -1.0, -1.0

TBGL_Color 255, 0, 0
TBGL_Vertex -1.0, -1.0, 1.0
TBGL_EndPoly

End Function


And to add one pyramid, you just call this:


' -- Add pyramid at random locaiton
Pyramid_Create(%sScene, Rndf(-5,5), Rndf(-5,5), 0)


It's really that simple :)

I attach full code for you.


Petr

Lionheart008
15-01-2011, 17:50
many thanks petr, I didn't know that article I have to read still. I will prove your example this evening and give more feeback next time, kind regards, frank

Lionheart008
18-01-2011, 11:05
good morning,

petr, I have two questions, important for me for understanding more about openGL (tbgl).

1) what`s secret (meaning of..) behind:

TBGL_EntityCreateFuncSlot(%sScene, id, 0, "Pyramid_Render")

2) it's possible to insert such a pyramid (for example) without using tbgl_entity modus like you did in formerly times with old modus (tbgl new list 1, tbgl_calllist) ?

would be good to hear more infos about this entityCreateFuncSlot, I wanted to create such an insertion example without using to understand openGL cosmos :) it`s sometimes black box system tbgl, but I like it so mucho !

thanks, nice day, frank

Petr Schreiber
18-01-2011, 16:57
Hi Frank,

1)
TBGL_EntityCreateFuncSlot does nothing else, than calling the specified function (that is where the funcSlot comes in) during call of TBGL_SceneRender, while performing the appropriate transformation on it.

2)
Its purpose is to make possible to render arbitrary geometry and plug it in to the scene graph done using scene entity system... Because function can contain any graphic code.

Both of these facts are mentioned in the linked article.

For calling display lists, it is better to use TBGL_EntityCreateDLSlot when dealing with entity system for performance reasons, but you can use these commands in func slot as well*.


Petr

* Not a good idea from design stand point to create new lists there. Possible, but not good practice. When display lists is created, display driver has to perform repeated allocations, as the size of cached object is not determined at the point of beginning of definition from coders point of view.

Lionheart008
22-01-2011, 17:18
hi petr, thanks for explanations!

my question belongs to powerbasic and openGL too. If I delete in winmain() for example "draw scene(hwnd,1,1)" the main scene for a nehe example I can insert or add primitives via button click too in my scene. but there is no chance to make a combination with an equate and a "call list 1" (for insertion of objects to the same %scene level) or another object. I understand only the half of tbgl entity system (whats the background of this function), but I will check if I can find similar things to openGL in powerbasic to understand all relations between primitives and a scene and a material for example. my little example I add here for you, if you like to see that one. I think the problem will be to specify for every new openGL primitive an unique equal to call or colorize it with different colour or such things. just an idea. I like tbgl and it is a very good learning partner :) so long, thanks, bye, frank