Noob + textures = fail...

Hi. I recently started to program opengl. And i want to create my own loader. But i did mistake somewhere where i cant find it.
It should look like this videotutorialsrock.com but mine look this image .

I wrote BMP class who takes only path to file “BMP(string filess);”. In this constructor i wrote bmp loader.
first it opens the file and loop to ent to see how big file is. Then malocate buffer that is filesize - (sizeof(char))*54. <- this is for piksels data.
Why (sizeof(char))*54? Because that size is BMP header and i read it with another array c_array.
And then crate images copy so that i would be shore that image loaded correctly.

Heres the code:

bitmap.h



#ifndef BITMAP_H
#define BITMAP_H
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <string>
#include <string.h>
using namespace std;


class BMP
{
public:
	
    BMP(string filess);
	~BMP();
	string filename;
   unsigned short int type;          //2 /* Magic identifier          */
   unsigned int size;                   //4 /* File size in bytes        */
   unsigned short int reserved1;    //2
   unsigned short int reserved2;   //2
   unsigned int offset;                 //4
   unsigned int header_size;        //4 /* Header size in bytes      */
   int width;			 //4
   int height;			 //4 /* Width and height of image */
   unsigned short int planes;        //2 /* Number of colour planes   */
   unsigned short int bits;            //2 /* Bits per pixel            */
   unsigned int compression;        //4 /* Compression type          */
   unsigned int imagesize;          //4 /* Image size in bytes       */
   int xresolution;                      //4
   int yresolution;		//4 /* Pixels per meter          */
   unsigned int ncolours;            //4  /* Number of colours         */
   unsigned int importantcolours;//4  /* Important colours         */


  long headersize;
  long bodysize;
  long filesize;
  char c_array[54];
  int BMP::chartoI(char i1, char i2, char i3,char i4);
  unsigned int BMP::chartoUI(char i1, char i2, char i3,char i4);
  unsigned short int BMP::chartoUSI (char i1,char i2);
  char * buffer;
};

#endif

bitmap.cpp


[size=12pt]#include "bitmap.h"
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <string>
#include <string.h>
#pragma warning(disable : 4996)
using namespace std;




   int BMP::chartoI(char i1, char i2, char i3,char i4)
   {
		return (int)(((unsigned char)i4 << 24) |
					 ((unsigned char)i3 << 16) |
					 ((unsigned char)i2 << 8)  |
					  (unsigned char)i1);
   
   }



   unsigned int BMP::chartoUI(char i1, char i2, char i3,char i4)
   {
		return (unsigned int)(((unsigned char)i4 << 24) |
							  ((unsigned char)i3 << 16) |
							  ((unsigned char)i2 << 8)  |
							   (unsigned char)i1);
   }




   unsigned short int BMP::chartoUSI (char i1,char i2)
   {
		return (unsigned short int)(((unsigned char)i2 << 8) |
							         (unsigned char)i1);
   }



    BMP::BMP(string filename)
{
	BMP::filename = filename;
    FILE * pfile;

headersize = (sizeof(char))*54;

filesize = 0;
pfile = fopen(filename.c_str(),"rb");
rewind (pfile);
fseek(pfile,filesize,SEEK_END);
filesize = ftell(pfile);
bodysize = filesize - (sizeof(char))*54;
rewind(pfile);
buffer = (char*) malloc( bodysize);
fread(c_array,1,headersize,pfile);
fread (buffer,1,bodysize,pfile);
fclose(pfile);
FILE * files;
files = fopen("BMPCOPYlol.bmp","wb");
fwrite(c_array,1,headersize,files);
fwrite(buffer,1,bodysize,files);
fclose(files);



   type			= chartoUSI (c_array[0] ,c_array[1]);                                         //2 /* Magic i  dentifier          */
   size			= chartoUI   (c_array[2] ,c_array[3]  ,c_array[4] ,c_array[5]) ;       //4 /* File size in bytes        */
   reserved1		= chartoUSI (c_array[6] ,c_array[7]);                                         //2
   reserved2		= chartoUSI (c_array[8] ,c_array[9]);                                         //2
   offset		= chartoUI   (c_array[10],c_array[11] ,c_array[12],c_array[13]);    //4
   header_size		= chartoUI   (c_array[14],c_array[15] ,c_array[16],c_array[17]);    //4 /* Header size in bytes      */
   width		= chartoI     (c_array[18],c_array[19] ,c_array[20],c_array[21]);    //4
   height		= chartoI     (c_array[22],c_array[23] ,c_array[24],c_array[25]);    //4 /* Width and height of image */
   planes		= chartoUSI (c_array[26],c_array[27]);                                       //2 /* Number of colour planes   */
   bits			= chartoUSI (c_array[28],c_array[29]) ;                                     //2 /* Bits per pixel            */
   compression		= chartoUI   (c_array[30],c_array[31] ,c_array[32],c_array[33]);    //4 /* Compression type          */
   imagesize		= chartoUI   (c_array[34],c_array[35] ,c_array[36],c_array[37]);    //4 /* Image size in bytes       */
   xresolution		= chartoI     (c_array[38],c_array[39] ,c_array[40],c_array[41]);    //4
   yresolution		= chartoI     (c_array[42],c_array[43] ,c_array[44],c_array[45]);    //4 /* Pixels per meter          */
   ncolours		= chartoUI   (c_array[46],c_array[47] ,c_array[48],c_array[49]);    //4 /* Number of colours         */
   importantcolours	= chartoUI   (c_array[50],c_array[51] ,c_array[52],c_array[53]);    //4 /* Important colours         */


}

