Author Topic: openGL scene + menu  (Read 5838 times)

0 Members and 1 Guest are viewing this topic.

Frankolinox

  • Guest
openGL scene + menu
« on: February 01, 2014, 01:58:31 AM »
this was a hard job.. I can say only.. looks so simple but it wasn't easy..
the example works, but there were some hurdles to take to make it run. here some more question:

a) qt: why a "declare function... lib... alias..." doesn't work in "openGL window frame" but with no problem in win api frame (like menu example)? I've got immediately an error message

b) what advantage I have with

Code: [Select]
% ExplicitMain
in top of code example ? some openGL example use it (newer and complexer ones) other use it not

c) if you like to test the example take attention. I have modified "openGLwindowfram.inc" with menu features..place this example in "example/openGL" folder.


Code: [Select]
 '
  '  openGL exercise: cube textured, gridlines, sphere
  '  a way how to insert a menu in openGL 31.01.2014 by frankolinox
  '
  includepath "$\inc\"
  $ FileName "openGL_scene+Menu_go.exe"
  'include "RTL32.inc"
  'include "RTL64.inc"
  ''include "minwin.inc"
  $ title  "Crates, sphere + gridlines"  
  ''% ExplicitMain
  include  "OpenglSceneFrame.inc"  
  includepath ""  
  include "shapes.inc"
  include "particles.inc"
  include "materials.inc"
  
' error: doesn't accept declare statements in openGL
'--------------------------------------------------------------------- //
''DECLARE FUNCTION CreateMenu LIB "USER32.DLL" ALIAS "CreateMenu" ( _
'' ) AS LONG                                            

