Alpha blending on a texture
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;
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
you blend function is correct
make sure you use 0 for te obaque and 255 for the transparent/invisible pixels in your TGA
When I put my texture map on the quad, and uses alpha blending nothing is shown at all?
What could be wrong? I have tried both mipmaps and ordinary texture maps
What could be wrong? I have tried both mipmaps and ordinary texture maps
Does it show up when the alpha blending is disabled?
Height Map Editor | Eternal Lands | Fast User Directory
Height Map Editor | Eternal Lands | Fast User Directory
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, iStride);<br> // Swap The Bottom Row With The Top Row<br> memcpy(&iTGA->iData, &iTGA->iData[iBottomRow], iStride);<br> // Swap The Bottom Row With The Top Row, Which Was Stored In The Temp<br> memcpy(&iTGA->iData[iBottomRow], bTemp, iStride);<br><br> }<br><br> // If The Temp Variabel Was Allocated - Free It<br> delete[] bTemp;<br><br> return true;<br>}<br><br>
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, iStride);<br> // Swap The Bottom Row With The Top Row<br> memcpy(&iTGA->iData, &iTGA->iData[iBottomRow], iStride);<br> // Swap The Bottom Row With The Top Row, Which Was Stored In The Temp<br> memcpy(&iTGA->iData[iBottomRow], bTemp, iStride);<br><br> }<br><br> // If The Temp Variabel Was Allocated - Free It<br> delete[] bTemp;<br><br> return true;<br>}<br><br>
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement