Alpha blending and scene nodes

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
SlashOwnsU
Posts: 7
Joined: Tue Feb 14, 2006 3:15 am

Alpha blending and scene nodes

Post by SlashOwnsU »

hi !
I'm trying to draw a semi-transparent node...and tried a few things that didn't work
I just want the node to be visible, though we can see through it, depending on its alpha value

thought this would do it
loading the texture from a tga file with preset alpha channels...
but it seems irrlicht only check the alpha to check if it draws a pixel, or not...no in-between

Code: Select all

inode->setMaterialTexture(0, smgr->getVideoDriver()->getTexture("Media/text.tga"));
inode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL);
then I tried manipulating the mesh

Code: Select all

scene::IAnimatedMesh* imesh = smgr->getMesh("Media/hitter.md2");
scene::IAnimatedMeshSceneNode* inode = smgr->addAnimatedMeshSceneNode(imesh);
inode->setMaterialTexture(0, smgr->getVideoDriver()->getTexture("Media/hitter.bmp"));
inode->setMaterialFlag(video::EMF_LIGHTING , false);
scene::IMeshManipulator *manipulator = smgr->getMeshManipulator();
manipulator->setVertexColorAlpha(imesh->getMesh(0), 100);
inode->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA );

but it does abolutely nothing more than rendering the node fully opaque...I really thought it'd work

now...is there anything I can do that would work ?[/code]
SlashOwnsU
Posts: 7
Joined: Tue Feb 14, 2006 3:15 am

Post by SlashOwnsU »

I've heard that by creating my one new material, I could do it...
any ideas ?
dhenton9000
Posts: 395
Joined: Fri Apr 08, 2005 8:46 pm

Post by dhenton9000 »

I've used TRANSPARENT_ADD_COLOR, accessed the color component of each vertex and faded it to black

Code: Select all



void CNebulaSceneNode::calcTexture()
{

 if (m_center.X == -9000) return;
ICameraSceneNode* camera = SceneManager->getActiveCamera();

vector3df v0(1,1,0);
vector3df v1(1,0,0);
vector3df v2(0,0,0);
vector3df v3(0,1,0);


if (!m_device) return;
if (m_initTime == 0)
	m_initTime = m_device->getTimer()->getTime();

u32 currentTime = m_device->getTimer()->getTime();

	// rotate
	 

	m_theta = (m_theta + m_direction* (currentTime-m_initTime)/333.0f) ;
	if (m_theta > 360.0f)
		m_theta = m_theta - 360.0f;

 
 
/////////////////////
  	vector3df pos = getAbsolutePosition() ;//-Box.getExtent()/4;
     
 //	vector3df pos = m_center;
	vector3df campos = camera->getAbsolutePosition();
	vector3df diff = campos - pos;
   	core::vector3df target = camera->getTarget();
	core::vector3df up = camera->getUpVector();
	core::vector3df view = target - campos;
	vector3df vtest = getAbsolutePosition() - campos;
	vtest.normalize();
	view.normalize();
	float vdot = vtest.dotProduct(view);
//	printf("vdot %4.3f\n",vdot);



	float dist = (float) diff.getLength();


	/*
		trapezoid 
		x0 left start up ramp
		x1 left start flat
		x2 end flat start right down ramp
		x3 end right ramp at 0
     */

	float x0 = 2.0f;
	float x1 = 140.0f;
	float x2 = 160.0f;
	float x3 = 300.0f;
	float xr = 0.0f;
	int r = 0;
	//char tt[125];

	if (dist > 0.0f && dist <= x0)
	{
		xr = 0;
	//	sprintf(tt,"section A %4.3f  %4.3f   \n",dist,xr);
	}


	if (dist > x0 && dist <  x1)
	{
	 	xr =  (dist - x0)/(x1 - x0);
//		sprintf(tt,"section B %4.3f  %4.3f   \n",dist,xr);


	}



	if (dist >= x1 && dist <=  x2)
	{
	 	xr = 1;
	//	sprintf(tt,"section C %4.3f  %4.3f   \n",dist,xr);

	}


	if (dist > x2 && dist <  x3)
	{
	 xr =  (x3 - dist)/(x3 - x2);
	//	sprintf(tt,"section D %4.3f  %4.3f   \n",dist,xr);
	}

	if (dist > x3 )
	{
	 xr = 0;
	//	sprintf(tt,"section e %4.3f  %4.3f   \n",dist,xr);

	}

 
  	xr = xr * ((2.0f* vdot) -1.0f); //effect for rotation
	if (xr > 1.0f)
		xr = 1.0f;
	if (xr < 0.0f)
		xr = 0.0f;
	

////////////////////////////////////////////////////////////////////////////////////
     r = xr * 255;
   
	 //printf("r %d xr %4.3f vdot %4.3f\n",r,xr,vdot);

     //printf(" r %d dist %4.3f, pos %4.3f, %4.3f,%4.3f\n",r,dist,pos.X,pos.Y,pos.Z);
	 //printf(tt);
 	if (r > 255)
		r = 255;

	SColor nColor(r,r,r,r);


 	vertices[0].Color = nColor;
	vertices[1].Color = nColor;
	vertices[2].Color = nColor;
	vertices[3].Color = nColor;



 	 m_initTime = currentTime;


  if (r <  20)
  {

	setVisible(false);

  }
  else
  {
	setVisible(true);


  }






the code sample is part of a custom bill board that fades out as a function of distance from the viewer. Max visibility is at distance x, and the closer or farther from that distance the visibility of the billboard drops. Also drops if they rotate away from directly facing the billboard.

HTH
SlashOwnsU
Posts: 7
Joined: Tue Feb 14, 2006 3:15 am

Post by SlashOwnsU »

thanks but...that's what I've been looking for for a while
how do you access a node's vertices ?
I've seen it in your code where you set the solors for the vertices, but I don't know how to access them
SlashOwnsU
Posts: 7
Joined: Tue Feb 14, 2006 3:15 am

Post by SlashOwnsU »

okay nevermind the above comment
I just found the way to access the vertices...
I've been looking for that solution for such a long time that I'm going to post what I did
it just accesses each vertices and applies a low alpha value on them
then use VERTEX_ALPHA material

Code: Select all

scene::IAnimatedMesh* imesh = smgr->getMesh("Media/model.md2");

    for(int i = 0; i < imesh->getFrameCount(); i++){
       scene::IMesh* mesh = imesh->getMesh(i);
       for (s32 b = 0; b < mesh->getMeshBufferCount(); ++b)
         {
            scene::IMeshBuffer* mb = mesh->getMeshBuffer(b);

            if (mb->getVertexType() == video::EVT_STANDARD)
            {

               video::S3DVertex* v = (video::S3DVertex*)mb->getVertices();

               for (s32 i = 0; i < mb->getVertexCount(); ++i, ++v)  
                   v->Color = video::SColor(100,100,100,100); 
            }
         }  
    }
    
    
    
    scene::IAnimatedMeshSceneNode* inode = smgr->addAnimatedMeshSceneNode(imesh);
    
    inode->setMaterialTexture(0, smgr->getVideoDriver()->getTexture("Media/model.png"));
    inode->setMaterialFlag(video::EMF_LIGHTING , false);
     
    inode->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA);
Post Reply