BMP::~BMP()
{
	free(buffer);
	delete [] c_array;
}

// the numbers in comments are size in bytes

main.cpp


[size=12pt]
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <string>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <malloc.h>
#include "poligonas.h"
#include "mdl.h"
#include "bitmap.h"

#include <gl.h>
#include <glu.h>
#include <glut.h>



//modelis mdl("untitled.x");
BMP bmp("lol.bmp");
	

using namespace std;


GLuint loadTexture() {
	GLuint textureId;
	glGenTextures(1, &textureId); //Make room for our texture
	glBindTexture(GL_TEXTURE_2D, textureId); //Tell OpenGL which texture to edit
	//Map the image to the texture
	glTexImage2D(GL_TEXTURE_2D,                //Always GL_TEXTURE_2D
				 0,                            //0 for now
				 GL_RGB,                       //Format OpenGL uses for image
				 bmp.width, bmp.height,		   //Width and height
				 0,                            //The border of the image
				 GL_RGB,					   //GL_RGB, because pixels are stored in RGB format
				 GL_UNSIGNED_BYTE,             //GL_UNSIGNED_BYTE, because pixels are stored
				                               //as unsigned numbers
				 bmp.buffer);                  //The actual pixel data
							   //Returns the id of the texture

return textureId;
}


GLuint _textureId = loadTexture();

//Called when a key is pressed
void handleKeypress(unsigned char key, int x, int y) {
	switch (key) {
		case 27: //Escape key
			exit(0);
	}
}

//Initializes 3D rendering
void initRendering() {
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_COLOR_MATERIAL); //Enable color
	glClearColor(0.7f, 0.9f, 1.0f, 1.0f); //Change the background to sky blue
}

//Called when the window is resized
void handleResize(int w, int h) {
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0, (double)w / (double)h, 1.0, 200.0);
}

float _angle = 30.0f;
float _cameraAngle = 0.0f;



