سؤال

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).

هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

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.

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!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top