Sign in to follow this  

Masking/Depth Testing Problem

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

Basically I'm having to disable depth testing to us masking, doing so is causing... well, depth testing to not be done. I just need to turn it off to mask (or do I?) and that's screwing with everything. Here's my code
void Character::show(void)
{

	glPushMatrix();
	glDepthFunc(GL_EQUAL);
	glEnable(GL_BLEND);
	glDisable(GL_DEPTH_TEST);
	glBlendFunc(GL_DST_COLOR,GL_ZERO);	
	BindMask();
	glBegin(GL_QUADS);
		glTexCoord2f(frameSize*mult*(frame-1)   , 1.0f-37*mult); glVertex3f(-0.9f, 0.0f,  0.0f);
		glTexCoord2f(frameSize*mult*frame, 1.0f-37*mult);		 glVertex3f( 0.9f, 0.0f,  0.0f);
		glTexCoord2f(frameSize*mult*frame, 1.0f        );		 glVertex3f( 0.9f, 0.0f,  1.5f);
		glTexCoord2f(frameSize*mult*(frame-1)   , 1.0f        ); glVertex3f(-0.9f, 0.0f,  1.5f);
	glEnd();
	glBlendFunc(GL_ONE, GL_ONE);
	BindTexture();
	glBegin(GL_QUADS);
		glTexCoord2f(frameSize*mult*(frame-1)   , 1.0f-37*mult); glVertex3f(-0.9f, 0.0f,  0.0f);
		glTexCoord2f(frameSize*mult*frame, 1.0f-37*mult);		 glVertex3f( 0.9f, 0.0f,  0.0f);
		glTexCoord2f(frameSize*mult*frame, 1.0f        );		 glVertex3f( 0.9f, 0.0f,  1.5f);
		glTexCoord2f(frameSize*mult*(frame-1)   , 1.0f        ); glVertex3f(-0.9f, 0.0f,  1.5f);
	glEnd();
	glEnable(GL_DEPTH_TEST);
	glDisable(GL_BLEND);
	glPopMatrix();
}
It's causing certain "characters" to be drawn in front of others randomly. Some are drawn "int front" of others properly, but others aren't. I know this has to be a simple fix

Share this post


Link to post
Share on other sites
glBlendFunc(GL_DST_COLOR,GL_ZERO);
This is the the kind of blending that would require sorting polygons back to front because the result depends on the order in which you render.

Share this post


Link to post
Share on other sites
I'm assuming that would be difficult : /



I gave transparent TGA loading a shot, and while it makes masking a lot easier, I have another problem in that when the transparent area of one polygon overlaps another, I see through BOTH. The transparency of the object in front is causing transparency of an object behind it that also uses transparency, in an area that's supposed to be opaque (and is as soon as the transparent portion of the object in front of it moves)

Lemme try and show an example:
o's are opaque, ___ is transparent
___ooo___
ooooooooo
ooooooooo
___ooo___


When one gets in front of another, the x's are where it's opaque but not supposed to be
___ooo___
oooxxxooo
ooooooooo
___oooooo

Here's a link to a screenshot of the issue
http://www.partyeastcarolina.com/photos/fullsize/271704.jpg

Share this post


Link to post
Share on other sites
This means glBlendFunc(GL_DST_COLOR,GL_ZERO)
source_color * destination_color + 0
so it doesn't use the alpha component. You probably want glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
which means source_color * source_alpha + destination_color * (1 - source_alpha)

For sorting, if the modelview matrix is identity, you can just use the z values of the vertices otherwise multiply by the modelview matrix.

Share this post


Link to post
Share on other sites
Yeah, but unfortunately I need to be able to rotate and what not. There's no command to get to the depth of an object using the current matrix with its position?

Share this post


Link to post
Share on other sites
I use my own lib for this kind of thing
http://www.geocities.com/vmelkon/glhlibrary.html

You would need to look into glhMultiplyMatrixByVector4by4f_1, glhMultiplyMatrixByVector4by4f_2, glhMultiplyMatrixByVector4by4f_3

and there are also SSE versions when you need to transform a LOT of vertices
glhMultiplyMatrixByVector4by4f_SSE_Aligned_1 and glhMultiplyMatrixByVector4by4f_SSE_Aligned_WarmCache_1

Share this post


Link to post
Share on other sites
Found an easy solution, posting for reference (from NeHe's Ipicture Basecode):

#pragma comment(lib, "oleaut32.lib");
#include <olectl.h>
#include <math.h>






int BuildTexture(char *szPathName, GLuint &texid) // Load Image And Convert To A Texture
{
HDC hdcTemp; // The DC To Hold Our Bitmap
HBITMAP hbmpTemp; // Holds The Bitmap Temporarily
IPicture *pPicture; // IPicture Interface
OLECHAR wszPath[MAX_PATH+1]; // Full Path To Picture (WCHAR)
char szPath[MAX_PATH+1]; // Full Path To Picture
long lWidth; // Width In Logical Units
long lHeight; // Height In Logical Units
long lWidthPixels; // Width In Pixels
long lHeightPixels; // Height In Pixels
GLint glMaxTexDim ; // Holds Maximum Texture Size

if (strstr(szPathName, "http://")) // If PathName Contains http:// Then...
{
strcpy(szPath, szPathName); // Append The PathName To szPath
}
else // Otherwise... We Are Loading From A File
{
GetCurrentDirectory(MAX_PATH, szPath); // Get Our Working Directory
strcat(szPath, "\\"); // Append "\" After The Working Directory
strcat(szPath, szPathName); // Append The PathName
}

MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH); // Convert From ASCII To Unicode
HRESULT hr = OleLoadPicturePath(wszPath, 0, 0, 0, IID_IPicture, (void**)&pPicture);

if(FAILED(hr)) // If Loading Failed
return FALSE; // Return False

hdcTemp = CreateCompatibleDC(GetDC(0)); // Create The Windows Compatible Device Context
if(!hdcTemp) // Did Creation Fail?
{
pPicture->Release(); // Decrements IPicture Reference Count
return FALSE; // Return False (Failure)
}

glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glMaxTexDim); // Get Maximum Texture Size Supported

