I need help. I tried to load an image using SOIL. I was having problems with it so I found another code I am using. However, it looks like I am not loading it properly. It's simple but I think I'm confusing myself. I still can't wrap my head around how the file will be read. Should I include the whole path name or just the image name? If I don't add the path name, how will the image be found? Please take a look at the two code segnments in the LoadGLTexture function and help me figure this out. Thanks.


filename is coming from the display functioon:

void display(void)
{
    
    
    glClear(GL_COLOR_BUFFER_BIT);

    glPushMatrix();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glRotatef(Angle, 0.0, 0.0, 0.0);

    GLuint texture = LoadGLTexture("face.png", 396, 734);

    glEnable(GL_TEXTURE_2D);
    glBindTexture( GL_TEXTURE_2D, texture );
    .
    .
    .
    .
 
}
GLint LoadGLTexture(const char *filename, int width, int height)
{
     GLuint texture;
     unsigned char *data;
     FILE *file;
 
    //CODE SEGMENT 1
     // open texture data
     file = fopen(filename, "C:\\Users\\annette\\My Pictures\\face.png");
     if (file == NULL) return 0;
 
     // allocate buffer
     data = (unsigned char*) malloc(width * height * 4);
 
     //read texture data
     fread(data, width * height * 4, 1, file);
     fclose(file);
     

    
    //CODE SEGMENT 2
    texture = SOIL_load_OGL_texture // load an image file directly as a new OpenGL texture 
	(
		"C:\\Users\\annette\\My Pictures\\face.png",
		SOIL_LOAD_AUTO,
		SOIL_CREATE_NEW_ID,
		SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
	);
	
	
    // check for an error during the load process 
    if(texture == 0)
    {
	    //printf( "SOIL loading error: '%s'\n", SOIL_last_result() );
    }

      
    glGenTextures(1, &texture); // allocate a texture name
    glBindTexture(GL_TEXTURE_2D, texture); // select our current texture
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_DECAL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_DECAL);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);  // when texture area is small, bilinear filter the closest mipmap
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // when texture area is large, bilinear filter the first mipmap
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);  // texture should tile
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    gluBuild2DMipmaps(GL_TEXTURE_2D, 4, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); // build our texture mipmaps

    free(data);  // free buffer
 
    return texture;
}

Dani AI

Generated

Two separate issues are tripping you up: file paths and image decoding. The string you pass (e.g., "face.png") is resolved relative to the process working directory at runtime, not the source file location. In Visual Studio that is typically the Debug/Release output folder and can be changed under Project Properties -> Debugging -> Working Directory. Prefer a stable, relative path such as "assets/face.png" and ship the asset alongside your executable. On Windows, use forward slashes ("assets/face.png") or escape backslashes, and open binary image files with "rb" if you ever use fopen. Absolute paths work but are brittle. Your texture is 396x734 (NPOT). Modern GPUs handle NPOT textures, but on very old hardware you may need to rescale or ask SOIL to do so.

Do not mix raw file I/O with SOIL. fread(width*height*4,...) is only correct for raw RGBA dumps; PNG/JPEG must be decoded. If you use SOIL_load_OGL_texture, it already uploads pixels (and can build mipmaps), so skip your manual glGenTextures/gluBuild2DMipmaps path. Also note GL_DECAL is not a filter; use glTexParameteri for filtering, and set env mode only if you are using fixed-function texturing.

GLuint loadTextureSOIL(const char* path) {
    GLuint tex = SOIL_load_OGL_texture(
        path,
        SOIL_LOAD_AUTO,
        SOIL_CREATE_NEW_ID,
        SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y
    );
    if (!tex) { fprintf(stderr, "SOIL error: %s\n", SOIL_last_result()); return 0; }
    glBindTexture(GL_TEXTURE_2D, tex);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    return tex;
}

Recommended Answers

All 4 Replies

>> Should I include the whole path name or just the image name?

If the file is in the same directory as your source file, then you can just use the filename, else you can either use relative path or full path. However it needs to be a valid path.


>>file = fopen(filename, "C:\\Users\\annette\\My Pictures\\face.png");

You want, file = fopen(filename,"r"); and the call can be GLuint texture = LoadGLTexture("C:\\Users\\annette\\My Pictures\\face.png", 396, 734);

commented: This post was helpful and well explained. I understood it clearly +2

>> Should I include the whole path name or just the image name?

If the file is in the same directory as your source file, then you can just use the filename, else you can either use relative path or full path. However it needs to be a valid path.


>>file = fopen(filename, "C:\\Users\\annette\\My Pictures\\face.png");

You want, file = fopen(filename,"r"); and the call can be GLuint texture = LoadGLTexture("C:\\Users\\annette\\My Pictures\\face.png", 396, 734);

Oh! This really makes sense. Thanks so much. By the way, what does "r" mean?

Oh! This really makes sense. Thanks so much. By the way, what does "r" mean?

"r" stands for read. Check out the documents for

"r" stands for read. Check out the documents for

Thanks so much.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.