''DECLARE FUNCTION GetMenu LIB "USER32.DLL" ALIAS "GetMenu" ( _
''   BYVAL hWnd AS LONG _                                
'' ) AS LONG                                            
'--------------------------------------------------------------------- //
' error: doesn't accept declare statements in openGL

  indexbase 1
  sys   texn[3]
  sys   GdiplusToken
  sys   cube,sphere,helix,tors
  float ang1
  float li[16]
  float ma[13]
  sys cube pent
  RECT   crect
  materials WhiteMaterial,RedMaterial
  
  sub initialize(sys hWnd)
  ========================
  '
  'GDIPLUS
  '
  sys hr
  GdiplusStartupInput StartupInput

  StartupInput.GdiplusVersion = 1
  hr=GdiplusStartup GdiplusToken, StartupInput, null
  '
  if hr then
    print "Error initializing GDIplus: " hex hr
    exit function
  end if
  '
  'PREPARE TEXTURES
  '
  glGenTextures 2, texn
  '
  static sys res=256
  string imgs[1]=""
  ''GetTexImage "../images/crate.jpg",res,imgs[1]
  GetTexImage "townColor.jpg",res,imgs[1] ''townColor.jpg
  MakeTexture *imgs[1],res,res,texn[1]
  '
  sphere=CompileList : Spheric 0.5,0.5,6 : glEndList '1,1,6 : glEndList
  cube=CompileList : CubeForm    : glEndList
  pent=CompileList : Sides 5,1,1 : glEndList
  '
  'standard lighting
  ------------------
  li<=
  0.0, 8.0, 8.0, 1.0,  'position
  1.0, 1.0, 1.0, 1.0,  'ambient
  1.0, 1.0, 1.0, 1.0,  'diffuse
  1.0, 1.0, 1.0, 1.0   'specular

  'standard material
  ------------------
  ma<=
  .15, .15, 0.2, 1.0, 'ambient
  0.7, 0.7, 0.6, 1.0, 'diffuse
  0.0, 0.0, 0.1, 1.0, 'specular  
  0                   'shininess
  Material ma
  Lighting li
  '
  ' below doesn't work at all ------------------ //
  WhiteMaterial.standard
  RedMaterial.standard
  RedMaterial.ambient <= .15,.0,.0,1.
  RedMaterial.diffuse <= .65,.0,.0,1.
  ' above doesn't work at all ------------------ //
  
  SetTimer hWnd,1,10,null
  end sub

  sub Release(sys hwnd)
  '====================
  glDeleteLists    cube,1
  glDeleteLists    pent,1
  glDeleteTextures 2, texn
  GdiplusShutdown GdiplusToken
  killTimer hwnd, 1
  end sub

  sub RenderCrate(float x,y,z,sc,sys tex)
  =======================================
  'glColor4f .99,.99,.99,.99
  glEnable GL_TEXTURE_2D
  glBindTexture GL_TEXTURE_2D,tex
  glPushMatrix
  gltranslatef x,y+0.35,z-1
  glrotatef    ang1,0,1,0
  glscalef sc,sc,sc
  glCallList Cube
  'glCallList Pent
  glPopMatrix
  glDisable GL_TEXTURE_2D
  end sub


  sub scene(sys hWnd)
  '==================
  '
  'Ctrl-P take snapshot
  '
  sys i,j
  static sys photo
  if key[80] and key[17] and photo=0
    TakeOpenglSnapShot hwnd,"tim50.jpg","image/jpeg",50
    photo=1
  elseif key[80]=0
    photo=0
  end if

  static single ra,ri,angi1=.5
  '
  glClear GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT
  glEnable GL_DEPTH_TEST
  glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
  glEnable GL_BLEND
  glLoadIdentity
  '
  glClearColor 0.5, 0.5, 0.7, 0
  '
  '
  float fcolor[4]={.5, .5, .7, .99}
  glfogi GL_FOG_MODE,GL_EXP
  glfogf GL_FOG_DENSITY,0.1
  glfogfv GL_FOG_COLOR,  fcolor
  glfogf GL_FOG_INDEX,  0
  glfogf GL_FOG_START, -1.0
  glfogf GL_FOG_END,   -100.0
  glEnable GL_FOG
  '
  glEnable GL_LIGHTING
  glEnable GL_NORMALIZE
  glColor4f .99,.99,.99,.99
  sys n=texn[1]
  RenderCrate  11.5,-0.9,-24.0,0.5,n
  RenderCrate   6.5,-0.9,-16.0,0.5,n
  RenderCrate   2.5,-0.9,-8.0, 0.5,n
  RenderCrate   0.5,-0.9,-4.0, 0.5,n
  RenderCrate  -0.5,-0.9,-2.0, 0.5,n
  '
  ' sphere ----------------------
  glLoadIdentity
  glPushMatrix
  glTranslatef -3.,1.,-7.0
  RedMaterial.act
  glScalef      2.,2.,2.
  glEnable GL_LIGHTING
  glCallList sphere
  glDisable GL_LIGHTING
  WhiteMaterial.act
  glPopMatrix
  '
  ' - gridlines ----------------- //
  glLoadIdentity
  glrotatef    ang1,0,1,0  
  GLBegin GL_LINES      
        GLColor3f 0,0,255 '0,255,0                        
        For i = -10 To 10        
          For j = -10 To 10            
            glVertex3f -10, -1,   j            
            glVertex3f  10, -1,   j                            
            glVertex3f  i,  -1, -10                
            glVertex3f  i,  -1,  10    
          Next
        Next
      GLEnd
  '
  ang1+=angi1
  if ang1>360 then ang1-=360
  '
  sleep 10      
  end sub

''MainWindows width,height,WS_OVERLAPPEDWINDOW
MainWindows 860,640,WS_OVERLAPPEDWINDOW

