Textures displaying red background

For some reason, when I draw my textures, the clear area retains a red background. Also, blending isn’t occurring.

[ATTACH=CONFIG]151[/ATTACH]

//main.cpp
#include "SDL/SDL.h"
#include "SDL/SDL_opengl.h"
#include "texture.h"
#include "utilities.h"
#include "animation.h"
#include "FTGL/ftgl.h"
#include "widgets.h"
#include <sstream>
#include "SDL/SDL_Image.h"
#include <cmath>
#include "iostream"

int main( int argc, char* args[] )
{
    freopen("CON", "w", stdout);
    freopen("CON", "w", stderr);

    //Start SDL,

    if( SDL_Init( SDL_INIT_EVERYTHING ) != 0 )
    {
        printf("SDL failed to initialize: %s
", SDL_GetError());
        return 1;
    }

    //Set up screen

    SDL_Surface* screen;

    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);

    if((screen = SDL_SetVideoMode( 900, 600, 32, SDL_OPENGL)) == NULL)
    {
     printf("Error creating SDL surface: %s
", SDL_GetError());
    }

    //3d options
    glEnable( GL_TEXTURE_2D );
    glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
    glEnable(GL_BLEND);
    glAlphaFunc(GL_NOTEQUAL, 1);
    glEnable(GL_ALPHA_TEST);
    glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f);
    glViewport( 0, 0, 900, 600 );
    glClear( GL_COLOR_BUFFER_BIT );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glOrtho(0.0f, 900, 600, 0.0f, -1.0f, 1.0f);
    glMatrixMode( GL_MODELVIEW );
    glScalef(1, -1, 1);
    glDisable(GL_DEPTH_TEST);
    glLoadIdentity();

    //debug text
    FTGLPixmapFont font("gfx/font.ttf");

    // If something went wrong, bail out.
    if(font.Error())
    {
                    fprintf(stderr, "Error loading font: %d", font.Error());
    return -1;
    }

    // Set the font size and render a small text.
    font.FaceSize(20);

    //main app class instantiation

    input oInput;
    widgetUI oWidgetUI;

    SDL_Rect rectBar;
    rectBar.x = 10;
    rectBar.y = 10;
    rectBar.w = 300;
    rectBar.h = 28;

    oWidgetUI.addSlider(std::string("frameSlider"), IMG_Load("gfx/slider_bar.tga"), IMG_Load("gfx/slider_slider.tga"), SDL_Rect(), 0, 0, 9);

    //main loop
    bool quit = false; //loop quit var

    while(quit == false)
    {
         //quit if necessary
         quit = oInput.poll();

         //clear the buffer
         glClear(GL_COLOR_BUFFER_BIT);

         //gui logic/render
         oWidgetUI.handle();

         //flip
         SDL_GL_SwapBuffers();
     }

    //Quit SDL
    SDL_Quit();

    return 0;
}

//texture.h
#pragma once
#include "SDL/SDL.h"
#include "SDL/SDL_opengl.h"
#include "utilities.h"
#include <cmath>

class texture
{
      private:
        int glTexture;
        SDL_Rect imageRect;
        SDL_Rect textureRect;
        int paddingW;
        int paddingH;
        void initList();
        static bool listInitialized;
        static GLuint textureBank[256];
        static bool textureFree[256];
        static int numTextures;

      public:
        texture();
        ~texture();
        texture(SDL_Surface *rawSurface);
        int getTextureIndex();
        void drawTexture(int x, int y);
        SDL_Rect getImageRect();
};

