Does anyone have any tutorials on how to integrate MiniB3D into wxMax instead of MaxGUI? I have been working on this for a couple days and still have not found any luck.
MiniB3D and wxMax
BlitzMax Modules Forums/MiniB3D/MiniB3D and wxMaxSuperStrict Framework wx.wxApp Import wx.wxFrame Import wx.wxTimer Import wx.wxPanel Import wx.wxglmax2D Import "MiniB3D.bmx" Const Menu_Exit:Int = 100 SetGraphicsDriver wxGLGraphicsDriver(),GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER New Window.run() Type Window Extends wxApp Field Frame:WinFrame Method OnInit:Int() Frame = WinFrame(New WinFrame.Create(Null, -1, "Terrain Editor", , , 800, 600)) Frame.show(True) SetTopWindow(Frame) Return True End Method End Type Type WinFrame Extends wxFrame Field Canvas:WinCanvas Method OnInit() Local FileMenu:wxMenu = wxMenu.CreateMenu() Local MenuBar:wxMenuBar = wxMenuBar.CreateMenuBar() Local Panel:wxPanel = New wxPanel.Create( Self ) Canvas = WinCanvas(New WinCanvas.Create(Panel, -1, GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER,0,0,800,600)) ConnectAny(wxEVT_CLOSE, OnClose) FileMenu.Append(Menu_Exit, "Exit~tAlt-X", "Quit this program") MenuBar.Append(FileMenu, "&File") SetMenuBar(MenuBar) CreateStatusBar(1) SetStatusText("Terrain Editor") End Method Function OnClose(event:wxEvent) WinFrame(event.parent).Canvas.timer.Stop() event.Skip() End Function End Type Type WinCanvas Extends wxGLCanvas Field Timer:wxTimer Method OnInit() SetBackgroundStyle(wxBG_STYLE_CUSTOM) Timer = New wxTimer.Create(Self) ConnectAny(wxEVT_TIMER, OnTick) Timer.Start(100) End Method Method OnPaint(event:wxPaintEvent) Render() End Method Method Render() SetGraphics CanvasGraphics2D( Self ) SetClsColor(0, 0, 0) SetColor(0, 0, 0) Cls Draw() Flip End Method Function OnTick(event:wxEvent) wxWindow(event.parent).Refresh() End Function Method Draw() TGlobal.width = 400 TGlobal.height = 300 TGlobal.GraphicsInit() Local cam:TCamera=CreateCamera() Local light:TLight=CreateLight(1) Local cube:TMesh=CreateCube() Local sphere:TMesh=CreateSphere() Local cylinder:TMesh=CreateCylinder() Local cone:TMesh=CreateCone() PositionEntity cam,0,0,-10 PositionEntity cube,-6,0,0 PositionEntity sphere,-2,0,0 PositionEntity cylinder,2,0,0 PositionEntity cone,6,0,0 TurnEntity cube,0,1,0 RenderWorld End Method End Type
I have that so far, still need help. I do not know what I should change it to instead of Max2D
Okay... this is your example with modifications based partly on the maxgui example :
If you want the 3d canvas to scale with the window you'll probably need to connect the size event and set TGlobal's width and height to match the new values.
Note that there are currently issues using a fullscreen-mode canvas with wxMax, in that input events seem to get lost somewhere. If you are only using it in a Window, it works fine.
SuperStrict Framework wx.wxApp Import wx.wxFrame Import wx.wxTimer Import wx.wxPanel Import wx.wxglmax2D 'Import "MiniB3D.bmx" Import sidesign.minib3d Const Menu_Exit:Int = 100 SetGraphicsDriver wxGLGraphicsDriver(),GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER New Window.run() Type Window Extends wxApp Field Frame:WinFrame Method OnInit:Int() Frame = WinFrame(New WinFrame.Create(Null, -1, "Terrain Editor", , , 800, 600)) Frame.show(True) SetTopWindow(Frame) Return True End Method End Type Type WinFrame Extends wxFrame Field Canvas:WinCanvas Method OnInit() Local FileMenu:wxMenu = wxMenu.CreateMenu() Local MenuBar:wxMenuBar = wxMenuBar.CreateMenuBar() Local Panel:wxPanel = New wxPanel.Create( Self ) Canvas = WinCanvas(New WinCanvas.Create(Panel, -1, GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER,0,0,800,600)) ConnectAny(wxEVT_CLOSE, OnClose) FileMenu.Append(Menu_Exit, "Exit~tAlt-X", "Quit this program") MenuBar.Append(FileMenu, "&File") SetMenuBar(MenuBar) CreateStatusBar(1) SetStatusText("Terrain Editor") End Method Function OnClose(event:wxEvent) WinFrame(event.parent).Canvas.timer.Stop() event.Skip() End Function End Type Type WinCanvas Extends wxGLCanvas Field Timer:wxTimer Field cam:TCamera Field light:TLight Field cube:TMesh Field sphere:TMesh Field cylinder:TMesh Field cone:TMesh Method OnInit() SetBackgroundStyle(wxBG_STYLE_CUSTOM) Timer = New wxTimer.Create(Self) ConnectAny(wxEVT_TIMER, OnTick) Timer.Start(17) ' ********** Local width:Int, height:Int GetSize(width, height) SetGraphics CanvasGraphics2D( Self ) TGlobal.width = width TGlobal.height = height TGlobal.depth=16 TGlobal.mode=0 TGlobal.rate=60 TGlobal.GraphicsInit() ' ************ cam=CreateCamera() light=CreateLight(1) cube=CreateCube() sphere=CreateSphere() cylinder=CreateCylinder() cone=CreateCone() End Method Method OnPaint(event:wxPaintEvent) Render() End Method Method Render() SetGraphics CanvasGraphics2D( Self ) Draw() Flip End Method Function OnTick(event:wxEvent) wxWindow(event.parent).Refresh() End Function Method Draw() PositionEntity cam,0,0,-10 PositionEntity cube,-6,0,0 PositionEntity sphere,-2,0,0 PositionEntity cylinder,2,0,0 PositionEntity cone,6,0,0 TurnEntity cube,0,1,0 RenderWorld End Method End Type
If you want the 3d canvas to scale with the window you'll probably need to connect the size event and set TGlobal's width and height to match the new values.
Note that there are currently issues using a fullscreen-mode canvas with wxMax, in that input events seem to get lost somewhere. If you are only using it in a Window, it works fine.
I am still not getting any sort of render in the canvas. I will work with it a bit and if I get it, I will post it for others.
Hmm... worked here on Mac (so I assumed it should work for Win32 too)... I'll need some time to set up my Parallels to have the latest everything in order to try it there...
What version of MiniB3D do you have?
Nothing is rendered here...
Windows XP, 3ghz P4 processer, NVIDIA 9600 GT video card
Windows XP, 3ghz P4 processer, NVIDIA 9600 GT video card
I have fixed the example posted by Brucey by sticking a TGLobal.EnableStates() in the draw method.
It now works on my intel macbook running Windows XP.
This is overkill because it seems EnableStates() only needs to be called once.
I'm not sure where to put it so that it happens once, after init(), but before render()
The modified render method looks like this:
It now works on my intel macbook running Windows XP.
This is overkill because it seems EnableStates() only needs to be called once.
I'm not sure where to put it so that it happens once, after init(), but before render()
The modified render method looks like this:
Method Render() SetGraphics CanvasGraphics2D( Self ) TGlobal.EnableStates() Draw() Flip End Method
EnableStates is called during Graphics3D(). I don't think it's ment to be called outside minib3d. It tells opengl to enable different features. Some state settings are missing resulting in garbled output in your original example above.
I found out that in your example it's simply called to early for some implementations. (all windows versions? )
It just needs to be called a little later in the application startup sequence.
I found out that in your example it's simply called to early for some implementations. (all windows versions? )
It just needs to be called a little later in the application startup sequence.
it's simply called to early for some implementations.
Quite likely.
Different platforms expect different things to have happened by the time you come to use particular APIs.
I suppose that's what makes cross-platform programming so much fun :-)
Running brucey's example (with fix added) i get a "runtime exception: unhandled memory exception error" on RenderWorld. why?
If i run the first code i'have no errors but no render, only black rect.
If i run the first code i'have no errors but no render, only black rect.
Running brucey's example (with fix added) i get a "runtime exception: unhandled memory exception error" on RenderWorld. why?
Try adding TGlobal.GraphicsInit() to the Render method.
By the way, I can't figure out how to render textures. I'm only getting white surfaces.
Thanks! Now i can use minib3d and wxMax. for texturese, same problem here :(
No textures here too...
I got it! :)
The textures have to be loaded after the graphics were initialized, which is after the first run of the Render Method. Also the graphics must be initialized once only.
Makes sense right?
The textures have to be loaded after the graphics were initialized, which is after the first run of the Render Method. Also the graphics must be initialized once only.
Field initialized_graphics:Int=False Method Render() If Not initialized_graphics Then TGlobal.GraphicsInit() EntityTexture cube,LoadTexture("path\to\texture.png") initialized_graphics=True End If Draw() Flip End Method
Makes sense right?
Yeah, that's it.
Great!
[Edit]
Has anyone tested it with an textured mesh?
My whole screen ist flickering while LoadMesh.
Great!
[Edit]
Has anyone tested it with an textured mesh?
My whole screen ist flickering while LoadMesh.
thanks!
My whole screen ist flickering while LoadMesh.
What exactly do you mean? Your screen shouldn't refresh at all while executing a LoadMesh call (except you do it in a separate thread). The mesh I tried (.b3d) worked well.
Besides of that I noticed that all meshes must be created after the GraphicsInit() or they'll get overwritten by other meshes.
My whole screen, not just the WxFrame, flashed black and white
and the app freezed under Vista.
This was the point. ALL meshes.
Not just overwritten, it caused some more serious errors.
The cube, sphere and cylinder were created in OnInit().
The other mesh was loaded in Render()
If I move them in Render() after the second "TGlobal.GraphicsInit()"
then it works. Don't know why..
My failing Code:
and the app freezed under Vista.
that all meshes must be created after the GraphicsInit() or they'll get overwritten by other meshes
This was the point. ALL meshes.
Not just overwritten, it caused some more serious errors.
The cube, sphere and cylinder were created in OnInit().
The other mesh was loaded in Render()
If I move them in Render() after the second "TGlobal.GraphicsInit()"
then it works. Don't know why..
My failing Code:
SuperStrict ' WARNING Code FAILS!! Framework wx.wxApp Import wx.wxFrame Import wx.wxTimer Import wx.wxPanel Import wx.wxglmax2D Import sidesign.minib3d Const Menu_Exit:Int = 100 SetGraphicsDriver wxGLGraphicsDriver(),GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER New Window.run() Type Window Extends wxApp Field Frame:WinFrame Method OnInit:Int() Frame = WinFrame(New WinFrame.Create(Null, -1, "Terrain Editor", , , 800, 600)) Frame.show(True) SetTopWindow(Frame) Return True End Method End Type Type WinFrame Extends wxFrame Field Canvas:WinCanvas Method OnInit() Local FileMenu:wxMenu = wxMenu.CreateMenu() Local MenuBar:wxMenuBar = wxMenuBar.CreateMenuBar() Local Panel:wxPanel = New wxPanel.Create( Self ) Canvas = WinCanvas(New WinCanvas.Create(Panel, -1, GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER,0,0,800,600)) ConnectAny(wxEVT_CLOSE, OnClose) FileMenu.Append(Menu_Exit, "Exit~tAlt-X", "Quit this program") MenuBar.Append(FileMenu, "&File") SetMenuBar(MenuBar) CreateStatusBar(1) SetStatusText("Terrain Editor") End Method Function OnClose(event:wxEvent) WinFrame(event.parent).Canvas.timer.Stop() event.Skip() End Function End Type Type WinCanvas Extends wxGLCanvas Field Timer:wxTimer Field cam:TCamera Field light:TLight Field cube:TMesh Field sphere:TMesh Field cylinder:TMesh Field cone:TMesh Field hd:TMesh ' Field initialized_graphics:Int = False Method OnInit() SetBackgroundStyle(wxBG_STYLE_CUSTOM) Timer = New wxTimer.Create(Self) ConnectAny(wxEVT_TIMER, OnTick) Timer.Start(17) ' ********** Local width:Int, height:Int GetSize(width, height) SetGraphics CanvasGraphics2D( Self ) TGlobal.width = width TGlobal.height = height TGlobal.depth=16 TGlobal.mode=0 TGlobal.rate=60 TGlobal.GraphicsInit() ' ************ cam=CreateCamera() light=CreateLight(1) cube=CreateCube() sphere=CreateSphere() cylinder=CreateCylinder() cone = CreateCone() End Method Method OnPaint(event:wxPaintEvent) Render() End Method Method Render() If Not initialized_graphics Then TGlobal.GraphicsInit() Local ufo:TMesh = LoadMesh ("ufo.b3d") ' flashing screen; fails under Vista ************************ initialized_graphics=True End If ' SetGraphics CanvasGraphics2D(Self) Global enabled:int If Not enabled Then enabled = True TGlobal.EnableStates() End If Draw() Flip End Method Function OnTick(event:wxEvent) wxWindow(event.parent).Refresh() End Function Method Draw() PositionEntity cam,0,0,-10 PositionEntity cube,-6,0,0 PositionEntity sphere,-2,0,0 PositionEntity cylinder,2,0,0 PositionEntity cone,6,0,0 TurnEntity cube,0,1,0 RenderWorld End Method End Type
Nice to hear it worked.
I'm not familiar with OpenGL but the problem seems to be that with the second GraphicsInit() the previous setup gets lost but isn't freed up properly as the graphics are never finished correctly, so some objects and settings still reside in the memory and interfere the rendering.
By the way, the first GraphicsInit() (at OnInit()) isn't necessary if you're anyways reinitializing the graphics in the Render method.
I'm not familiar with OpenGL but the problem seems to be that with the second GraphicsInit() the previous setup gets lost but isn't freed up properly as the graphics are never finished correctly, so some objects and settings still reside in the memory and interfere the rendering.
By the way, the first GraphicsInit() (at OnInit()) isn't necessary if you're anyways reinitializing the graphics in the Render method.