I'm trying to get myself familiar with the GLUT framework in XCode 9 for a future project I want to work on, but now I'm stuck with getting textures to display properly.
So my goal is it display this bmp image as a texture:
to where this red square is:
And the result is this:
When it should be this:
Here is the code I used for initializing the texture.
GLuint loadAndBufferImage(const char * filename){
GLuint texture;
unsigned char header[54];
unsigned int dataPos;
unsigned int width, height;
unsigned int imageSize;
unsigned char * data;
FILE * file = fopen(filename, "rb");
if(!file){printf("Image could not load\n"); exit(2);}
if(fread(header, 1, 54, file) != 54){
printf("Not a correct BMP file.\n");
return -1;
}
if(header[0] != 'B' || header[1] != 'M'){
printf("Not a correct BMP file.\n");
return -1;
}
dataPos = *(int*)&(header[0x0A]);
imageSize = *(int*)&(header[0x22]);
width = *(int*)&(header[0x12]);
height = *(int*)&(header[0x16]);
if(imageSize == 0) imageSize = width * height * 4;
if(dataPos==0) dataPos=54;
data = malloc(imageSize);
if(!data){printf("No more memory\n"); exit(1);}
fread(data, 1, imageSize, file);
fclose(file);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
free(data);
return texture;
}
And this is where that function is called.
GameWindow *initializeGameWindow(){
GameWindow *gw = malloc(sizeof(*gw));
if(gw == NULL){
printf("Error: no more memory");
exit(1);
}
gw->render = render;
gw->update = update;
gw->isRunning = isRunning;
gw->setRunning = setRunning;
glClearColor(1.0, 1.0, 1.0, 1.0);
glEnable(GL_TEXTURE_2D);
glViewport(0.0f, 0.0f, _width, _height);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0, _width, 0, _height);
glMatrixMode(GL_MODELVIEW);
glGenBuffers(1, &_vertexBufferID);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexData), (GLvoid *)offsetof(VertexData, pos));
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexData), (GLvoid *)offsetof(VertexData, tex));
_textureBufferID = loadAndBufferImage("test.bmp");
return gw;
}
I'm going to take a guess and say it has to do with how I'm getting the data from the image and possibly the texture parameters. If so then how do I fix this? Otherwise is there something else I need to do to set up the texture?
Edit:
So I added the fseek(file, (long)dataPos, SEEK_SET);
above the fread(data, 1, imageSize, file);
in the texture initialization code as suggested and it seems to have shifted the image a little bit compared to initial results.
I also tried changing GL_RGBA and GL_BGRA to GL_RGB and GL_BGR respectively as in the glTexImage2D function and this happened.
Edit 2: So after some research and some experimentation, it turns out the other problem was because the image was set to indexed color mode instead of RGB color mode when I saved it as a bitmap file. (I'm using the Gimp editor.) It must have affected how the data was stored because the hex values in the pixel data sections of the file and the total file sizes were different when I compared them. But switching it to RBG color mode in the editor was the final key to solving this problem.
https://image.ibb.co/fC99Lm/Screen_Shot_2017_10_18_at_4_15_36_AM.png
Thank you for all your help.
Resources:
glTexImage2D
). – Matso