//texture.cpp   
    #include "texture.h"
    #include "iostream"

    GLuint texture::textureBank[256] = {};
    bool texture::textureFree[256] = {};
    int texture::numTextures = 0;
    bool texture::listInitialized = false;

    void texture::initList()
    {
        glGenTextures( 256, textureBank);
        std::fill_n(textureFree, 256, true);
        listInitialized = true;
    }

   void texture::drawTexture(int x, int y)
{
    x = x - paddingW;
     // Bind the texture to which subsequent calls refer to
    glBindTexture( GL_TEXTURE_2D, textureBank[glTexture] );
    glColor4f(1,1,1,1);
    glBegin( GL_QUADS );
        //Bottom-left vertex (corner)
        glTexCoord2i( 0, 0 );
        glVertex3f( x, (y + textureRect.h), 0.0f );

        //Bottom-right vertex (corner)
        glTexCoord2i( 1, 0 );
        glVertex3f( (x + textureRect.w), (y + textureRect.h), 0.f );

        //Top-right vertex (corner)
        glTexCoord2i( 1, 1 );
        glVertex3f( (x + textureRect.w), y, 0.f );

        //Top-left vertex (corner)
        glTexCoord2i( 0, 1 );
        glVertex3f( x, y, 0.f );
    glEnd();
}

    int texture::getTextureIndex()
    {
           return glTexture;
    }

    texture::texture()
    {
        if(listInitialized == false)
        {
            initList();

        }

    }

    texture::~texture()
    {
        numTextures--;
        textureFree[glTexture] = true;
    }

    SDL_Rect texture::getImageRect()
    {
             return imageRect;
    }

    texture::texture(SDL_Surface *rawSurface)
    {
         if(listInitialized == false)
        {
            initList();

        }

        for(int a = 0; a < 256; a++)
        {
            if(textureFree[a] == true)
            {

                glTexture = a;
                numTextures++;
                textureFree[a] = false;
                break;
            }
        }

        SDL_PixelFormat pixF = *rawSurface->format;
        std::cout << "BPP : " << (int) pixF.BytesPerPixel;

        SDL_Surface *surface;

        textureRect.w = nextPowerOfTwo(rawSurface->w);
        textureRect.h = nextPowerOfTwo(rawSurface->h);
        textureRect.x = 0;
        textureRect.y = 0;

        imageRect.w = rawSurface->w;
        imageRect.h = rawSurface->h;
        imageRect.x = 0;
        imageRect.y = 0;

        paddingW = textureRect.w - imageRect.w;
        paddingH = textureRect.h - imageRect.h;

        //where within the texture surface is the actual image?
        SDL_Rect rectDestination;
        rectDestination.w = imageRect.w;
        rectDestination.h = imageRect.h;
        rectDestination.x = paddingW;
        rectDestination.y = paddingH;

        GLint  nOfColors = rawSurface->format->BytesPerPixel;
        GLenum texture_format;

         if (nOfColors == 4)     // contains an alpha channel
            {
                    if (rawSurface->format->Rmask == 0x000000ff)
                    {
                         std::cout << "format RGBA
";
                         texture_format = GL_RGBA;
                    }
                    else
                    {
                        std::cout << "format BGRA
";
                        texture_format = GL_BGRA;
                    }

            } else if (nOfColors == 3)     // no alpha channel
            {
                    if (rawSurface->format->Rmask == 0x000000ff)
                    {
                        std::cout << "format RGB
";
                            texture_format = GL_RGB;

                    }
                    else
                    {
                        std::cout << "format BGR
";
                        texture_format = GL_BGR;
                    }

            }

        surface = SDL_CreateRGBSurface(SDL_SWSURFACE, textureRect.w , textureRect.h , 32, rawSurface->format->Rmask, rawSurface->format->Gmask, rawSurface->format->Bmask, rawSurface->format->Amask);
        SDL_FillRect(surface, &textureRect, SDL_MapRGBA(surface->format, 255, 0, 0, 9));
        SDL_SetAlpha(rawSurface, 0, SDL_ALPHA_OPAQUE);
        SDL_SetAlpha(surface, 0, SDL_ALPHA_OPAQUE);
        SDL_BlitSurface(rawSurface, &imageRect, surface, &rectDestination);
        SDL_SetAlpha(rawSurface, SDL_SRCALPHA, 0);
        SDL_SetAlpha(surface, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);

        glBindTexture(GL_TEXTURE_2D, textureBank[glTexture]);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 4, surface->w, surface->h, 0, texture_format, GL_UNSIGNED_BYTE, surface->pixels);

        if(surface)
           {SDL_FreeSurface( surface );}
    }

