CSCI441 OpenGL Library 5.21.1.0
CS@Mines CSCI441 Computer Graphics Course Library
Loading...
Searching...
No Matches
TextureUtils.hpp
Go to the documentation of this file.
1
14#ifndef CSCI441_TEXTURE_UTILS_HPP
15#define CSCI441_TEXTURE_UTILS_HPP
16
17#include "constants.h"
18
19#ifdef CSCI441_USE_GLEW
20 #include <GL/glew.h>
21#else
22 #include <glad/gl.h>
23#endif
24
25#ifdef CSCI441_TEXTURE_UTILS_IMPLEMENTATION
26#define STB_IMAGE_IMPLEMENTATION
27#endif
28#include <stb_image.h>
29
30#include <cstdio>
31#include <cstring>
32#include <string>
33
34//**********************************************************************************
35
36namespace CSCI441 {
37
42 namespace TextureUtils {
43
62 bool loadPPM( const char *filename, int &imageWidth, int &imageHeight, unsigned char* &imageData );
63
78 [[maybe_unused]] GLuint loadAndRegisterTexture( const char *filename,
79 GLint minFilter = GL_LINEAR,
80 GLint magFilter = GL_LINEAR,
81 GLint wrapS = GL_REPEAT,
82 GLint wrapT = GL_REPEAT,
83 GLboolean flipOnY = GL_TRUE,
84 GLboolean printAllMessages = GL_TRUE,
85 GLboolean enableMipmaps = GL_TRUE,
86 GLboolean enableAniso = GL_TRUE);
87
104 GLuint loadAndRegister2DTexture( const char *filename,
105 GLint minFilter = GL_LINEAR,
106 GLint magFilter = GL_LINEAR,
107 GLint wrapS = GL_REPEAT,
108 GLint wrapT = GL_REPEAT,
109 GLboolean flipOnY = GL_TRUE,
110 GLboolean printAllMessages = GL_TRUE,
111 GLboolean enableMipmaps = GL_TRUE,
112 GLboolean enableAniso = GL_TRUE);
113
120 [[maybe_unused]] void loadCubeMapFaceTexture(GLint cubeMapFace, const char* filename);
121 }
122}
123
124//**********************************************************************************
125// Outward facing function implementations
126
127inline bool CSCI441::TextureUtils::loadPPM( const char *filename, int &imageWidth, int &imageHeight, unsigned char* &imageData ) {
128 FILE *fp = fopen(filename, "r");
129 int temp, maxValue;
130 fscanf(fp, "P%d", &temp);
131 if(temp != 3) {
132 fprintf(stderr, "[ERROR]: CSCI441::TextureUtils::loadPPM(): PPM file is not of correct format! (Must be P3, is P%d.)\n", temp);
133 fclose(fp);
134 return false;
135 }
136
137 //got the file header right...
138 fscanf(fp, "%d", &imageWidth);
139 fscanf(fp, "%d", &imageHeight);
140 fscanf(fp, "%d", &maxValue);
141
142 //now that we know how big it is, allocate the buffer...
143 imageData = new unsigned char[imageWidth*imageHeight*3];
144 if(!imageData) {
145 fprintf(stderr, "[ERROR]: CSCI441::TextureUtils::loadPPM(): couldn't allocate image memory. Dimensions: %d x %d.\n", imageWidth, imageHeight);
146 fclose(fp);
147 return false;
148 }
149
150 //and read the data in.
151 for(int j = 0; j < imageHeight; j++) {
152 for(int i = 0; i < imageWidth; i++) {
153 int r, g, b;
154 fscanf(fp, "%d", &r);
155 fscanf(fp, "%d", &g);
156 fscanf(fp, "%d", &b);
157
158 imageData[(j*imageWidth+i)*3+0] = r;
159 imageData[(j*imageWidth+i)*3+1] = g;
160 imageData[(j*imageWidth+i)*3+2] = b;
161 }
162 }
163
164 fclose(fp);
165 return true;
166}
167
168[[maybe_unused]]
169inline GLuint CSCI441::TextureUtils::loadAndRegisterTexture( const char *filename, const GLint minFilter, const GLint magFilter, const GLint wrapS, const GLint wrapT, const GLboolean flipOnY, const GLboolean printAllMessages, const GLboolean enableMipmaps, const GLboolean enableAniso ) {
170 return loadAndRegister2DTexture( filename, minFilter, magFilter, wrapS, wrapT, flipOnY, printAllMessages, enableMipmaps, enableAniso );
171}
172
173inline GLuint CSCI441::TextureUtils::loadAndRegister2DTexture( const char *filename, const GLint minFilter, const GLint magFilter, const GLint wrapS, const GLint wrapT, const GLboolean flipOnY, const GLboolean printAllMessages, const GLboolean enableMipmaps, const GLboolean enableAniso ) {
174 int imageWidth, imageHeight, imageChannels;
175 GLuint texHandle = 0;
176 stbi_set_flip_vertically_on_load(flipOnY);
177 unsigned char *data = stbi_load( filename, &imageWidth, &imageHeight, &imageChannels, 0);
178
179 if( !data ) {
180 if( strstr(filename, ".ppm") != NULL ) {
181 loadPPM(filename, imageWidth, imageHeight, data);
182 imageChannels = 3;
183 }
184 if( !data ) {
185 if(printAllMessages) printf( "[ERROR]: CSCI441::TextureUtils::loadAndRegister2DTexture(): Could not load texture \"%s\"\n", filename );
186 return texHandle;
187 }
188 }
189
190 glGenTextures(1, &texHandle );
191 glBindTexture( GL_TEXTURE_2D, texHandle );
192 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter );
193 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter );
194 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS );
195 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT );
196 const GLint STORAGE_TYPE = (imageChannels == 4 ? GL_RGBA : GL_RGB);
197 glTexImage2D( GL_TEXTURE_2D, 0, STORAGE_TYPE, imageWidth, imageHeight, 0, STORAGE_TYPE, GL_UNSIGNED_BYTE, data);
198
199 if(enableMipmaps) glGenerateMipmap(GL_TEXTURE_2D);
200
201 if(enableAniso) {
202 // anisotropic filtering became core in OpenGL 4.6, but was widely supported via extensions prior to then
203 GLint major = 0, minor = 0;
204 glGetIntegerv(GL_MAJOR_VERSION, &major);
205 glGetIntegerv(GL_MINOR_VERSION, &minor);
206 // check if anisotropic filtering is enabled
207 if( (major > 4 || (major == 4 && minor >= 6)) || GL_EXT_texture_filter_anisotropic ) {
208 GLfloat maxAniso = 1.0f;
209 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso);
210 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAniso);
211 }
212 }
213
214 printf( "[INFO]: Successfully loaded texture \"%s\" with handle %d\n", filename, texHandle );
215
216 return texHandle;
217}
218
219[[maybe_unused]]
220inline void CSCI441::TextureUtils::loadCubeMapFaceTexture(const GLint cubeMapFace, const char* FILENAME) {
221 int imageWidth, imageHeight, imageChannels;
222 unsigned char *data = stbi_load( FILENAME, &imageWidth, &imageHeight, &imageChannels, 0);
223
224 if( data ) {
225 const GLint STORAGE_TYPE = (imageChannels == 4 ? GL_RGBA : GL_RGB);
226 glTexImage2D(cubeMapFace, 0, STORAGE_TYPE, imageWidth, imageHeight, 0, STORAGE_TYPE, GL_UNSIGNED_BYTE, data);
227 stbi_image_free(data);
228 } else {
229 fprintf( stderr, "[ERROR]: CSCI441::TextureUtils::loadCubeMapFaceTexture(): Could not load texture map \"%s\"\n", FILENAME );
230 }
231}
232
233#endif // CSCI441_TEXTURE_UTILS_HPP
void loadCubeMapFaceTexture(GLint cubeMapFace, const char *filename)
loads a texture into memory of a cube face
Definition: TextureUtils.hpp:220
bool loadPPM(const char *filename, int &imageWidth, int &imageHeight, unsigned char *&imageData)
loads a PPM into memory
Definition: TextureUtils.hpp:127
GLuint loadAndRegister2DTexture(const char *filename, GLint minFilter=GL_LINEAR, GLint magFilter=GL_LINEAR, GLint wrapS=GL_REPEAT, GLint wrapT=GL_REPEAT, GLboolean flipOnY=GL_TRUE, GLboolean printAllMessages=GL_TRUE, GLboolean enableMipmaps=GL_TRUE, GLboolean enableAniso=GL_TRUE)
loads and registers a texture into memory returning a texture handle
Definition: TextureUtils.hpp:173
GLuint loadAndRegisterTexture(const char *filename, GLint minFilter=GL_LINEAR, GLint magFilter=GL_LINEAR, GLint wrapS=GL_REPEAT, GLint wrapT=GL_REPEAT, GLboolean flipOnY=GL_TRUE, GLboolean printAllMessages=GL_TRUE, GLboolean enableMipmaps=GL_TRUE, GLboolean enableAniso=GL_TRUE)
loads and registers a texture into memory returning a texture handle
Definition: TextureUtils.hpp:169
CSCI441 Helper Functions for OpenGL.
Definition: ArcballCam.hpp:17
OpenGL Texture Utility functions.