//Draws the 3D scene
void drawScene() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
	
	glTranslatef(0.0f, 1.0f, -6.0f);
	
	GLfloat ambientLight[] = {0.2f, 0.2f, 0.2f, 1.0f};
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
	
	GLfloat directedLight[] = {0.7f, 0.7f, 0.7f, 1.0f};
	GLfloat directedLightPos[] = {-10.0f, 15.0f, 20.0f, 0.0f};
	glLightfv(GL_LIGHT0, GL_DIFFUSE, directedLight);
	glLightfv(GL_LIGHT0, GL_POSITION, directedLightPos);
	
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, _textureId);
	
	//Bottom
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glColor3f(1.0f, 0.2f, 0.2f);
	glBegin(GL_QUADS);
	
	glNormal3f(0.0, 1.0f, 0.0f);    glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-2.5f, -2.5f, 2.5f); glTexCoord2f(0.0f, 1.0f);
	glVertex3f(2.5f, -2.5f, 2.5f);  glTexCoord2f(1.0f, 1.0f);
	glVertex3f(2.5f, -2.5f, -2.5f); glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-2.5f, -2.5f, -2.5f);
	
	glEnd();
	
	//Back
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glColor3f(1.0f, 1.0f, 1.0f);
	glBegin(GL_TRIANGLES);
	
	glNormal3f(0.0f, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-2.5f, -2.5f, -2.5f);
	glTexCoord2f(5.0f, 5.0f);
	glVertex3f(0.0f, 2.5f, -2.5f);
	glTexCoord2f(10.0f, 0.0f);
	glVertex3f(2.5f, -2.5f, -2.5f);
	
	glEnd();
	
	//Left
	glDisable(GL_TEXTURE_2D);
	glColor3f(1.0f, 0.7f, 0.3f);
	glBegin(GL_QUADS);
	
	glNormal3f(1.0f, 0.0f, 0.0f);
	glVertex3f(-2.5f, -2.5f, 2.5f);
	glVertex3f(-2.5f, -2.5f, -2.5f);
	glVertex3f(-2.5f, 2.5f, -2.5f);
	glVertex3f(-2.5f, 2.5f, 2.5f);
	
	glEnd();
	
	glutSwapBuffers();
}

void update(int value) {
	_angle += 2.0f;
	if (_angle > 360) {
		_angle -= 360;
	}
	
	glutPostRedisplay();
	glutTimerFunc(25, update, 0);
}

int main(int argc, char** argv) {
	//Initialize GLUT
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(400, 400);
	
	//Create the window
	glutCreateWindow("lol");
	initRendering();
	
	//Set handler functions
	glutDisplayFunc(drawScene);
	glutKeyboardFunc(handleKeypress);
	glutReshapeFunc(handleResize);
	
	glutTimerFunc(25, update, 0); //Add a timer
	
	glutMainLoop();
	return 0;
}

I don’t care bad or wrong working function for now untill i correctrly load image.

Thanx for help and sorry for grammar mistakes (in school teach only Russian )

mmm… there are a lot’s of errors


class BMP{
  char c_array[54];
  ....
}
BMP::~BMP()
{
	free(buffer);
	delete [] c_array;
}

You can free memory allocated on the stack… you will get a segmentation fault.
Also why you mix C++ memory allocation with malloc/free?


BMP bmp("lol.bmp");
GLuint _textureId = loadTexture();

both bmp and _textureId are global static object. The compiler can initialize static object in the order it prefer. So you are not sure that loadTexture is called after the constructor of BMP.
Move BMP inside loadTexture

Also you are calling loadTexture at the very beginning of the program (global variable are initialized before the main), so you are calling glGenTexture when the openGL context is not initialized. Move the loadTexture function call in the main after glutCreateWindow(“lol”);

Also, check your texture format.
Bmp are stored in reverse order, BGR not RGB also the header include the number of bit per pixel.
If bits is 24 you must use BGR if bits is 32 you must use BGRA.

I think that this videotutorial don’t rock too much… :-/

your dots are incorrect. bmp.width and bmp.height. It should read bmp->width and bmp->height. you could always do (bmp).hight and (bmp).width too I think. It has to do with order of operation.

To be honest I think you’re better off with an image loading library here; the BMP format contains plenty of traps for the unwary (wait till you hit a BMP with a negative height!) and you’ll be spending your time chasing down subtle bugs and implementation problems instead of doing anything productive.

Look at DevIL (http://openil.sourceforge.net) as an example of one you could use.

Well, don’t forget to also check out:

http://nothings.org/stb_image.c

the devil library is to me just a wrapper, with some image processing thrown into it.