//widgets.h
#include "SDL/SDL.h"
#include "SDL/SDL_opengl.h"
#include "texture.h"
#include "utilities.h"
#include "input.h"
#include "vector"
#include "string"
#include "iostream"

class widget
{
    protected:
        static input *pInput;

        SDL_Rect rectWidget;

        std::string key;

        int z;

    public:
        virtual void drawWidget()
        {
            std::cout << "WTF";
            return;
        };

        void setZ(int newZ);
        int getZ();

        void setRect(SDL_Rect rectToSet);
        SDL_Rect getRect();
};

class wSliderBar: public widget
{
    private:

        texture* barTexture;
        texture* sliderTexture;

        int min;
        int max;
        int curValue;
        SDL_Rect rectBar;

    public:

        wSliderBar();
        wSliderBar(std::string setKey, SDL_Surface* setBarSurf, SDL_Surface* setSliderSurf, SDL_Rect setRectBar, int setZ, int setMin, int setMax, int setCurrent = NULL);
        ~wSliderBar();
        void drawWidget();
};

class widgetUI
{
    private:

        std::vector<widget*> widgets;

    public:
        void handle();
        widgetUI();
        ~widgetUI();
        widget* getWidget(std::string widgetKey);
        void addSlider(std::string setKey, SDL_Surface* setBarSurf, SDL_Surface* setSliderSurf, SDL_Rect setRectBar, int setZ, int setMin, int setMax, int setCurrent = NULL);

};

widgets.cpp
#include "widgets.h"

widget* widgetUI::getWidget(std::string widgetKey)
{
    return NULL;
}

void widgetUI::addSlider(std::string setKey, SDL_Surface *setBarSurf, SDL_Surface *setSliderSurf, SDL_Rect setRectBar, int setZ, int setMin, int setMax, int setCurrent)
{
    widgets.push_back(new wSliderBar(setKey, setBarSurf, setSliderSurf, setRectBar, setZ, setMin, setMax, setCurrent));
}

void widgetUI::handle()
{
    for(int i = 0; i < (int)widgets.size(); i++)
    {
       widgets.at(i)->drawWidget();

       std::cout << "I DREW A WIDGET LOLZ " << i << "
";
    }

}

void wSliderBar::drawWidget()
{
    //draw background/bar
    barTexture->drawTexture(rectWidget.x, rectWidget.y);
    std::cout << "x: " << rectWidget.x << " y: " << rectWidget.y;
    //draw slider!
    //sliderTexture->drawTexture(rectWidget.x,rectWidget.y);
}

wSliderBar::wSliderBar()
{

}

wSliderBar::wSliderBar(std::string setKey, SDL_Surface* setBarSurf, SDL_Surface* setSliderSurf, SDL_Rect setRectBar, int setZ, int setMin, int setMax, int setCurrent)
{
    key = setKey;
    barTexture  = new texture(setBarSurf);
    sliderTexture = new texture(setSliderSurf);
    rectBar = setRectBar;
    rectWidget = setRectBar;
    z = setZ;
    min = setMin;
    max = setMax;
    curValue = setCurrent;
}

wSliderBar::~wSliderBar()
{

}

widgetUI::widgetUI()
{

}

widgetUI::~widgetUI()
{

}

void widget::setZ(int newZ)
{
    z = newZ;
}

int widget::getZ()
{
    return z;
}

void widget::setRect(SDL_Rect rectToSet)
{
    rectWidget = rectToSet;
}

