Archived

This topic is now archived and is closed to further replies.

Alpha blending on a texture

This topic is 5336 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

Hey, Can You please tell what I''m doing wrong with my particle engine here!!! The alpha blending dosn''t work... GL_BLEND is enabled and if I enable the glBlendFunc the texture isn''t showed at all I''m using TGA files, which are created as Mipmaps My Code -> //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(glParticle.pColor[0], glParticle.pColor[1], glParticle.pColor[2], 1.0f); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, pTexture[0]); glBegin(GL_TRIANGLE_STRIP); glTexCoord2d(1, 1); glVertex3f(glParticle.pPosition[0] + 0.5f, glParticle.pPosition[1] + 0.5f, glParticle.pPosition[2]); glTexCoord2d(0, 1); glVertex3f(glParticle.pPosition[0] - 0.5f, glParticle.pPosition[1] + 0.5f, glParticle.pPosition[2]); glTexCoord2d(1, 0); glVertex3f(glParticle.pPosition[0] + 0.5f, glParticle.pPosition[1] - 0.5f, glParticle.pPosition[2]); glTexCoord2d(0, 0); glVertex3f(glParticle.pPosition[0] - 0.5f, glParticle.pPosition[1] - 0.5f, glParticle.pPosition[2]); glEnd(); glDisable(GL_TEXTURE_2D); glParticle.pPosition[0] += glParticle.pSpeed[0] / 1000; glParticle.pPosition[1] += glParticle.pSpeed[1] / 1000; glParticle.pPosition[2] += glParticle.pSpeed[2] / 1000; glParticle.pSpeed[0] += glParticle.pGravity[0]; glParticle.pSpeed[1] += glParticle.pGravity[1]; glParticle.pSpeed[2] += glParticle.pGravity[2]; glParticle.pTransparency -= glParticle.pTime;

Share this post


Link to post
Share on other sites
why don t you use vertex array and why don t you have a look at point sprites extension from nvidia?

you blend function is correct
make sure you use 0 for te obaque and 255 for the transparent/invisible pixels in your TGA

Share this post


Link to post
Share on other sites
Just a post with my TGA loading code... Maybe the mistake is hidden in that??

My code ->

bool CreateTexture(char *fileName, GLuint textureArray[], GLuint textureID){

// If No File Name Is Given - Return
if (!fileName)
return false;

// The Texture Struct And File Holder
STextureTGA *iTGA = NULL;
FILE *fileTGA;

// If The File Won''t Open - Return
if (!(fileTGA = fopen(fileName, "rb")))
return false;

// Allocate Memory For The Struct
iTGA = new STextureTGA;

// If The Allocation Failed - Close The File And Return
if (!iTGA){

fclose(fileTGA);
return false;
}

// If The Image Can''t Be Loaded - Free The Memory, Close The File And Return
if (!LoadTGA(fileTGA, iTGA)){

delete[] iTGA;
fclose(fileTGA);
return false;
}

// Generate The Texture
glGenTextures(1, &textureArray[textureID]);
// Bind It
glBindTexture(GL_TEXTURE_2D, textureArray[textureID]);
// Build It
gluBuild2DMipmaps( GL_TEXTURE_2D, iTGA->iChannels, iTGA->iWidth,
iTGA->iHeight, iTGA->iType, GL_UNSIGNED_BYTE, iTGA->iData);

// Set The Quality Of The Texture Map
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);

// Free The Memory
delete[] iTGA->iData;
delete[] iTGA;

// Return True
return true;
}

