Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
SceneTexturedPlane.cpp
1 #include "SceneTexturedPlane.hh"
2 
3 #include <bias_config.h>
4 #include <Gui/biasgl.h>
5 #include <Base/Image/ImageIO.hh>
6 
7 using namespace BIAS;
8 using namespace std;
9 
12  const BIAS::Vector3<double> &width,
13  const BIAS::Vector3<double> &height,
14  const int widthSubsections,
15  const int heightSubsections,
16  const int minFilter, const int magFilter,
17  const int wrapping)
18 {
19  isInitialized_ = false;
20  drawNormal_ = false;
21  drawNormalLength_ = 1.0f;
22  texID_ = 0;
23  texCoords_[0].Set(0.0f, 0.0f);
24  texCoords_[1].Set(1.0f, 1.0f);
25  texSize_.Set(1, 1);
26  minFilter_ = minFilter;
27  magFilter_ = magFilter;
28  wrapping_ = wrapping;
29  Resize(topLeft, width, height, widthSubsections, heightSubsections);
30 }
31 
33 {
34 }
35 
38  const BIAS::Vector3<double> &width,
39  const BIAS::Vector3<double> &height,
40  const int widthSubsections,
41  const int heightSubsections)
42 {
43  BIAS::Vector3<double> normal = width.CrossProduct(height);
44  normal.Normalize();
45  for (unsigned int i = 0; i < 3; i++) {
46  corners_[0][i] = topLeft[i]; // top left
47  corners_[1][i] = topLeft[i] + width[i]; // top right
48  corners_[2][i] = topLeft[i] + width[i] + height[i]; // bottom right
49  corners_[3][i] = topLeft[i] + height[i]; // bottom left
50  normal_[i] = -normal[i];
51  }
52  subsectionsX_ = subsectionsY_ = 1;
53  if (widthSubsections > 1)
54  subsectionsX_ = widthSubsections;
55  if (heightSubsections > 1)
56  subsectionsY_ = heightSubsections;
57 }
58 
61  BIAS::Vector3<double> &maxVal)
62 {
63  // TODO Obtain min. and max. values from corners in Resize!
64  minVal.Set(corners_[0][0], corners_[0][1], corners_[0][2]);
65  maxVal.Set(corners_[2][0], corners_[2][1], corners_[2][2]);
66 }
67 
69 {
70  if (!isInitialized_) return;
71 
72  glPushAttrib(GL_TEXTURE_BIT);
73  glPushAttrib(GL_LIGHTING);
74  glEnable(GL_TEXTURE_2D);
75  glEnable(GL_LIGHTING);
76 
77  glBindTexture(GL_TEXTURE_2D, texID_);
78 
79  glMatrixMode(GL_TEXTURE);
80  glLoadIdentity();
81 
82  //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping_);
83  //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping_);
84 
85  float material[] = { 1.0f, 1.0f, 1.0f, 1.0f };
86  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, material);
87 
88  glBegin(GL_QUADS);
89 
90  if (subsectionsX_ < 2 && subsectionsY_ < 2) {
91  // top left
92  glTexCoord2f(texCoords_[0][0], texCoords_[0][1]);
93  glNormal3f(normal_[0], normal_[1], normal_[2]);
94  glVertex3f(corners_[0][0], corners_[0][1], corners_[0][2]);
95 
96  // top right
97  glTexCoord2f(texCoords_[1][0], texCoords_[0][1]);
98  glNormal3f(normal_[0], normal_[1], normal_[2]);
99  glVertex3f(corners_[1][0], corners_[1][1], corners_[1][2]);
100 
101  // bottom right
102  glTexCoord2f(texCoords_[1][0], texCoords_[1][1]);
103  glNormal3f(normal_[0], normal_[1], normal_[2]);
104  glVertex3f(corners_[2][0], corners_[2][1], corners_[2][2]);
105 
106  // bottom left
107  glTexCoord2f(texCoords_[0][0], texCoords_[1][1]);
108  glNormal3f(normal_[0], normal_[1], normal_[2]);
109  glVertex3f(corners_[3][0], corners_[3][1], corners_[3][2]);
110 
111  } else {
112 
113  // Draw all subsections from top left to bottom right
114  // TODO Precompute corners and texture coordinates!
115 
116  BIAS::Vector3<float> dx = corners_[1] - corners_[0];
117  BIAS::Vector3<float> dy = corners_[3] - corners_[0];
118  BIAS::Vector2<float> dtex = texCoords_[1] - texCoords_[0];
119  dx /= (float)subsectionsX_; dy /= (float)subsectionsY_;
120  dtex[0] /= subsectionsX_; dtex[1] /= subsectionsY_;
121 
122  for (int j = 0; j < subsectionsY_; j++) {
123  BIAS::Vector3<float> pos = corners_[0] + (float) j * dy;
124  BIAS::Vector2<float> tex(texCoords_[0][0], texCoords_[0][1] + j * dtex[1]);
125 
126  for (int i = 0; i < subsectionsX_; i++, pos += dx, tex[0] += dtex[0]) {
127  // top left
128  glTexCoord2f(tex[0], tex[1]);
129  glNormal3f(normal_[0], normal_[1], normal_[2]);
130  glVertex3f(pos[0], pos[1], pos[2]);
131 
132  // top right
133  glTexCoord2f(tex[0] + dtex[0], tex[1]);
134  glNormal3f(normal_[0], normal_[1], normal_[2]);
135  glVertex3f(pos[0] + dx[0], pos[1] + dx[1], pos[2] + dx[2]);
136 
137  // bottom right
138  glTexCoord2f(tex[0] + dtex[0], tex[1] + dtex[1]);
139  glNormal3f(normal_[0], normal_[1], normal_[2]);
140  glVertex3f(pos[0] + dx[0] + dy[0], pos[1] + dx[1] + dy[1], pos[2] + dx[2] + dy[2]);
141 
142  // bottom left
143  glTexCoord2f(tex[0], tex[1] + dtex[1]);
144  glNormal3f(normal_[0], normal_[1], normal_[2]);
145  glVertex3f(pos[0] + dy[0], pos[1] + dy[1], pos[2] + dy[2]);
146  }
147  }
148  }
149 
150  glEnd();
151 
152  // draw normal for debugging
153  if (drawNormal_)
154  {
155  BIAS::Vector3<float> start =
156  (corners_[0] + corners_[1] + corners_[2] + corners_[3]) * 0.25f;
157  BIAS::Vector3<float> end = start + normal_ * drawNormalLength_;
158  glDisable(GL_LIGHTING);
159  glDisable(GL_TEXTURE_2D);
160 
161  glBegin(GL_LINES);
162  glColor3f(1.0f, 1.0f, 0.0f);
163  glVertex3f(start[0], start[1], start[2]);
164  glVertex3f(end[0], end[1], end[2]);
165  glEnd();
166 
167  GLfloat pointSize;
168  glGetFloatv(GL_POINT_SIZE, &pointSize);
169  glPointSize(8.0f);
170  glBegin(GL_POINTS);
171  glColor3f(1.0f, 1.0f, 0.0f);
172  glVertex3f(end[0], end[1], end[2]);
173  glEnd();
174  glPointSize(pointSize);
175  }
176 
177  glPopAttrib(); // GL_LIGHTING
178  glPopAttrib(); // GL_TEXTURE_BIT
179 }
180 
183  const BIAS::Vector2<int> bottomRight)
184 {
185  texCoords_[0][0] = topLeft[0] / (float)texSize_[0];
186  texCoords_[0][1] = topLeft[1] / (float)texSize_[1];
187  texCoords_[1][0] = bottomRight[0] / (float)texSize_[0];
188  texCoords_[1][1] = bottomRight[1] / (float)texSize_[1];
189 }
190 
193  const BIAS::Vector2<float> bottomRight)
194 {
195  texCoords_[0][0] = topLeft[0];
196  texCoords_[0][1] = topLeft[1];
197  texCoords_[1][0] = bottomRight[0];
198  texCoords_[1][1] = bottomRight[1];
199 }
200 
202 SetImage(const int texID, const int width, const int height)
203 {
204  // Delete previous texture
205  glDeleteTextures(1, &texID_);
206 
207  // Pad texture size to power of two
208  texSize_.Set(1, 1);
209  while (texSize_[0] < width) texSize_[0] *= 2;
210  while (texSize_[1] < height) texSize_[1] *= 2;
211 
212  // Reset texture coordinates
213  texCoords_[0].Set(0.0f, 0.0f);
214  texCoords_[1].Set(width / (float)texSize_[0], height / (float)texSize_[1]);
215 
216  // Set and return texture ID
217  texID_ = texID;
218  isInitialized_ = true;
219  return texID;
220 }
221 
223 SetImage(const std::string &imageFilename)
224 {
226  BIAS::ImageIO::Load(imageFilename, image);
227  return SetImage(image);
228 }
229 
232 {
233  // Check color model of texture image
234  if (image.GetColorModel() != BIAS::ImageBase::CM_Grey &&
236  BIASERR("Unsupported texture color model (use Gray or RGB)!");
237  return -1;
238  }
239 
240  // Check size of texture image and pad to power of two if needed
241  BIAS::Image<unsigned char> texture = image;
242  texture.PadToPowerOfTwo();
243  int maxTexSize = 0;
244  glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
245  if ((int)texture.GetWidth() > maxTexSize ||
246  (int)texture.GetHeight() > maxTexSize) {
247  BIASERR("Texture size is too large (use max. " << maxTexSize << ")!");
248  return -1;
249  }
250 
251  // Reset texture coordinates
252  texCoords_[0].Set(0.0f, 0.0f);
253  texCoords_[1].Set(image.GetWidth() / (float)texture.GetWidth(),
254  image.GetHeight() / (float)texture.GetHeight());
255 
256  // Initialize or resize and bind texture
257  if (!isInitialized_ || (int)texture.GetWidth() != texSize_[0] ||
258  (int)texture.GetHeight() != texSize_[1]) {
259  return InitializeTexture_(texture);
260  }
261 
262  // Bind texture if it is already initialized and has right size
263  glBindTexture(GL_TEXTURE_2D, texID_);
264  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
265  glPixelStorei(GL_PACK_ALIGNMENT, 1);
266  if (texture.GetChannelCount() == 3) {
267  BIASASSERT(texture.GetColorModel() == BIAS::ImageBase::CM_RGB);
268  glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texSize_[0], texSize_[1],
269  GL_RGB, GL_UNSIGNED_BYTE, texture.GetImageData());
270  } else {
271  BIASASSERT(texture.GetChannelCount() == 1 &&
273  glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texSize_[0], texSize_[1],
274  GL_LUMINANCE, GL_UNSIGNED_BYTE, texture.GetImageData());
275  }
276 
277  // Return texture ID
278  return texID_;
279 }
280 
283 {
284  // Delete old texture, generate new texture
285  glDeleteTextures(1, &texID_);
286  glGenTextures(1, &texID_);
287 
288  // Bind texture
289  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
290  glPixelStorei(GL_PACK_ALIGNMENT, 1);
291  glBindTexture(GL_TEXTURE_2D, texID_);
292 
293  texSize_.Set(texture.GetWidth(), texture.GetHeight());
294  if (texture.GetChannelCount() == 3) {
295  BIASASSERT(texture.GetColorModel() == BIAS::ImageBase::CM_RGB);
296  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texSize_[0], texSize_[1], 0,
297  GL_RGB, GL_UNSIGNED_BYTE, texture.GetImageData());
298  } else {
299  BIASASSERT(texture.GetChannelCount() == 1 &&
301  glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, texSize_[0], texSize_[1], 0,
302  GL_LUMINANCE, GL_UNSIGNED_BYTE, texture.GetImageData());
303  }
304  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
305  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter_);
306  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter_);
307  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping_);
308  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping_);
309 
310  // Return new texture ID
311  isInitialized_ = true;
312  return texID_;
313 }
int SetImage(const BIAS::Image< unsigned char > &image)
Set texture image and reset texture coordinates for plane.
void Set(const T *pv)
copy the array of vectorsize beginning at *T to this-&gt;data_
Definition: Vector3.hh:532
void SetTextureCoordinates(const BIAS::Vector2< int > topLeft, const BIAS::Vector2< int > bottomRight)
Set texture coordinates for plane texture in pixels.
SceneTexturedPlane(const BIAS::Vector3< double > &topLeft, const BIAS::Vector3< double > &width, const BIAS::Vector3< double > &height, const int widthSubsections=1, const int heightSubsections=1, const int minFilter=GL_NEAREST, const int magFilter=GL_NEAREST, const int wrapping=GL_REPEAT)
Create new plane with given position, size and orientation.
gray values, 1 channel
Definition: ImageBase.hh:130
virtual void Draw()
Implementation of the SceneBase Draw method.
void Resize(const BIAS::Vector3< double > &topLeft, const BIAS::Vector3< double > &width, const BIAS::Vector3< double > &height, const int widthSubsections=1, const int heightSubsections=1)
Reset position and size of plane.
unsigned int GetWidth() const
Definition: ImageBase.hh:312
void CrossProduct(const Vector3< T > &argvec, Vector3< T > &destvec) const
cross product of two vectors destvec = this x argvec
Definition: Vector3.hh:594
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
color values, 3 channels, order: red,green,blue
Definition: ImageBase.hh:131
unsigned int GetHeight() const
Definition: ImageBase.hh:319
int InitializeTexture_(BIAS::Image< unsigned char > &texture)
Initialize and bind texture.
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
Definition: Image.hh:137
enum EColorModel GetColorModel() const
Definition: ImageBase.hh:407
virtual void GetBoundingBox(BIAS::Vector3< double > &minVal, BIAS::Vector3< double > &maxVal)
Implementation of the SceneBase GetBoundingBox method.
static int Load(const std::string &FileName, ImageBase &img)
first tries a call to Read MIP image and if that fails, tries to Import Image with all other availabl...
Definition: ImageIO.cpp:141
Vector3< T > & Normalize()
normalize this vector to length 1
Definition: Vector3.hh:663
int PadToPowerOfTwo(BIAS::ImageBase &dest, const int &padVal=0) const
increase the size of this image to next power of two (e.g.
Definition: ImageBase.cpp:1154