Unhandled Exception: CreateSurface failed.

BlitzMax Forums/BlitzMax Beginners Area/Unhandled Exception: CreateSurface failed.

sswift(Posted 2006) [#1]
I'm having a problem getting my app to work in both fullscreen and windowed mode. The code fails on the CreateGraphics line. I tried setting the Hertz to 0 at first, but that failed, so I tried 60 which I know should work and that also failed.

Any ideas?

'Global App:Application = Application.Create("Fruit Sliders", 800, 600)


Type Application

	Field Name$
	
	Field Width%
	Field Height%
	Field Depth%

	Field Window:TGadget
	Field Canvas:TGadget
	Field Panel:TGadget
	
	Field GRAPHICS_Window:TGraphics
	Field GRAPHICS_Fullscreen:TGraphics
	
	Field Windowed%


	' -------------------------------------------------------------------------------------------------------------------------------------------------------
	' This function creates the game window, and sets up the graphics objects for windowed and fullscreen modes. 
	' -------------------------------------------------------------------------------------------------------------------------------------------------------

		Function Create:Application(AppName$, AppWidth%, AppHeight%, AppDepth%=0, Fullscreen%=False)
	
			Local X%, Y%	
			Local App:Application
			
			' Create new application.
				App = New Application 				
									
			' Store application settings.
				App.Name$  = AppName$
				App.Width  = AppWidth
				App.Height = AppHeight	
				App.Depth  = AppDepth
				
			' If Depth is 0, try to find a suitable fullscreen bit depth.
			
				If App.Depth = 0
				
					App.Depth = 16
					If GraphicsModeExists(App.Width, App.Height, 24) Then App.Depth = 24
					If GraphicsModeExists(App.Width, App.Height, 32) Then App.Depth = 32
				
				EndIf		
														
			' Create a window in the center of the screen.
		
				X = GadgetWidth(Desktop())/2  - App.Width/2
				Y = GadgetHeight(Desktop())/2 - App.Height/2

				App.Window = CreateWindow(App.Name$, X, Y, App.Width, App.Height, Null, WINDOW_TITLEBAR|WINDOW_RESIZABLE|WINDOW_CLIENTCOORDS|WINDOW_HIDDEN)
				SetMinWindowSize(App.Window, App.Width, App.Height)
																
			' Create a canvas in the window to draw graphics to.
				App.Canvas = CreateCanvas(0, 0, App.Width, App.Height, App.Window)
								
			' Create a panel in the window, drawn behind the canvas, which fills the empty space around the gameplay area when the window is maximized.
				App.Panel = CreatePanel(0, 0, App.Width, App.Height, App.Window)
				SetPanelColor(App.Panel, 0, 0, 0)
				SetGadgetLayout(App.Panel, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED)
		
			' Create a fullscreen graphics object, and save canvas graphics object for later.
				App.GRAPHICS_Fullscreen = CreateGraphics(App.Width, App.Height, App.Depth, 60, GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER)
				App.GRAPHICS_Window     = CanvasGraphics(App.Canvas)  
		
			' Set game to windowed or fullscreen as desired.
				Select Fullscreen
					Case False App.SetWindowed()
					Case True  App.SetFullscreen()
				End Select
														
		End Function
		

	' -------------------------------------------------------------------------------------------------------------------------------------------------------
	' This method puts the application in windowed mode.
	' -------------------------------------------------------------------------------------------------------------------------------------------------------
		
		Method SetWindowed()
			SetGraphics GRAPHICS_Window
			ShowGadget Window
			Windowed = True
		End Method	


	' -------------------------------------------------------------------------------------------------------------------------------------------------------
	' This method sets the application to fullscreen mode, unless no fullscreen mode in the desired resolution exists.
	' -------------------------------------------------------------------------------------------------------------------------------------------------------

		Method SetFullscreen()
		
			If GRAPHICS_Fullscreen = Null 
				SetWindowed()
				Return
			Else
				HideGadget Window
				SetGraphics GRAPHICS_Fullscreen 
				Windowed = False
			EndIf
			
		End Method

				
End Type


It fails on this line in Create():
App.GRAPHICS_Fullscreen = CreateGraphics(App.Width, App.Height, App.Depth, 60, GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER)


sswift(Posted 2006) [#2]
Hm... works under OpenGL. I tried that after I read another post by someone having some problems with CreateGraphics which mentioned problems with DX.

But even if using OpenGL were an option, using this method resulted in two items being on the taskbar. The fullscreen app and the windowed app.

I'm gonna have to say that's a bug. Creating a graphics object should not make extra items on the taskbar.


Chris C(Posted 2006) [#3]
for me it fails on
Method SetWindowed()
SetGraphics GRAPHICS_Window

App.GRAPHICS_Fullscreen = CreateGraphics(

is probably destroying the window, (I dont think you can have two in existance at the same time...)


edit: at any rate it needs looking at there should be an integrated way to flip between fullscreen and a canvas, without some almighty kluge depending what driver you are using...


Dreamora(Posted 2006) [#4]
I've never been able to set hertz on my notebook at all without having it fail (60hz, 1280x800 Acer Aspire internal screen)


sswift(Posted 2006) [#5]
I rearranged stuff so as to avoid having two instanced of TGraphics in existence at once, but I'm still having trouble:

'Global App:Application = Application.Create("Fruit Sliders", 800, 600)


Type Application

	Field Name$
	
	Field Width%
	Field Height%
	Field Depth%

	Field Window:TGadget
	Field Canvas:TGadget
	Field Panel:TGadget
	
	Field TG:TGraphics
	
	Field Windowed%


	' -------------------------------------------------------------------------------------------------------------------------------------------------------
	' This function creates the game window, and sets up the graphics objects for windowed and fullscreen modes. 
	' -------------------------------------------------------------------------------------------------------------------------------------------------------

		Function Create:Application(AppName$, AppWidth%, AppHeight%, AppDepth%=0, Fullscreen%=False)
	
			Local X%, Y%	
			Local App:Application
			
			'SetGraphicsDriver GLMax2DDriver()
			
			' Create new application.
				App = New Application 				
									
			' Store application settings.
				App.Name$  = AppName$
				App.Width  = AppWidth
				App.Height = AppHeight	
				App.Depth  = AppDepth
				
			' If Depth is 0, try to find a suitable fullscreen bit depth.
			
				If App.Depth = 0
				
					App.Depth = 16
					If GraphicsModeExists(App.Width, App.Height, 24) Then App.Depth = 24
					If GraphicsModeExists(App.Width, App.Height, 32) Then App.Depth = 32
				
				EndIf		
					
			' Create a window in the center of the screen.
		
				X = GadgetWidth(Desktop())/2  - App.Width/2
				Y = GadgetHeight(Desktop())/2 - App.Height/2

				App.Window = CreateWindow(App.Name$, X, Y, App.Width, App.Height, Null, WINDOW_TITLEBAR|WINDOW_RESIZABLE|WINDOW_CLIENTCOORDS|WINDOW_HIDDEN)
				SetMinWindowSize(App.Window, App.Width, App.Height)
																
			' Create a canvas in the window to draw graphics to.
				App.Canvas = CreateCanvas(0, 0, App.Width, App.Height, App.Window)
								
			' Create a panel in the window, drawn behind the canvas, which fills the empty space around the gameplay area when the window is maximized.
				App.Panel = CreatePanel(0, 0, App.Width, App.Height, App.Window)
				SetPanelColor(App.Panel, 0, 0, 0)
				SetGadgetLayout(App.Panel, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED)
		
			' Set game to windowed or fullscreen as desired.
				Select Fullscreen
					Case False App.SetWindowed()
					Case True  App.SetFullscreen()
				End Select
			
			' Return new application instance.
				Return App
												
		End Function
		

	' -------------------------------------------------------------------------------------------------------------------------------------------------------
	' This method toggles between fullscreen or windowed mode, choosing the opposite of whichever is currently enabled.
	' -------------------------------------------------------------------------------------------------------------------------------------------------------
	
		Method ToggleFullscreen()
			Select Windowed
				Case False SetWindowed()
				Case True  SetFullscreen()
			End Select
		End Method

	' -------------------------------------------------------------------------------------------------------------------------------------------------------
	' This method puts the application in windowed mode.
	' -------------------------------------------------------------------------------------------------------------------------------------------------------
		
		Method SetWindowed()
		
			' Set drawing operations to go to canvas.
				EndGraphics
				'If TG <> Null Then CloseGraphics(TG)
				DebugStop
				TG = CanvasGraphics(Canvas) 
				SetGraphics TG
				
				Windowed = True
				
			' Show window.
				ShowGadget Window
				
			' Canvas must be activated for input or else game will make user click on canvas before any polled keyboard input is returned.
				EnablePolledInput()			
													
		End Method	


	' -------------------------------------------------------------------------------------------------------------------------------------------------------
	' This method sets the application to fullscreen mode, unless no fullscreen mode in the desired resolution exists.
	' -------------------------------------------------------------------------------------------------------------------------------------------------------

		Method SetFullscreen()
			
			' Set drawing operations to fullscreen.
				EndGraphics
				'If TG <> Null Then CloseGraphics(TG)
				TG = Graphics(Width, Height, Depth)
			
			' If the operation fails, put us back in windowed mode.  Otherwise, hide the window, and record that fullscreen is enabled.
			
				If TG = Null 
					SetWindowed()
					Return
				Else
					HideGadget Window
					Windowed = False
					EnablePolledInput()
				EndIf
			
		End Method

				
End Type	


This works in OpenGL, (Not exactly lighting fast on the switch.) and in DirectX it will switch from windowed to fullscreen mode, (Much faster and nicer switch) but it won't switch back from fullscreen to windowed in DirectX mode. It fails right after the DebugStop on the "SetGraphics TG" line, with an error about trying to access a null object. I thought the Null object was TG, but that is fine. The Canvas too, still exists. So something internal to BlitzMax itself is going wrong I think.

Even weirder... When the debugger stops, check out Canvas. It has a field _graphics:TGraphics, and it is set to something, even though I've ended the graphics modes. And I tried two different ways to end the graphics mode and both failed.

Hm... Actually come to think of it, after I end the grpahics mode, I didn't set TG to Null. Maybe saving the graphics object pointer causes an issue? I don't think it is supposed to though... I think freeing it should be enough and I am not allowed to use it after that, but keeping it around hsould be fine. Oh well guess I'll test it to be sure.

[edit]
Nope, that did bupkiss.
[/edit]


sswift(Posted 2006) [#6]
Ugh, I got it to switch back and forth finally but now I can't seem to read events from the mouse, and polled input seems broken as well. Perhaps the mouse position is being reported wrong, but it doesn't seem to dtect clicks at all either.


Type Application

	Field Name$
	
	Field Width%
	Field Height%
	Field Depth%

	Field Window:TGadget
	Field Canvas:TGadget
	Field Panel:TGadget
	
	Field TG:TGraphics
	
	Field Windowed%


	' -------------------------------------------------------------------------------------------------------------------------------------------------------
	' This function creates the game window, and sets up the graphics objects for windowed and fullscreen modes. 
	' -------------------------------------------------------------------------------------------------------------------------------------------------------

		Function Create:Application(AppName$, AppWidth%, AppHeight%, AppDepth%=0, Fullscreen%=False)
	
			Local X%, Y%	
			Local App:Application
			
			'SetGraphicsDriver GLMax2DDriver()
			
			' Create new application.
				App = New Application 				
									
			' Store application settings.
				App.Name$  = AppName$
				App.Width  = AppWidth
				App.Height = AppHeight	
				App.Depth  = AppDepth
				
			' If Depth is 0, try to find a suitable fullscreen bit depth.
			
				If App.Depth = 0
				
					App.Depth = 16
					If GraphicsModeExists(App.Width, App.Height, 24) Then App.Depth = 24
					If GraphicsModeExists(App.Width, App.Height, 32) Then App.Depth = 32
				
				EndIf		
					
			' Create a window in the center of the screen.
		
				X = GadgetWidth(Desktop())/2  - App.Width/2
				Y = GadgetHeight(Desktop())/2 - App.Height/2

				App.Window = CreateWindow(App.Name$, X, Y, App.Width, App.Height, Null, WINDOW_TITLEBAR|WINDOW_RESIZABLE|WINDOW_CLIENTCOORDS|WINDOW_HIDDEN)
				SetMinWindowSize(App.Window, GadgetWidth(App.Window), GadgetHeight(App.Window))
								
			' Create a panel in the window, drawn behind the canvas, which fills the empty space around the gameplay area when the window is maximized.
				App.Panel = CreatePanel(0, 0, App.Width, App.Height, App.Window)
				SetPanelColor(App.Panel, 0, 0, 0)
				SetGadgetLayout(App.Panel, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED)
		
			' Set game to windowed or fullscreen as desired.
				Select Fullscreen
					Case False App.SetWindowed()
					Case True  App.SetFullscreen()
				End Select
			
			' Return new application instance.
				Return App
												
		End Function
		

	' -------------------------------------------------------------------------------------------------------------------------------------------------------
	' This method toggles between fullscreen or windowed mode, choosing the opposite of whichever is currently enabled.
	' -------------------------------------------------------------------------------------------------------------------------------------------------------
	
		Method ToggleFullscreen()
			Select Windowed
				Case False SetWindowed()
				Case True  SetFullscreen()
			End Select
		End Method

	' -------------------------------------------------------------------------------------------------------------------------------------------------------
	' This method puts the application in windowed mode.
	' -------------------------------------------------------------------------------------------------------------------------------------------------------
		
		Method SetWindowed()
		
			' Set drawing operations to go to canvas.
			
				If TG <> Null Then CloseGraphics(TG)
				If Canvas <> Null Then FreeGadget(Canvas)
				
				Canvas = CreateCanvas(ClientWidth(Window)/2-Width/2, ClientHeight(Window)/2-Height/2, Width, Height, Window)
				
				TG = CanvasGraphics(Canvas) 
				SetGraphics TG
				
				Windowed = True
				
				ShowGadget Window
				
			'	EnableGadget Canvas
				
			'	ActivateWindow Window
			'	ActivateGadget Canvas
				
			' Canvas must be activated for input or else game will make user click on canvas before any polled keyboard input is returned.
				EnablePolledInput()			
													
		End Method	


	' -------------------------------------------------------------------------------------------------------------------------------------------------------
	' This method sets the application to fullscreen mode, unless no fullscreen mode in the desired resolution exists.
	' -------------------------------------------------------------------------------------------------------------------------------------------------------

		Method SetFullscreen()
			
			' Set drawing operations to fullscreen.
			
				If TG <> Null Then CloseGraphics(TG)
				If Canvas <> Null Then FreeGadget(Canvas)
			
				TG = Graphics(Width, Height, Depth)
			
				Windowed = False
			
			' If the operation fails, put us back in windowed mode.  Otherwise, hide the window, and record that fullscreen is enabled.
			
				If TG = Null 
					SetWindowed()
					Return
				Else
					HideGadget Window
				EndIf
			
		End Method

				
End Type						



[/code]
' -----------------------------------------------------------------------------------------------------------------------------------------------------------
' This function checks for events in the event queue and acts upon them.
' -----------------------------------------------------------------------------------------------------------------------------------------------------------

Function EventHandler()

MouseHit_Left = False
MouseHit_Right = False
MouseHit_Middle = False

While PollEvent() <> 0

DebugLog("EventID: " + EventID())

Select EventID()

Case EVENT_APPSUSPEND ' Application suspended.
Case EVENT_APPRESUME ' Application resumed.
Case EVENT_APPTERMINATE ' Application wants to terminate.
Case EVENT_KEYDOWN ' Key pressed. Event data contains keycode.
Case EVENT_KEYUP ' Key released. Event data contains keycode.
Case EVENT_KEYCHAR ' Key character. Event data contains unicode value.

Case EVENT_MOUSEDOWN ' Mouse button pressed. Event data contains mouse button code.

Select EventData()

Case 1
MouseDown_Left = True
MouseHit_Left = True

Case 2
MouseDown_Right = True
MouseHit_Right = True

Case 3
MouseDown_Middle = True
MouseHit_Right = True

End Select


Case EVENT_MOUSEUP ' Mouse button released. Event data contains mouse button code.

Select EventData()
Case 1 MouseDown_Left = False
Case 2 MouseDown_Right = False
Case 3 MouseDown_Middle = False
End Select


Case EVENT_MOUSEMOVE ' Mouse moved. Event x and y contain mouse coordinates.

Mouse_X = EventX()
Mouse_Y = EventY()


Case EVENT_MOUSEWHEEL ' Mouse wheel spun. Event data contains delta clicks.
Case EVENT_MOUSEENTER ' Mouse entered gadget area.
Case EVENT_MOUSELEAVE ' Mouse left gadget area.
Case EVENT_TIMERTICK ' Timer ticked. Event source contains timer object.
Case EVENT_HOTKEYHIT ' Hot key hit. Event data and mods contains hotkey keycode and modifier.
Case EVENT_MENUACTION ' Menu has been selected.
Case EVENT_WINDOWMOVE ' Window has been moved.
Case EVENT_WINDOWSIZE ' Window has been resized.

Case EVENT_WINDOWCLOSE ' Window close icon clicked.
End

Case EVENT_WINDOWACTIVATE ' Window activated.
Case EVENT_WINDOWACCEPT ' Drag and drop operation was attempted.
Case EVENT_GADGETACTION ' Gadget state has been updated.
Case EVENT_GADGETPAINT ' A canvas gadget needs to be redrawn.
Case EVENT_GADGETSELECT ' A treeview node has been selected.
Case EVENT_GADGETMENU ' User has right clicked a treeview node or textarea gadget.
Case EVENT_GADGETOPEN ' A treeview node has been expanded.
Case EVENT_GADGETCLOSE ' A treeview node has been collapsed.
Case EVENT_GADGETDONE ' An HTMLview has completed loading a page.

End Select

Wend

End Function
[/code]


	Global MouseDown_Left%, MouseDown_Right%, MouseDown_Middle%
	Global MouseHit_Left%, MouseHit_Right%, MouseHit_Middle%
	Global Mouse_X%, Mouse_Y%
	
' -----------------------------------------------------------------------------------------------------------------------------------------------------------
' -----------------------------------------------------------------------------------------------------------------------------------------------------------

	Function GetInput()								

		Local MouseOver:Fruit
		Local ThisLink:TLink, NextLink:TLink
		Local ThisFruit:Fruit, NextFruit:Fruit

		If App.Windowed Then ActivateGadget App.Canvas
	
		' Process all events in the queue.
			EventHandler()
				
		' Get mouse input when not in windowed mode.
		
			'If Not App.Windowed 
			
				Mouse_X = MouseX()
				Mouse_Y = MouseY()

				MouseDown_Left   = MouseDown(1)
				MouseDown_Right  = MouseDown(2)
				MouseDown_Middle = MouseDown(3)	
				
				MouseHit_Left    = MouseHit(1)
				MouseHit_Right   = MouseHit(2)
				MouseHit_Middle  = MouseHit(3)
								
			'EndIf
														
		
		' Allow user to switch to fullscreen mode and back.
			If KeyHit(KEY_F) Then App.ToggleFullscreen()



Any ideas?


sswift(Posted 2006) [#7]
Surely SOMEONE here know how to get windowed modes accepting user input!


sswift(Posted 2006) [#8]
I had someone else test the code today and with DirectX it just crashed for them when trying to go fullscreen. They have the latest version though. So I guess I'll have to upgrade to the latest and see if it crashes for me now as well. :-(


Chris C(Posted 2006) [#9]
if you use [codebox] its easier for people to read all of your post...

have you not considered using a borderless window the same size as the screen?


sswift(Posted 2006) [#10]
A borderless window the size of the screen would require more pixels to be rendered which would be slower, and it would need to stretch the image if I wanted to maintain a certain aspect ratio which would mean pixels would get filtered. Not an option.