Page 1 of 1

[5.31] OGRE Engine3D ScreenOutput to Image or Sprite crash.

Posted: Sun Mar 15, 2015 3:12 am
by Henry00
Hello!
I wish to get a PureBasic image handle for my OGRE windowed screen's buffer. Sadly whenever "InitEngine3D()" is called GrabSprite, ScreenOutput and GrabDrawingImage all break immediately. The reason I wish to have this functionality is because I have a really fun project in RPG Maker. I wish to run OGRE in the background on an invisible window and simply get the frame and pass it to the program as a bitmap. I have tried for hours but cannot find any solution except "WindowOutput" which doesn't work on invisible windows. The image it returns on an invisible window is always black and all it actually does with GrabDrawingImage is make screen-shots which is very slow.

Image

Here is a very small test program to clearly show the problem and errors:

Code: Select all

InitEngine3D() ; Without this line it works fine.
InitSprite()
OpenWindow(0,0,0,800,600,"VXOGRE Screen")
OpenWindowedScreen(WindowID(0), 0, 0, 800, 600, #True, 0, 0)

While 1
  
  WindowEvent()
  RenderWorld(1)
  FlipBuffers()
  
  ; Always Fails.
  If GrabSprite(0,0,0,800,600) = 0
    MessageRequester("Error", "Unable to grab sprite!")
  EndIf
  
  ; The specified output is NULL.
  StartDrawing(ScreenOutput())
  GrabDrawingImage(0, 0, 0, 800, 600)
  StopDrawing()
  
  ; This workaround does function but it's slow and doesn't render properly when it's invisible or alike.
  StartDrawing(WindowOutput(0))
  GrabDrawingImage(0, 0, 0, 800, 600)
  StopDrawing()
  
  Delay(1)
Wend
Thank you so much! :(

Re: [5.31] OGRE Engine3D ScreenOutput to Image or Sprite cra

Posted: Tue Mar 17, 2015 4:45 pm
by Henry00
I have the feeling there really is no way to get a frame from Ogre in InitEngine3D mode. :cry:

Re: [5.31] OGRE Engine3D ScreenOutput to Image or Sprite cra

Posted: Tue Mar 17, 2015 8:39 pm
by Samuel
You can save frames pretty easily. All you need to do is use CreateRenderTexture(#Texture, CameraID, Width, Height [, Flags [, RenderTextureName$]]) to create a texture linked to your camera.
Then you can use SaveRenderTexture(#Texture, Filename$) to save the texture as a bmp, png, and so on.

I'd post an example, but I don't have time at the moment.

Also for future reference you might want to post any 3D related questions in the 3D Programming section.
Makes it easier for us 3D nerds to spot your question. :wink:

Re: [5.31] OGRE Engine3D ScreenOutput to Image or Sprite cra

Posted: Tue Mar 17, 2015 9:28 pm
by DK_PETER
@Henry00

Samuel is right. You should have posted in the 3D section.
Here's a simple example, which shows, what Samuel was talking about.

Code: Select all

InitEngine3D()
InitSprite()
InitKeyboard()

OpenWindow(0, 0, 0, 1024, 768, "Grab", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0), 0, 0, 1024, 768, #False, 0, 0)


CreateCamera(0, 0, 0, 100, 100)
MoveCamera(0, 0, 0, 6)

CreateLight(0, $DDDDDD, 0, -20, 10, #PB_Light_Directional)
LightDirection(0, 0, 0, -1)

CreateTexture(0, 128, 128)
StartDrawing(TextureOutput(0))
DrawingMode(#PB_2DDrawing_Gradient)
FrontColor($8df3f4)
BackColor($d41128)
BoxedGradient(0, 0, 128, 128)
Box(0, 0, 128, 128)
StopDrawing()

CreateMaterial(0, TextureID(0))

CreateCube(0, 1)
CreateSphere(1, 1, 10, 10)

CreateEntity(0, MeshID(0), MaterialID(0), -1, 0, 0)
CreateEntity(1, MeshID(1), MaterialID(0), 1, 0, 0)

quit.i = 0

Repeat
  Repeat
    ev = WindowEvent()
    If ev = #PB_Event_CloseWindow
      quit = 1
    EndIf
  Until ev = 0
  
  ExamineKeyboard()
  
  
  If KeyboardReleased(#PB_Key_Return)
    CreateRenderTexture(2, CameraID(0), 512, 512)
    UpdateRenderTexture(2)
    SaveRenderTexture(2, "D:\Testing.jpg")
  EndIf
  
  RenderWorld()
  
  FlipBuffers()
  
Until KeyboardPushed(#PB_Key_Escape) Or quit = 1

Re: [5.31] OGRE Engine3D ScreenOutput to Image or Sprite cra

Posted: Wed Mar 18, 2015 3:05 am
by oreopa
Excellent question and responses. I was gonna ask how to do this also. Cheers!

Re: [5.31] OGRE Engine3D ScreenOutput to Image or Sprite cra

Posted: Wed Mar 18, 2015 8:15 am
by Henry00
Very sorry about the forum and many thanks for this solution :D ! This really is a great way to capture the scene to a texture and even to an image on the hard-drive yet the help file says:
"TextureOutput() is not supported on rendered textures."
Is it not possible to get the pixel data (a memory address is fine with me) or a PureBasic Image handle? Saving the image to the hard-drive and then LoadImage() it so I can use the pixel data every frame sounds a bit excessive. Any advice on this last issue would be extremely welcome!

edit:
http://www.purebasic.fr/english/viewtop ... 36&t=56095 <- my problem exactly.
Should I take this to the feature request forum?

Re: [5.31] OGRE Engine3D ScreenOutput to Image or Sprite cra

Posted: Tue Jan 03, 2017 1:07 am
by coco2
I'm also having trouble with screen capturing while using Ogre. On the SaveSprite command it fails with [ERROR] The specified #Sprite is not initialised.

Code: Select all

Procedure SaveScreen(*P.Game_Parametres_Type)
  Protected s.i
  s = GrabSprite(#PB_Any, 0, 0, ScreenWidth(), ScreenHeight())
  SaveSprite(s, "test.png", #PB_ImagePlugin_PNG)
  FreeSprite(s)
EndProcedure
I will submit a bug report if others agree with this.

Re: [5.31] OGRE Engine3D ScreenOutput to Image or Sprite cra

Posted: Fri Jan 06, 2017 8:33 pm
by PMV
If i remember right, GrabSprite() has never worked with InitEngine3D().
Use the solution above with rendertextures and you should get your screenshot. :)

MFG PMV

Re: [5.31] OGRE Engine3D ScreenOutput to Image or Sprite cra

Posted: Sat Jan 07, 2017 4:44 am
by coco2
Thanks but I have decided to abandon using the built in Ogre, I will look for an alternative 3D system.