Jump to content
  • Advertisement
Sign in to follow this  
Deliverance

Blending, textures, pixels and filtering

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

What i want: draw a textured quad with a texel pixel proportion of 1:1 and i want to see the final image as if i would rendered it with glDrawPixels. What goes wrong: it seems that when i draw the textured quad the image appears blurred and don't understand why. Here is a little demo: http://www.filecrunch.com/file/~aeo5b0 Here's the code i'm using when drawing the image with glDrawPixels:

    glDisable(GL_TEXTURE_2D);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glOrtho(0, 800, 0, 600, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_TEXTURE_2D);
    glRasterPos2f(200.0f-(mImage.GetWidth()>>1)+1, 300.0f-(mImage.GetHeight()>>1)+1);
    glDrawPixels(mImage.GetWidth(),
                mImage.GetHeight(),
                mImage.GetChannels() == 3 ? GL_RGB : GL_RGBA,
                GL_UNSIGNED_BYTE, mImage.GetPixelData());

    glPopMatrix();
    glMatrixMode(GL_PROJECTION);    
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);    
    glEnable(GL_TEXTURE_2D);


The code i'm using to draw the textured quad:
void CGameEngine::EnterOrtho()
{
    glDisable(GL_TEXTURE_2D);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glOrtho(0, 800, 0, 600, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
}

void CGameEngine::LeaveOrtho()
{
    glPopMatrix();
    glMatrixMode(GL_PROJECTION);    
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);    
    glEnable(GL_TEXTURE_2D);
}

void DrawQuad(const tTexturePortion &texp, CVector3D pos, float width, float height)
{
    float verts[8]={pos.x-width/2, pos.y-height/2,
                    pos.x+width/2, pos.y-height/2,
                    pos.x+width/2, pos.y+height/2,
                    pos.x-width/2, pos.y+height/2};
    
    glBindTexture(GL_TEXTURE_2D, texp.texID);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, verts);
    glTexCoordPointer(2, GL_FLOAT, 0, texp.texCoords);
    glEnable(GL_TEXTURE_2D);
    glDrawArrays(GL_QUADS, 0, 4);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
    
CGameEngine::EnterOrtho();
glTranslatef(200.0f ,300.0f, 0.0f);
DrawQuad(texAnims.anim.GetCurrTexPortion(), texAnims.pos ,250, 91);
CGameEngine::LeaveOrtho();

And the code which loads a texture:
#include "CTexture.h"
#include "portability.h"
#include "CLogger.h"

void CTexture::SetParameters(int target, int flags)
{
    if (flags & NEAREST)
    {
        glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    }else
    if (flags & LINEAR)
    {
        glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    }else
    if (flags & LINEAR_MIPMAP_LINEAR)
    {
        glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    }
        
    if (flags & ANISOTROPY_MAX)
    {
        glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy);
    }
    else
    if (flags & ANISOTROPY_2)
        glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0f);
    else
    if (flags & ANISOTROPY_4)
        glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4.0f);
    else
    if (flags & ANISOTROPY_Cool
        glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8.0f);
    else
    if (flags & ANISOTROPY_16)
        glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f);
    
    if (flags & REPEAT)
    {
        glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
    }else
    if (flags & CLAMP)
    {
        glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP);
        glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP);
    }
    if (flags & CLAMP_TO_EDGE)
    {
        glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    }    
        
    if (flags & GENERATE_MIPMAP_SGIS)
        glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);    
}
int CTexture::LoadTexture(char *fileName, char *pakName, int flags, texInfo &newInfo)            
{    
    int tex;
    for ( tex = 0; tex fileName);
    if (image->pakName[0]!='�')
    {
        strcpy(newInfo.pakName, image->pakName);        
    }                                    
    newInfo.flags = flags;
    SetParameters(target, flags);        
                
    int dataType = GL_UNSIGNED_BYTE;    
    int internalFormat = image->components == 3 ? GL_RGB : GL_RGBA;
    if ( flags & LINEAR_MIPMAP_LINEAR )
    {
        if ( target == GL_TEXTURE_2D )
            gluBuild2DMipmaps( target, image->components, image->width, image->height, internalFormat, dataType, image->pixelData);
        else
            gluBuild1DMipmaps( target, image->components, image->width, internalFormat, dataType, image->pixelData);
    }
    else    
    {
        glTexImage2D( target, 0, image->components, image->width, image->height, 0, internalFormat,
                dataType, image->pixelData);    
    }    
    textureList.push_back(newInfo);
    
    return newInfo.texID;    
}
                                                
int CTexture::CreateTexture(int width, int height, int components, int flags, unsigned char *pixelData)
{        
    int target = 0;
    int dataType = 0;
    int internalFormat = 0;
    texInfo newInfo = ;

    flags & TEXTURE_1D ? target = GL_TEXTURE_1D : target = GL_TEXTURE_2D;
        
    if (flags & TEXTURE_1D)
        glEnable(GL_TEXTURE_1D);
    else
        glEnable(GL_TEXTURE_2D);
        
    glGenTextures(1, &newInfo.texID);        
    glBindTexture(target, (GLuint)newInfo.texID);
    
    sprintf(newInfo.fileName, "__$#$Unique@#$%d", emptyCount);
    emptyCount ++;
    newInfo.flags = flags;
    SetParameters(target, flags);        
    
    components==3 ? internalFormat = GL_RGB : internalFormat = GL_RGBA;
                
    if ( flags & FORMAT_UNSIGNED_BYTE )
        dataType = GL_UNSIGNED_BYTE;
    else
    if ( flags & FORMAT_FLOAT )
    {
//        components==3 ? dataType = GL_FLOAT_RGB_NV : dataType = GL_FLOAT_RGBA_NV;
        dataType = GL_FLOAT;
    }
            
    if ( flags & LINEAR_MIPMAP_LINEAR )
    {
        if ( target == GL_TEXTURE_2D )
            gluBuild2DMipmaps( target, components, width, height, internalFormat, dataType, pixelData);
        else
            gluBuild1DMipmaps( target, components, width, internalFormat, dataType, pixelData);
    }
    else
        glTexImage2D( target, 0, components, width, height, 0, internalFormat,
                dataType, pixelData);    
        
    textureList.push_back(newInfo);    
    
    return newInfo.texID;
}
int CTexture::Load(char *fileName, char *pakName, int flags)
{    
    texInfo newInfo = ;
    int texID = LoadTexture(fileName, pakName, flags, newInfo);
    
    if (texID)
        return texID;
        
    if (!newInfo.texID)
        return 0;
    
    textureList.push_back(newInfo);    
    return newInfo.texID;            
}

