An addition to the transparent material

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
archilife
Posts: 16
Joined: Thu Oct 04, 2007 9:06 am

An addition to the transparent material

Post by archilife »

I added the following code to the OpenGL material renderers,
Because I needed a transparent material which will take
BOTH texture color AND diffuse color into consideration.

*update*: You'll also need to add a few lines to EMaterialTypes.h and COpenGLDriver.cpp

Code: Select all

// >> added by arch.jslin 2010.06.27
//! Transparency is determined by modulating both the texture and the primary color.
class COpenGLMaterialRenderer_TRANSPARENT_MODULATE : public COpenGLMaterialRenderer
{
public:
	COpenGLMaterialRenderer_TRANSPARENT_MODULATE(video::COpenGLDriver* d)
		: COpenGLMaterialRenderer(d) {}

	virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
		bool resetAllRenderstates, IMaterialRendererServices* services)
	{
		Driver->disableTextures(1);
		Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);

		if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates
			|| material.MaterialTypeParam != lastMaterial.MaterialTypeParam )
		{
#ifdef GL_ARB_texture_env_combine
			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
			glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
			glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
			glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB);

			glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
			glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
			glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
#else
			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
			glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
			glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
			glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT);

			glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
			glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
			glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);

#endif //GL_ARB_texture_env_combine
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
			glEnable(GL_BLEND);
			glEnable(GL_ALPHA_TEST);

			glAlphaFunc(GL_GREATER, material.MaterialTypeParam);
		}
	}

	virtual void OnUnsetMaterial() {
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
#ifdef GL_ARB_texture_env_combine
		glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );
#else
		glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
#endif
		glDisable(GL_ALPHA_TEST);
		glDisable(GL_BLEND);
	}

	//! Returns if the material is transparent.
	virtual bool isTransparent() const {
		return true;
	}
};
// << end of addition
Using this material, if you have a mesh with a certain
texture, and somehow you want to blend that object with
a specific color, say originally you have a gray monster,
and now you want it to be a red monster, you can simply
set node->getMaterial(0).DiffuseColor = SColor(255,255,0,0);
and boom! you have a red monster.

Lets think of another example. Now the player character
killed the red monster, and you want that monster to "fade
out", just set up a loop which decreases the alpha value
of that DiffuseColor from 255 to 0 frame by frame, and the
task is taken care of.

If sometimes you need to setup a loading splash screen which
will fade in and out before and after the scene transition,
this material will also help.

In Irrlicht 1.7 a ColorMaterial property is added to
SMaterial struct, it's defaulted to ECM_DIFFUSE, which
will use vertex color as if it is diffuse color instead of
using SMaterial.DiffuseColor to modulate the final color,
if you happens to need to adjust those colors vertex by
vertex or face by face, this is a cool feature. But if you
are like me, just need the SMaterial.DiffuseColor to get
everything done, set SMaterial.ColorMaterial to ECM_NONE.


I actually am not a OpenGL / D3D programmer, so I just
simply hacked this material to suit my need, and I don't
know how to code that in D3D. If anyone happens to be able
to help, I'd be very very appreciated.
shadowslair
Posts: 758
Joined: Mon Mar 31, 2008 3:32 pm
Location: Bulgaria

Post by shadowslair »

Really nice, but a D3d compatibility would make it even more applicable. :P

PS: some screenies or videos of the material in action will ne nice also for those who wanna take a peek, but are too lazy to set up a tast app. (like me) :wink:
"Although we walk on the ground and step in the mud... our dreams and endeavors reach the immense skies..."
archilife
Posts: 16
Joined: Thu Oct 04, 2007 9:06 am

Post by archilife »

Sure, there you go. ; )

Image
Image
Image
Image

I am too lazy to put up a video too :p
Hope these screenshots can clarify things up.

All objects you see above are actually custom planes with texture
in 3D space rendered Orthogonally. (in short, sprites.)

And all the colors on the cubes floating around the screen are
modulated by material diffuse. They share and use only EXACTLY ONE
gray-white texture. (except the title in the middle of the screen)


About D3D, as I said I am not a OpenGL / D3D programmer,
we use Irrlicht in the hope that we'll never touch that part,
but in the end we managed to added some feature we want to Irrlicht,
just coded very badly, and we still don't know how to deal with that
in D3D, sorry buddy :)
Buck1000
Posts: 93
Joined: Sun Dec 14, 2008 8:02 pm
Location: Seattle, WA

Post by Buck1000 »

I tried integrating this into Irrlicht so I can use it in my project, but it just crashes. Can you provide a tutorial on how to use this material? I desperately need it to "fade out" my scene nodes as you described. Thanks :D
archilife
Posts: 16
Joined: Thu Oct 04, 2007 9:06 am

Post by archilife »

Ok, in order to use this code snippet there are a little more steps than
just simply paste this into COpenGLMaterialRenderer.h :p

first...
paste the code in the original post into COpenGLMaterialRenderer.h XD

second,
add EMT_TRANSPARENT_MODULATE to the EMaterialTypes.h enumerations,
and add "trans_modulate" (or any name you want) to
sBuiltInMaterialTypeNames[] in the same file, just below the enums.

third,
add addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_MODULATE(this));
to COpenGLDriver::createMaterialRenderers() in COpenGLDriver.cpp

lastly,
BE VERY VERY CAREFUL about the order of the MaterialType list AFTER
you made these additions. The additions in the second and third part
above MUST NOT break the original list's order.
Because it's how Irrlicht find pre-created material renderers
just by setting SMaterial.MaterialType.

about the usage:

Code: Select all

    //I assume you have a light & camera & a scene node already.

    video::SMaterial& mat = myNode->getMaterial(0);

    //the lighting must be set to true because that's how what diffuse 
    //color do, they reflect and modulate their color based on their  
    //material color and lighting color.
    mat.setFlag(video::EMF_LIGHTING, true);

    //I usually set this because I am doing a lot of scaling within
    //my code, and I don't want they automatically become brighter or
    //dimmer just because I scaled them.
    mat.setFlag(video::EMF_NORMALIZE_NORMALS, true);

    //ColorMaterial is a added feature in Irrlicht 1.7 so that Vertex Color can be used as
    //Material colors when doing blending. But if you want the ordinary material color
    //to be used and not vertex color, this must be set to ECM_NONE.
    //I think it is a bad naming because you cannot understand the meaning by just looking
    //at the "ColorMaterial" name...
    mat.ColorMaterial = video::ECM_NONE;

    mat.MaterialType = video::EMT_TRANSPARENT_MODULATE;
    mat.MaterialTypeParam = 0.01f;
    mat.DiffuseColor.set(128, 255, 255, 0);

    //ok now you should have a yellow tone half transparent "thing."
hybrid
Admin
Posts: 14144
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

You can also add the material from within your app, no need to change Irrlicht at all. Just create the material and pass it to the driver.
Post Reply