'' -------------------------------------------- //
  Function MainWindows(sys width,height,style)
  ===========================================
  '
  sys      a,b,c,hWnd
  WNDCLASS wc
  MSG      wm
  '
  inst=GetModuleHandle 0
  '
  with wc.                 '
    style=CS_HREDRAW or CS_VREDRAW
    lpfnWndProc   = @wndprocs
    cbClsExtra    = 0
    cbWndExtra    = 0    
    hInstance     = inst
    hIcon         = LoadIcon 0, IDI_APPLICATION
    hCursor       = LoadCursor 0,IDC_ARROW
    hbrBackground = GetStockObject WHITE_BRUSH '
    lpszMenuName  = 0
    lpszClassName = strptr "wins"
  end with

  if not RegisterClass @wc
    MessageBox 0,"Registration failed","Problem",MB_ICONERROR
    exit function
  end if

  'Create the main window.
  hwnd = CreateWindowEx(
    0,                      'no extended styles          
    "wins",                 'class name                  
    "Main Window",          'window name  
    style,                  '                
    CW_USEDEFAULT,          'default horizontal position  
    CW_USEDEFAULT,          'default vertical position    
    100+width,                  'default width                
    100+height,                 'default height              
    null,                   'no parent or owner window    
    null,                   'class menu used              
    inst,                   'instance handle              
    null);                  'no window creation data      
  if not hWnd then
    MessageBox 0,"Unable to create window","problem",MB_ICONERROR
    exit function
  end if
  '
   sys hMenu,hMenuPopup,hSysMenu
  
  ShowWindow hWnd,SW_NORMAL
  UpdateWindow hWnd
  '
  'MESSAGE LOOP
  '============
  '
  sys bRet
  '
  while bRet := GetMessage @wm, 0, 0, 0
    if bRet == -1 then
      'show an error message?
    else
      #ifdef EscapeKeyEnd
      if wm.message=WM_KEYDOWN
        if wm.wparam=27
          SendMessage hwnd,WM_DESTROY,0,0
        end if  
      end if
      #endif
      #ifdef RelayMessages
      m=wm.message
      select m
      '
      case WM_LBUTTONDBLCLK
      =====================
        '
        SendMessage hwnd,WM_COMMAND,1100-0x200+m, 0
        '
      case WM_KEYDOWN
      ===============
        '
        m=wm.wparam
        select m
        case VK_RETURN
          for i=1 to nchw
            if wm.hwnd=hchw(i)
              SendMessage hwnd,WM_COMMAND,2000+VK_RETURN,0
              if i>1 then continue while 'first window is editor
            end if
          next
        case VK_F1 to VK_F10
          SendMessage hwnd,WM_COMMAND,1001+m-VK_F1, 0
        case "A" to "Z"
          if CtrlKey
            SendMessage hwnd,WM_COMMAND,2000+m, 0
            if m=65 or m=70 or m=71 then continue while
          end if
        case VK_ESCAPE
          SendMessage hwnd,WM_COMMAND,2200+VK_ESCAPE, 0
          Continue do
        end select
        '
      end select
      '
      #endif
      TranslateMessage @wm
      DispatchMessage @wm
    end if
  wend
  '
  end function ; end of WinMain
  '
  '---------------
  'DEFAULT WNDPROC
  '
  function WndProcs(sys hwnd, uMsg, wParam, lParam) as long callback
  =================================================================
  '
  'MENU ITEMS
  '
  %IDM_FILE_NEW     40001
  %IDM_FILE_OPEN    40002
  %IDM_FILE_SAVE    40003
  %IDM_FILE_SAVE_AS 40004
  %IDM_APP_EXIT     40005
  %IDM_EDIT_UNDO    40006
  %IDM_EDIT_CUT     40007
  %IDM_EDIT_COPY    40008
  %IDM_EDIT_PASTE   40009
  %IDM_EDIT_CLEAR   40010
  %IDM_APP_HELP     40011
  %IDM_APP_ABOUT    40012
  
  static sys hDC,hRC

  select umsg
  '
  case WM_CREATE
    PostQuitMessage 0
  
  case WM_COMMAND

      
  case WM_DESTROY
  '
  PostQuitMessage 0

  case WM_KEYDOWN

    Select wParam
    Case 27 : SendMessage hwnd, WM_CLOSE, 0, 0      'ESCAPE
    End Select
      
  case else
  '
  function=DefWindowProc hWnd,uMsg,wParam,lParam
  '
  end select
  end function

I have fun at all with this example because of three learning hours with win api and openGL and a lot of error messages ;)

all you need, source code, exe + oxygen.dll you find in zip folder.

best regards, frank

.

Charles Pegge

  • Guest
Re: openGL scene + menu
« Reply #1 on: February 01, 2014, 07:49:26 AM »
Hi Frank,

Thanks for your hard work!

There is a solution for extending the OpenGLSceneFrame WndProc, which is what you need for adding a set of menus, and any other windows items you require.

I have added a few lines to OpenglSceneFrame to make this possible:

 sys WndProcExtra 'callback for customised windows message processing

  function WndProc(sys hwnd, uMsg, wParam, lParam) as sys callback
  ================================================================
  '
  static sys hDC,hRC
  '
 if WndProcExtra
    if call WndProcExtra(hwnd,uMsg,wParam,lParam) then exit function
  end if


