4

I'm trying to follow an OpenGL tutorial but the tutorial uses SOIL (which doesn't work for me) and I use FreeImage.

Could you tell me why my code doesnt work?

Tutorial code:

// Load texture
GLuint tex;
glGenTextures(1, &tex);

int width, height;
unsigned char* image = SOIL_load_image("sample.png", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

My code:

// Load textures
GLuint tex;
glGenTextures(1, &tex);

int width, height;

FREE_IMAGE_FORMAT formato = FreeImage_GetFileType("sample.png",0);
FIBITMAP* imagen = FreeImage_Load(formato, "sample.png");
FIBITMAP* temp = imagen;  
imagen = FreeImage_ConvertTo32Bits(imagen);
FreeImage_Unload(temp);

width = FreeImage_GetWidth(imagen);
height = FreeImage_GetHeight(imagen);

GLubyte* textura = new GLubyte[4*width*height];
char* pixeles = (char*)FreeImage_GetBits(imagen);

for(int j= 0; j<width*height; j++)
{
    textura[j*4+0]= pixeles[j*4+2];
    textura[j*4+1]= pixeles[j*4+1];
    textura[j*4+2]= pixeles[j*4+0];
    textura[j*4+3]= pixeles[j*4+3];
}

glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA, width, height, 0, GL_RGBA,GL_UNSIGNED_BYTE,(GLvoid*)textura );

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

My "solution" simply results in a black window (no errors).

genpfault
  • 51,148
  • 11
  • 85
  • 139
UndeadLeech
  • 133
  • 5
  • 17

3 Answers3

4

Coding in C is very funny

You're programmer. You'd better debug your program, because "black screen" in OpenGL app can be caused by zillion different reasons. From our point of view we can only guess. And we don't like it.

My guess

(okay, sometimes we like to guess)

This:

FIBITMAP* temp = imagen;  
imagen = FreeImage_ConvertTo32Bits(imagen);
FreeImage_Unload(temp);

Your temp and imagen points to same place, so after FreeImage_Unload(temp); both points to... we don't know where. Then you get pixels from it:

char* pixeles = (char*)FreeImage_GetBits(imagen);

What does it returns? We don't' know. You don't check if pixels exists after that. Undefined behavior etc. It doesn't even crash. Also, AFAIR, you cannot read and write at same dib.

Instead do:

FREE_IMAGE_FORMAT formato = FreeImage_GetFileType("sample.png",0);
if(formato  == FIF_UNKNOWN) { /* go angry here */ } 
FIBITMAP* imagen = FreeImage_Load(formato, "sample.png");
if(!imagen ) { /* go very angry here */ } 
FIBITMAP* temp = FreeImage_ConvertTo32Bits(imagen);
if(!imagen) { /* go mad here */ } 
FreeImage_Unload(imagen);
imagen = temp;

(or just comment out all conversion stuff)

How to debug:

  • Check for errors after loading and processing image. Does image loads at all?
  • Check for OpenGL errors. Does everything go right there?
  • In pixel shader, set output color to white, so you can be sure that your geometry is fine (what? you don't use shaders? =( )
  • After texture loading, write it directly to .raw file (or in other format) and inspect it with bitmap editor

How to check for errors:

Carefully read the FreeImage documentation and tutorial samples. Look at error checking implementation. Basically, you will need to set callback function. Implement it. Set it. (Or at least copy-paste). Do same + glGetError() for OpenGL.

Happy coding! =)

Edit: FreeImage have SwapRedBlue32() helper function, so you don't need those for loop.

Paul Wintz
  • 2,542
  • 1
  • 19
  • 33
Ivan Aksamentov - Drop
  • 12,860
  • 3
  • 34
  • 61
  • Your code seems fine only "imagen = temp;" results in application crash but works without this line. Can't get SwapRedBlue32() working but my loop is working so it's ok. Do u know a good way to turn a pic? – UndeadLeech Oct 27 '13 at 14:42
  • 1
    You can use `FreeImage_Rotate()`. Download documentation from [here](http://freeimage.sourceforge.net/download.html) for details. Also check `FreeImage_SetOutputMessage` function. So, next time we will not need to guess, where your code failed =) – Ivan Aksamentov - Drop Oct 27 '13 at 15:11
  • Is it possible to use `imagen = FreeImage_FlipHorizontal(imagen)` in this situation? Because I can't get it working because it returns a Boolean. With rotating it works but it's vertically flipped then :/. – UndeadLeech Oct 27 '13 at 16:21
  • 1
    use `bool result = FreeImage_FlipHorizontal(imagen);` it will change `imagen` in place, no need to copy to another variable. Don't forget to check for erors after: `if(!result) { /* Error message here*/ }`. – Ivan Aksamentov - Drop Oct 27 '13 at 16:32
0

You never seem to bind the texture object you create.

Add a glBindTexture( GL_TEXTURE_2D, tex ) call after glGenTextures() and again before you try to render with the texture.

genpfault
  • 51,148
  • 11
  • 85
  • 139
0

Okay, I found the answer to my question. :P

I have to start the application in the "Debug" folder instead of Debugging it with VC++.

Only problem is that now the pic loaded is upside down but I think I could fix it when I change the for loop.

Thanks for all answers!

UndeadLeech
  • 133
  • 5
  • 17
  • 1
    So, your program just cannot find picture file specified. To set up working directory on program start-up under Visual Studio debugger: `Right Click on Project` -> `Properties` -> `Debugging` -> `Working Directory`. – Ivan Aksamentov - Drop Oct 27 '13 at 15:07