Blame view

stim/gl/gl_texture.h 9.74 KB
197e13de   Pavel Govyadinov   Added new class g...
1
2
3
  #ifndef STIM_GL_TEXTURE_H
  #define STIM_GL_TEXTURE_H
  
197e13de   Pavel Govyadinov   Added new class g...
4
5
  #include <math.h>
  #include <iostream>
197e13de   Pavel Govyadinov   Added new class g...
6
  #include <vector>
197e13de   Pavel Govyadinov   Added new class g...
7
  #include "../grids/image_stack.h"
26da82c8   David Mayerich   finalized stim::g...
8
9
10
11
12
  //Visual Studio requires GLEW
  #ifdef _WIN32
  	#include <GL/glew.h>
  #endif
  //#include <GL/glut.h>
983b730b   David Mayerich   texture updates
13
  #include <stim/gl/error.h>	
197e13de   Pavel Govyadinov   Added new class g...
14
15
  namespace stim{
  
a4042c24   Pavel Govyadinov   Updated the gl_te...
16
17
18
19
20
  /*
  class gl_texture
  	Uses image_stack class in order to create a texture object.
  */
  
26da82c8   David Mayerich   finalized stim::g...
21
22
  template<typename T, typename F = float>
  class gl_texture : public virtual image_stack<T, F>
197e13de   Pavel Govyadinov   Added new class g...
23
  {
197e13de   Pavel Govyadinov   Added new class g...
24
  	protected:
983b730b   David Mayerich   texture updates
25
  		//std::string path;
372b5963   Pavel Govyadinov   added support for...
26
27
  		GLuint texID;				//OpenGL object
  		GLenum texture_type;			//1D, 2D, 3D
26da82c8   David Mayerich   finalized stim::g...
28
29
30
31
32
  		GLint interpolation;
  		GLint wrap;	
  		GLenum cpu_type;
  		GLenum gpu_type;
  		GLenum format;					//format for the texture (GL_RGBA, GL_LUMINANCE, etc.)
2eefb035   Pavel Govyadinov   added debugging c...
33
  		using image_stack<T,F>::R;
26da82c8   David Mayerich   finalized stim::g...
34
  		//using image_stack<T>::S;
2eefb035   Pavel Govyadinov   added debugging c...
35
  		using image_stack<T,F>::ptr;
197e13de   Pavel Govyadinov   Added new class g...
36
  
983b730b   David Mayerich   texture updates
37
38
39
40
41
42
43
44
45
46
47
48
49
  		///	Sets the internal texture_type, based on the data dimensions
  		void setTextureType(){
  			if (R[3] > 1)						//if the third dimension is greater than 1
  				texture_type = GL_TEXTURE_3D;	//this is a 3D texture
  			else if (R[2] > 1)					//if the second dimension is greater than 1
  				texture_type = GL_TEXTURE_2D;	//this is a 2D texture
  			else if (R[1] > 1)					//if the dimension value is greater than 1
  				texture_type = GL_TEXTURE_1D;	//this is a 1D texture
  		}
  
  		//initializes important variables
  		void init() {
  			texID = 0;							//initialize texture ID to zero, default if OpenGL returns an error
256b431c   david   fixed Linux compi...
50
51
  			//memset(R, 0, sizeof(size_t));
  			//memset(grid<T, 4, F>::S, 0, sizeof(F));
26da82c8   David Mayerich   finalized stim::g...
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  		}
  
  		//guesses the color format of the texture
  		GLenum guess_format(){
  			size_t channels = R[0];
  			switch(channels){
  			case 1:
  				return GL_LUMINANCE;
  			case 2:
  				return GL_RG;
  			case 3:
  				return GL_RGB;
  			case 4:
  				return GL_RGBA;
  			default:
fac43319   Pavel Govyadinov   Changed the posit...
67
  				std::cout<<"Error in stim::gl_texture - unable to guess texture format based on number of channels" << std::endl;
26da82c8   David Mayerich   finalized stim::g...
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
  				exit(1);
  			}
  		}
  
  		//guesses the OpenGL CPU data type based on T
  		GLenum guess_cpu_type(){
  			// The following is C++ 11 code, but causes problems on some compilers (ex. nvcc). Below is my best approximation to a solution
  
  			//if(std::is_same<T, unsigned char>::value)	return CV_MAKETYPE(CV_8U, (int)C());
  			//if(std::is_same<T, char>::value)			return CV_MAKETYPE(CV_8S, (int)C());
  			//if(std::is_same<T, unsigned short>::value)	return CV_MAKETYPE(CV_16U, (int)C());
  			//if(std::is_same<T, short>::value)			return CV_MAKETYPE(CV_16S, (int)C());
  			//if(std::is_same<T, int>::value)				return CV_MAKETYPE(CV_32S, (int)C());
  			//if(std::is_same<T, float>::value)			return CV_MAKETYPE(CV_32F, (int)C());
  			//if(std::is_same<T, double>::value)			return CV_MAKETYPE(CV_64F, (int)C());
  
  			if(typeid(T) == typeid(unsigned char))		return GL_UNSIGNED_BYTE;
  			if(typeid(T) == typeid(char))				return GL_BYTE;
  			if(typeid(T) == typeid(unsigned short))		return GL_UNSIGNED_SHORT;
  			if(typeid(T) == typeid(short))				return GL_SHORT;
  			if(typeid(T) == typeid(unsigned int))		return GL_UNSIGNED_INT;
  			if(typeid(T) == typeid(int))				return GL_INT;
  			if(typeid(T) == typeid(float))				return GL_FLOAT;
  
  			std::cout<<"ERROR in stim::gl_texture - no valid data type found"<<std::endl;
  			exit(1);
  		}
  
  		//Guesses the "internal format" of the texture to closely approximate the original format
  		GLint guess_gpu_type(){
  			switch(format){
  			case GL_LUMINANCE:
  				switch(cpu_type){
  				case GL_BYTE:
  				case GL_UNSIGNED_BYTE:
  					return GL_LUMINANCE8;
  				case GL_SHORT:
  				case GL_UNSIGNED_SHORT:
  					return GL_LUMINANCE16;
  				case GL_INT:
  				case GL_UNSIGNED_INT:
  					return GL_LUMINANCE32I_EXT;
  				case GL_FLOAT:
  					return GL_LUMINANCE32F_ARB;
  				default:
  					std::cout<<"error in stim::gl_texture - unable to guess GPU internal format"<<std::endl;
  					exit(1);
  				}
  			case GL_RGB:
  				switch(cpu_type){
  				case GL_BYTE:
  				case GL_UNSIGNED_BYTE:
  					return GL_RGB8;
  				case GL_SHORT:
  				case GL_UNSIGNED_SHORT:
  					return GL_RGB16;
  				case GL_INT:
  				case GL_UNSIGNED_INT:
  					return GL_RGB32I;
  				case GL_FLOAT:
  					return GL_RGB32F;
  				default:
  					std::cout<<"error in stim::gl_texture - unable to guess GPU internal format"<<std::endl;
  					exit(1);
  				}
  			case GL_RGBA:
  				switch(cpu_type){
  				case GL_BYTE:
  				case GL_UNSIGNED_BYTE:
  					return GL_RGBA8;
  				case GL_SHORT:
  				case GL_UNSIGNED_SHORT:
  					return GL_RGBA16;
  				case GL_INT:
  				case GL_UNSIGNED_INT:
  					return GL_RGBA32I;
  				case GL_FLOAT:
  					return GL_RGBA32F;
  				default:
  					std::cout<<"error in stim::gl_texture - unable to guess GPU internal format"<<std::endl;
  					exit(1);
  				}
  			default:
  				std::cout<<"error in stim::gl_texture - unable to guess GPU internal format"<<std::endl;
  				exit(1);
  			}
  		}
  		///	creates this texture in the current OpenGL context
  		void generate_texture(){
  			glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  			CHECK_OPENGL_ERROR
  			glGenTextures(1, &texID);
  			CHECK_OPENGL_ERROR
  			glBindTexture(texture_type, texID);
  			CHECK_OPENGL_ERROR
  			glTexParameteri(texture_type, GL_TEXTURE_MIN_FILTER, interpolation);
  			CHECK_OPENGL_ERROR
  			glTexParameteri(texture_type, GL_TEXTURE_MAG_FILTER, interpolation);
  			CHECK_OPENGL_ERROR
  			switch(texture_type){
  				case GL_TEXTURE_3D:
  					glTexParameteri(texture_type, GL_TEXTURE_WRAP_S, wrap);
  					glTexParameteri(texture_type, GL_TEXTURE_WRAP_T, wrap);
  					glTexParameteri(texture_type, GL_TEXTURE_WRAP_R, wrap);
  					glTexImage3D(texture_type, 0, gpu_type, (GLsizei)R[1], (GLsizei)R[2], (GLsizei)R[3], 0, format, cpu_type, ptr);
  					break;
  				case GL_TEXTURE_2D:
  					glTexParameteri(texture_type, GL_TEXTURE_WRAP_S, wrap);
  					CHECK_OPENGL_ERROR
  					glTexParameteri(texture_type, GL_TEXTURE_WRAP_T, wrap);
  					CHECK_OPENGL_ERROR
  					glTexImage2D(texture_type, 0, gpu_type, (GLsizei)R[1], (GLsizei)R[2], 0, format, cpu_type, ptr);
  					CHECK_OPENGL_ERROR
  					break;
  				case GL_TEXTURE_1D:
  					glTexParameteri(texture_type, GL_TEXTURE_WRAP_S, wrap);
  					CHECK_OPENGL_ERROR
  					glTexImage1D(texture_type, 0, gpu_type, (GLsizei)R[1], 0, format, cpu_type, ptr);
  					CHECK_OPENGL_ERROR
  					break;
  				default:
  					std::cout<<"Error in stim::gl_texture - unrecognized texture target when generating texture"<<std::endl;
  					exit(1);
  					break;
  			}
  			CHECK_OPENGL_ERROR
983b730b   David Mayerich   texture updates
194
  		}
c512fb94   David Mayerich   fixed file series...
195
196
197
198
199
200
  		void guess_parameters(){
  			setTextureType();									//set the texture type: 1D, 2D, 3D
  			format = guess_format();							//guess the texture format based on the number of image channels
  			cpu_type = guess_cpu_type();						//guess the CPU type based on the template
  			gpu_type = guess_gpu_type();						//guess the GPU type based on the format and template
  		}
983b730b   David Mayerich   texture updates
201
  
197e13de   Pavel Govyadinov   Added new class g...
202
203
  	public:
  
035d798f   Pavel Govyadinov   modified the spid...
204
  		///default constructor
26da82c8   David Mayerich   finalized stim::g...
205
206
207
208
209
210
  		gl_texture(	GLint interp = GL_LINEAR,					//default to linear interpolation
  					GLint twrap = GL_REPEAT)					//default repeating the texture at the edges					
  						: image_stack<T>() {
  			init();												//initialize the texture with NULL values
  			interpolation = interp;								//store the interpolation type
  			wrap = twrap;										//store the wrap type
a4042c24   Pavel Govyadinov   Updated the gl_te...
211
  		}
197e13de   Pavel Govyadinov   Added new class g...
212
  
7b20b4e5   david   fixed image stack...
213
214
  		///@param is a mask indicating the files to load
  		///Creates an instance of the gl_texture object and initializes it with a file list
372b5963   Pavel Govyadinov   added support for...
215
  
26da82c8   David Mayerich   finalized stim::g...
216
217
218
219
  		gl_texture(std::string file_mask, GLint interp = GL_LINEAR, GLint twrap = GL_REPEAT){
  			init();
  			interpolation = interp;								//store interpolation type
  			wrap = twrap;										//store wrap type
7b20b4e5   david   fixed image stack...
220
221
222
223
224
225
226
227
228
229
230
231
  			load_images(file_mask);
  		}
  
  		///Creates an instance of gl_texture and initializes with a file list
  		///@param file_list is a list of files
  		///@param interp is the type of texture interpolation (GL_LINEAR, GL_NEAREST)
  		///@param twrap is the type of texture wrapping
  		gl_texture(std::vector<std::string> file_list, GLint interp = GL_LINEAR, GLint twrap = GL_REPEAT){
  			init();
  			interpolation = interp;
  			wrap = twrap;
  			load_images(file_list);
26da82c8   David Mayerich   finalized stim::g...
232
233
234
235
236
237
238
  		}
  
  		///Attaches the texture to the current OpenGL context and makes it ready to render
  		void attach(){
  			if(texID == 0) generate_texture();					//generate the texture if it doesn't already exist
  			else{
  				std::cout<<"Texture has already been attached to a context."<<std::endl;
fac43319   Pavel Govyadinov   Changed the posit...
239
  				//exit(1);     Why do we need to quit if it's attached. print the message and continue.
26da82c8   David Mayerich   finalized stim::g...
240
241
242
243
244
245
246
  			}
  		}
  
  		//binds a texture to be the current render source
  		void bind(){
  			glBindTexture(texture_type, texID);					//bind the texture to the appropriate texture target
  			CHECK_OPENGL_ERROR
197e13de   Pavel Govyadinov   Added new class g...
247
  		}
035d798f   Pavel Govyadinov   modified the spid...
248
249
  
  		///returns the dimentions of the data in the x, y, z directions. 
2eefb035   Pavel Govyadinov   added debugging c...
250
  		stim::vec<int> getSize(){
b710b044   Pavel Govyadinov   Added more tempor...
251
252
253
  			stim::vec<int> size(R[1], R[2], R[3]);
  			return size;
  		}
a4042c24   Pavel Govyadinov   Updated the gl_te...
254
  
983b730b   David Mayerich   texture updates
255
256
257
258
  		void getSize(size_t& x, size_t& y, size_t& z) {
  			x = R[0]; y = R[1]; z = R[2];
  		}
  
385d2447   Pavel Govyadinov   Checkpoint: Conve...
259
260
261
262
  		///@param x size of the voxel in x direction
  		///@param y size of the voxel in y direction
  		///@param z size of the voxel in z direction
  		///	Sets the dimenstions of the voxels.
983b730b   David Mayerich   texture updates
263
  		void setSpacing(float sx, float sy, float sz){
256b431c   david   fixed Linux compi...
264
265
266
  			grid<T, 4, F>::S[1] = sx;
  			grid<T, 4, F>::S[2] = sy;
  			grid<T, 4, F>::S[3] = sz;
385d2447   Pavel Govyadinov   Checkpoint: Conve...
267
268
  		}
  
035d798f   Pavel Govyadinov   modified the spid...
269
  		///Returns a stim::vec that contains the x, y, z sizes of the voxel.
983b730b   David Mayerich   texture updates
270
  		vec<float> getDims(){
256b431c   david   fixed Linux compi...
271
  			vec<float> dims(grid<T, 4, F>::S[1], grid<T, 4, F>::S[2], grid<T, 4, F>::S[3]);
385d2447   Pavel Govyadinov   Checkpoint: Conve...
272
  			return dims;
c512fb94   David Mayerich   fixed file series...
273
274
275
276
277
278
279
280
  		}
  
  		/// Loads a series of files specified by a list of strings
  		/// @param file_list is the vector of file names as strings
  		void load_images(std::vector<std::string> file_list){
  			image_stack<T, F>::load_images(file_list);			//load the images
  			guess_parameters();
  		}
385d2447   Pavel Govyadinov   Checkpoint: Conve...
281
  
983b730b   David Mayerich   texture updates
282
  		///@param file_mask specifies the file(s) to be loaded
385d2447   Pavel Govyadinov   Checkpoint: Conve...
283
  		///	Sets the path and calls the loader on that path.
c512fb94   David Mayerich   fixed file series...
284
  		void load_images(std::string file_mask){
2eefb035   Pavel Govyadinov   added debugging c...
285
  			image_stack<T, F>::load_images(file_mask);				//load images
c512fb94   David Mayerich   fixed file series...
286
  			guess_parameters();
197e13de   Pavel Govyadinov   Added new class g...
287
  		}
a4042c24   Pavel Govyadinov   Updated the gl_te...
288
  
035d798f   Pavel Govyadinov   modified the spid...
289
  		///	Returns the GLuint id of the texture created by/associated with the 
983b730b   David Mayerich   texture updates
290
291
  		///	instance of the gl_texture class.				
  		GLuint getTexture(){
a4042c24   Pavel Govyadinov   Updated the gl_te...
292
  			return texID;
197e13de   Pavel Govyadinov   Added new class g...
293
  		}
385d2447   Pavel Govyadinov   Checkpoint: Conve...
294
  		
2eefb035   Pavel Govyadinov   added debugging c...
295
  	
26da82c8   David Mayerich   finalized stim::g...
296
  		T* getData(){
63fcb5c8   Pavel Govyadinov   added some tempor...
297
298
  			return ptr;
  		}
2eefb035   Pavel Govyadinov   added debugging c...
299
300
301
302
303
304
  	
  		void setData(T* rts)
  		{
  				
  		}
  
a4042c24   Pavel Govyadinov   Updated the gl_te...
305
  	};
2eefb035   Pavel Govyadinov   added debugging c...
306
  
197e13de   Pavel Govyadinov   Added new class g...
307
308
309
310
311
312
313
314
  }
  
  
  	
  	
  
  
  #endif