Then you can create a procedure in your application, to intercept, and possibly override the standard WndProc message processing

 function WindowMessages(sys hwnd, uMsg, wParam, lParam) as sys, link WndProcExtra
...


Code: [Select]
 function WindowMessages(sys hwnd, uMsg, wParam, lParam) as sys, link WndProcExtra
  =================================================================================
  'MENU ITEMS
  '
  %IDM_FILE_NEW     40001
  %IDM_FILE_OPEN    40002
  %IDM_FILE_SAVE    40003
  %IDM_FILE_SAVE_AS 40004
  %IDM_APP_EXIT     40005
  %IDM_EDIT_UNDO    40006
  %IDM_EDIT_CUT     40007
  %IDM_EDIT_COPY    40008
  %IDM_EDIT_PASTE   40009
  %IDM_EDIT_CLEAR   40010
  %IDM_APP_HELP     40011
  %IDM_APP_ABOUT    40012
  '
  static sys hdc,hMenu,hMenuPopup
  static String txt
  static rect crect
  static PaintStruct Paintst
  sys id
  '
  select case uMsg
  '
  case WM_CREATE
  '
  hMenu = CreateMenu
  hMenuPopup = CreateMenu
  AppendMenu hMenuPopup, MF_STRING,    IDM_FILE_NEW,     "&New"
  AppendMenu hMenuPopup, MF_STRING,    IDM_FILE_OPEN,    "&Open..."
  AppendMenu hMenuPopup, MF_STRING,    IDM_FILE_SAVE,    "&Save"
  AppendMenu hMenuPopup, MF_STRING,    IDM_FILE_SAVE_AS, "Save &As..."
  AppendMenu hMenuPopup, MF_SEPARATOR, 0,                null
  AppendMenu hMenuPopup, MF_STRING,    IDM_APP_EXIT,     "E&xit"
  AppendMenu hMenu,      MF_POPUP,     hMenuPopup,       "&File"

  hMenuPopup = CreateMenu
  AppendMenu hMenuPopup, MF_STRING,    IDM_EDIT_UNDO,    "&Undo"
  AppendMenu hMenuPopup, MF_SEPARATOR, 0,                null
  AppendMenu hMenuPopup, MF_STRING,    IDM_EDIT_CUT,     "Cu&t"
  AppendMenu hMenuPopup, MF_STRING,    IDM_EDIT_COPY,    "&Copy"
  AppendMenu hMenuPopup, MF_STRING,    IDM_EDIT_PASTE,   "&Paste"
  AppendMenu hMenuPopup, MF_STRING,    IDM_EDIT_CLEAR,   "De&lete"
  AppendMenu hMenu,      MF_POPUP,     hMenuPopup,       "&Edit"

  hMenuPopup = CreateMenu
  AppendMenu hMenuPopup, MF_STRING,    IDM_APP_HELP,     "&Help"
  AppendMenu hMenuPopup, MF_STRING,    IDM_APP_ABOUT,    "&About MenuDemo..."
  AppendMenu hMenu,      MF_POPUP,     hMenuPopup,       "&Help"
  '
  SetMenu       hwnd, hMenu
  SetWindowText hwnd,"Menu Demo"
  '
  sys dis=MF_DISABLED or MF_GRAYED
  CheckMenuItem hMenu,IDM_FILE_NEW, MF_CHECKED
  EnableMenuItem hMenu,IDM_FILE_OPEN,dis
      
  case WM_COMMAND

  hMenu = GetMenu(hwnd)
  if wparam = IDM_APP_EXIT then        
    SendMessage hwnd, WM_CLOSE, 0, 0
    return 1 'indicate this message has been intercepted / no further action
  end if
  '
  case WM_KEYDOWN
    select case wparam
    keydown 'macro
            'default cases
    case 27 : return 1 'intercept Esc key: prevent sutdown / take no action
    end select
  end select
  end function

App demo and new OpenglSceneFrame Attached:

.

Frankolinox

  • Guest
Re: openGL scene + menu
« Reply #2 on: February 03, 2014, 03:06:57 AM »
thank you very mucho charles for this good idea :)

