[GLMax2D] White Texture bug ... honing in?

Community Forums/Bug Reports/[GLMax2D] White Texture bug ... honing in?

_Skully(Posted 2010) [#1]
This is code using my framework:

SuperStrict
Import skully.TileMax
SetGraphicsDriver GLMax2DDriver()
TMStart()
'--------------------------------------------------------------------------
' Load Game Sprites
'--------------------------------------------------------------------------
Incbin "media/graphics/fplanes2.png"
Global spaceship:TImage=LoadImage("Incbin::media/graphics/fplanes2.png",DYNAMICIMAGE|MASKEDIMAGE )
TMSetImageMask(spaceship,121,173,183)

'--------------------------------------------------------------------------
' Set up Players
'--------------------------------------------------------------------------
Const ID_Actor:Int=0
Const ID_Player:Int=1

Global player:TMSprite=createplayer()
player.BindKey(KEY_LEFT,0,0,P_Angle,-1,KeyState_Held)
player.BindKey(KEY_RIGHT,1,0,P_Angle,1,KeyState_Held)
player.BindKey(KEY_UP,2,0,P_Velocity,0.01,KeyState_Held)
player.BindKey(KEY_DOWN,3,0,P_Velocity,-0.01,KeyState_Held)
'--------------------------------------------------------------------------
' Start Game Loop
'--------------------------------------------------------------------------
Global showtext:Int=False
While Not KeyDown(KEY_ESCAPE)
	TMUpdateTiming()
	TMUpdateIteration()
	TMSprite.UpdateAll()
	TMSprite.DrawAll(400,300)
	If KeyHit(KEY_T) showtext=1-showtext
	If showtext DrawText "Hello",0,0
	If KeyHit(KEY_P) TMSaveScreen()
	Flip
	Cls
Wend
'--------------------------------------------------------------------------
EndGraphics
End

Function CreatePlayer:TMSprite()
	Local player:TMSprite=TMCreateSprite(ID_Player,0,0,spaceship)
		player.MaxVelocity=5
		player.JumpSpeed=4
		player.pa.Anim.rot=270
		player.pa.SetScale(0.2,0.2)
		player.pa.SetAngleAligned()
		player.pa.SetFriction(0.999)
		player.Activate()
	Return player
End Function


Drawtext commented


Drawtext uncommented


Compiled Version (Zipped)
LT/RT Arrows turn, Up Arrow accelerates, down arrow decelerates.
Press T to turn drawtext on and off.. let me know if you see the same thing.

Pressing P saves the screen.


_Skully(Posted 2010) [#2]
Oh... it works fine with the DX driver... no white texture.

Anyone else getting the white texture after pressing T?


jkrankie(Posted 2010) [#3]
I've come across this behavior before using Indiepaths Render to texture module. To be honest i thought it was probably that modules fault, but seeing as these are the exact same symptoms (having to use drawtext to get GL to render correctly) then perhaps it wasn't.

What exactly are you doing to the images? you haven't included running source code.

Cheers
Charlie


_Skully(Posted 2010) [#4]
In the case of the sprites, they are Sprite Types with Particles for visual representation. The particles also have anims attached which actually control display...

essentially, the only thing I do with the image itself is this bit:

		TMPushDraw()
		TMSetDraw(rsx,rsy,rr,blend,alpha)
		DrawSubImageRect (Self.image,x+ox,y+oy,sizeX,sizeY,frameX[frame],frameY[frame],sizeX,sizeY)
	'	DebugLog "Image w,h:"+Self.image.width+","+Self.image.Height+" DrawSubImageRect(x:"+(x+ox)+" y:"+(y+oy)+" w:"+sizeX+" h:"+sizeY+" sx:"+frameX[frame]+" sy:"+frameY[frame]+" sw:"+sizeX+" sh:"+sizeY+")"
		TMPopDraw()


As you can see I have monitored the values here too


therevills(Posted 2010) [#5]
Just tested on my rig, as soon as I press T the sprite goes white... also I did notice before I pressed T when I rotated the sprite you could see this:



Didnt you have an issue with the letter P not displaying correctly?


_Skully(Posted 2010) [#6]
I noticed the burr on the side of the image and have removed it from the one I have.. but I have an interesting development...

I expanded the code a bit to create comets.. I'll compile it... but the point is that if I create a comet first, its the comet texture that gets wrecked.

SuperStrict
Import skully.TileMax
SetGraphicsDriver GLMax2DDriver()
TMStart()
'--------------------------------------------------------------------------
' Load Game Sprites
'--------------------------------------------------------------------------
Incbin "media/graphics/fplanes2.png"
Incbin "media/graphics/comet.bmp"
Global comet:TImage=LoadImage("Incbin::media/graphics/comet.bmp",DYNAMICIMAGE|MASKEDIMAGE )
Global spaceship:TImage=LoadImage("Incbin::media/graphics/fplanes2.png",DYNAMICIMAGE|MASKEDIMAGE )
TMSetImageMask(spaceship,121,173,183)
'--------------------------------------------------------------------------
' Set up Players
'--------------------------------------------------------------------------
Const ID_Actor:Int=0
Const ID_Player:Int=1
Const ID_Comet:Int=2

CreateComet(Rnd(-1800,1800),Rnd(-1400,1400))
Global player:TMSprite=CreatePlayer()
player.BindKey(KEY_LEFT,0,0,P_Angle,-2,KeyState_Held)
player.BindKey(KEY_RIGHT,1,0,P_Angle,2,KeyState_Held)
player.BindKey(KEY_UP,2,0,P_Velocity,0.1,KeyState_Held)
player.BindKey(KEY_DOWN,3,0,P_Velocity,-0.1,KeyState_Held)
'--------------------------------------------------------------------------
' Start Game Loop
'--------------------------------------------------------------------------
Global showtext:Int=False
Global focusx:Float=player.y
Global focusy:Float=player.x
While Not KeyDown(KEY_ESCAPE)
	If KeyDown(KEY_C) Then CreateComet(Rnd(-1800,1800),Rnd(-1400,1400))
	focusx:+((player.x-focusx)/12.0)
	focusy:+((player.y-focusy)/12.0)
	TMUpdateTiming()
	TMUpdateIteration()
	TMSprite.UpdateAll()
	TMSprite.DrawAll(-focusx+400,-focusy+300)
	If KeyHit(KEY_T) showtext=1-showtext
	If showtext Then DrawText "Hello",0,0
	If KeyHit(KEY_P) TMSaveScreen()
	Flip
	Cls
Wend
'--------------------------------------------------------------------------
EndGraphics
End

Function CreatePlayer:TMSprite()
	Local player:TMSprite=TMCreateSprite(ID_Player,0,0,spaceship)
		player.MaxVelocity=5
		player.JumpSpeed=4
		player.pa.Anim.rot=270
		player.pa.SetScale(0.2,0.2)
		player.pa.SetAngleAligned()
		player.pa.SetFriction(0.999)
		player.Activate()
	Return player
End Function

Function CreateComet:TMSprite(x:Float,y:Float)
	Local icomet:TMSprite=TMCreateSprite(ID_Comet,x,y)
	Local an:TMAnim=TMAnim.CreateAnim("comet",comet,27,31,1)
	an.AddFrames(0,0,5,0)
	an.AutoSetMidHandle()
	icomet.AddAnim(an)
	icomet.pa.P[P_AnimFrame ]=Rnd(0,5)
	icomet.SetVelocity(-Cos(ATan2(y,x)),-Sin(ATan2(y,x)))
	icomet.pa.P[P_RotVelocity]=1
	icomet.Activate()
End Function


OpenGL


DirectX


Download and run... here

press C to add more comets


_Skully(Posted 2010) [#7]
Added a little map and some starting comets:


If you want to see what this should look like download this one, its DirectX


_Skully(Posted 2010) [#8]
this bug ALWAYS effects the very first texture displayed. I can change what turns white by initially displaying something different... if i show sprites first and a comet is the first thing drawn, then all comets are white. If the player is drawn first (created first) then it turns white. If I display a tile system in the background first it's texture goes white... ugh


therevills(Posted 2010) [#9]
Hey Skully, try my code:



Its just simple BlitzMax code, press T to display text and Q to switch render mode of the sprite. (I was getting carried away with the stars etc)

Code, Image and Exe:
https://sites.google.com/site/therevillsgames/blitz/spaceShip_pureBlitz.zip

Does it work fine for you?




jkrankie(Posted 2010) [#10]
Does DrawSubImageRect use a viewport/viewports to get the data to display?

Cheers
Charlie


Oddball(Posted 2010) [#11]
I've experienced exactly this before. I found the issue was the amount of RAM being used by the app. It happened with the same app on both windows and mac. Once I reduced the size of the IncBin'ed files the problem went away. After extensive testing I could get it to a point where the white rectangles would appear when in debug mode, but not in release mode because the debug exe/app was slightly larger. It's a really strange one.


_Skully(Posted 2010) [#12]
therevilles,
No problems with your code.. nice banking spaceship by the way :) I'm going to modify it so it uses drawsubimagerect exclusively and see what happens.
{edit} no difference so I'll add a second image (since there has to be two for this to occur)


Does DrawSubImageRect use a viewport/viewports to get the data to display?


I've followed the DrawSubImageRect through the Max2D module right to the GLMAX2D driver (including adding debuglog statements) and I can't see whats causing the issue... no weirdness with it with the exception that in drawimagerect x0 and y0 were displaying as -0.0000000... so I added a max (num,0) wrapper on the x0,x1 initializations which did remove the -0.000000 but didn't change the results (white texture still) so I figured the -0.000000 is a blitz floating point anomaly.

DrawSubImageRect:
Function DrawSubImageRect( image:TImage,x#,y#,w#,h#,sx#,sy#,sw#,sh#,hx#=0,hy#=0,frame=0 )
	Local x0#=-hx*w/sw,x1#=x0+w
	Local y0#=-hy*h/sh,y1#=y0+h
	Local iframe:TImageFrame=image.Frame(frame)
	If iframe iframe.Draw(x0,y0,x1,y1,x+gc.origin_x,y+gc.origin_y,sx,sy,sw,sh)
'	If iframe DebugLog "iframe.Draw (x,y,x1,y1,tx,ty,sx,sy,sw,sh) "+x0+","+y0+","+x1+","+y1+","+(x+gc.origin_x)+","+(y+gc.origin_y)+","+sx+","+sy+","+sw+","+sh+")"
End Function


and the glmax2d driver frame draw... I had a debuglog statement for each gl statement and no negatives or texture breaching numbers there either:
	Method Draw( x0#,y0#,x1#,y1#,tx#,ty#,sx#,sy#,sw#,sh# )
		Assert seq=GraphicsSeq Else "Image does not exist"

		Local u0#=sx * uscale
		Local v0#=sy * vscale
		Local u1#=(sx+sw) * uscale
		Local v1#=(sy+sh) * vscale
		
		EnableTex name
		glBegin GL_QUADS
		glTexCoord2f u0,v0
		glVertex2f x0*ix+y0*iy+tx,x0*jx+y0*jy+ty
		glTexCoord2f u1,v0
		glVertex2f x1*ix+y0*iy+tx,x1*jx+y0*jy+ty
		glTexCoord2f u1,v1
		glVertex2f x1*ix+y1*iy+tx,x1*jx+y1*jy+ty
		glTexCoord2f u0,v1
		glVertex2f x0*ix+y1*iy+tx,x0*jx+y1*jy+ty
		glEnd
	End Method


Oddball,
Agreed..its a weird one. two images I'm using are really small so I'm not sure how memory consumption would be the problem... its also ONLY openGL which is what makes it even weirder


_Skully(Posted 2010) [#13]
I found out what was causing the issue! So excited!

I DON'T know why but this code removed from the tilemax graphics initialization removes the white texture bug...


			Local ti:TImage=LoadImage("incbin::splash.png",DYNAMICIMAGE|MASKEDIMAGE)
			MidHandleImage ti
			
			Local TMS:TMSequencer=TMSequencer.CreateSequencer(1,0,1.5)
			Local tms2:TMSequencer=TMCreateSequencer(ti.width/2,ti.width,1.5)
			SetBlend ALPHABLEND
			While TMS.Position<1
				TMUpdateTiming()
				SetAlpha TMS.GetValue()
				SetScale 0.4,0.4
				DrawImage ti,tms2.GetValue(),height-(ti.height*0.4/2)
				Flip
				Cls
			Wend
			SetAlpha 1
			SetScale 1,1

This was the TileMax logo that flew across the bottom of the screen!


jkrankie(Posted 2010) [#14]
What about if you changed the flags on loading the image?

Cheers
Charlie


_Skully(Posted 2010) [#15]
Just tried DYNAMICIMAGE|MASKEDIMAGE, MASKEDIMAGE, and none... all the same.


Oddball(Posted 2010) [#16]
How about if you don't IncBin splash.png?


_Skully(Posted 2010) [#17]
No change... incbin'd or not the white texture bug comes back so I don't know what would be causing that...

I'll just leave the code out. Its not necessary


Dabhand(Posted 2010) [#18]
Scary thing is that this bug is still there, buried somewhere, and it'll obviously poke its ugly head again.

Shame it couldnt be nailed directly, but well done for fixing your issue, since it's had you tearing your head out for the last few week! ;)

Dabz


therevills(Posted 2010) [#19]
nice banking spaceship by the way :)

Good old Xenon 2000 ship there :P



Have you hacked that piece of code which you have found which causes your issue?

For example, try removing your TMUpdateTiming() call... then the scale commands etc.

Have you compiled on different PCs to see if you get the same issue?


_Skully(Posted 2010) [#20]
I've done all I can to that code.. commenting this and that.. the only thing that works is to comment out anything to do with the image...

It shows up no matter what PC... I even compiled on two separate PC's to check that it wasn't my laptop OpenGL intallation... all the same

I'm going to package up the code an zip it just in case Mark wants to take a look... I've followed it as far as I can really and I don't want to stall development any further than it has already.

For now, all I know is that I'm back up and running an coding/commenting like crazy again :)... waiting for the wife to tell me to "get off that damn computer" again ;)


Tachyon(Posted 2010) [#21]
I am getting reports from some people seeing white squares in my game, exclusively on the newer Macintoshes.

I just made a post on this here:

http://www.blitzbasic.com/Community/posts.php?topic=91759


Jur(Posted 2010) [#22]
I have the same situation in OpenGL. I am working on a project and I am adding new images. In rare occasion (for now, hopefully) I will get an image which will be drawn constantly as a white rectangle. It doesnt matter if I change the size of that image, build in debug or release mode, the problem persists.

I did found out that problem is related to the drawing order. I have a flag in my loading routine, which allows to draw image to some offscreen location after loading (to get the image into vram). If I skip this "pre-drawing" then the problem goes away.

It looks to me that in specific situations the image can get corrupted when loaded into vram.


AntonM(Posted 2011) [#23]
I have this problem too.

Here is my code:
SuperStrict
SetGraphicsDriver GLMax2DDriver()
Graphics 800,600


'DrawImage LoadImage("1.png"),0,0
Loading()


For Local i:Int=0 To 100
	Local img:TImage = LoadImage("1.png")
Next


Global image1:TImage = LoadImage("1.png") 
Global image2:TImage = LoadImage("2.png") 


DrawImage image2,0,0 'draw normal
'Flip;WaitMouse
DrawImage image1,0,0
'Flip;WaitMouse
DrawImage image2,0,0 'draw white rect
	
Flip
WaitMouse
End
	
Function Loading()
	Local i:TImage = LoadImage("1.png")
	DrawImage i,0,0
EndFunction

Maybe somebody knows how to solve this problem?


Brucey(Posted 2011) [#24]
The most obvious conclusion is that the texture reference is being freed up by OpenGL for whatever reason (which is what I've always said).


shinkiro1(Posted 2011) [#25]
Try putting
GLShareContexts()

before setting your graphics driver.

I had the same problem in a maxgui-app with multiple canvases. Maybe it will fix this one too.

Edit: o_O Brucey is back

Last edited 2011


therevills(Posted 2011) [#26]
Just tried AntonM code... and yes the white texture bug displays!!!

Messing with the code I found:

* If you dont call Loading() its fine
* If you do the Loading() code outside the function its fine
* GLShareContexts didnt fix it
* If you change the ordering of the drawing to: image1, image2, image2 - its fine
* Using DirectX its fine

Strange...

Last edited 2011


shinkiro1(Posted 2011) [#27]
Declaring the image in the Loading Function Global also fixes the problem.


Difference(Posted 2011) [#28]
The most obvious conclusion is that the texture reference is being freed up by OpenGL for whatever reason (which is what I've always said).

seems correct, because


Declaring the image in the Loading Function Global also fixes the problem.

fixes this problem using the code above on my Mac.


Difference(Posted 2011) [#29]
I'm trying out this temporary solution:

Could you let me know if it works for any of you?

[EDIT] Sorry, this does not seem to fix anything :-( look below for another version.

' put this in the top of any OpenGl program, to avoid the white image?

Global whitefixer:TImage = CreateImage(32,32)


I've investigated a little and
	For Local i:Int =1  To 10
		DebugLog glIsTexture(i)
	Next	
seems to indicate that OpenGl still has the textures loaded.

in the example above, changing the loop to
For Local i:Int=0 To 1
	Local img:TImage = LoadImage("1.png")
        GCCollect() 
Next

will also show a white texture

EDIT: Now trying this:
' call WhiteFix() at the start of your OpenGL program 
Function WhiteFix()
	Global whitefixer:TImage = CreateImage(32,32)
End Function	


Could you let me know if it works for any of you?

[EDIT] no need, that didn't fix anything, sticking all images in a global list seems to help?

Last edited 2011


Difference(Posted 2011) [#30]
I think I found a semi solid soulution, although it will need some testing.

In glmax2d Function CreateTex() textures are flushed.

The problem seems to be related to allocating a new texture name, that is the same as one just deleted.

I've changed the first part of the code to not use a newly deleted name, and that seems to work.

Please test
Function CreateTex( width,height,flags )

	'flush dead texs
	If dead_tex_seq=GraphicsSeq
		For Local i=0 Until n_dead_texs
			'DebugLog "deleting " + dead_texs[i]
			glDeleteTextures 1,Varptr dead_texs[i]
		Next
	EndIf

	'
	'alloc new tex
	Local name

	Local safename:Int = False

	While Not safename
		glGenTextures 1,Varptr name
		safename = True
		For Local i=0 Until n_dead_texs
			If dead_texs[i] = name Then
				safename = False
			EndIf
		Next
	Wend

	'DebugLog "generated texture name " + name

	n_dead_texs=0
	dead_tex_seq=GraphicsSeq
	
	BindTex name



therevills(Posted 2011) [#31]
Have you removed this line?:

glGenTextures 1,Varptr name


This is my CreateTex in glmax2d in v1.41:



Could you post your entire CreateTex function?

Last edited 2011


Difference(Posted 2011) [#32]
Have you removed this line?:

Nope. It's in the loop.

Full version:



Difference(Posted 2011) [#33]
Looking at that code, It will probably need something to free up the "unsafe" names for reuse. I'll add that and see if it still works.


Difference(Posted 2011) [#34]
. still working on it

Last edited 2011


Difference(Posted 2011) [#35]
This seems to be ok.




Difference(Posted 2011) [#36]
It just occured to me that simply changing the glGenTextures(), glDeleteTextures() order should fix this in a mush simpler way than the convoluted approach above.

It seems to work well here.

It would be really nice if you could take the time and test this.




therevills(Posted 2011) [#37]
Just tested AntonM code using v1.42 at work and no white texture bug :)

I did try it at home yesterday but I couldn't repeat it using v1.41 (freshly downloaded), but at work I get the white texture bug using v1.41.

So v1.42 looks good :)

@Skully - can you try this with your TileMax stuff? (where are you btw!?!??! :P )


dw817(Posted 2016) [#38]
No-one seems to have found a simple solution to this problem, and yes, it was happening to me. Total WHITEOUT when I tried to use DrawText(), it would WHITEOUT my primary image (the entire screen).

I found a solution of sorts, create a dummy image thus:
Global dumi:TImage=CreateImage(1,1) ' necessary because of white rectangle error
' (see thread) http://www.blitzbasic.com/Community/posts.php?topic=91541
Draw it just prior to wherever in your code you are using CLS, you don't actually want it appearing.

THIS image will become the WHITEOUT one, and your other images will be safely left intact.

This is a nasty bug that BlitzMAX has, didn't appear until I really started to add some serious drawing elements and code to my project, at least now I know how to control it.

Hope This Helps !


dw817(Posted 2016) [#39]
I did want to add, this WHITE rectangle phenomenon VANISHES COMPLETELY (at least for me) if you use Front Buffering for your graphics.

I think that pins it down to FLIP()