Cant do multi-texturing...?

BlitzMax Forums/MiniB3D Module/Cant do multi-texturing...?

SLotman(Posted 2011) [#1]
You'll need these two textures for this:




I tried something simple like:



The code above creates a cube, with two textures overlapped on blitz3d - but on miniB3d, just the second texture appears, and without any alpha.

Doing something like:

Local s:TSurface = GetSurface(cube,1)
BrushFX s.brush, 32

makes the alpha to appear on the 2nd texture - but still, the 1st one isn't draw at all.

Also, even changing the texture to masked doesn't solve the problem... is multi-texturing really implemented?

I took a quick look at the source, but couldn't see where lies the problem...

Here's blitz3d code for comparison:


And here's the result from miniB3D and Blitz3D:


Last edited 2011


AdamRedwoods(Posted 2011) [#2]
miniB3D does multitexturing.

Check your card's extensions and make sure it supports multitexturing (it should).

My second tip would be to try using brushes and see if you get the same problem.

Also try "TextureBlend 2" which is multiply, just to see if you get different results.

TWO MORE THOUGHTS:
- try "EntityFX 32" , as this forces alpha blending
- try forcing gl(ALPHA_TEST) by forcing texture flag 4 : "LoadTexture("texture.jpg",1+2+4)"

Last edited 2011


SLotman(Posted 2011) [#3]
The card does multitexturing, that's not the problem.

Using brushes makes no difference - I tried that before posting here...

miniB3D does multi-texturing indeed - but multi-texturing with alpha (or a mask) looks broken - and I can't figure out exactly where.

Last edited 2011


AdamRedwoods(Posted 2011) [#4]
I've updated two more thoughts above, which are basically forcing gl Blend and Alpha_test.


SLotman(Posted 2011) [#5]
Already tested with BrushFX 32 (instead of EntityFX) - as I said in the first post, this only shows the 2nd texture with alpha - but the texture below doesnt appear.

1+2+4 had the same effect :(


AdamRedwoods(Posted 2011) [#6]
....and you've tried different TextureBlend modes, too, for the top layer (tex2)?
(TextureBlend 2 = modulate, 3 = add, 4 = combine+dot3)

This may be a bug, I see where there MAY be a problem (glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE)), but unless someone else knows I can't test this until later.

try using a texture with shapes on it instead of just green for the first texture, try the other textureblend modes and see if you can see your texture underneath. if so, then it's a problem with the glTexEnvf.

Last edited 2011


SLotman(Posted 2011) [#7]
I did all of that. I was actually working on a prototype, and tried to overlay a texture on a wall - those textures above I just did to show off the problem.


AdamRedwoods(Posted 2011) [#8]
Wellllllllllllllll.............

I did some research, here are my findings (as far as I know):

This is a common problem with OpenGL without shaders.
Some solutions use 3 textures, one being an inverse alpha.

But I would suggest hacking miniB3D to use a GL_DECAL combiner.
The problem with the decal combiner will be that it doesn't use the vertex lighting, since it's overwritten and lighting happens earlier in the pipeline.

So under TMesh.bmx under the update method:
Select tex_blend
	Case 0 glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE)

	Case 1 glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL)
	
	Case 2 glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE)

	Case 3 glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_ADD)
	
	Case 4
		glTexEnvf GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT
		glTexEnvf GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_DOT3_RGB_EXT
	Case 5
		glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE)
		glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_MODULATE)
		glTexEnvi(GL_TEXTURE_ENV,GL_RGB_SCALE,2.0)
	Case 6
		glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE)
	Default glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE)
End Select



I set it as case 1, since it's suppose to be for alpha combining--or you could set it to case 7.

Here is the code example with a light added to it, so you can see how decal doesn't light the top texture. Note that GL_REPLACE overwrites the lighting as well (case 0), so I used GL_MODULATE (case 2) instead to include the vertex lighting.


I tired to create the proper lighting effects with register combiners, but wasn't able to find the correct functions.

Now, I don't know how the actual Blitz3D does its textures, I'm assuming it's GL_DECAL as well. (?) ....if so, then is this a miniB3D bug?

Hope this helps.

Last edited 2011


AdamRedwoods(Posted 2011) [#9]
I'll also post my source references for the above info:

http://www.opengl.org/sdk/docs/man/xhtml/glTexEnv.xml

21.030 Why doesn't lighting work when I turn on texture mapping?
http://www.opengl.org/resources/faq/technical/texture.htm

Last edited 2011


ima747(Posted 2011) [#10]
Blitz3D is written under Direct3D (hence no cross platform), so it's handling of things like this is fundamentally different.

Thanks for the workarounds, may not be a 100% smooth solution but it's definitely a viable option in many circumstances.


AdamRedwoods(Posted 2011) [#11]
Ah, D3D makes sense.

To do a vanilla miniB3D version, you could use 3 textures (untested by me):
1. base texture
2. mask texture-- grey scale: white areas alpha, black area solid, grey for mixed. (basically an inverse alpha channel.)
3. color texture-- black background, color as is, no alpha.

then:
Local tex01:TTexture=LoadTexture("green.png",1)
Local tex02:TTexture=LoadTexture("red_mask.png",1)
Local tex03:TTexture=LoadTexture("red.png",1)

Local cube:TMesh=CreateCube()

EntityTexture cube,tex01,0,0
EntityTexture cube,tex02,0,1
EntityTexture cube,tex03,0,2

TextureBlend tex01,2
TextureBlend tex02,2
TextureBlend tex03,3


and that *should* (untested) result in

Cfinal = (Cf * Ct0 * (black out mask Ct1) ) + (add in color Ct2)


SLotman(Posted 2011) [#12]
hmmm? I guess you lost me there...

I really don't remember needing masks (and wasting a texture layer with it) to do multi-texturing in opengl, but it was a long time ago I coded it 'by hand' :/

I checked TMesh for the blend modes, and at least the GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA is correct. What it seems to be the problem is that it's trashing the previous texture before going on the second layer - so it draws the red "x", but the green below is replaced with the alpha 0.

Maybe, this is the culprit:
Select tex_blend
   Case 0 
     glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE)
   Case 1 
     glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE)


maybe GL_REPLACE isn't the correct flag for tex_blend=1?

YES! That was the answer apparently. just replace it for the code below, and the cube will render correctly!
Select tex_blend
   Case 0 
     glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE)
   Case 1 
     'glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE)
     glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL)


Apparently it does work...! I'm very, very confused, and will test this even further...

Last edited 2011


AdamRedwoods(Posted 2011) [#13]
Right, that's why I wondered if it was a miniB3D bug, since both case0 and case1 were the same...


BLaBZ(Posted 2012) [#14]
Is there any hack to acquire the vertex shading?