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 <fvcams/camera.h>
26 #include <fvutils/color/colorspaces.h>
27 #include <fvutils/color/conversions.h>
28 
29 #include <cstdlib>
30 #include <cstdio>
31 #include <algorithm>
32 #include <GL/glut.h>
33 
34 using namespace fawkes;
35 using namespace firevision;
36 
37 /** @class SkelGuiTextureDrawer "texture_drawer.h"
38  * Draw images from camera in texture.
39  * Uses texture mapping to show an image acquired from a camera in the
40  * background.
41  * @author Tim Niemueller
42  *
43  * @fn SkelGuiTextureDrawer::fill_texture()
44  * Fill texture with data.
45  * This function is called during draw() and the sub-class shall implement it
46  * to fill the texture with the data to show. Be aware that the texture size
47  * and the actually shown size will likely differ.
48  */
49 
50 /** Constructor.
51  * @param width width of visible area
52  * @param height height of visible area
53  */
54 SkelGuiTextureDrawer::SkelGuiTextureDrawer(unsigned int width, unsigned int height)
55  : __width(width), __height(height),
56  __texture_width(get_closest_power_of_two(__width)),
57  __texture_height(get_closest_power_of_two(__height))
58 {
59  __texture = (unsigned char *)malloc(__texture_width *__texture_height * 3);
60  memset(__texture, 0, __texture_width * __texture_height * 3);
61 
62  __texture_initialized = false;
63 }
64 
65 /** Destructor. */
67 {
68  free(__texture);
69 }
70 
71 unsigned int
72 SkelGuiTextureDrawer::get_closest_power_of_two(unsigned int n)
73 {
74  unsigned int m = 2;
75  while(m < n) m<<=1;
76 
77  return m;
78 }
79 
80 void
81 SkelGuiTextureDrawer::init_texture()
82 {
83  glGenTextures(1, &__texture_id);
84  glBindTexture(GL_TEXTURE_2D, __texture_id);
85 
86  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
87  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
88 
89  memset(__texture_coords, 0, sizeof(__texture_coords));
90  __texture_coords[0] = (float)__width / __texture_width;
91  __texture_coords[1] = (float)__height / __texture_height;
92  __texture_coords[2] = (float)__width / __texture_width;
93  __texture_coords[7] = (float)__height / __texture_height;
94 
95  __texture_initialized = true;
96 }
97 
98 
99 void
100 SkelGuiTextureDrawer::draw_rectangle(float topLeftX, float topLeftY,
101  float bottomRightX, float bottomRightY)
102 {
103  GLfloat verts[8] = { topLeftX, topLeftY, topLeftX, bottomRightY,
104  bottomRightX, bottomRightY, bottomRightX, topLeftY };
105  glVertexPointer(2, GL_FLOAT, 0, verts);
106  glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
107  glFlush();
108 }
109 
110 /** Draw texture to screen. */
111 void
113 {
114  if (!__texture_initialized) init_texture();
115 
116  fill_texture();
117 
118  glBindTexture(GL_TEXTURE_2D, __texture_id);
119  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, __texture_width, __texture_height,
120  0, GL_RGB, GL_UNSIGNED_BYTE, __texture);
121 
122  // Display the OpenGL texture map
123  glColor4f(0.75,0.75,0.75,1);
124 
125  glEnable(GL_TEXTURE_2D);
126  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
127  glTexCoordPointer(2, GL_FLOAT, 0, __texture_coords);
128  draw_rectangle(__width, __height, 0, 0);
129  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
130  glDisable(GL_TEXTURE_2D);
131 }
132 
133 /** Copy an RGB buffer to texture.
134  * @param rgb_buf the RGB buffer to copy, it must exactly of dimensions __width
135  * and __height.
136  */
137 void
138 SkelGuiTextureDrawer::copy_rgb_to_texture(const unsigned char *rgb_buf)
139 {
140  unsigned char *row = __texture;
141  unsigned char *tex = __texture;
142  const unsigned char *rgb = rgb_buf;
143  unsigned int bytes = 0;
144  for (unsigned int h = 0; h < __height; ++h) {
145  tex = row;
146  for (unsigned int w = 0; w < __width; ++w) {
147  *tex++ = *rgb++;
148  *tex++ = *rgb++;
149  *tex++ = *rgb++;
150  ++bytes;
151  }
152  row += __texture_width * 3;
153  }
154 }
const unsigned int __texture_width
Real texture width.
Fawkes library namespace.
const unsigned int __width
Width of visible area from texture.
unsigned char * __texture
Texture buffer.
void draw()
Draw texture to screen.
void copy_rgb_to_texture(const unsigned char *rgb_buf)
Copy an RGB buffer to texture.
virtual void fill_texture()=0
Fill texture with data.
const unsigned int __texture_height
Real texture height.
SkelGuiTextureDrawer(unsigned int width, unsigned int height)
Constructor.
const unsigned int __height
Height of visible area from texture.
virtual ~SkelGuiTextureDrawer()
Destructor.