Graphics contexts

BlitzMax Forums/BlitzMax Programming/Graphics contexts

_JIM(Posted 2009) [#1]
I think this is what's my problem about.

I'm working on a level editor. I have a setup like an "editing" canvas, and a "preview" canvas.

I also have one other canvas that I use for displaying the whole level.

Now, my problem is that I want to have the same images all over the place. Basically, I will have to draw them in different canvases in certain cases.

I know graphics contexts are not thread-safe. Now I know that most probably they're not "switching graphics"-safe either. When I start the program, it usually works the way it should, but somethimes, some images come out as white rectangles.

For a quick test, I tried to do something like:

SetGraphics CanvasGraphics(MyOtherCanvas)
Local TempImg:TImage = LoadImage(MyOriginal_notsafe_image.pixmaps[0])

DrawImage TempImg,0,0


The image gets drawn once, which is good, but then my application freezes. I suppose it's a bad idea to use the same pixmap for 2 images from 2 different "Graphics".

Is there a "clean" way to do this? I'd hate to have copies of all my graphics for each canvas.


Brucey(Posted 2009) [#2]
I white rectangle sometimes implies that there's not enough VRAM to display your textures.

It also sometimes means there's an driver issue.

And of course, it could simply be a problem with BlitzMax and multiple contexts.


_JIM(Posted 2009) [#3]
Thanks for the fast answer!

Limited VRAM is NOT the problem.. I barely got 3 images in the editor, and my video card has 1GB for each GPU.

Driver issues... I would cross this one out as well since the problem appeared when I moved on from 1 canvas to 3. Until then, I've never had any problems with any other BlitzMAX app.

This would leave no. 3, but I already assumed that and I'm looking for a way to fix this preferably without any hacks.

EDIT:

Well, I made a little progress. The app no longer freezes (apparently BMax doesn't like it when I'm using "LoadImage" from a pixmap every frame)

However, as soon as I use LoadImage with the original images pixmap, the original image grabs another (apparently random) pixmap from the application and uses it. So its like one pixmap exclusively belongs to 1 image. This would kind of explain the freeze problem. If loading an image from another one's pixmap changes the original, then a loop would infinitely cicle through all the pixmaps in the app.

EDIT #2:

Too tired... I was reloading the same image from its own old pixmaps (a bit weird) and it was causing those strange issues. I fixed it by using another copy of the image. Not very nice, but its a fix.

Anyone got any idea if this could be fixed without another copy?


xlsior(Posted 2009) [#4]
...Why on earth would you be using a loadimage from a single pixmap every frame? I think you'll be running into serious throughput issues on many computers that way.

If nothing else: if you truly are changing your pixmap every single frame (and if not, you really should be more selective choosing when to reload it) then you may want to consider simply using DrawPixmap instead of explicitely converting it to an image every single frame.


_JIM(Posted 2009) [#5]
xlsior, you got it wrong. That was just a quick test to see if reuploading the image to the video card from a different "CanvasGraphics" by using LoadImage on a pixmap would fix the "white rectangle" issue.

And it did fix it, but it caused more trouble. Guess I should stop coding when I'm extra-tired AND extra-lazy. :-)


_JIM(Posted 2009) [#6]
I seem to have hit yet another problem, and I fear it's related to multiple canvases.

At home, my editor works just fine.
At work, everything works fine until I decide to draw on 3 canvases at the same time.

That's when the app freezes. No error, no exception, just freezes. It might be a hidden infinite loop, not sure.

The awkward thing is that it works on one PC and not on the other. I'm using the same BMax version (1.33rc5) and the same MaxGUI version (1.32).

The only noticeable differences between the PCs are the OS (W7 works, XP doesn't) and video card manufacturer (ATi works, nVidia doesn't)

I'll work a bit on solving the issue when I get the time.

I'd be interested however to know if BMax was intended to be used with just one canvas (or one "Graphics"). If so, then how would you have 2 windows rendering at the same time?


_JIM(Posted 2009) [#7]
I still haven't managed to solve this last problem. Anyone got any ideas?


jsp(Posted 2009) [#8]
Don't know if you use a Max2D OpenGL based context, but if - did you try to put GLShareContexts before defining the Graphics context in your code?


_JIM(Posted 2009) [#9]
I'm using GLMax2DDriver and GLShareContexts doesn't seem to help, but it should be there anyway :)


Tommo(Posted 2009) [#10]
GLShareContexts should help here.
Here's the test code.

Import maxgui.drivers

Local Window:TGadget = CreateWindow("test", 0, 0, 600, 300,, WINDOW_TITLEBAR)

Local c1:TGadget = CreateCanvas(0, 0, 290, 300, Window)
Local c2:TGadget = CreateCanvas(300, 0, 290, 300, Window)

SetGraphicsDriver(GLMax2DDriver())
GLShareContexts()

Local img:TImage = LoadImage("image.png") 'Your image


While True
	WaitEvent()
	Select EventID()
		Case EVENT_GADGETPAINT
			SetGraphics(CanvasGraphics(c1))
			Cls
			DrawImage(img, 0, 0)
			DrawText("CONTEXT 1", 0, 0)
			Flip
			
			SetGraphics(CanvasGraphics(c2))
			Cls
			DrawImage(img, 0, 0)
			DrawText("CONTEXT 2", 0, 0)
			Flip
			
		Case EVENT_WINDOWCLOSE
			Exit
	End Select
Wend



_JIM(Posted 2009) [#11]
Well, I managed to find the problem.

GLShareContexts() helped me with my first problem. Thank you very much for the info :)

However, my second problem (freezing application) was not solved by this and I did find the problem.

Apparently the application tries to run faster than it actually is (weird).

I have a main canvas that I use to display the level. This gets updated at 60 fps by a timer. It is then draw by checking event type and source to make sure it's this timer.

Then I have another timer for each of the other canvases. The problem is if I set those other timers to something more than 25 ticks per second, the ticks are faster than the application can process. Therefore, it's stuck in a loop picking up tick events and drawing to the canvases.

It's really weird because at home I tried 4 timers with 75 ticks per second each... no problem. Here at work, I have to use 40 for main canvas and 25 for the others.

It might be something else in my code, but the editor actually runs very fast. I can hardly slow it down to lower than 40 fps for the main canvas. However, when I draw to 3 canvases at once, it slows down a lot.