Thx ahead of time.
// frag
#version 410 core
in vec2 UV;
out vec3 out_Color;
uniform sampler2D myTextureSampler[2];
void main(void)
{
out_Color = texture2D(myTextureSampler[0], UV ).rgb;
}
//C++ setup code
std::array<GLuint, 2> m_textureID; // global
void LoadTextures()
{
Texture texture;
texture.Load24BMP(_T("mybmp.bmp"));
Texture texture2;
texture2.Load24BMP(_T("mybmp2.bmp"));
glGenTextures(2, &m_textureID[0]);
glBindTexture(GL_TEXTURE_2D, m_textureID.at(0));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture.m_infoHeader->biWidth,
texture.m_infoHeader->biHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, &texture.m_vData.front());
glBindTexture(GL_TEXTURE_2D, m_textureID.at(1));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture2.m_infoHeader->biWidth,
texture2.m_infoHeader->biHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, &texture2.m_vData.front());
}
const short BITMAP_MAGIC_NUMBER=19778;
const int RGB_BYTE_SIZE=3;
typedef struct tagBitmapFileHeader {
unsigned short bfType;
unsigned int bfSize;
unsigned short bfReserved1;
unsigned short bfReserved2;
unsigned int bfOffBits;
} BitmapFileHeader;
typedef struct tagBitmapInfoHeader {
unsigned int biSize;
int biWidth;
int biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned int biCompression;
unsigned int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
} BitmapInfoHeader;
class Texture
{
public:
int Load24BMP(TCHAR *file)
{
FILE *in = NULL; //file stream for reading
m_loaded = false; //bitmap is not loaded yet
// need fix unload if not loaded
//open the file for reading in binary mode
if(_tfopen_s(&in, file,_T("rb")) != 0)
return -1;
//if the file does not exist return in m_strError
if(in==NULL)
{
fclose(in);
return -2;
}
//BITMAPFILEHEADER
m_fileHeader = new BitmapFileHeader;
fread(&m_fileHeader->bfType, 2, 1, in);
fread(&m_fileHeader->bfSize, 4, 1, in);
fread(&m_fileHeader->bfReserved1, 2, 1, in);
fread(&m_fileHeader->bfReserved2, 2, 1, in);
fread(&m_fileHeader->bfOffBits, 4, 1, in);
//check for the magic number that says this is a bitmap
if(m_fileHeader->bfType != BITMAP_MAGIC_NUMBER)
{
fclose(in);
return -3;
}
//BITMAPINFOHEADER
m_infoHeader = new BitmapInfoHeader;
fread(&m_infoHeader->biSize, 4, 1, in);
fread(&m_infoHeader->biWidth, 4, 1, in);
fread(&m_infoHeader->biHeight, 4, 1, in);
fread(&m_infoHeader->biPlanes, 2, 1, in);
fread(&m_infoHeader->biBitCount, 2, 1, in);
if(m_infoHeader->biBitCount != 24)
{
fclose(in);
return -4;
}
fread(&m_infoHeader->biCompression, 4, 1, in);
//biSizeImage is rounded to next 4 byte boundary
//A0 37 F2 8B 31 C4 = A0 37 F2 8B 31 C4 00 00 in file
fread(&m_infoHeader->biSizeImage, 4, 1, in);
fread(&m_infoHeader->biXPelsPerMeter, 4, 1, in);
fread(&m_infoHeader->biYPelsPerMeter, 4, 1, in);
fread(&m_infoHeader->biClrUsed, 4, 1, in);
fread(&m_infoHeader->biClrImportant, 4, 1, in);
//make buffer big enough for data(with padding)
m_vData.resize(m_infoHeader->biSizeImage);
//read in the entire image
fread(&m_vData[0],sizeof(char),m_infoHeader->biSizeImage,in);
//close the file now that we have all the info
fclose(in);
RemovePadding();
FlipDataUp();
//3 Bytes = blue/green/red colors
unsigned int elements = m_infoHeader->biWidth * m_infoHeader->biHeight * 3;
m_vData.resize(elements);
//sticks data blue green red * Heightscale + Offset in tables
//Reformat(heightScale, offset);
//bitmap is now loaded
m_loaded = true;
//return success
return 1;
}
/*
Dibs are upside down so flip it up
101 001
010 -> 010
001 101
*/
void FlipDataUp()
{
// red/green/blue = 3 bytes
int pwidth = m_infoHeader->biWidth * 3;
//put rightside up due to fact image is upside down(not reversed)
std::vector<BYTE> buff;
buff.resize(pwidth);
for(int i = 0; i < m_infoHeader->biHeight; i++)
{
if(&m_vData[(m_infoHeader->biHeight * pwidth) - (pwidth + (pwidth * i))] == &m_vData[pwidth * i])
break;
memmove(&buff[0], &m_vData[pwidth * i], pwidth);
memmove(&m_vData[pwidth * i], &m_vData[(m_infoHeader->biHeight * pwidth) - (pwidth + (pwidth * i))], pwidth);
memmove(&m_vData[(m_infoHeader->biHeight * pwidth) - (pwidth + (pwidth * i))], &buff[0], pwidth);
}
}
/*
BMP image is rounded to next 4 byte boundary
A0 37 F2 8B 31 C4 = A0 37 F2 8B 31 C4 00 00 in file
So function removes 00 00
*/
void RemovePadding()
{
// red/green/blue = 3 bytes
const unsigned int elements = m_infoHeader->biWidth * m_infoHeader->biHeight * 3;
const unsigned int padding = m_infoHeader->biSizeImage - elements;
const unsigned int paddperrow = padding / m_infoHeader->biHeight;
const int pwidth = m_infoHeader->biWidth * 3;
//remove padding
for(int i = 0; i < m_infoHeader->biHeight; i++)
{
memmove(&m_vData[pwidth * i], &m_vData[(pwidth * i) + (paddperrow * i)], pwidth);
}
}
bool m_loaded; //file loaded or not
std::vector<BYTE> m_vData; //buffer for bmp file data
unsigned int m_dataSize; //size of bmp file data buffer
//BITMAPFILEHEADER
BitmapFileHeader *m_fileHeader;
// BITMAPINFOHEADER
BitmapInfoHeader *m_infoHeader;
};