SDL_Rect widget::getRect()
{
    return rectWidget;
}

I figured I would clarify as I have not yet received a response :slight_smile:

Here are my source image files:

http://dl.dropbox.com/u/31186025/slider_bar.tga
http://dl.dropbox.com/u/31186025/slider_slider.tga

Here are all my OpenGL options:

glEnable( GL_TEXTURE_2D );
    glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
    glEnable(GL_BLEND);
    glAlphaFunc(GL_NOTEQUAL, 1);
    glEnable(GL_ALPHA_TEST);
    glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f);
    glViewport( 0, 0, 900, 600 );
    glClear( GL_COLOR_BUFFER_BIT );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glOrtho(0.0f, 900, 600, 0.0f, -1.0f, 1.0f);
    glMatrixMode( GL_MODELVIEW );
    glScalef(1, -1, 1);
    glDisable(GL_DEPTH_TEST);
    glLoadIdentity();

Here is my texture loading/initialization code:

    texture::texture(SDL_Surface *rawSurface)
    {
         if(listInitialized == false)
        {
            initList();

        }

        for(int a = 0; a < 256; a++)
        {
            if(textureFree[a] == true)
            {

                glTexture = a;
                numTextures++;
                textureFree[a] = false;
                break;
            }
        }

        SDL_PixelFormat pixF = *rawSurface->format;
        std::cout << "BPP : " << (int) pixF.BytesPerPixel;

        SDL_Surface *surface;

        textureRect.w = nextPowerOfTwo(rawSurface->w);
        textureRect.h = nextPowerOfTwo(rawSurface->h);
        textureRect.x = 0;
        textureRect.y = 0;

        imageRect.w = rawSurface->w;
        imageRect.h = rawSurface->h;
        imageRect.x = 0;
        imageRect.y = 0;

        paddingW = textureRect.w - imageRect.w;
        paddingH = textureRect.h - imageRect.h;

        //where within the texture surface is the actual image?
        SDL_Rect rectDestination;
        rectDestination.w = imageRect.w;
        rectDestination.h = imageRect.h;
        rectDestination.x = paddingW;
        rectDestination.y = paddingH;

        GLint  nOfColors = rawSurface->format->BytesPerPixel;
        GLenum texture_format;

         if (nOfColors == 4)     // contains an alpha channel
            {
                    if (rawSurface->format->Rmask == 0x000000ff)
                    {
                         std::cout << "format RGBA
";
                         texture_format = GL_RGBA;
                    }
                    else
                    {
                        std::cout << "format BGRA
";
                        texture_format = GL_BGRA;
                    }

            } else if (nOfColors == 3)     // no alpha channel
            {
                    if (rawSurface->format->Rmask == 0x000000ff)
                    {
                        std::cout << "format RGB
";
                            texture_format = GL_RGB;

                    }
                    else
                    {
                        std::cout << "format BGR
";
                        texture_format = GL_BGR;
                    }

            }

        surface = SDL_CreateRGBSurface(SDL_SWSURFACE, textureRect.w , textureRect.h , 32, rawSurface->format->Rmask, rawSurface->format->Gmask, rawSurface->format->Bmask, rawSurface->format->Amask);
        SDL_FillRect(surface, &textureRect, SDL_MapRGBA(surface->format, 255, 0, 0, 9));
        SDL_SetAlpha(rawSurface, 0, SDL_ALPHA_OPAQUE);
        SDL_SetAlpha(surface, 0, SDL_ALPHA_OPAQUE);
        SDL_BlitSurface(rawSurface, &imageRect, surface, &rectDestination);
        SDL_SetAlpha(rawSurface, SDL_SRCALPHA, 0);
        SDL_SetAlpha(surface, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);

        glBindTexture(GL_TEXTURE_2D, textureBank[glTexture]);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, 4, surface->w, surface->h, 0, texture_format, GL_UNSIGNED_BYTE, surface->pixels);

        if(surface)
           {SDL_FreeSurface( surface );}
    }

