• Advertisement
Sign in to follow this  

Transparency blending

This topic is 4307 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm working on a particle system and I'm stuck on getting them blended the correct way. I have 2 ways of blending that i want to put in my engine: 1. transparency 2. additive the way i'm doing my particles is by texture so i've been messing around with the glBlendFunc() and glTexEnvi() functions. Also, when I create my texture, i should be doing something like this, right? glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_lWidth, m_lHeight, 0, GL_RGBA, GL_FLOAT, ilGetData()); Note: i'm using OpenIL (DevIL) for loading textures. To achieve the two effects i want for my particles, what combinations of glBlendFunc() and glTexEnvi() functions should i do? Edit: forgot to mention the texture i'm using for my particles is just a white circle that has an alpha of 0.0f on the outside and as it gets closer to the middle it fades to an alpha of 1.0f

Share this post


Link to post
Share on other sites
Advertisement
Regular: GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
Additive: GL_SRC_ALPHA, GL_ONE (or maybe GL_DST_ALPHA)

Share this post


Link to post
Share on other sites
Quote:
Original post by Boder
Regular: GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
Additive: GL_SRC_ALPHA, GL_ONE (or maybe GL_DST_ALPHA)


yes this is parameters for glBlendFunc and be sure that you have turn the depth test.

Share this post


Link to post
Share on other sites
those aren't working... is there a certain glTexEnvi() i should pass? or maybe i'm using glTexImage2D() wrong?

Share this post


Link to post
Share on other sites
The default texEnv should be fine, I believe it is GL_MODULATE.

Make sure to call glEnable( GL_BLEND ); to enable blending [smile] Hope this helps.

Share this post


Link to post
Share on other sites
yes blending is enabled.

yea, the texture has an alpha channel and it's using GL_FLOAT for it's components and GL_RGBA

Share this post


Link to post
Share on other sites
Quote:
Original post by EvilKnuckles666
do I need to change the format to GL_UNSIGNED_BYTE?
If that's the data type that ilGetData returns the image as, yes you should be using that instead of GL_FLOAT.

It looks like ilGetData does indeed return an array of unsigned bytes.

Share this post


Link to post
Share on other sites
ok... not even that is working.. so, here's my entire code for loading and rendering a texture.. what could be wrong?


bool cWTexture::Load(std::string Filename)
{
FILE *file = NULL;

if (IsLoaded())
Shutdown();

if (Filename == "")
return cWUtility::ErrorLog.Write("cWTexture::Load() no filename");

// Check if file exists
file = fopen(Filename.c_str(), "r");
if (file == NULL)
return cWUtility::ErrorLog.Write("cWTexture::Load() no file ", Filename);
fclose(file);

ilGenImages(1, &m_ILTexID);
ilBindImage(m_ILTexID);

if (ilLoadImage((const ILstring)Filename.c_str()) == IL_FALSE)
return cWUtility::ErrorLog.Write("cWTexture::Load() ilLoadImage() failed");

if (ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE) == IL_FALSE)
return cWUtility::ErrorLog.Write("cWTexture::Load() ilConvertImage() failed");

glGenTextures(1, &m_TexID);
glBindTexture(GL_TEXTURE_2D, m_TexID);

m_lWidth = ilGetInteger(IL_IMAGE_WIDTH);
m_lHeight = ilGetInteger(IL_IMAGE_HEIGHT);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_lWidth, m_lHeight,
0, GL_RGBA, GL_UNSIGNED_BYTE, ilGetData());

return true;
}

// then a pointer to this texture is set to the particle system.. then here's the render