my new openGL menu example is now running fine, nice day to the north.

kind regards, frank

.

Frankolinox

  • Guest
Re: how to insert a sphere into an openGL scene + menu
« Reply #3 on: February 03, 2014, 08:11:36 AM »
hi charles, do you know a chance or programming technic how to "insert" a sphere in an existing openGL scene by clicking a menu item? do you have a link or an idea if that's possible with oxygen? My idea was to catch a "sphere" by name (string) in wndproc callback part, but how does the "scene" know that's this new sphere is placed in it? the scene has to be rendered in updated modus ? :)

regards, frank

Charles Pegge

  • Guest
Re: openGL scene + menu
« Reply #4 on: February 03, 2014, 09:40:55 AM »
Interesting idea, Frank. A right-click pop-up menu could be used to create, or delete picked objects in the scene. To do this, the program needs to maintain an array of objects to be displayed, giving shape, color position etc. The shapes can be pre-compiled glLists.

examples/Opengl/MovObjKeyb.o2bas would a good basis for building such a menu-controlled demo. I will give it some further thought. :)

Frankolinox

  • Guest
Re: openGL scene + menu
« Reply #5 on: February 04, 2014, 10:05:32 AM »
hi charles, if I am using the "MovObjKeyb.o2bas" example as basis (a good one!) how I can setup a

"sphere" class? ;)

thanks, frank

Frankolinox

  • Guest
Re: openGL scene + menu
« Reply #6 on: February 05, 2014, 08:01:35 AM »
here's my first attempt, but I don't know if that's correct..

Code: [Select]
  '
  '-------- test: sphere class by frankolinox, 5.2.2014, oxygenbasic
  '
  includepath "$\inc\"
  $ FileName  "t.exe"
  'include    "RTL32.inc"
  'include    "RTL64.inc"
  '
  % ExplicitMain
  % UsesClasses
  $ title        "sphere class"
  $ fontA        "Arial",FW_SEMIBOLD
  '
  include "OpenglSceneFrame.inc"
  '
  includepath ""
  include "shapes.inc"

  indexbase 1
  sys       texn[16]
  sys       GdiplusToken
  float     ang1
  float     li[16]
  float     ma[13]
  sys       cube,pent,sphere,helix,tors
 
  '---------------------- that's ok for sphere class? ----------------- //
  ============
  class sphere
  ============
  float x,y,z
  float rw,rh,m 'sphere
  sys   tex
  '
  float  angx,angy,angz ' I needed that one too?
  float  xx,yy,zz       ' I needed that one too?

  method Render()
  ===============
  if tex then glBindTexture GL_TEXTURE_2D,tex
  glPushMatrix
  gltranslatef  x,y,z
  glrotatef     angx,1,0,0 'rotate yz  : pitch
  glrotatef     angy,0,1,0 'rotate xz  : yaw
  glrotatef     angz,0,0,1 'rotate xy  : yaw
  glscalef      rw,rw,rw 'sc,sc,sc
  ''ConeFaces     n,rz,ry,sm
  Spheric rw,rh,m ''1,1,6
  glPopMatrix
  end method
  '
  method anchor()
  ===============
  xx=x
  yy=y
  zz=z
  end method
  '
  method move(single mx,my,mz)
  ============================
  x=xx+mx
  y=yy+my
  z=zz+mz
  limit
  end method
  '
  method limit()
  ==============
  float d=-z,id=-1/z
  if  x*id<-0.5 then x=-.5*d
  if  y*id<-0.4 then y=-.4*d
  if z>-1.0 then z=-1.0
  if x*id>.5  then x=.5*d
  if y*id>.4 then y=.4*d
  end method
  '
  method drag()
  =============
  float dx,dy,dz
  dx=mposx-sposx
  dy=sposy-mposy
  dz=-z/crect.right
  move dx*dz,dy*dz,0
  end method
  '
  end class

'---------------------- that's ok for sphere class? ----------------- //

