Masking/Depth Testing Problem

Started by
6 comments, last by Xasz 15 years, 10 months ago
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
Advertisement
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.
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
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
So how do I find out which quads are further away?
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.
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
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?
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
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
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);                            // 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

This topic is closed to new replies.

Advertisement