pPicture->get_Width(&lWidth); // Get IPicture Width (Convert To Pixels)
lWidthPixels = MulDiv(lWidth, GetDeviceCaps(hdcTemp, LOGPIXELSX), 2540);
pPicture->get_Height(&lHeight); // Get IPicture Height (Convert To Pixels)
lHeightPixels = MulDiv(lHeight, GetDeviceCaps(hdcTemp, LOGPIXELSY), 2540);

// Resize Image To Closest Power Of Two
if (lWidthPixels <= glMaxTexDim) // Is Image Width Less Than Or Equal To Cards Limit
lWidthPixels = 1 << (int)floor((log((double)lWidthPixels)/log(2.0f)) + 0.5f);
else // Otherwise Set Width To "Max Power Of Two" That The Card Can Handle
lWidthPixels = glMaxTexDim;

if (lHeightPixels <= glMaxTexDim) // Is Image Height Greater Than Cards Limit
lHeightPixels = 1 << (int)floor((log((double)lHeightPixels)/log(2.0f)) + 0.5f);
else // Otherwise Set Height To "Max Power Of Two" That The Card Can Handle
lHeightPixels = glMaxTexDim;

// Create A Temporary Bitmap
BITMAPINFO bi = {0}; // The Type Of Bitmap We Request
DWORD *pBits = 0; // Pointer To The Bitmap Bits

bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // Set Structure Size
bi.bmiHeader.biBitCount = 32; // 32 Bit
bi.bmiHeader.biWidth = lWidthPixels; // Power Of Two Width
bi.bmiHeader.biHeight = lHeightPixels; // Make Image Top Up (Positive Y-Axis)
bi.bmiHeader.biCompression = BI_RGB; // RGB Encoding
bi.bmiHeader.biPlanes = 1; // 1 Bitplane

// Creating A Bitmap This Way Allows Us To Specify Color Depth And Gives Us Imediate Access To The Bits
hbmpTemp = CreateDIBSection(hdcTemp, &bi, DIB_RGB_COLORS, (void**)&pBits, 0, 0);

if(!hbmpTemp) // Did Creation Fail?
{
DeleteDC(hdcTemp); // Delete The Device Context
pPicture->Release(); // Decrements IPicture Reference Count
return FALSE; // Return False (Failure)
}

SelectObject(hdcTemp, hbmpTemp); // Select Handle To Our Temp DC And Our Temp Bitmap Object

// Render The IPicture On To The Bitmap
pPicture->Render(hdcTemp, 0, 0, lWidthPixels, lHeightPixels, 0, lHeight, lWidth, -lHeight, 0);

// Convert From BGR To RGB Format And Add An Alpha Value Of 255
for(long i = 0; i < lWidthPixels * lHeightPixels; i++) // Loop Through All Of The Pixels
{
BYTE* pPixel = (BYTE*)(&pBits[i]); // Grab The Current Pixel
BYTE temp = pPixel[0]; // Store 1st Color In Temp Variable (Blue)
pPixel[0] = pPixel[2]; // Move Red Value To Correct Position (1st)
pPixel[2] = temp; // Move Temp Value To Correct Blue Position (3rd)

// This Will Make Any Black Pixels, Completely Transparent (You Can Hardcode The Value If You Wish)
if ((pPixel[0]==0) && (pPixel[1]==0) && (pPixel[2]==0)) // Is Pixel Completely Black
pPixel[3] = 0; // Set The Alpha Value To 0
else // Otherwise
pPixel[3] = 255; // Set The Alpha Value To 255
}

glGenTextures(1, &texid); // Create The Texture

// Typical Texture Generation Using Data From The Bitmap
glBindTexture(GL_TEXTURE_2D, texid); // Bind To The Texture ID
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // (Modify This For The Type Of Filtering You Want)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // (Modify This For The Type Of Filtering You Want)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lWidthPixels, lHeightPixels, 0, GL_RGBA, GL_UNSIGNED_BYTE, pBits); // (Modify This If You Want Mipmaps)

DeleteObject(hbmpTemp); // Delete The Object
DeleteDC(hdcTemp); // Delete The Device Context

pPicture->Release(); // Decrements IPicture Reference Count

return TRUE; // Return True (All Good)
}





In your initialization code:

glAlphaFunc(GL_GREATER,0.1f);
glEnable(GL_ALPHA_TEST);



And then just use

BuildTexture("Data/OldMan.bmp",texture[0])



Where texture[0] is a GLuint

This makes any black area in the bmp file transparent simply by binding the texture. It's magic

Share this post


Link to post
Share on other sites

This topic is 3479 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this