Awesome, thanks for help, that worked. What I needed it for was I just added a function to IrrSpintz to draw2DImage with using a separate texture for the alpha mask.
Here's function in OpenGL -
Code: Select all
//! Draws a texture, using another textures color
void COpenGLDriver::draw2DImageUsingAlphaTexture(video::ITexture* texture, video::ITexture* alphaTexture,
const core::rect<s32>& destRect, const core::rect<s32>& sourceRect )
{
if (!texture || !alphaTexture )
return;
const core::dimension2d<s32>& renderTargetSize = getCurrentRenderTargetSize();
const core::dimension2d<s32>& ss = texture->getOriginalSize();
float ssw=1.0f/ss.Width;
float ssh=1.0f/ss.Height;
core::rect<f32> tcoords;
tcoords.UpperLeftCorner.X = (((f32)sourceRect.UpperLeftCorner.X)+0.5f) * ssw;
tcoords.UpperLeftCorner.Y = (((f32)sourceRect.UpperLeftCorner.Y)+0.5f) * ssh;
tcoords.LowerRightCorner.X = (((f32)sourceRect.UpperLeftCorner.X +0.5f + (f32)sourceRect.getWidth())) * ssw;
tcoords.LowerRightCorner.Y = (((f32)sourceRect.UpperLeftCorner.Y +0.5f + (f32)sourceRect.getHeight())) * ssh;
s32 xPlus = -(renderTargetSize.Width>>1);
f32 xFact = 1.0f / (renderTargetSize.Width>>1);
s32 yPlus = renderTargetSize.Height-(renderTargetSize.Height>>1);
f32 yFact = 1.0f / (renderTargetSize.Height>>1);
core::rect<float> npos;
npos.UpperLeftCorner.X = (f32)(destRect.UpperLeftCorner.X+xPlus+0.5f) * xFact;
npos.UpperLeftCorner.Y = (f32)(yPlus-destRect.UpperLeftCorner.Y+0.5f) * yFact;
npos.LowerRightCorner.X = (f32)(destRect.LowerRightCorner.X+xPlus+0.5f) * xFact;
npos.LowerRightCorner.Y = (f32)(yPlus-destRect.LowerRightCorner.Y+0.5f) * yFact;
setTexture( 0, texture );
setRenderStates2DMode( false, true, true );
setTexture( 1, alphaTexture );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
extGlActiveTextureARB( GL_TEXTURE1 );
glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE );
glTexEnvf( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS );
glTexEnvf( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
extGlActiveTextureARB( GL_TEXTURE0 );
glBegin(GL_QUADS);
pGlMultiTexCoord2f( GL_TEXTURE0, tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y );
pGlMultiTexCoord2f( GL_TEXTURE1, tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y );
glVertex2f( npos.UpperLeftCorner.X, npos.UpperLeftCorner.Y );
pGlMultiTexCoord2f( GL_TEXTURE0, tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y );
pGlMultiTexCoord2f( GL_TEXTURE1, tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y );
glVertex2f( npos.LowerRightCorner.X, npos.UpperLeftCorner.Y );
pGlMultiTexCoord2f( GL_TEXTURE0, tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
pGlMultiTexCoord2f( GL_TEXTURE1, tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y );
glVertex2f( npos.LowerRightCorner.X, npos.LowerRightCorner.Y );
pGlMultiTexCoord2f( GL_TEXTURE0, tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y );
pGlMultiTexCoord2f( GL_TEXTURE1, tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y );
glVertex2f( npos.UpperLeftCorner.X, npos.LowerRightCorner.Y );
glEnd();
// Reset Render States
extGlActiveTextureARB( GL_TEXTURE1 );
glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
glTexEnvf( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );
glTexEnvf( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );
glDisable( GL_BLEND );
glBlendFunc( GL_ONE, GL_ZERO );
setTexture( 1, 0 );
}
And in DirectX9 -
Code: Select all
//! Draws a texture, using another textures color
void CD3D9Driver::draw2DImageUsingAlphaTexture(video::ITexture* texture, video::ITexture* alphaTexture,
const core::rect<s32>& destRect, const core::rect<s32>& sourceRect )
{
if( !texture || !alphaTexture )
return;
const core::dimension2d<s32>& ss = texture->getOriginalSize();
f32 ssw=1.0f/ss.Width;
f32 ssh=1.0f/ss.Height;
core::rect<f32> tcoords;
tcoords.UpperLeftCorner.X = (((f32)sourceRect.UpperLeftCorner.X)+0.5f) * ssw ;
tcoords.UpperLeftCorner.Y = (((f32)sourceRect.UpperLeftCorner.Y)+0.5f) * ssh;
tcoords.LowerRightCorner.X = (((f32)sourceRect.UpperLeftCorner.X +0.5f + (f32)sourceRect.getWidth())) * ssw;
tcoords.LowerRightCorner.Y = (((f32)sourceRect.UpperLeftCorner.Y +0.5f + (f32)sourceRect.getHeight())) * ssh;
core::dimension2d<s32> renderTargetSize = getCurrentRenderTargetSize();
s32 xPlus = -(renderTargetSize.Width>>1);
f32 xFact = 1.0f / (renderTargetSize.Width>>1);
s32 yPlus = renderTargetSize.Height-(renderTargetSize.Height>>1);
f32 yFact = 1.0f / (renderTargetSize.Height>>1);
core::rect<f32> npos;
npos.UpperLeftCorner.X = (f32)(destRect.UpperLeftCorner.X+xPlus+0.5f) * xFact;
npos.UpperLeftCorner.Y = (f32)(yPlus-destRect.UpperLeftCorner.Y+0.5f) * yFact;
npos.LowerRightCorner.X = (f32)(destRect.LowerRightCorner.X+xPlus+0.5f) * xFact;
npos.LowerRightCorner.Y = (f32)(yPlus-destRect.LowerRightCorner.Y+0.5f) * yFact;
setTexture( 0, texture );
setTexture( 1, alphaTexture );
setRenderStates2DMode( false, true, true );
// Set alphaTexture as texture 1, get the alpha value, and then use that on texture 2
// the actual texture, to draw with texture 1's alpha
pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
pID3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
pID3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0 );
pID3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
pID3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
pID3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
S3DVertex vtx[4]; // clock wise
vtx[0] = S3DVertex(npos.UpperLeftCorner.X, npos.UpperLeftCorner.Y , 0.0f, 0.0f, 0.0f, 0.0f, 0xFFFFFFFF, tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
vtx[1] = S3DVertex(npos.LowerRightCorner.X, npos.UpperLeftCorner.Y , 0.0f, 0.0f, 0.0f, 0.0f, 0xFFFFFFFF, tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
vtx[2] = S3DVertex(npos.LowerRightCorner.X, npos.LowerRightCorner.Y, 0.0f, 0.0f, 0.0f, 0.0f, 0xFFFFFFFF, tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
vtx[3] = S3DVertex(npos.UpperLeftCorner.X, npos.LowerRightCorner.Y, 0.0f, 0.0f, 0.0f, 0.0f, 0xFFFFFFFF, tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
s16 indices[6] = {0,1,2,0,2,3};
setVertexShader(EVT_STANDARD);
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], D3DFMT_INDEX16, &vtx[0], SizeOfS3DVertex);
// Reset Changed RenderStates
pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
pID3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
pID3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
pID3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
pID3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
pID3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR );
setTexture( 1, 0 );
}
I needed this cause I was doing a render to texture, and then wanted to render that texture onto a circular HUD radar, and needed to use a texture to specify the alpha mask for the render texture into the HUD. Basically, it's like Texture Splatting in 2D. Here's screenshot of result -
These are the beginnings of a HUD i started putting together today for a spaceship. The texture for radar on the bottom is generated by doing a renderToTexture and rendering certain texture for the planets, sun and your location and scaled to 2D space on the render target. That texture is then drawn, using this new function with a TGA texture specifying the transparency to use. Then another texture is drawn with draw2DImage to draw the rest of the HUD ( which needs a lot of work

)
Oh, and I had to add a pointer and get the function using wglGetProcAddress for PFNGLMULTITEXCOORD2FPROC. Thanks again, was banging my head on that one for a couple hours.