bool LoadTGA(FILE *fileTGA, STextureTGA *iTGA){

// Variables
GLubyte TGAType = NULL;
GLubyte TGAHeader[6]= {0};
GLuint iSize, iDepth;

// Read The Type
fseek(fileTGA, 2, SEEK_SET);
if (!(fread(&TGAType, sizeof(GLubyte), 1, fileTGA)))
return false;

// Read The Image Header
fseek(fileTGA, 12, SEEK_SET);
if (!(fread(TGAHeader, sizeof(TGAHeader), 1, fileTGA)))
return false;

// Calculate The Width, Height And Depth Of The Image
iTGA->iWidth = TGAHeader[1] * 256 + TGAHeader[0];
iTGA->iHeight = TGAHeader[3] * 256 + TGAHeader[2];
iDepth = TGAHeader[4];

if (iTGA->iWidth <= 0 || iTGA->iHeight <= 0 || (iDepth != 24 && iDepth != 32))
return false;

// Check If The Image Is A 24 Or 32-Bit Image
if (iDepth == 24)
iTGA->iType = GL_RGB;

else
iTGA->iType = GL_RGBA;

// Calculate The Channels And The Size Of The Image
iTGA->iChannels = (iDepth / 8);
iSize = iTGA->iChannels * iTGA->iWidth * iTGA->iHeight;

// If It''s Uncompressed
if (TGAType == 2){

// Allocate Memory For The Image Data
iTGA->iData = new GLubyte[iSize];

// If The Allocation Failed - Return
if (!iTGA->iData)
return false;

// Read The Image Data
fseek(fileTGA, 18, SEEK_SET);
if (!(fread(iTGA->iData, 1, iSize, fileTGA))){

delete[] iTGA->iData;
return false;
}

// Make A Loop That Swaps The Colors From BGR To RGB
for (GLint sColor = 0; sColor < (GLint)iSize; sColor += iTGA->iChannels){

iTGA->iData[sColor] ^= iTGA->iData[sColor+2] ^=
iTGA->iData[sColor] ^= iTGA->iData[sColor+2];
}

// Check If A Vertical Flip Is Need
if ((TGAHeader[5] & 0x80) == 0x00){

if (!SwapTGA(iTGA)){

delete[] iTGA->iData;
return false;
}
}

// Return True
return true;
}

// If The Image Is Compressed
else if (TGAType == 10){

// Allocate Memory For The Image Data
iTGA->iData = new GLubyte[iSize];

// If The Allocation Failed - Return
if (!iTGA->iData)
return false;

// Make Variables
GLuint rleID = 0;
GLuint cPixel = 0;
GLuint cColor = 0;
// Allocate Memory For The Color Buffer
GLubyte *colorBuffer = new GLubyte[iTGA->iChannels];

// If The Allocation Failed - Free Memory And Return
if (!colorBuffer){

delete[] iTGA->iData;
return false;
}

// Jump To Where The Image Data Begins
fseek(fileTGA, 18, SEEK_SET);

// Load In All The Pixel Data
while (GLuint(iTGA->iHeight * iTGA->iWidth) > cPixel){

// Read In The Current Color Count
if (!(fread(&rleID, sizeof(GLubyte), 1, fileTGA))){

delete[] iTGA->iData;
delete[] colorBuffer;

return false;
}

// Check If There''s A Encoded String Of Colors
if (rleID < 128){

// Increase The Count By 1
rleID++;

// Go Through And Read All The Colors
while (rleID){

// Read The Current Color
if (!(fread(colorBuffer, iTGA->iChannels, 1, fileTGA))){

delete[] iTGA->iData;
delete[] colorBuffer;

return false;
}

// Assign The Current Pixel To The Pixel Array
iTGA->iData[cColor] = colorBuffer[2];
iTGA->iData[cColor + 1] = colorBuffer[1];
iTGA->iData[cColor + 2] = colorBuffer[0];

// If There''s A Fourth Channel - Assign One More For Alpha
if (iTGA->iChannels == 4)
iTGA->iData[cColor + 3] = colorBuffer[3];

// Increase The Current Pixel Read, Decrease The Amount Of Pixels Left
// Increase The Starting Point For The Next Pixel Read
cColor += iTGA->iChannels;
cPixel++;
rleID--;
}
}

else {

// Get The Color Count Needed To Be Read
rleID -= 127;

// Read The Current Color
if (!(fread(colorBuffer, iTGA->iChannels, 1, fileTGA))){

delete[] iTGA->iData;
delete[] colorBuffer;

return false;
}

// Read Pixels
while (rleID){

// Assign The Current Pixel To The Pixel Array
iTGA->iData[cColor] = colorBuffer[2];
iTGA->iData[cColor + 1] = colorBuffer[1];
iTGA->iData[cColor + 2] = colorBuffer[0];

// If There''s A Fourth Channel - Assign One More For Alpha
if (iTGA->iChannels == 4)
iTGA->iData[cColor + 3] = colorBuffer[3];

// Increase The Current Pixel Read, Decrease The Amount Of Pixels Left
// Increase The Starting Point For The Next Pixel Read
cColor += iTGA->iChannels;
cPixel++;
rleID--;
}
}
}

// Free Memory Used To Store The Colors
delete[] colorBuffer;

// Check If A Vertical Flip Is Need
if ((TGAHeader[5] & 0x80) == 0x00){

if (!SwapTGA(iTGA)){

delete[] iTGA->iData;

return false;
}
}

// Return True
return true;
}

else
return false;
}

bool SwapTGA(STextureTGA *iTGA){

// A Temp Variabel
GLubyte *bTemp;
// The Stride Or Row
GLuint iStride = iTGA->iWidth * iTGA->iChannels;
// Calculate The Half Height Of The Image
GLuint iHalf = iTGA->iHeight / 2;
// Allocate Memory For The Temp Variabel
bTemp = new GLubyte[iStride];

// If It Wasn''t Allocated - Return False
if (!bTemp)
return false;

for (GLuint i = 0; i < iHalf; i++){

// Calculate Where The Bottom Row - Which Isn''t Swapped - Is
GLuint iBottomRow = (iTGA->iHeight - 1 - i) * iStride;

// Copy The Top Row To The Temp Variabel
memcpy(bTemp, &iTGA->iData[i * iStride], iStride);
// Swap The Bottom Row With The Top Row
memcpy(&iTGA->iData[i * iStride], &iTGA->iData[iBottomRow], iStride);
// Swap The Bottom Row With The Top Row, Which Was Stored In The Temp
memcpy(&iTGA->iData[iBottomRow], bTemp, iStride);

}

// If The Temp Variabel Was Allocated - Free It
delete[] bTemp;

return true;
}

Share this post


Link to post
Share on other sites