PDA

View Full Version : Textures displaying red background



Flustration
05-06-2012, 11:13 AM
For some reason, when I draw my textures, the clear area retains a red background. Also, blending isn't occurring.

710


//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\n", 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\n", 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\n";
texture_format = GL_RGBA;
}
else
{
std::cout << "format BGRA\n";
texture_format = GL_BGRA;
}

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

}
else
{
std::cout << "format BGR\n";
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 << "\n";
}

}

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;
}

Flustration
05-09-2012, 11:36 AM
I figured I would clarify as I have not yet received a response :)

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\n";
texture_format = GL_RGBA;
}
else
{
std::cout << "format BGRA\n";
texture_format = GL_BGRA;
}

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

}
else
{
std::cout << "format BGR\n";
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...

http://i.imgur.com/AS6RM.png

Halp :) Thanks

V-man
05-09-2012, 12:14 PM
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?

Flustration
05-09-2012, 12:19 PM
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?

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.

Flustration
05-09-2012, 01:06 PM
No dice. I feel like I must be setting a flag or two wrong somewhere.

stefkos
05-09-2012, 01:31 PM
Your problem could be here:

if (rawSurface->format->Rmask == 0x000000ff)
{
std::cout << "format RGBA\n";
texture_format = GL_RGBA;
}
else
{
std::cout << "format BGRA\n";
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.

Flustration
05-09-2012, 03:12 PM
Your problem could be here:

if (rawSurface->format->Rmask == 0x000000ff)
{
std::cout << "format RGBA\n";
texture_format = GL_RGBA;
}
else
{
std::cout << "format BGRA\n";
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.

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

http://i.imgur.com/7UpoI.png

Flustration
05-09-2012, 06:24 PM
Okay, I see that the red pixels were actually ENTIRELY by my own hand... however, I cannot get blending to actually work.

http://i.imgur.com/vblF2.png

V-man
05-12-2012, 08:49 AM
Okay, I see that the red pixels were actually ENTIRELY by my own hand... however, I cannot get blending to actually work.

http://i.imgur.com/vblF2.png

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.

Flustration
05-12-2012, 04:14 PM
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.


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.