Commit 26da82c8bdc9c3289d5dfae45b2629acd99edda6
1 parent
983b730b
finalized stim::gl_texture edits for Windows
Showing
4 changed files
with
296 additions
and
103 deletions
Show diff stats
stim/gl/gl_texture.h
@@ -5,8 +5,11 @@ | @@ -5,8 +5,11 @@ | ||
5 | #include <iostream> | 5 | #include <iostream> |
6 | #include <vector> | 6 | #include <vector> |
7 | #include "../grids/image_stack.h" | 7 | #include "../grids/image_stack.h" |
8 | -#include <GL/glut.h> | ||
9 | -#include <GL/glext.h> | 8 | +//Visual Studio requires GLEW |
9 | +#ifdef _WIN32 | ||
10 | + #include <GL/glew.h> | ||
11 | +#endif | ||
12 | +//#include <GL/glut.h> | ||
10 | #include <stim/gl/error.h> | 13 | #include <stim/gl/error.h> |
11 | namespace stim{ | 14 | namespace stim{ |
12 | 15 | ||
@@ -15,21 +18,21 @@ class gl_texture | @@ -15,21 +18,21 @@ class gl_texture | ||
15 | Uses image_stack class in order to create a texture object. | 18 | Uses image_stack class in order to create a texture object. |
16 | */ | 19 | */ |
17 | 20 | ||
18 | -template<typename T> | ||
19 | -class gl_texture : public virtual image_stack<T> | 21 | +template<typename T, typename F = float> |
22 | +class gl_texture : public virtual image_stack<T, F> | ||
20 | { | 23 | { |
21 | protected: | 24 | protected: |
22 | //std::string path; | 25 | //std::string path; |
23 | GLuint texID; //OpenGL object | 26 | GLuint texID; //OpenGL object |
24 | GLenum texture_type; //1D, 2D, 3D | 27 | GLenum texture_type; //1D, 2D, 3D |
25 | - GLint interpType; | ||
26 | - GLint texWrap; | ||
27 | - GLenum type; | ||
28 | - GLenum format; | 28 | + GLint interpolation; |
29 | + GLint wrap; | ||
30 | + GLenum cpu_type; | ||
31 | + GLenum gpu_type; | ||
32 | + GLenum format; //format for the texture (GL_RGBA, GL_LUMINANCE, etc.) | ||
29 | using image_stack<T>::R; | 33 | using image_stack<T>::R; |
30 | - using image_stack<T>::S; | 34 | + //using image_stack<T>::S; |
31 | using image_stack<T>::ptr; | 35 | using image_stack<T>::ptr; |
32 | - using image_stack<T>::samples; | ||
33 | 36 | ||
34 | /// Sets the internal texture_type, based on the data dimensions | 37 | /// Sets the internal texture_type, based on the data dimensions |
35 | void setTextureType(){ | 38 | void setTextureType(){ |
@@ -44,22 +47,186 @@ class gl_texture : public virtual image_stack<T> | @@ -44,22 +47,186 @@ class gl_texture : public virtual image_stack<T> | ||
44 | //initializes important variables | 47 | //initializes important variables |
45 | void init() { | 48 | void init() { |
46 | texID = 0; //initialize texture ID to zero, default if OpenGL returns an error | 49 | texID = 0; //initialize texture ID to zero, default if OpenGL returns an error |
47 | - memset(R, 0, sizeof) | 50 | + memset(R, 0, sizeof(size_t)); |
51 | + memset(S, 0, sizeof(F)); | ||
52 | + } | ||
53 | + | ||
54 | + //guesses the color format of the texture | ||
55 | + GLenum guess_format(){ | ||
56 | + size_t channels = R[0]; | ||
57 | + switch(channels){ | ||
58 | + case 1: | ||
59 | + return GL_LUMINANCE; | ||
60 | + case 2: | ||
61 | + return GL_RG; | ||
62 | + case 3: | ||
63 | + return GL_RGB; | ||
64 | + case 4: | ||
65 | + return GL_RGBA; | ||
66 | + default: | ||
67 | + std::cout<<"Error in stim::gl_texture - unable to guess texture format based on number of channels ("<<R[4]<<")"<<std::endl; | ||
68 | + exit(1); | ||
69 | + } | ||
70 | + } | ||
71 | + | ||
72 | + //guesses the OpenGL CPU data type based on T | ||
73 | + GLenum guess_cpu_type(){ | ||
74 | + // The following is C++ 11 code, but causes problems on some compilers (ex. nvcc). Below is my best approximation to a solution | ||
75 | + | ||
76 | + //if(std::is_same<T, unsigned char>::value) return CV_MAKETYPE(CV_8U, (int)C()); | ||
77 | + //if(std::is_same<T, char>::value) return CV_MAKETYPE(CV_8S, (int)C()); | ||
78 | + //if(std::is_same<T, unsigned short>::value) return CV_MAKETYPE(CV_16U, (int)C()); | ||
79 | + //if(std::is_same<T, short>::value) return CV_MAKETYPE(CV_16S, (int)C()); | ||
80 | + //if(std::is_same<T, int>::value) return CV_MAKETYPE(CV_32S, (int)C()); | ||
81 | + //if(std::is_same<T, float>::value) return CV_MAKETYPE(CV_32F, (int)C()); | ||
82 | + //if(std::is_same<T, double>::value) return CV_MAKETYPE(CV_64F, (int)C()); | ||
83 | + | ||
84 | + if(typeid(T) == typeid(unsigned char)) return GL_UNSIGNED_BYTE; | ||
85 | + if(typeid(T) == typeid(char)) return GL_BYTE; | ||
86 | + if(typeid(T) == typeid(unsigned short)) return GL_UNSIGNED_SHORT; | ||
87 | + if(typeid(T) == typeid(short)) return GL_SHORT; | ||
88 | + if(typeid(T) == typeid(unsigned int)) return GL_UNSIGNED_INT; | ||
89 | + if(typeid(T) == typeid(int)) return GL_INT; | ||
90 | + if(typeid(T) == typeid(float)) return GL_FLOAT; | ||
91 | + | ||
92 | + std::cout<<"ERROR in stim::gl_texture - no valid data type found"<<std::endl; | ||
93 | + exit(1); | ||
94 | + } | ||
95 | + | ||
96 | + //Guesses the "internal format" of the texture to closely approximate the original format | ||
97 | + GLint guess_gpu_type(){ | ||
98 | + switch(format){ | ||
99 | + case GL_LUMINANCE: | ||
100 | + switch(cpu_type){ | ||
101 | + case GL_BYTE: | ||
102 | + case GL_UNSIGNED_BYTE: | ||
103 | + return GL_LUMINANCE8; | ||
104 | + case GL_SHORT: | ||
105 | + case GL_UNSIGNED_SHORT: | ||
106 | + return GL_LUMINANCE16; | ||
107 | + case GL_INT: | ||
108 | + case GL_UNSIGNED_INT: | ||
109 | + return GL_LUMINANCE32I_EXT; | ||
110 | + case GL_FLOAT: | ||
111 | + return GL_LUMINANCE32F_ARB; | ||
112 | + default: | ||
113 | + std::cout<<"error in stim::gl_texture - unable to guess GPU internal format"<<std::endl; | ||
114 | + exit(1); | ||
115 | + } | ||
116 | + case GL_RGB: | ||
117 | + switch(cpu_type){ | ||
118 | + case GL_BYTE: | ||
119 | + case GL_UNSIGNED_BYTE: | ||
120 | + return GL_RGB8; | ||
121 | + case GL_SHORT: | ||
122 | + case GL_UNSIGNED_SHORT: | ||
123 | + return GL_RGB16; | ||
124 | + case GL_INT: | ||
125 | + case GL_UNSIGNED_INT: | ||
126 | + return GL_RGB32I; | ||
127 | + case GL_FLOAT: | ||
128 | + return GL_RGB32F; | ||
129 | + default: | ||
130 | + std::cout<<"error in stim::gl_texture - unable to guess GPU internal format"<<std::endl; | ||
131 | + exit(1); | ||
132 | + } | ||
133 | + case GL_RGBA: | ||
134 | + switch(cpu_type){ | ||
135 | + case GL_BYTE: | ||
136 | + case GL_UNSIGNED_BYTE: | ||
137 | + return GL_RGBA8; | ||
138 | + case GL_SHORT: | ||
139 | + case GL_UNSIGNED_SHORT: | ||
140 | + return GL_RGBA16; | ||
141 | + case GL_INT: | ||
142 | + case GL_UNSIGNED_INT: | ||
143 | + return GL_RGBA32I; | ||
144 | + case GL_FLOAT: | ||
145 | + return GL_RGBA32F; | ||
146 | + default: | ||
147 | + std::cout<<"error in stim::gl_texture - unable to guess GPU internal format"<<std::endl; | ||
148 | + exit(1); | ||
149 | + } | ||
150 | + default: | ||
151 | + std::cout<<"error in stim::gl_texture - unable to guess GPU internal format"<<std::endl; | ||
152 | + exit(1); | ||
153 | + } | ||
154 | + } | ||
155 | + /// creates this texture in the current OpenGL context | ||
156 | + void generate_texture(){ | ||
157 | + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | ||
158 | + CHECK_OPENGL_ERROR | ||
159 | + glGenTextures(1, &texID); | ||
160 | + CHECK_OPENGL_ERROR | ||
161 | + glBindTexture(texture_type, texID); | ||
162 | + CHECK_OPENGL_ERROR | ||
163 | + glTexParameteri(texture_type, GL_TEXTURE_MIN_FILTER, interpolation); | ||
164 | + CHECK_OPENGL_ERROR | ||
165 | + glTexParameteri(texture_type, GL_TEXTURE_MAG_FILTER, interpolation); | ||
166 | + CHECK_OPENGL_ERROR | ||
167 | + switch(texture_type){ | ||
168 | + case GL_TEXTURE_3D: | ||
169 | + glTexParameteri(texture_type, GL_TEXTURE_WRAP_S, wrap); | ||
170 | + glTexParameteri(texture_type, GL_TEXTURE_WRAP_T, wrap); | ||
171 | + glTexParameteri(texture_type, GL_TEXTURE_WRAP_R, wrap); | ||
172 | + glTexImage3D(texture_type, 0, gpu_type, (GLsizei)R[1], (GLsizei)R[2], (GLsizei)R[3], 0, format, cpu_type, ptr); | ||
173 | + break; | ||
174 | + case GL_TEXTURE_2D: | ||
175 | + glTexParameteri(texture_type, GL_TEXTURE_WRAP_S, wrap); | ||
176 | + CHECK_OPENGL_ERROR | ||
177 | + glTexParameteri(texture_type, GL_TEXTURE_WRAP_T, wrap); | ||
178 | + CHECK_OPENGL_ERROR | ||
179 | + glTexImage2D(texture_type, 0, gpu_type, (GLsizei)R[1], (GLsizei)R[2], 0, format, cpu_type, ptr); | ||
180 | + CHECK_OPENGL_ERROR | ||
181 | + break; | ||
182 | + case GL_TEXTURE_1D: | ||
183 | + glTexParameteri(texture_type, GL_TEXTURE_WRAP_S, wrap); | ||
184 | + CHECK_OPENGL_ERROR | ||
185 | + glTexImage1D(texture_type, 0, gpu_type, (GLsizei)R[1], 0, format, cpu_type, ptr); | ||
186 | + CHECK_OPENGL_ERROR | ||
187 | + break; | ||
188 | + default: | ||
189 | + std::cout<<"Error in stim::gl_texture - unrecognized texture target when generating texture"<<std::endl; | ||
190 | + exit(1); | ||
191 | + break; | ||
192 | + } | ||
193 | + CHECK_OPENGL_ERROR | ||
48 | } | 194 | } |
49 | 195 | ||
50 | public: | 196 | public: |
51 | 197 | ||
52 | ///default constructor | 198 | ///default constructor |
53 | - gl_texture() : image_stack<T>() { | ||
54 | - | 199 | + gl_texture( GLint interp = GL_LINEAR, //default to linear interpolation |
200 | + GLint twrap = GL_REPEAT) //default repeating the texture at the edges | ||
201 | + : image_stack<T>() { | ||
202 | + init(); //initialize the texture with NULL values | ||
203 | + interpolation = interp; //store the interpolation type | ||
204 | + wrap = twrap; //store the wrap type | ||
55 | } | 205 | } |
56 | 206 | ||
57 | ///@param string path to the directory with the image files. | 207 | ///@param string path to the directory with the image files. |
58 | ///Creates an instance of the gl_texture object with a path to the data. | 208 | ///Creates an instance of the gl_texture object with a path to the data. |
59 | 209 | ||
60 | - gl_texture(std::string file_mask){ | ||
61 | - image_stack<T>::load_images(file_mask); | ||
62 | - setTextureType(); | 210 | + gl_texture(std::string file_mask, GLint interp = GL_LINEAR, GLint twrap = GL_REPEAT){ |
211 | + init(); | ||
212 | + interpolation = interp; //store interpolation type | ||
213 | + wrap = twrap; //store wrap type | ||
214 | + load(file_mask); | ||
215 | + } | ||
216 | + | ||
217 | + ///Attaches the texture to the current OpenGL context and makes it ready to render | ||
218 | + void attach(){ | ||
219 | + if(texID == 0) generate_texture(); //generate the texture if it doesn't already exist | ||
220 | + else{ | ||
221 | + std::cout<<"Texture has already been attached to a context."<<std::endl; | ||
222 | + exit(1); | ||
223 | + } | ||
224 | + } | ||
225 | + | ||
226 | + //binds a texture to be the current render source | ||
227 | + void bind(){ | ||
228 | + glBindTexture(texture_type, texID); //bind the texture to the appropriate texture target | ||
229 | + CHECK_OPENGL_ERROR | ||
63 | } | 230 | } |
64 | 231 | ||
65 | ///returns the dimentions of the data in the x, y, z directions. | 232 | ///returns the dimentions of the data in the x, y, z directions. |
@@ -72,21 +239,6 @@ class gl_texture : public virtual image_stack<T> | @@ -72,21 +239,6 @@ class gl_texture : public virtual image_stack<T> | ||
72 | x = R[0]; y = R[1]; z = R[2]; | 239 | x = R[0]; y = R[1]; z = R[2]; |
73 | } | 240 | } |
74 | 241 | ||
75 | - ///@param GLint interp --GL_LINEAR, GL_NEAREST... | ||
76 | - ///@param GLint twrap --GL_REPEAR, GL_CLAMP_TO_EDGE... | ||
77 | - ///@param GLenum dataType --GL_UNSIGNED_BYTE, GL_FLOAT16... | ||
78 | - ///@param GLenum dataFormat--GL_LUMINANCE, GL_RGB... | ||
79 | - /// Texture paramenters. | ||
80 | - void setTexParam(GLint interp = GL_LINEAR, | ||
81 | - GLint twrap = GL_CLAMP_TO_EDGE, | ||
82 | - GLenum dataType = GL_UNSIGNED_BYTE, | ||
83 | - GLenum dataFormat = GL_LUMINANCE){ | ||
84 | - interpType = interp; | ||
85 | - texWrap = twrap; | ||
86 | - type = dataType; | ||
87 | - format = dataFormat; | ||
88 | - } | ||
89 | - | ||
90 | ///@param x size of the voxel in x direction | 242 | ///@param x size of the voxel in x direction |
91 | ///@param y size of the voxel in y direction | 243 | ///@param y size of the voxel in y direction |
92 | ///@param z size of the voxel in z direction | 244 | ///@param z size of the voxel in z direction |
@@ -106,15 +258,12 @@ class gl_texture : public virtual image_stack<T> | @@ -106,15 +258,12 @@ class gl_texture : public virtual image_stack<T> | ||
106 | ///@param file_mask specifies the file(s) to be loaded | 258 | ///@param file_mask specifies the file(s) to be loaded |
107 | /// Sets the path and calls the loader on that path. | 259 | /// Sets the path and calls the loader on that path. |
108 | void load(std::string file_mask){ | 260 | void load(std::string file_mask){ |
109 | - image_stack<T>::load_images(file_mask); | ||
110 | - setTextureType(); | 261 | + image_stack<T>::load_images(file_mask); //load images |
262 | + setTextureType(); //set the texture type: 1D, 2D, 3D | ||
263 | + format = guess_format(); //guess the texture format based on the number of image channels | ||
264 | + cpu_type = guess_cpu_type(); //guess the CPU type based on the template | ||
265 | + gpu_type = guess_gpu_type(); //guess the GPU type based on the format and template | ||
111 | } | 266 | } |
112 | - | ||
113 | - /// Returns an std::string path associated with an instance of the gl_texture class. | ||
114 | - //std::string getPath() | ||
115 | - //{ | ||
116 | - // return path; | ||
117 | - //} | ||
118 | 267 | ||
119 | /// Returns the GLuint id of the texture created by/associated with the | 268 | /// Returns the GLuint id of the texture created by/associated with the |
120 | /// instance of the gl_texture class. | 269 | /// instance of the gl_texture class. |
@@ -122,39 +271,8 @@ class gl_texture : public virtual image_stack<T> | @@ -122,39 +271,8 @@ class gl_texture : public virtual image_stack<T> | ||
122 | return texID; | 271 | return texID; |
123 | } | 272 | } |
124 | 273 | ||
125 | - /// Creates a texture and from the loaded data and | ||
126 | - /// assigns that texture to texID | ||
127 | - //TO DO :::: 1D textures | ||
128 | - //TO DO:::add methods for handling the cases of T | ||
129 | - // and convert them to GL equivalent. | ||
130 | - // i.e. an overloaded function that handles paramenter conversion. | ||
131 | - void createTexture(){ | ||
132 | - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | ||
133 | - glGenTextures(1, &texID); | ||
134 | - glBindTexture(texture_type, texID); | ||
135 | - glTexParameteri(texture_type, GL_TEXTURE_MIN_FILTER, interpType); | ||
136 | - glTexParameteri(texture_type, GL_TEXTURE_MAG_FILTER, interpType); | ||
137 | - switch(texture_type){ | ||
138 | - case GL_TEXTURE_3D: | ||
139 | - glTexParameteri(texture_type, GL_TEXTURE_WRAP_S, texWrap); | ||
140 | - glTexParameteri(texture_type, GL_TEXTURE_WRAP_T, texWrap); | ||
141 | - glTexParameteri(texture_type, GL_TEXTURE_WRAP_R, texWrap); | ||
142 | - glTexImage3D(texture_type, 0, 1, R[1], R[2], R[3], 0, format, type, ptr); | ||
143 | - glPixelStorei(GL_PACK_ALIGNMENT,1); | ||
144 | - break; | ||
145 | - case GL_TEXTURE_2D: | ||
146 | - glTexParameteri(texture_type, GL_TEXTURE_WRAP_S, texWrap); | ||
147 | - glTexParameteri(texture_type, GL_TEXTURE_WRAP_T, texWrap); | ||
148 | - glTexImage2D(texture_type, 0, 1, R[1], R[2], 0, format, type, ptr); | ||
149 | - break; | ||
150 | - } | ||
151 | - } | ||
152 | - ///Temporary methods for debugging and testing are below. | ||
153 | - ///Self-explanatory. | ||
154 | 274 | ||
155 | - T* | ||
156 | - getData() | ||
157 | - { | 275 | + T* getData(){ |
158 | return ptr; | 276 | return ptr; |
159 | } | 277 | } |
160 | 278 |
stim/grids/grid.h
@@ -24,27 +24,26 @@ protected: | @@ -24,27 +24,26 @@ protected: | ||
24 | F S[D]; //spacing between element samples | 24 | F S[D]; //spacing between element samples |
25 | T* ptr; //pointer to the data (on the GPU or CPU) | 25 | T* ptr; //pointer to the data (on the GPU or CPU) |
26 | 26 | ||
27 | - ///Return the total number of values in the binary file | ||
28 | - size_t samples(){ | ||
29 | - size_t s = 1; | ||
30 | - for(size_t d = 0; d < D; d++) | ||
31 | - s *= R[d]; | ||
32 | - return s; | ||
33 | - } | 27 | + |
34 | 28 | ||
35 | ///Initializes a grid by allocating the necessary memory and setting all values to zero | 29 | ///Initializes a grid by allocating the necessary memory and setting all values to zero |
36 | void init(){ | 30 | void init(){ |
37 | - size_t N = samples(); //calculate the total number of values | ||
38 | - ptr = (T*)calloc(sizeof(T) * N); //allocate memory to store the grid | 31 | + ptr = NULL; //initialize the data pointer to NULL |
32 | + memset(R, 0, sizeof(size_t) * D); //set the resolution to zero | ||
33 | + for(size_t d = 0; d < D; d++) S[d] = (F)1.0; //initialize the spacing to unity | ||
34 | + } | ||
35 | + | ||
36 | + void alloc(){ | ||
37 | + if(ptr != NULL) free(ptr); //if memory has already been allocated, free it | ||
38 | + size_t N = samples(); //calculate the total number of values | ||
39 | + ptr = (T*)calloc(sizeof(T), N); //allocate memory to store the grid | ||
39 | } | 40 | } |
40 | 41 | ||
41 | public: | 42 | public: |
42 | 43 | ||
43 | ///Default constructor doesn't do anything | 44 | ///Default constructor doesn't do anything |
44 | grid(){ | 45 | grid(){ |
45 | - memset(R, 0, sizeof(size_t) * D); //initialize the grid dimensions to zero | ||
46 | - memset(S, 0, sizeof(F) * D); //initialize the grid size to zero | ||
47 | - ptr = NULL; //set the data pointer to NULL | 46 | + init(); |
48 | } | 47 | } |
49 | 48 | ||
50 | ///Constructor used to specify the grid size as a vector | 49 | ///Constructor used to specify the grid size as a vector |
@@ -56,6 +55,19 @@ public: | @@ -56,6 +55,19 @@ public: | ||
56 | init(); | 55 | init(); |
57 | } | 56 | } |
58 | 57 | ||
58 | + ///Return the total number of values in the binary file | ||
59 | + size_t samples(){ | ||
60 | + size_t s = 1; | ||
61 | + for(size_t d = 0; d < D; d++) | ||
62 | + s *= R[d]; | ||
63 | + return s; | ||
64 | + } | ||
65 | + | ||
66 | + ///Return the number of bytes in the binary file | ||
67 | + size_t bytes(){ | ||
68 | + return samples() * sizeof(T); | ||
69 | + } | ||
70 | + | ||
59 | void | 71 | void |
60 | setDim(stim::vec<float> s){ | 72 | setDim(stim::vec<float> s){ |
61 | for(size_t d = 0; d < D; d++) | 73 | for(size_t d = 0; d < D; d++) |
@@ -64,7 +76,7 @@ public: | @@ -64,7 +76,7 @@ public: | ||
64 | 76 | ||
65 | ///Constructor used to specify the grid size as a set of parameters | 77 | ///Constructor used to specify the grid size as a set of parameters |
66 | /// @param X0... is a list of values describing the grid size along each dimension | 78 | /// @param X0... is a list of values describing the grid size along each dimension |
67 | - grid( size_t X0, ...){ | 79 | + /*grid( size_t X0, ...){ |
68 | R[0] = X0; //set the grid size of the first dimension | 80 | R[0] = X0; //set the grid size of the first dimension |
69 | va_list ap; //get a variable list | 81 | va_list ap; //get a variable list |
70 | va_start(ap, X0); //start the variable list at the first element | 82 | va_start(ap, X0); //start the variable list at the first element |
@@ -72,18 +84,35 @@ public: | @@ -72,18 +84,35 @@ public: | ||
72 | R[d] = va_arg(ap, size_t); //read the value from the variable list as a size_t | 84 | R[d] = va_arg(ap, size_t); //read the value from the variable list as a size_t |
73 | va_end(ap); | 85 | va_end(ap); |
74 | init(); //initialize the grid | 86 | init(); //initialize the grid |
75 | - } | 87 | + }*/ |
76 | 88 | ||
77 | ///Set the spacing between grid sample points | 89 | ///Set the spacing between grid sample points |
78 | /// @param X0... is a list of values describing the grid sample spacing | 90 | /// @param X0... is a list of values describing the grid sample spacing |
79 | - void spacing(F X0, ...) { | 91 | + /*void spacing(F X0, ...) { |
80 | S[0] = X0; //set the grid size of the first dimension | 92 | S[0] = X0; //set the grid size of the first dimension |
81 | va_list ap; //get a variable list | 93 | va_list ap; //get a variable list |
82 | va_start(ap, X0); //start the variable list at the first element | 94 | va_start(ap, X0); //start the variable list at the first element |
83 | for (size_t d = 1; d<D; d++) //for each additional element | 95 | for (size_t d = 1; d<D; d++) //for each additional element |
84 | - S[d] = va_arg(ap, size_t); //read the value from the variable list as a size_t | 96 | + S[d] = va_arg(ap, F); //read the value from the variable list as a size_t |
85 | va_end(ap); | 97 | va_end(ap); |
86 | - init(); //initialize the grid | 98 | + }*/ |
99 | + | ||
100 | + /// Set the spacing between grid sample points for the specified dimension | ||
101 | + void spacing(size_t d, F sp){ | ||
102 | + if(d < D) S[d] = sp; | ||
103 | + else{ | ||
104 | + std::cout<<"error in stim::grid::spacing() - insufficient dimensions"<<std::endl; | ||
105 | + exit(1); | ||
106 | + } | ||
107 | + } | ||
108 | + | ||
109 | + /// Return the spacing for a given dimension | ||
110 | + F spacing(size_t d){ | ||
111 | + if(d < D) return S[d]; | ||
112 | + else{ | ||
113 | + std::cout<<"error in stim::grid::spacing() - insufficient dimensions"<<std::endl; | ||
114 | + exit(1); | ||
115 | + } | ||
87 | } | 116 | } |
88 | 117 | ||
89 | /// Get the sample spacing for the given dimension | 118 | /// Get the sample spacing for the given dimension |
@@ -91,6 +120,16 @@ public: | @@ -91,6 +120,16 @@ public: | ||
91 | return S[d]; | 120 | return S[d]; |
92 | } | 121 | } |
93 | 122 | ||
123 | + /// Get the size of the grid along the specified dimension | ||
124 | + F size(size_t d){ | ||
125 | + return (F)R[d] * S[d]; | ||
126 | + } | ||
127 | + | ||
128 | + /// Return the number of samples | ||
129 | + size_t samples(size_t d){ | ||
130 | + return R[d]; | ||
131 | + } | ||
132 | + | ||
94 | ///Writes the binary data to disk | 133 | ///Writes the binary data to disk |
95 | 134 | ||
96 | /// @param filename is the name of the binary file to be written | 135 | /// @param filename is the name of the binary file to be written |
@@ -118,7 +157,7 @@ public: | @@ -118,7 +157,7 @@ public: | ||
118 | 157 | ||
119 | ///Gets a single value from the grid given a set of coordinates | 158 | ///Gets a single value from the grid given a set of coordinates |
120 | /// @param x0... is a list of coordinates specifying the desired value | 159 | /// @param x0... is a list of coordinates specifying the desired value |
121 | - T get(unsigned long x0, ...){ | 160 | + /*T get(unsigned long x0, ...){ |
122 | 161 | ||
123 | va_list ap; //create a variable list | 162 | va_list ap; //create a variable list |
124 | 163 | ||
@@ -133,13 +172,13 @@ public: | @@ -133,13 +172,13 @@ public: | ||
133 | va_end(ap); | 172 | va_end(ap); |
134 | 173 | ||
135 | return ptr[idx]; //access the appropriate element and return the value | 174 | return ptr[idx]; //access the appropriate element and return the value |
136 | - } | 175 | + }*/ |
137 | 176 | ||
138 | ///Sets a value in the grid | 177 | ///Sets a value in the grid |
139 | 178 | ||
140 | /// @param value is the grid point value | 179 | /// @param value is the grid point value |
141 | /// @x0... is the coordinate of the value to be set | 180 | /// @x0... is the coordinate of the value to be set |
142 | - void set(T value, unsigned long x0, ...){ | 181 | + /*void set(T value, unsigned long x0, ...){ |
143 | va_list ap; //create a variable list | 182 | va_list ap; //create a variable list |
144 | unsigned long F = 1; //initialize the dimension counter to 1 | 183 | unsigned long F = 1; //initialize the dimension counter to 1 |
145 | unsigned long idx = x0; //initialize the index to the first variable | 184 | unsigned long idx = x0; //initialize the index to the first variable |
@@ -151,7 +190,7 @@ public: | @@ -151,7 +190,7 @@ public: | ||
151 | } | 190 | } |
152 | va_end(ap); | 191 | va_end(ap); |
153 | ptr[idx] = value; //set the value at the indexed location | 192 | ptr[idx] = value; //set the value at the indexed location |
154 | - } | 193 | + }*/ |
155 | 194 | ||
156 | 195 | ||
157 | ///Outputs grid data as a string | 196 | ///Outputs grid data as a string |
stim/grids/image_stack.h
@@ -10,16 +10,15 @@ namespace stim{ | @@ -10,16 +10,15 @@ namespace stim{ | ||
10 | 10 | ||
11 | ///This class is used to load 3D grid data from stacks of images | 11 | ///This class is used to load 3D grid data from stacks of images |
12 | // The class uses a 4D grid object, where the first dimension is a color value. | 12 | // The class uses a 4D grid object, where the first dimension is a color value. |
13 | -template<typename T> | ||
14 | -class image_stack : public virtual stim::grid<T, 4>{ | 13 | +template<typename T, typename F = float> |
14 | +class image_stack : public virtual stim::grid<T, 4, F>{ | ||
15 | 15 | ||
16 | enum image_type {stimAuto, stimMono, stimRGB, stimRGBA}; | 16 | enum image_type {stimAuto, stimMono, stimRGB, stimRGBA}; |
17 | 17 | ||
18 | protected: | 18 | protected: |
19 | - using stim::grid<T, 4>::S; | 19 | + //using stim::grid<T, 4>::S; |
20 | using stim::grid<T, 4>::R; | 20 | using stim::grid<T, 4>::R; |
21 | using stim::grid<T, 4>::ptr; | 21 | using stim::grid<T, 4>::ptr; |
22 | - using stim::grid<T, 4>::samples; | ||
23 | using stim::grid<T, 4>::read; | 22 | using stim::grid<T, 4>::read; |
24 | 23 | ||
25 | public: | 24 | public: |
@@ -28,6 +27,42 @@ public: | @@ -28,6 +27,42 @@ public: | ||
28 | 27 | ||
29 | } | 28 | } |
30 | 29 | ||
30 | + /// Overloads grid::samples() to return the number of samples associated with a given spatial dimension | ||
31 | + /// this is necessary because R[0] stores the color | ||
32 | + size_t samples(size_t d){ | ||
33 | + return grid<T, 4, F>::samples(d + 1); | ||
34 | + } | ||
35 | + | ||
36 | + size_t samples(){ | ||
37 | + return R[1] * R[2] * R[3]; //return the number of spatial samples | ||
38 | + } | ||
39 | + | ||
40 | + /// Returns the number of color channels | ||
41 | + size_t channels(){ | ||
42 | + return R[0]; | ||
43 | + } | ||
44 | + | ||
45 | + /// Overloads grid::size() to return the size of the grid associated with a given spatial dimension | ||
46 | + F size(size_t d){ | ||
47 | + return grid<T, 4, F>::size(d + 1); | ||
48 | + } | ||
49 | + | ||
50 | + /// Sets the spacing between samples in the image stack | ||
51 | + void spacing(F sx, F sy, F sz){ | ||
52 | + grid<T, 4, F>::S[1] = sx; //set the sample spacing for the appropriate spatial dimension | ||
53 | + grid<T, 4, F>::S[2] = sy; | ||
54 | + grid<T, 4, F>::S[3] = sz; | ||
55 | + } | ||
56 | + | ||
57 | + F spacing(size_t d){ | ||
58 | + return grid<T, 4, F>::spacing(d + 1); | ||
59 | + } | ||
60 | + | ||
61 | + /// Overloads the spacing parameter to set the size of the grid associated with a given spatial dimension | ||
62 | + //void spacing(F sx, F sy = 1.0f, F sz = 1.0f){ | ||
63 | + // grid<T, 4, F>::spacing((F)1.0, sx, sy, sz); | ||
64 | + //} | ||
65 | + | ||
31 | ///Load an image stack based on a file mask. Images are loaded in alphanumeric order | 66 | ///Load an image stack based on a file mask. Images are loaded in alphanumeric order |
32 | /// @param file_mask is the mask describing images to be loaded | 67 | /// @param file_mask is the mask describing images to be loaded |
33 | void load_images(std::string file_mask){ | 68 | void load_images(std::string file_mask){ |
@@ -42,17 +77,15 @@ public: | @@ -42,17 +77,15 @@ public: | ||
42 | std::cout<<"STIM ERROR (image_stack): No matching files for loading a stack."<<std::endl; | 77 | std::cout<<"STIM ERROR (image_stack): No matching files for loading a stack."<<std::endl; |
43 | exit(1); | 78 | exit(1); |
44 | } | 79 | } |
45 | - for(int i = 0; i < file_list.size(); i++) | ||
46 | - std::cout << file_list[i].str() << std::endl; | ||
47 | 80 | ||
48 | //load the first image and set all of the image_stack properties | 81 | //load the first image and set all of the image_stack properties |
49 | stim::image<T> I(file_list[0].str()); | 82 | stim::image<T> I(file_list[0].str()); |
50 | 83 | ||
51 | //set the image resolution and number of channels | 84 | //set the image resolution and number of channels |
52 | - R.push(I.channels()); | ||
53 | - R.push(I.width()); | ||
54 | - R.push(I.height()); | ||
55 | - R.push(file_list.size()); | 85 | + R[0] = I.channels(); |
86 | + R[1] = I.width(); | ||
87 | + R[2] = I.height(); | ||
88 | + R[3] = file_list.size(); | ||
56 | 89 | ||
57 | //allocate storage space | 90 | //allocate storage space |
58 | ptr = (T*)malloc(sizeof(T) * samples()); | 91 | ptr = (T*)malloc(sizeof(T) * samples()); |
stim/image/image.h
@@ -159,7 +159,10 @@ public: | @@ -159,7 +159,10 @@ public: | ||
159 | std::cout<<"ERROR stim::image::load() - unable to find image "<<filename<<std::endl; | 159 | std::cout<<"ERROR stim::image::load() - unable to find image "<<filename<<std::endl; |
160 | exit(1); | 160 | exit(1); |
161 | } | 161 | } |
162 | - allocate(cvImage.cols, cvImage.rows, cvImage.channels()); //allocate space for the image | 162 | + int cols = cvImage.cols; |
163 | + int rows = cvImage.rows; | ||
164 | + int channels = cvImage.channels(); | ||
165 | + allocate(cols, rows, channels); //allocate space for the image | ||
163 | unsigned char* cv_ptr = (unsigned char*)cvImage.data; | 166 | unsigned char* cv_ptr = (unsigned char*)cvImage.data; |
164 | if(C() == 1) //if this is a single-color image, just copy the data | 167 | if(C() == 1) //if this is a single-color image, just copy the data |
165 | memcpy(img, cv_ptr, bytes()); | 168 | memcpy(img, cv_ptr, bytes()); |