bool cWEmitter::RenderParticles()
{
if (m_bActive == true)
{
if (Update() == false)
return false;

float PosX, PosY, PosZ;
float TexLeft, TexRight, TexTop, TexBottom;
float FraWidth, FraHeight;
sWParticle* Particle;
cWUtility::sWPosition *Pos;

TexLeft = m_FrameSrcRect.left * 1.0f / m_pEmitterDef->m_pTex->GetWidth();
TexRight = m_FrameSrcRect.right * 1.0f / m_pEmitterDef->m_pTex->GetWidth();
TexTop = m_FrameSrcRect.top * 1.0f / m_pEmitterDef->m_pTex->GetHeight();
TexBottom = m_FrameSrcRect.bottom * 1.0f / m_pEmitterDef->m_pTex->GetHeight();

for (unsigned long i=0 ; i<m_ParticleVList.GetNetItems() ; i++)
{
Particle = m_ParticleVList.GetItem((long)i);
Pos = &Particle->m_Pos;

FraWidth = ((m_FrameSrcRect.right - m_FrameSrcRect.left) * 0.5f) * Pos->ScaleX;
FraHeight = ((m_FrameSrcRect.bottom - m_FrameSrcRect.top) * 0.5f) * Pos->ScaleY;

PosX = Pos->X;
PosY = Pos->Y;
PosZ = Pos->Z;

// Position particle
glTranslatef(PosX, PosY, -PosZ);
glRotatef(Pos->Radian * (180/W_PI), 0.0f, 0.0f, 1.0f);

// Bind the texture
glBindTexture(GL_TEXTURE_2D, m_pEmitterDef->m_pTex->GetTextureID());

// Draw particle
glBegin(GL_QUADS);
{
// Set color
//glMaterialfv(GL_FRONT, GL_DIFFUSE, Particle->m_Color);

// Top-left
glTexCoord2d(TexLeft, TexTop);
glVertex3f(-FraWidth, FraHeight, 0.0f);

// Bottom-left
glTexCoord2d(TexLeft, TexBottom);
glVertex3f(-FraWidth, -FraHeight, 0.0f);

// Bottom-right
glTexCoord2d(TexRight, TexBottom);
glVertex3f(FraWidth, -FraHeight, 0.0f);

// Top-right
glTexCoord2d(TexRight, TexTop);
glVertex3f(FraWidth, FraHeight, 0.0f);
}
glEnd();
}
} else
return false;

return true;
}



Share this post


Link to post
Share on other sites
woops.. forgot to mention, before that render is called, these are called:

glEnable(GL_BLEND);

//Regular: GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
//Additive: GL_SRC_ALPHA, GL_ONE or GL_DST_ALPHA

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);

Share this post


Link to post
Share on other sites
Quote:
Original post by EvilKnuckles666
ok... not even that is working.. so, here's my entire code for loading and rendering a texture.. what could be wrong?

*** Source Snippet Removed ***
Quote:
Original post by EvilKnuckles666
woops.. forgot to mention, before that render is called, these are called:

glEnable(GL_BLEND);

//Regular: GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
//Additive: GL_SRC_ALPHA, GL_ONE or GL_DST_ALPHA

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);
Hmm... I don't see you enabling texturing, you are doing that right?

One other thing I noticed is that you use GL_RGBA as the internalformat parameter to glTexImage2D. This is usually fine but if you want a specific bit depth for the texture, you should use one of the formats that specify bit depth, such as GL_RGBA8 for a 32-bit texture. This is because if you just use GL_RGBA, your drivers are free to return any RGBA format. When the quality settings in the drivers aren't set to the highest quality they usually create a 16-bit texture if you just ask for GL_RGBA, and you will get significant banding on most of your textures. This certainly shouldn't be causing your problem though.

Speaking of which, what exactly is your problem? Is it that the texture isn't being created at all? Is it just not being rendered properly? Is it a blending issue? We need a little more description of what's going wrong, and possibly a screenshot.

Share this post


Link to post
Share on other sites
This is what's happening:



I want this effect to happen:


^This WAS my engine when i was using DirectX but now i'm switching to OpenGL

In the first image, see how the particle is being rendered without any blending? And it looks like the alpha isn't even being rendered either because the image looks like it's all black and gets slowly white as it gets to the center, but it's actually all white and the alpha gets more full as it gets to the center. I don't know why it's being drawn black and now blending like it should..

Share this post


Link to post
Share on other sites
i thought depth testing needed to be on in order for blending to work?? people kept telling me that...

Share this post


Link to post
Share on other sites
Quote:
Original post by EvilKnuckles666
i thought depth testing needed to be on in order for blending to work?? people kept telling me that...
Depth testing should be kept on so that you don't see the particles through walls and other opaque objects. Depth writing should be turned off for all transparent objects. Use glDepthMask to turn on/off depth writing.

EDIT: So the order of operations for a basic scene is this...
 - enable depth writing and depth testing
- render all opaque objects
- disable depth writing only
- render all transparent objects from back to front

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement