Page 1 of 1

Problem with alpha channel when rendering to ARGB texture

Posted: Tue Feb 15, 2011 4:03 pm
by helmuthschmitz
Hi, first of all, sorry for my bad english. I will try to explain
my problem best i can.


I´m rendering all stuff to a ARGB texture using DirectX device:

Code: Select all

   //note i create a 1x1 window, cause all that i want is use the rendered texture in
   //other application... so i dont need to see irrlicht window in any moment.
   device =   createDevice(EDT_DIRECT3D9, dimension2d<u32>(1, 1), 16, false, false, true);
    
   driver = device->getVideoDriver();
   smgr = device->getSceneManager(); 
  

   rt = driver->addRenderTargetTexture(core::dimension2d<u32>(1920,1080), "RTT1", irr::video::ECF_A8R8G8B8);
   
   t1 = driver->getTexture("test1.png");   
   t2 = driver->getTexture("test3.png");      
   t3 = driver->getTexture("hello.png");   

   d1 = GetTickCount();
So, test1.png is an image with alpha channel. It have a "hole"(a transparent part) in the middle. So, i draw it with:

Code: Select all

void draw()
{
   video::S3DVertex vertices[4]; 

   vertices[0].TCoords = core::vector2df(0.0f, 0.0f); 
   vertices[0].Pos = core::vector3df(10,0,0); 

   vertices[1].TCoords = core::vector2df(1.0f, 0.0f); 
   vertices[1].Pos = core::vector3df(1920,0,0); 

   vertices[2].TCoords = core::vector2df(1.0f, 1.0f); 
   vertices[2].Pos = core::vector3df(1920,1080,0); 

   vertices[3].TCoords = core::vector2df(0.0f, 1.0f); 
   vertices[3].Pos = core::vector3df(10,1080,0);   

   short int index[4];
   for(unsigned int i=0; i<4; i++) 
   { 
        index[i]=i; 
        vertices[i].Color = video::SColor(255, 255, 255, 255); 
   } 

   video::SMaterial m; 
   m.setTexture(0, t1); 
   m.MaterialType = EMT_TRANSPARENT_ALPHA_CHANNEL; 


   driver->setMaterial(m);    
   driver->draw2DVertexPrimitiveList(vertices, 4, index, 4-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN);      
}
Then i renderize it to that texture called "rt", and save rt to a png file.
So, if a open generated file with gimp(for example) i got this:


Image


Ok, everything is fine until now. But if i draw the same image again, but using
a color with alpha, the background will have the same alpha value. i know all this
have something with ALPHA BLENDING. But i dont know what to do:
See whats happining when i draw the same image over the first draw, but using
a color with alpha(video::SColor(100, 255, 255, 255)):

Image


i draw the second time with:

Code: Select all

void draw2()
{
   video::S3DVertex vertices[4]; 

   vertices[0].TCoords = core::vector2df(0.0f, 0.0f); 
   vertices[0].Pos = core::vector3df(200,100,0); 

   vertices[1].TCoords = core::vector2df(1.0f, 0.0f); 
   vertices[1].Pos = core::vector3df(560,100,0); 

   vertices[2].TCoords = core::vector2df(1.0f, 1.0f); 
   vertices[2].Pos = core::vector3df(560,260,0); 

   vertices[3].TCoords = core::vector2df(0.0f, 1.0f); 
   vertices[3].Pos = core::vector3df(200,260,0);   

   short int index[4];
   for(unsigned int i=0; i<4; i++) 
   { 
        index[i]=i; 

        //this alpha(100) should alter only this draw, and not the render
        //target background
        vertices[i].Color = video::SColor(100, 255, 255, 255); 
   } 

    video::SMaterial m; 
    m.setTexture(0, t1); 
    m.MaterialType = EMT_ONETEXTURE_BLEND;
    m.MaterialTypeParam = pack_texureBlendFunc(video::EBF_DST_ALPHA, video::EBF_ONE_MINUS_SRC_ALPHA,  video::EMFN_MODULATE_1X, video::EAS_TEXTURE | video::EAS_VERTEX_COLOR);
    m.ZWriteEnable = false; 


   driver->setMaterial(m);    
   driver->draw2DVertexPrimitiveList(vertices, 4, index, 4-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN);    
}

