• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************
2  *
3  * Copyright (C) 2018 Advanced Driver Information Technology Joint Venture GmbH
4  *
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  ****************************************************************************/
19 #include "TextureLoader.h"
20 
TextureLoader()21 TextureLoader::TextureLoader(){
22     ;
23 }
24 
25 // source: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-5-a-textured-cube/
loadBMP(const char * imagePath)26 bool TextureLoader::loadBMP(const char * imagePath) {
27     // Data read from the header of the BMP file
28     const unsigned char headerSize = 54; // Each BMP file begins by a 54-bytes header
29     unsigned char header[headerSize];
30     GLsizei width, height;
31     uint16_t pixelSizeBits;
32     uint8_t pixelSizeBytes;
33     // imageSize == width*height*pixelSize, because each pixel consists of pixelSize bytes (red, green and blue)
34     unsigned int imageSize;
35     unsigned char * data;
36     FILE * file = fopen(imagePath,"rb");
37     if (!file) {
38         //cout << "Image file could not be opened: " << imagePath << endl;
39         return false;
40     }
41     if (fread(header, 1, headerSize, file) != headerSize) {
42         cout << "Not a correct BMP file (could not read the header): " << imagePath << endl;
43         fclose(file);
44         return false;
45     }
46     if (header[0]!='B' || header[1]!='M' ) {
47         cout << "Not a correct BMP file (wrong header format) :" << imagePath << endl;
48         fclose(file);
49         return false;
50     }
51     // Read fields from the BMP file header
52     imageSize  = *(int*)(header + 0x22);
53     width      = *(GLsizei*)(header + 0x12);
54     height     = *(GLsizei*)(header + 0x16);
55     pixelSizeBits  = *(uint16_t*)(header + 0x1C);
56     pixelSizeBytes = pixelSizeBits / 8;
57 
58     if ((pixelSizeBits != 24) and (pixelSizeBits != 32)) {
59         cout << "unsupported pixel size of " << pixelSizeBits << " bits" << endl;
60         fclose(file);
61         return false;
62     }
63 
64     // calculate the image size if there is no information in the header
65     if (imageSize==0) {
66         imageSize=width*height*pixelSizeBytes;
67     }
68 
69     data = new unsigned char [imageSize];
70     fread(data,1,imageSize,file);
71     fclose(file);
72 
73     if (pixelSizeBits == 32) {
74         // BMP files with an alpha channel use ABGR format for storing pixels
75         // OpenGLES does not have an ABGR format specifier
76         // therefore change pixel format from ABGR to RGBA
77         for (long long i = 0; i < width*height; i++) {
78             unsigned char a = data[i*pixelSizeBytes + 0];
79             unsigned char b = data[i*pixelSizeBytes + 1];
80             unsigned char g = data[i*pixelSizeBytes + 2];
81             unsigned char r = data[i*pixelSizeBytes + 3];
82             data[i*pixelSizeBytes]     = r;
83             data[i*pixelSizeBytes + 1] = g;
84             data[i*pixelSizeBytes + 2] = b;
85             data[i*pixelSizeBytes + 3] = a;
86         }
87     } else if (pixelSizeBits == 24) {
88         for (long long i = 0; i < width*height; i++) {
89             unsigned char b = data[i*pixelSizeBytes];
90             unsigned char g = data[i*pixelSizeBytes + 1];
91             unsigned char r = data[i*pixelSizeBytes + 2];
92             data[i*pixelSizeBytes]     = r;
93             data[i*pixelSizeBytes + 1] = g;
94             data[i*pixelSizeBytes + 2] = b;
95         }
96     }
97 
98     bool loaded = loadArray(data, width, height, pixelSizeBits);
99     delete[] data;
100     return loaded;
101 }
102 
103 // This function loads an array with image data
loadArray(void * data,unsigned int width,unsigned int height,unsigned int pixelSizeBits)104 bool TextureLoader::loadArray(void * data, unsigned int width, unsigned int height, unsigned int pixelSizeBits) {
105     if (loaded)
106         // don't load the thexture if a texture was already loaded for this object
107         return false;
108     else
109         loaded = true;
110     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
111     glGenTextures(1, &textureID);
112     glBindTexture(GL_TEXTURE_2D, textureID);
113     if (pixelSizeBits == 32) {
114         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
115         glEnable(GL_BLEND);
116         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
117     } else if (pixelSizeBits == 24) {
118         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
119         glEnable(GL_BLEND);
120         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
121     }
122     glGenerateMipmap(GL_TEXTURE_2D);
123     // set texture parameters
124     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
125     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
126     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
127     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
128     return loaded;
129 }
130 
getId()131 GLuint TextureLoader::getId() {
132     return textureID;
133 }
134