Quad With Transparency Mask Texture

Blitz3D Forums/Blitz3D Programming/Quad With Transparency Mask Texture

_PJ_(Posted 2015) [#1]
This really should not be as problematic as it is apparently proving.

All I am trying to achieve is a simple Quad mesh (two triangles aligned on a plane) this quad has a single texture which is drawn with black as the default background.

The intent is for the black pixels to be masked as transparent whilst the other pixels are displayed normally when the texture is applied.

With the Mask flag set on the texture, the effect is not achieved:
Graphics3D 800,600,32,6
SetBuffer BackBuffer()

Local Cam=CreateCamera()
CameraViewport Cam,0,0,800,600
CameraClsColor Cam,255,0,0;Just so as to determine transparency of foreground objects

MoveEntity Cam,0,0,-5 ; Move the camera back so as to get a reasonable viewpoint

Local Quad=CreateQuad()

Local Texture=CreateTexture(128,128,5)

SetBuffer TextureBuffer(Texture)
ClsColor 0,0,0
Cls
Color 255,255,255
Oval 32,32,64,64,True
SetBuffer BackBuffer()

EntityTexture Quad,Texture

While (Not KeyHit(True))
	TurnEntity Quad,0,1,0
	RenderWorld
	Flip
Wend


Function CreateQuad(X#=1,Y#=1,Parent=0) 
	Local Surf
	Local Mesh=CreateMesh(Parent)
	Surf=CreateSurface(Mesh)
	Local Vertex0=AddVertex (Surf,X#*0.5,0-(Y#*0.5),00,0)
	Local Vertex1=AddVertex (Surf,0-(X#*0.5),0-(Y#*0.5),0,1,0)
	Local Vertex2=AddVertex (Surf,0-(X#*0.5),Y#*0.5,0,1,1)
	Local Vertex3=AddVertex (Surf,X#*0.5,Y#*0.5,0,1,0)
	
	AddTriangle Surf,Vertex0,Vertex1,Vertex2
	AddTriangle Surf,Vertex0,Vertex2,Vertex3
	
	Return Mesh
End Function


The addition of the EntityBlend mode seems to be necessary in order to suggest the ENTITY itself is to be made partially transparent as result of the texture:
EntityBlend Quad,3


However this appies an alpha level to ALL pixels, the white oval is also slightly affected.

The only thing I can think of is to manually edit the ALPHA values of the pixels, but are these in aRGB, RGBa and is the a value 0-255 or ???


Rroff(Posted 2015) [#2]
Not something I've touched in a long time but pulling up the source for an old project I'm using loadtexture flag of 12 (not sure why not 13) and entityblend 2 for some reason.

I think that was to do foliage with minimal issues (jagged edges, sort order, see through) though and probably highly specific to that use.


RemiD(Posted 2015) [#3]
You are an ancient user, i am surprised that you don't know about this.

Basically, when you load a texture with the flag 2 or 4, Blitz3d calculates and sets the alpha value of each pixel, but if you create a texture, you need to do it yourself with readpixel/writepixel.

Search the forum and code archives, there are several examples to do that.


Floyd(Posted 2015) [#4]
Check the documentation for ReadPixel. The format is argb, all values 0-255.

The old 2d graphics commands like Oval set an alpha value of 255, meaning fully opaque. You can see it in the following example. DottedIP() is handy for viewing the four bytes in an integer without doing any work to separate them.

Graphics3D 800, 600, 0, 2

Local Texture=CreateTexture(128,128,5)

SetBuffer TextureBuffer(Texture)
Color 100, 150, 200
Oval 32,32,64,64,True

argb = ReadPixel( 64, 64 ) ; center of oval

SetBuffer BackBuffer()
Color 255,255,0
Text 150, 250, "Center pixel of oval a.r.g.b = " + DottedIP( argb )
Flip
WaitKey



Rroff(Posted 2015) [#5]
Ooof didn't even notice topic was really about createtexture instead of loadtexture :S mind very much not in programming these days.


_PJ_(Posted 2015) [#6]

Not something I've touched in a long time but pulling up the source for an old project I'm using loadtexture flag of 12 (not sure why not 13) and entityblend 2 for some reason.

The lack of Flag 1 was likely because, from personal experience, prior to Windowes Vista and v1.06 or so of Blitz I think, one could get away with not setting the colour flag without issue (not good practice)

Trying EntityBlend 2 seems to make the "coloured" pixels transparent and the 'black' pixels opaque for me.


You are an ancient user, i am surprised that you don't know about this.

Basically, when you load a texture with the flag 2 or 4, Blitz3d calculates and sets the alpha value of each pixel, but if you create a texture, you need to do it yourself with readpixel/writepixel.

Search the forum and code archives, there are several examples to do that.



I did try a search throught the entire forums, but honestly didn't turn up anything that seemed to refer to this, but thank you for the explanation.

___

Thanks Floyd
Funny coincidence but I realised the use of DottedIP in this kind of way for making Version Numbers recently :)

_________________________________________________


It still does not explain, however, why the oval in my example is semi-transparent.


RemiD(Posted 2015) [#7]

I did try a search throught the entire forums, but honestly didn't turn up anything that seemed to refer to this


I am not sure that Blitz3d does that, but it seems it does that. Because when you load a texture with black pixels with the flag 2 or 4, the black pixels will be masked/transparent, but when you copyrect the backbuffer to a texture (where there are black pixels) the pixels will still be black, so this means that the alpha values are not calculated and set automatically...
More infos about that here : http://www.blitzbasic.com/b3ddocs/command.php?name=CreateTexture


_PJ_(Posted 2015) [#8]
Not used copyrect at all, but wonder if Cls on the Texturebuffer affects this?
________________

"2: Alpha - alpha map. If an image contains an alpha map, this will be used to make certain areas of the texture transparent. Otherwise, the colour map will be used as an alpha map. With alpha maps, the dark areas always equal high-transparency, light areas equal low-transparency. "

This tells me that if only Flag 1 set, then colour 255 ought to be fully opaque, or does Blitz simply define a level of "high transparency" AND a level of "low transparency" rather than actually use a smoother (maybe 255 resolution based on mean RGB) gradient of values???

"4: Masked - all areas of a texture coloured 0,0,0 will not be drawn to the screen." No mention of any transparency effects on non-black pixels...


_PJ_(Posted 2015) [#9]
nevermind, I see now the last comment on the web version of the documentation explains the cutoff of 128 for an alpha value.
Thanks :)


RemiD(Posted 2015) [#10]

No mention of any transparency effects on non-black pixels


When you use loadtexture(), if the pixels have already an alpha value, it is used, else it is calculated depending on the darkness/brightness of the color. This is how i understand it.
Also the textureblend may change how the pixels are blended with the colors of the others surfaces in the scene.


Matty(Posted 2015) [#11]
In the past i have created an alpha texture as a base template. .. purely alpha =0 for all pixels and then copyrected that to any new textures before drawing on them. It solved the problem of drawing rects and ovals to textures you wanted masked. Something else to remember is that there has in the past been inconsistent behaviour on pcs when the color flag is not set...you have to specify both colour and alpha 1+2 for compatibility not just 2 ... on some machines it will crash if you specify 2 by itself....or it did in the past. There are threads about this.


_PJ_(Posted 2015) [#12]

In the past i have created an alpha texture as a base template. .. purely alpha =0 for all pixels and then copyrected that to any new textures before drawing on them. It solved the problem of drawing rects and ovals to textures you wanted masked. Something else to remember is that there has in the past been inconsistent behaviour on pcs when the color flag is not set...you have to specify both colour and alpha 1+2 for compatibility not just 2 ... on some machines it will crash if you specify 2 by itself....or it did in the past. There are threads about this.


I specified flags 1 and 4 ( = 5 ) Notice there is no intention of semi/graded transparency, only masked.

I think you are taking this a little far offtopic now, the issue is the non-opacity of pixels drawn with the 'Oval' command in the example provided.


jfk EO-11110(Posted 2015) [#13]
Intrestingly, flags 1+8 were thought to be default set (unless you ClearTextureFilters()).

But as it was said, you have to explicitly set the 1, like for alpha: 1 + 2.

I remember I had tuff issues with the alphachannel of created textures, ended up loading the thing from a file.

You may also load a dummy texture file with Alpha/Mask-flags and then draw to it. Whether alpha or mask, this goes for both.

so you would...

argb=readpixelfast(x,y)
rgb= argb and $ffffff
if rgb=0 then writepixelfast x,y,rgb

to make all black pixels transparent. Don't forget to Lockbuffer when you ReadpixelFAST...


Bobysait(Posted 2015) [#14]
flag 1 is mostly used if your desktop is set on 16 bit color (as long as it can still happen with windows 10, you should use the flag...)

ps : just use this on a "black background" or on a "newly created black" texture to set all black pixels to alpha 0. (of course, the texture needs the flag 4)

Function MaskTexture(Texture)
	Local curbuffer = GraphicsBuffer()
	SetBuffer TextureBuffer(Texture)
	LockBuffer()
		Local h= TextureHeight(Texture)-1, w= TextureWidth(Texture)-1
		Local y,x
		For y=0 To h:For x= 0 To w
			If ReadPixelFast(x,y) Shl(8)=0 Then WritePixelFast(x,y,0);
		Next:Next
	UnlockBuffer()
	SetBuffer curbuffer
End Function


ps 2 : As far as I know, there is no issue here. The functions Oval/Rect works perfectly, but your created texture is $FF000000 by default.
So, you draw opac stuff on opac texture.

ps 3 :
You can remove pixels after drawing on the texture, or directly clear all pixels after texture creation.
Your oval/rect stuff will draw perfectly without modifying neighboored alpha pixels

Local Texture=CreateTexture(128,128,5) : MaskTexture(Texture);
SetBuffer TextureBuffer(Texture)
	Color 255,255,255
	Oval 32,32,64,64,True
SetBuffer BackBuffer()



ps 4 : your UVs are really nasty (you forgot the z coord on the last vertex which does not give {1.0,0.0} but {0.0,Optional_Default_V_Coord} )



ps 5 : just for fun, my 2cents procedural code of the day