and i was expecting this:


Image


The main Loop is:

Code: Select all

while(device->run())
       {
		   driver->beginScene(true, true, video::SColor(0,255,255,255));


		   // set render target texture
		   driver->setRenderTarget(rt, true, true, video::SColor(0,255,255,255));

		   // draw whole scene into render buffer
		   smgr->drawAll();            
         
         draw();

         draw2();
        
   		
	      driver->endScene();	
         break;
      }	


      char* bits = (char*)rt->lock();
      if (bits)
      {
         //...
         Here is the part i save the "rt" texture bits to a file
	 //...

         rt->unlock();
      }
What am i doing wrong?

I hope somebody can help me.

Thanks anyway.

humm.... i think the images are missing....

Posted: Tue Feb 15, 2011 4:51 pm
by helmuthschmitz
i think the images i did post above are missing... so ...

i´m posting the links again:



http://piczasso.com/i/bumma.png
http://piczasso.com/i/pxzxl.png
http://piczasso.com/i/pl8m8.png

I hope somebody can help me.

:D

Posted: Tue Feb 15, 2011 7:31 pm
by bitplane
This should work:

Code: Select all

pack_texureBlendFunc(video::EBF_SRC_ALPHA, video::EBF_ONE_MINUS_SRC_ALPHA ... 

Posted: Wed Feb 16, 2011 11:53 am
by helmuthschmitz
Hi bitplane,

thanks for helping me. i change "draw2()" function code to:

Code: Select all

void draw2()
{
   video::S3DVertex vertices[4]; 

   vertices[0].TCoords = core::vector2df(0.0f, 0.0f); 
   vertices[0].Pos = core::vector3df(200,100,0); 

   vertices[1].TCoords = core::vector2df(1.0f, 0.0f); 
   vertices[1].Pos = core::vector3df(660,100,0); 

   vertices[2].TCoords = core::vector2df(1.0f, 1.0f); 
   vertices[2].Pos = core::vector3df(660,460,0); 

   vertices[3].TCoords = core::vector2df(0.0f, 1.0f); 
   vertices[3].Pos = core::vector3df(200,460,0);   

   short int index[4];
   for(unsigned int i=0; i<4; i++) 
   { 
        index[i]=i; 
        vertices[i].Color = video::SColor(100, 255, 255, 255); 
   } 

    video::SMaterial m; 
    m.setTexture(0, t1); 
    m.MaterialType = EMT_ONETEXTURE_BLEND;
    m.MaterialTypeParam = pack_texureBlendFunc(video::EBF_SRC_ALPHA, video::EBF_ONE_MINUS_SRC_ALPHA,  video::EMFN_MODULATE_1X, video::EAS_TEXTURE | video::EAS_VERTEX_COLOR);
    m.ZWriteEnable = false; 


   driver->setMaterial(m);    
   driver->draw2DVertexPrimitiveList(vertices, 4, index, 4-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN);    
}

But, i´m still have same results. "draw2()" change alpha value of background.

I never noticed it, because I always used RGB textures as Render Target. So I did not see this problem. but this time using ARGB textures, I can see this problem.

This is getting me crazy.

Posted: Wed Feb 16, 2011 7:52 pm
by helmuthschmitz
I´m still got NO SUCESS with this issue.

i have been tried every possible combination for pack_texureBlendFunc, but
the results are the same.

I cant see what really is going on

Posted: Thu Feb 17, 2011 6:49 am
by Bear_130278
Try TGA?

Posted: Thu Feb 17, 2011 2:44 pm
by bitplane
I still haven't actually tried this code, but I imagine that the inverse source alpha and the source alpha don't add up to one because of the vertex colours. You may need to do it in two stages, so one texture blend may not work for this.

Posted: Thu Feb 17, 2011 5:08 pm
by helmuthschmitz
Bear, i got same result with TGA. But, thanks for helping me anyway man.

Bitplane, you are right. What is killing me is vertex colours. Could you explain me better , what do you mean with "two stages" ?

Thanks for helping me again man.

Have a nice day

Posted: Fri Feb 18, 2011 5:22 pm
by helmuthschmitz
Hi, bitplane, how are yoU?

I was almost killing my self when i have a simple idea.

Not to use EAS_VERTEX_COLOR and EAS_TEXTURE together anymore.

Change the alpha for hole texture "outside the irrlicht"
(this new texture has alpha 100 for each pixel) and
them draw texturing using just EAS_TEXTURE.

Like this:


Code: Select all

void draw2()
{
   video::S3DVertex vertices[4]; 

   vertices[0].TCoords = core::vector2df(0.0f, 0.0f); 
   vertices[0].Pos = core::vector3df(200,100,0); 

   vertices[1].TCoords = core::vector2df(1.0f, 0.0f); 
   vertices[1].Pos = core::vector3df(660,100,0); 

   vertices[2].TCoords = core::vector2df(1.0f, 1.0f); 
   vertices[2].Pos = core::vector3df(660,460,0); 

   vertices[3].TCoords = core::vector2df(0.0f, 1.0f); 
   vertices[3].Pos = core::vector3df(200,460,0);   

   short int index[4];
   for(unsigned int i=0; i<4; i++) 
   { 
        index[i]=i; 
	
	//this dosent metter cause i will not use EAS_VERTEX_COLOR 
        vertices[i].Color = video::SColor(255, 255, 255, 255); 
   } 

    video::SMaterial m; 
    m.setTexture(0, t3); 
    m.MaterialType = EMT_ONETEXTURE_BLEND;
    m.MaterialTypeParam = pack_texureBlendFunc(video::EBF_SRC_ALPHA, video::EBF_ONE_MINUS_SRC_ALPHA,  video::EMFN_MODULATE_1X, video::EAS_TEXTURE);
    m.ZWriteEnable = false; 


   driver->setMaterial(m);    
   driver->draw2DVertexPrimitiveList(vertices, 4, index, 4-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN);    
}
So, if the hole texture have alpha 100 for each pixel, and i´m using just
EPT_TRIANGLE_FAN for drawing this texture on the render target, everithing will
be alright, right?

No. I have the same results. Now, i think i can kill my self. hahahaha.
The fact is, dosent metter if i´am using EAS_VERTEX_COLOR or if texture has
alpha 100 for each pixel, if i draw it to a ARGB Texture as render target...
the render target will have alpha 100 for each pixel in the drawed area.

I dont know what to do.

Sometimes, i want to make my pc feel pain... a lot of pain. hahahah

So, i pray for somebody help me in this issue;

Thanks

Posted: Fri Feb 18, 2011 5:38 pm
by helmuthschmitz
hi Folks... just to help you understand better what i wrote above:

Image

Hope somebody can help me

Posted: Fri Feb 18, 2011 5:51 pm
by helmuthschmitz
the hole image with no legends:

This is what iam seeing right now:

Image

Posted: Sat Feb 19, 2011 9:19 am
by bitplane
By that I mean two render stages in the material renderer, the first blends the alpha channels together, the second blends the vertex colours. I don't think we support this internally (we should IMO)

It would be very simple two-line vertex shader program, or quite painful to do it in the fixed-function pipeline. See this topic for D3D implementations.

Posted: Mon Feb 28, 2011 1:11 pm
by helmuthschmitz
Hi bitplane.... thanks for replay again.

I think you right!

I will try your indication.

If i get some success, i will post here.

Thanks again