00001 #ifndef OPENTISSUE_GPU_TEXTURE_TEXTURE_TEXTURE2D_H
00002 #define OPENTISSUE_GPU_TEXTURE_TEXTURE_TEXTURE2D_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/math_power2.h>
00013 #include <OpenTissue/gpu/texture/texture_types.h>
00014 #include <OpenTissue/utility/gl/gl_check_errors.h>
00015
00016 #include <boost/shared_ptr.hpp>
00017
00018 #include <iostream>
00019 #include <cassert>
00020
00021 namespace OpenTissue
00022 {
00023 namespace texture
00024 {
00025
00030 class Texture2D
00031 {
00032 protected:
00033
00034 GLuint m_texture_ID;
00035 int m_internal_format;
00036 bool m_owned;
00037 int m_width;
00038 int m_height;
00039 unsigned int m_format;
00040 unsigned int m_type;
00041 bool m_rectangular;
00042 unsigned int m_texture_target;
00043
00044 public:
00045
00046 unsigned int get_texture_ID() const { return m_texture_ID; }
00047 unsigned int get_texture_target() const { return m_texture_target; }
00048 int width() const { return m_width; }
00049 int height() const { return m_height; }
00050 int get_internal_format() const { return m_internal_format; }
00051 bool rectangular() const { return m_rectangular; }
00052
00053 protected:
00054
00055 void create(unsigned int texture_ID = 0)
00056 {
00057 m_texture_ID = texture_ID;
00058 m_owned=false;
00059 if (m_texture_ID==0)
00060 {
00061 glGenTextures(1, &m_texture_ID);
00062 m_owned = true;
00063 if(m_texture_ID == 0)
00064 {
00065 std::cerr<< "Texture2D::create(): Could not create texture ID";
00066 }
00067 }
00068 }
00069
00070 public:
00071
00099 Texture2D(
00100 int internal_format
00101 , int width
00102 , int height
00103 , int format
00104 , int type
00105 , const void *pixels
00106 , bool rectangular=false
00107 , int border=0
00108 )
00109 : m_internal_format(internal_format)
00110 , m_width(width)
00111 , m_height(height)
00112 , m_format(format)
00113 , m_type(type)
00114 , m_rectangular(rectangular)
00115 , m_texture_target( rectangular?GL_TEXTURE_RECTANGLE_ARB:GL_TEXTURE_2D )
00116 {
00117 glPushAttrib(GL_TEXTURE_BIT );
00118
00119 assert((m_rectangular || math::is_power2( m_width )) || !"Texture2D(): Width was not a power of two");
00120 assert((m_rectangular || math::is_power2( m_height )) || !"Texture2D(): Height was not a power of two");
00121 create();
00122 if(!glIsEnabled( m_texture_target ) )
00123 glEnable(m_texture_target);
00124 glBindTexture(m_texture_target, m_texture_ID);
00125
00126 glTexImage2D(m_texture_target, 0, internal_format, width, height, border, format, (GLenum) type, pixels);
00127
00128 glTexParameteri( m_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP);
00129 glTexParameteri( m_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP);
00130 glTexParameteri( m_texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00131 glTexParameteri( m_texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00132
00133 glPopAttrib();
00134 }
00135
00136 Texture2D()
00137 : m_rectangular(false)
00138 , m_texture_target( m_rectangular?GL_TEXTURE_RECTANGLE_ARB:GL_TEXTURE_2D )
00139 {
00140 create();
00141 glEnable(m_texture_target);
00142 glBindTexture(m_texture_target, m_texture_ID);
00143 }
00144
00145 Texture2D(int w, int h, bool r=false)
00146 : m_width(w)
00147 , m_height(h)
00148 , m_rectangular(r)
00149 , m_texture_target( m_rectangular?GL_TEXTURE_RECTANGLE_ARB:GL_TEXTURE_2D )
00150 {
00151 create();
00152 glEnable(m_texture_target);
00153 glBindTexture(m_texture_target, m_texture_ID);
00154 }
00155
00156 ~Texture2D()
00157 {
00158 if (m_texture_ID!=0 && m_owned)
00159 glDeleteTextures(1, &m_texture_ID);
00160 }
00161
00162 public:
00163
00169 void bind() const
00170 {
00171
00172 if(m_texture_target==GL_TEXTURE_2D)
00173 {
00174 if(glIsEnabled(GL_TEXTURE_RECTANGLE_ARB))
00175 glDisable(GL_TEXTURE_RECTANGLE_ARB);
00176 if(glIsEnabled(GL_TEXTURE_RECTANGLE_NV))
00177 glDisable(GL_TEXTURE_RECTANGLE_NV);
00178 }
00179 else
00180 {
00181 if(glIsEnabled(GL_TEXTURE_2D))
00182 glDisable(GL_TEXTURE_2D);
00183 }
00184 if( !glIsEnabled(m_texture_target) )
00185 glEnable(m_texture_target);
00186
00187 glBindTexture(m_texture_target, m_texture_ID);
00188 }
00189
00196 template<typename T>
00197 void load(T const * pixels)
00198 {
00199 assert(pixels != 0 || !"Texture2D::load() - pixels are null");
00200
00201
00202
00203
00204
00205 bind();
00206 glTexSubImage2D(
00207 m_texture_target
00208 , 0
00209 , 0
00210 , 0
00211 , m_width
00212 , m_height
00213 , m_format
00214 , m_type
00215 , pixels
00216 );
00217 }
00218
00224 void set_repeating(bool flag)
00225 {
00226 bind();
00227 if(flag)
00228 {
00229 glTexParameteri( m_texture_target, GL_TEXTURE_WRAP_S, GL_REPEAT);
00230 glTexParameteri( m_texture_target, GL_TEXTURE_WRAP_T, GL_REPEAT);
00231 }
00232 else
00233 {
00234 glTexParameteri( m_texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP);
00235 glTexParameteri( m_texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP);
00236 }
00237 }
00238
00239 void set_mipmapping(bool flag)
00240 {
00241 assert( (flag && (m_texture_target == GL_TEXTURE_2D)) || !"Texture2D::set_mipmapping(): Mipmap generation only supported on GL_TEXTURE_2D texture targets");
00242
00243 bind();
00244
00245 if(flag)
00246 {
00247 glTexParameteri( m_texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00248 glTexParameteri( m_texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
00249 OpenTissue::gl::gl_check_errors("GL_TEXTURE_MIN_FILTER = GL_LINEAR_MIPMAP_LINEAR");
00250
00251 glTexParameterf( m_texture_target, GL_GENERATE_MIPMAP, GL_TRUE);
00252 OpenTissue::gl::gl_check_errors("GL_GENERATE_MIPMAP = TRUE");
00253
00254 glHint( GL_GENERATE_MIPMAP_HINT, GL_NICEST );
00255 OpenTissue::gl::gl_check_errors("GL_GENERATE_MIPMAP_HINT = GL_NICEST");
00256
00257 glGenerateMipmapEXT( m_texture_target );
00258 OpenTissue::gl::gl_check_errors("glGenerateMipmapEXT");
00259 }
00260 else
00261 {
00262 glTexParameteri( m_texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00263 glTexParameteri( m_texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00264 }
00265 }
00266
00267
00268
00269 #ifdef MACOS
00270 void parameter(GLenum pname, int i)
00271 {
00272 glTexParameteri(m_texture_target, pname, i);
00273 }
00274 #endif
00275
00276 void parameter(GLenum pname, GLint i)
00277 {
00278 glTexParameteri(m_texture_target, pname, i);
00279 }
00280
00281 void parameter(GLenum pname, GLfloat f)
00282 {
00283 glTexParameterf(m_texture_target, pname, f);
00284 }
00285
00286 void parameter(GLenum pname, GLint * ip)
00287 {
00288 glTexParameteriv(m_texture_target, pname, ip);
00289 }
00290
00291 void parameter(GLenum pname, GLfloat * fp)
00292 {
00293 glTexParameterfv(m_texture_target, pname, fp);
00294 }
00295
00296
00307 bool is_valid_sampler_type(std::string const & sampler_type) const
00308 {
00309 if (m_rectangular)
00310 {
00311 if (sampler_type!= "sampler2DRect" && sampler_type!="samplerRECT")
00312 {
00313 std::cerr << "Texture2D::validate_sampler_type(): TextureRectangle attempted to bound to sampler type " << sampler_type << std::endl;
00314 return false;
00315 }
00316 }
00317 else
00318 {
00319 if (sampler_type!="sampler2D")
00320 {
00321 std::cerr << "Texture2D::validate_sampler_type(): Attempted to bound to sampler type " << sampler_type << std::endl;
00322 return false;
00323 }
00324 }
00325 return true;
00326 }
00327
00328 };
00329
00330 typedef boost::shared_ptr<Texture2D> texture2D_pointer;
00331
00332 }
00333 }
00334
00335
00336 #endif