tTexturePortion CTexture::Load(char *fileName, char *pakName, char* taiFile, int flags)
{
    tTexturePortion ret;
    
    FILE *f = fopen(taiFile, "rt");
    char file[255];
    char atlasFileName[255];
    char atlasType[10];
    int atlasidx;
    float wOffset, hOffset, dOffset, width, height;
    while(!feof(f))
    {        
        fscanf(f, "%s %s %d %s %f %f %f %f %fn", file, atlasFileName, &atlasidx, atlasType,
            &wOffset, &hOffset, &dOffset, &width, &height);
            //printf("--%s %sn", file, fileName);
        if (strcmp(file, fileName)==0)
        {            
            ret.texID = Load(atlasFileName, pakName, flags);
            printf("%s %s afn=%s %dn",file, fileName, atlasFileName, ret.texID);
            //printf("ID is:%d %s n",ret.texID, fileName, file, atlasFileName,
            // wOffset, hOffset, width, height);    
                        
            hOffset = 1.0f - height - hOffset;
            
            ret.texCoords[0][0] = wOffset;
            ret.texCoords[0][1] = hOffset;
            
            ret.texCoords[1][0] = wOffset+width;
            ret.texCoords[1][1] = hOffset;

            ret.texCoords[2][0] = wOffset+width;
            ret.texCoords[2][1] = hOffset+height;

            ret.texCoords[3][0] = wOffset;
            ret.texCoords[3][1] = hOffset+height;
            break;
        }
    }
    fclose(f);

    return ret;
}
int CTexture::Reload(char *fileName, int flags)
{
    int tex;
    for ( tex = 0; tex < textureList.size(); tex ++)
    {        
        if ( STRCASECMP(fileName, textureList[tex].fileName) == 0 && memcmp("__$#$Unique", textureList[tex].fileName, 11)!=0)
        {     
            if (textureList[tex].flags == flags)
            {                
                return textureList[tex].texID;
            }
            else
            {    
                LoadTexture(fileName, textureList[tex].pakName[0]=='&#65533;' ? NULL : textureList[tex].pakName,
                        flags, textureList[tex]);                            
                return textureList[tex].texID;
            }
        }
    }
    
    return 0;
}

void CTexture::ReloadAll(int flags)
{
    int tex;
    for ( tex = 0; tex < textureList.size(); tex ++)
    {
        Reload(textureList[tex].fileName, flags);
    }        
}

void CTexture::Free()
{         
    int texID;
    for( texID = 0; texID < textureList.size(); texID++ )
    {    
        glDeleteTextures(1, &textureList[texID].texID);
    }
    textureList.clear();
}

Share this post


Link to post
Share on other sites
Advertisement
I don't think this is what you want:


float verts[8]={pos.x-width/2, pos.y-height/2,
pos.x+width/2, pos.y-height/2,
pos.x+width/2, pos.y+height/2,
pos.x-width/2, pos.y+height/2};


and


DrawQuad(texAnims.anim.GetCurrTexPortion(), texAnims.pos ,250, 91);


It produces something like that:


float verts[8]={pos.x-125, pos.y-45.5,
pos.x+125, pos.y-45.5,
pos.x+125, pos.y+45.5,
pos.x-125, pos.y+45.5};


Which positions your quad between your pixels. Maybe this even draws the quad one pixel too wide and one pixel too high, but I'm not sure about that.

It would help to see the problem, but I can't get your demo to run. Do you have a screenshot?

Share this post


Link to post
Share on other sites
Okay here are the screenshots:
http://img90.imageshack.us/img90/7971/texturesvv5.png
http://img85.imageshack.us/img85/9973/pixelsmc8.png

Notice that when rendering with textures the image is blurred.

Share this post


Link to post
Share on other sites
Hmm.... Ok, try this:


void DrawQuad(const tTexturePortion &texp, CVector3D pos, float width, float height)
{
int left, top, right, bottom;

left = pos.x-width/2;
top = pos.y-height/2;

right = left + width;
bottom = top + height;

float verts[8]={left, top,
right, top,
right, bottom,
left, bottom};

...

Share this post


Link to post
Share on other sites
I managed to solve the problem. So here's what was happening: I created a texture atlas with nvidia's atlas tool but it seems that this program resizes the input images to the closest power of two dimensions. So my input images having the dimensions 250x91 were resized at 256x128 which is freaky. I was rendering a portion of a texture of 256x128 to a quad with the dimensions 250x91 so that's why the blur appeared. So i've taken some time and managed to created my own atlas creation tool that does not resize the input images. Now i can obtain what i want. Thank you all!

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!