and finally, rendering…

   void texture::drawTexture(int x, int y)
{
    x = x - paddingW;
     // Bind the texture to which subsequent calls refer to
    glBindTexture( GL_TEXTURE_2D, textureBank[glTexture] );
    glColor4f(1,1,1,1);
    glBegin( GL_QUADS );
        //Bottom-left vertex (corner)
        glTexCoord2i( 0, 0 );
        glVertex3f( x, (y + textureRect.h), 0.0f );

        //Bottom-right vertex (corner)
        glTexCoord2i( 1, 0 );
        glVertex3f( (x + textureRect.w), (y + textureRect.h), 0.f );

        //Top-right vertex (corner)
        glTexCoord2i( 1, 1 );
        glVertex3f( (x + textureRect.w), y, 0.f );

        //Top-left vertex (corner)
        glTexCoord2i( 0, 1 );
        glVertex3f( x, y, 0.f );
    glEnd();
}

And my output…

Halp :slight_smile: Thanks

I guess you are rendering a bunch of quads on your screen, although it isn’t clear to me how many you are rendering.
You should check to see which one is drawing as a red quad and perhaps check what textureID it is using and if it is valid.
You can also use GLIntercept or some debugging tool to take screen captures for every draw call.

http://www.opengl.org/wiki/Debugging_Tools

Also, any reason why you are only clearing the color. Why don’t you clear the depth buffer as well?

[QUOTE=V-man;1237370]I guess you are rendering a bunch of quads on your screen, although it isn’t clear to me how many you are rendering.
You should check to see which one is drawing as a red quad and perhaps check what textureID it is using and if it is valid.
You can also use GLIntercept or some debugging tool to take screen captures for every draw call.

http://www.opengl.org/wiki/Debugging_Tools

Also, any reason why you are only clearing the color. Why don’t you clear the depth buffer as well?[/QUOTE]

I’ll try clearing the depth buffer each frame. I have already discovered through testing that all the textures I load are drawing a red background instead of rendering transparent.

No dice. I feel like I must be setting a flag or two wrong somewhere.

Your problem could be here:

if (rawSurface->format->Rmask == 0x000000ff)
{
std::cout << "format RGBA
";
texture_format = GL_RGBA;
}
else
{
std::cout << "format BGRA
";
texture_format = GL_BGRA;
}

please set texture_format = GL_BGRA; or texture_format = GL_ARGB; without this if().
I didnt look exactly how do you load textures but if Red is Transparent and Transparence is Red then something is wrong with endians/checking endians.

[QUOTE=stefkos;1237374]Your problem could be here:

if (rawSurface->format->Rmask == 0x000000ff)
{
std::cout << "format RGBA
";
texture_format = GL_RGBA;
}
else
{
std::cout << "format BGRA
";
texture_format = GL_BGRA;
}

please set texture_format = GL_BGRA; or texture_format = GL_ARGB; without this if().
I didnt look exactly how do you load textures but if Red is Transparent and Transparence is Red then something is wrong with endians/checking endians.[/QUOTE]

I tried forcing the texture_format to GL_RGBA (the source images are GL_BGRA) and got this output:

Okay, I see that the red pixels were actually ENTIRELY by my own hand… however, I cannot get blending to actually work.

Normally, people use glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
You have the parameters reversed in your code. Also, you should take a look at the document to see how glBlendFunc works. It will help you in the future.

[QUOTE=V-man;1237493]Normally, people use glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
You have the parameters reversed in your code. Also, you should take a look at the document to see how glBlendFunc works. It will help you in the future.
[/QUOTE]

I figured it out. The problem was actually in my source images… the reason reversing the glBlendFunc parameter order was working the best for me was that my images had 0 alpha values for every pixel. Thanks all for the suggestions that ultimately led to figuring out this stupid/whacky issue.