'------------------------------- shapes.inc ------------- //
  sub HemiSpheric(float rw, rh, m)
  ================================
  float s,c,r,r1,r2,x1,x2,y1,y2,z1,z2
  sys e,i,j,st=m
  e=90-st
  for j=0 to e step st
    r=rad(j)    : r1=rw*cos(r) : y1=rh*sin(r)
    r=rad(j+st) : r2=rw*cos(r) : y2=rh*sin(r)
    glBegin GL_QUAD_STRIP
    for i=0 to 360 step st
      r=rad(i)
      c=cos(r) : s=sin(r)
      x1=r1*c  : z1=r1*s
      x2=r2*c  : z2=r2*s
      glNormal3f x2, y2, z2
      glVertex3f x2, y2, z2
      glNormal3f x2, y1, z1
      glVertex3f x1, y1, z1
    next
    glEnd
  next
  end sub

  sub spheric(float rw,rh,m)
  ==========================
  glPushMatrix
  hemispheric   rw, rh, m
  glRotatef     180.0,1,0,0
  hemispheric   rw, rh, m
  glPopMatrix
  end sub

  '-------------- // test
  print "ok"
  '--------------- //
 
  ' 'sphere=CompileList : Spheric 1,1,6 : glEndList

and step two how to make a sphere data setup (like charles have done for cones) that's not clear here

regards, frank

Charles Pegge

  • Guest
Re: openGL scene + menu
« Reply #7 on: February 05, 2014, 11:36:04 AM »
glCompiling


include "shapes.inc"

initialising:
 cube=CompileList   : CubeForm      : glEndList
  sphere=CompileList : Spheric 1,1,6 : glEndList

Calling:
  'MYSTERIOUS RED PLANET
  glPushMatrix
  glTranslatef -20.,10.,-95.0
  RedMaterial.act
  glScalef      6.,6.,6.
  glEnable GL_LIGHTING
  glCallList sphere
  'glDisable GL_LIGHTING
  WhiteMaterial.act
  glPopMatrix

Releasing:
 glDeleteLists    cube,1
  glDeleteLists    sphere,1


Compiled lists are very efficient in Opengl. Once the shape is compiled, it can be used with materials & textures, and scaled to any proprtion.



Frankolinox

  • Guest
Re: openGL scene + menu
« Reply #8 on: February 06, 2014, 02:32:08 AM »
yes, charles, that was basis for my first example above (post 1, post 3) :)

a) I thought as you've mentioned the "pickup and move objects" ("MovObjKeyb.o2bas") oxygen example, that it's better to use "classes" for the primitives, that confused me a little bit. therefore I've started with a "sphere class" setup (my last post), but I was not sure how that's going correct with "sphere data" setup, as you did it with "cone" data setup. I will send a new example and if you have time you can check it :)

b) to pick up objects the method I like so I will follow this example and try to insert primitives in openGL scene by "name" (string) or %sphere  equates for example.

regards, frank

Charles Pegge

  • Guest
Re: openGL scene + menu
« Reply #9 on: February 06, 2014, 04:06:12 AM »
Hi Frank,

I'm using classes to keep all the variables and functions bunched together. When you have multiple objects with varioust behaviours, it keeps the program manageable.

I've got the menu integrated with MoveObjKeyb. But not doing anything yet.

Still using cones but this is easily abstracted to support other shapes.

progress so far:

.

Charles Pegge

  • Guest
Re: openGL scene + menu
« Reply #10 on: February 08, 2014, 08:30:55 AM »
The menu is now functional for selecting materials

Needs this Oxygen.dll update, for some of the OOP:

http://www.oxygenbasic.org/forum/index.php?topic=749.0



.

Charles Pegge

  • Guest
Re: openGL scene + menu
« Reply #11 on: February 09, 2014, 04:40:34 AM »
More fun and games:

SceneObject has replaced the Cones class. So you can change shapes from the menu, as well as select materials. If no object has been picked the a new object is created

Using the shift key with the mouse enables movement in the z direction. The ctrl key enables object rotation. The home key sets all rotations to 0 for the selected object.

Make sure you have the latest Oxygen.dll (link above), released yesterday

.
« Last Edit: February 09, 2014, 07:24:23 AM by Charles Pegge »

Frankolinox

  • Guest
Re: openGL scene + menu
« Reply #12 on: February 11, 2014, 01:33:29 AM »
thanks charles for these both openGL examples, that's very liked here with right-click material apply :) that's similar what I wanted to create last year but I haven't that big knowledge so far with oxygen and win api at that time.

regards, frank