canvas

BlitzMax Forums/BlitzMax Programming/canvas

Gavin Beard(Posted 2006) [#1]
hi, i have 2 differnt canvas objects on 2 diff. tabs of a maxgui app. i have a if statement to see which one tab is active and then draw 2 the relevent canvas, however i can swap to the second canvas ok but not back to the first, as soon as i do it gives me a memory violation error? is there a reason for this or prob something i've screwed up?


CS_TBL(Posted 2006) [#2]
sourcecode?


Gavin Beard(Posted 2006) [#3]
If actTab = 0 Then
    SetGraphics CanvasGraphics(canvas)
    DrawImage(tmpImg,0,0)
elseif actTab = 1 then
    SetGraphics CanvasGraphics(canvas2)
    DrawImage(tmpImg,0,0)		
EndIf
Flip

its the DrawImage(tmpImg,0,0) in the first part that throws the error


Qweeg(Posted 2006) [#4]
That's weird because I was just setting up something similar. I have a main canvas and another canvas on a small popup window, and altenate drawing depending on if the popup is open.

I tested it first using this as a test case and it seems to work fine, not sure if it will help though:

Global gWindow:TGadget
Global gCanvas1:TGadget
Global gCanvas2:TGadget

gWindow = CreateWindow("Dual Canvas Test",10,10,800,600)
gCanvas1 = CreateCanvas(20,20,200,150,gWindow)
gCanvas2 = CreateCanvas(20,220,200,150,gWindow)

ActivateGadget(gCanvas1)
SetGraphics CanvasGraphics(gCanvas1)
EnablePolledInput()
While KeyHit(KEY_ESCAPE) = False

	ActivateGadget(gCanvas1)
	SetGraphics CanvasGraphics(gCanvas1)

	DrawText("HELLO FROM CANVAS 1",10,10)
	Flip

	Delay 1000
	Cls
	Flip

	ActivateGadget(gCanvas2)
	SetGraphics CanvasGraphics(gCanvas2)

	DrawText("HELLO FROM CANVAS 2",10,10)
	Flip

	Delay 1000
	Cls
	Flip
	
Wend



Gavin Beard(Posted 2006) [#5]
hmmm.... ok i'll try again, where would be the best place to use flip? inside each if or after?


Qweeg(Posted 2006) [#6]
Well for me I flip for each canvas that is drawn to and that seems to work. The extra flips in the example after the delays are just to show the fields clearing out. but in your code I would have thought either would work


Gavin Beard(Posted 2006) [#7]
ok so i got my main loop
While True
	myApp.DrawGFX()
Wend 

myApp.drawgfx() is:
	Method drawGFX()
			'--------------------------------------------------------
		If (loginWindow <> Null) Or (actTab = 0) Then
			SetGraphics CanvasGraphics(canvas)
			DrawImage(tmpImg,0,0)
					
			Flip
		EndIf
		If flgvisi =1 Then
			SetGraphics CanvasGraphics(flagcanv)
			DrawImage(FlagImg,0,0)
			Flip
		EndIf

	End Method


but this just locks the program up? why should this happen?


Gavin Beard(Posted 2006) [#8]
*bump


Dreamora(Posted 2006) [#9]
Are both canvases globally defined or at least as fields?
Another thing might be that one canvas uses DX and the other OpenGL in which case I'm not sure if you would need a special setup when loading the image (ie setting the canvas they are used in before loading)


Gavin Beard(Posted 2006) [#10]
hmmm. both are global and both setup the same way....not sure what to try next


Dreamora(Posted 2006) [#11]
btw: are you sure that the program locks up? Isn't it possible that both IFs fail so that nothing is drawn at all? ...


Gavin Beard(Posted 2006) [#12]
well the rest of the window stops responding, buttons etc... so i presume locking,

it may just be my untidy coding i dont know, but as soon a si remove it it works ok


tonyg(Posted 2006) [#13]
Can't you post your full code or the smallest example that shows the problem?


Gavin Beard(Posted 2006) [#14]
hmmm...sure when i get home tonight i'll post something to show the problem :)


neilo(Posted 2006) [#15]
I'm having this exact problem. Create a canvas, SetGraphics() to it, and it works. Create another canvas, SetGraphics() to it, and all is well. Go back to the original canvas, SetGraphics() to it, and splat.

Some points:
1. Retrieving info from the canvas works ok; ie. GraphicsWidth() and GraphicsHeight() return the correct values.

2. Writing info to the canvas causes the splat.

This has got to be a bug within the MaxGUI runtime code. I'm working my way through the code right now, looking for the bug, but I'm quite unfamilier with the code, so it's taking some time.

I suspect that the core Gadget definition has a static variable in it somewhere, rather than a regular, stack-based variable, and when the context changes (or, in my case, I free the second canvas), the handle is getting a null or otherwise illegal value. BUT, I'm working my way through the code. Hopefully someone more familier with the code can have a look in this area.


tonyg(Posted 2006) [#16]
It would really help if somebody who has this problem posted some runnable source code.


assari(Posted 2006) [#17]
In my Making a MaxGUI Application: StripAnimMakerLite Tutorial, I use 3 canvases without any problem. You may want to check out how I did that as full source code is provided there.


Gavin Beard(Posted 2006) [#18]
*EDIT - removed


neilo(Posted 2006) [#19]
@tonyg:

Here's a minimum sample to show the problem:
Function DoSomething(canvas:TGadget)
	SetGraphics CanvasGraphics(canvas)
	Cls
	DrawText "Hello :)",10,10
End Function

Local win1:TGadget
Local win2:TGadget
Local can1:TGadget
Local can2:TGadget

win1=CreateWindow("Window 1",60,60,100,100,Null,WINDOW_TITLEBAR|WINDOW_CLIENTCOORDS)
win2=CreateWindow("Window 2",200,60,100,100,Null,WINDOW_TITLEBAR|WINDOW_CLIENTCOORDS)

can1=CreateCanvas(0,0,100,100,win1)
can2=CreateCanvas(0,0,100,100,win2)

DoSomething can1
DoSomething can2
FreeGadget can2
DoSomething can1

If you run the program, it goes splat in the final DoSomething can1.

@assari,
Your tutorial is good - however, from what I could see you keep the canvas' open at all times, whereas this problem seems to be related to closing a canvas.

Neil


Dreamora(Posted 2006) [#20]
You should do the SetGraphics before you free the gadget, otherwise it might lead to problems.


neilo(Posted 2006) [#21]
Ok, I've isolated the line of code that causes the crash. It's in BRL.D3D7Max2D:
Method Cls()
	device.Clear 1,vp_rect,D3DCLEAR_TARGET,clscolor,0,0
End Method


device is null.

I believe this comes about in the SetGraphics method
Method SetGraphics( g:TGraphics )
	If Not g
		D3D7GraphicsDriver().SetGraphics Null
		Return
	EndIf
		
	Local t:TMax2DGraphics=TMax2DGraphics( g )
	Local d3d7graphics:TD3D7Graphics=TD3D7Graphics( t._graphics )
	device=d3d7Graphics.GetDevice( Self )
	If Not device Return


The last line of the posted code is where the action is.

Digging deeper into d3d7graphics.bmx, I find this:
Method GetDevice:IDirect3DDevice7(user:Object)
	If (state&DX7LOST)=False And device
		painter=user
		Return device
	EndIf
End Method


Now, state was 0, device was valid. If I understand things correctly, we're doing a bitwise comparison on state using DX7LOST. Since state is zero, the comparison SHOULD be false (unless DX7LOST is zero, but I can't find it's definition). device is non-zero, so the code should execute.

@Dreamora, tried your suggestion; no change.

Any suggestions?

Neil


assari(Posted 2006) [#22]
skid had a post where he said this will be fixed in the next update. see post here
I get the same problem. Changing the driver to
SetGraphicsDriver GLMax2DDriver()
fixes the problem
so you are right its a DX problem


Kanati(Posted 2006) [#23]
looks like it's dropping the dx instance entirely when you close the canvas. Tried to find it in the source specifically but was unsuccessful.


neilo(Posted 2006) [#24]
@assari,

Perfect!

Thank you.

Neil


Dreamora(Posted 2006) [#25]
huh ... didn't think that the DX Device problem even interferes with canvases ... *putting in my knowledge list for later problem solving*

thanks for that assari