Fawkes API  Fawkes Development Version
texture_drawer.cpp
1 
2 /***************************************************************************
3  * texture_drawer.cpp - Skeleton Visualization GUI: texture drawer
4  *
5  * Created: Tue Mar 29 17:09:25 2011 (on the way to Magdeburg for GO2011)
6  * Copyright 2006-2011 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include "texture_drawer.h"
24 
25 #include <GL/glut.h>
26 #include <fvcams/camera.h>
27 #include <fvutils/color/colorspaces.h>
28 #include <fvutils/color/conversions.h>
29 
30 #include <algorithm>
31 #include <cstdio>
32 #include <cstdlib>
33 #include <cstring>
34 
35 using namespace fawkes;
36 using namespace firevision;
37 
38 /** @class SkelGuiTextureDrawer "texture_drawer.h"
39  * Draw images from camera in texture.
40  * Uses texture mapping to show an image acquired from a camera in the
41  * background.
42  * @author Tim Niemueller
43  *
44  * @fn SkelGuiTextureDrawer::fill_texture()
45  * Fill texture with data.
46  * This function is called during draw() and the sub-class shall implement it
47  * to fill the texture with the data to show. Be aware that the texture size
48  * and the actually shown size will likely differ.
49  */
50 
51 /** Constructor.
52  * @param width width of visible area
53  * @param height height of visible area
54  */
55 SkelGuiTextureDrawer::SkelGuiTextureDrawer(unsigned int width, unsigned int height)
56 : width_(width),
57  height_(height),
58  texture_width_(get_closest_power_of_two(width_)),
59  texture_height_(get_closest_power_of_two(height_)),
60  texture_raii_(malloc(texture_width_ * texture_height_ * 3))
61 {
62  texture_ = (unsigned char *)*texture_raii_;
63  memset(texture_, 0, texture_width_ * texture_height_ * 3);
64 
65  texture_initialized_ = false;
66 }
67 
68 /** Destructor. */
70 {
71 }
72 
73 unsigned int
74 SkelGuiTextureDrawer::get_closest_power_of_two(unsigned int n)
75 {
76  unsigned int m = 2;
77  while (m < n)
78  m <<= 1;
79 
80  return m;
81 }
82 
83 void
84 SkelGuiTextureDrawer::init_texture()
85 {
86  glGenTextures(1, &texture_id_);
87  glBindTexture(GL_TEXTURE_2D, texture_id_);
88 
89  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
90  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
91 
92  memset(texture_coords_, 0, sizeof(texture_coords_));
93  texture_coords_[0] = (float)width_ / texture_width_;
94  texture_coords_[1] = (float)height_ / texture_height_;
95  texture_coords_[2] = (float)width_ / texture_width_;
96  texture_coords_[7] = (float)height_ / texture_height_;
97 
98  texture_initialized_ = true;
99 }
100 
101 void
102 SkelGuiTextureDrawer::draw_rectangle(float topLeftX,
103  float topLeftY,
104  float bottomRightX,
105  float bottomRightY)
106 {
107  GLfloat verts[8] = {
108  topLeftX, topLeftY, topLeftX, bottomRightY, bottomRightX, bottomRightY, bottomRightX, topLeftY};
109  glVertexPointer(2, GL_FLOAT, 0, verts);
110  glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
111  glFlush();
112 }
113 
114 /** Draw texture to screen. */
115 void
117 {
118  if (!texture_initialized_)
119  init_texture();
120 
121  fill_texture();
122 
123  glBindTexture(GL_TEXTURE_2D, texture_id_);
124  glTexImage2D(GL_TEXTURE_2D,
125  0,
126  GL_RGB,
129  0,
130  GL_RGB,
131  GL_UNSIGNED_BYTE,
132  texture_);
133 
134  // Display the OpenGL texture map
135  glColor4f(0.75, 0.75, 0.75, 1);
136 
137  glEnable(GL_TEXTURE_2D);
138  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
139  glTexCoordPointer(2, GL_FLOAT, 0, texture_coords_);
140  draw_rectangle(width_, height_, 0, 0);
141  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
142  glDisable(GL_TEXTURE_2D);
143 }
144 
145 /** Copy an RGB buffer to texture.
146  * @param rgb_buf the RGB buffer to copy, it must exactly of dimensions width_
147  * and height_.
148  */
149 void
150 SkelGuiTextureDrawer::copy_rgb_to_texture(const unsigned char *rgb_buf)
151 {
152  unsigned char * row = texture_;
153  unsigned char * tex = texture_;
154  const unsigned char *rgb = rgb_buf;
155  for (unsigned int h = 0; h < height_; ++h) {
156  tex = row;
157  for (unsigned int w = 0; w < width_; ++w) {
158  *tex++ = *rgb++;
159  *tex++ = *rgb++;
160  *tex++ = *rgb++;
161  }
162  row += texture_width_ * 3;
163  }
164 }
const unsigned int height_
Height of visible area from texture.
const unsigned int width_
Width of visible area from texture.
Fawkes library namespace.
void draw()
Draw texture to screen.
void copy_rgb_to_texture(const unsigned char *rgb_buf)
Copy an RGB buffer to texture.
const unsigned int texture_height_
Real texture height.
unsigned char * texture_
Texture buffer.
const unsigned int texture_width_
Real texture width.
virtual void fill_texture()=0
Fill texture with data.
SkelGuiTextureDrawer(unsigned int width, unsigned int height)
Constructor.
virtual ~SkelGuiTextureDrawer()
Destructor.