00001 #define GL_GLEXT_PROTOTYPES
00002
00003 #include "bcsynchronous.h"
00004 #include "bctexture.h"
00005 #include "bcwindowbase.h"
00006 #include "colormodels.h"
00007
00008
00009 BC_Texture::BC_Texture(int w, int h, int colormodel)
00010 {
00011 this->w = w;
00012 this->h = h;
00013 this->colormodel = colormodel;
00014 texture_id = -1;
00015 texture_id = -1;
00016 texture_w = 0;
00017 texture_h = 0;
00018 texture_components = 0;
00019 window_id = -1;
00020 create_texture(w, h, colormodel);
00021 }
00022
00023
00024 BC_Texture::~BC_Texture()
00025 {
00026 clear_objects();
00027 }
00028
00029 void BC_Texture::clear_objects()
00030 {
00031 if(get_texture_id() >= 0)
00032 {
00033
00034
00035 BC_WindowBase::get_synchronous()->release_texture(
00036 window_id,
00037 texture_id);
00038 texture_id = -1;
00039 }
00040 }
00041
00042 void BC_Texture::new_texture(BC_Texture **texture,
00043 int w,
00044 int h,
00045 int colormodel)
00046 {
00047 if(!(*texture))
00048 {
00049 (*texture) = new BC_Texture(w, h, colormodel);
00050 }
00051 else
00052 {
00053 (*texture)->create_texture(w, h, colormodel);
00054 }
00055 }
00056
00057 void BC_Texture::create_texture(int w, int h, int colormodel)
00058 {
00059 #ifdef HAVE_GL
00060
00061
00062
00063 int max_texture_size = 0;
00064 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
00065
00066
00067 int new_w = calculate_texture_size(w, &max_texture_size);
00068 int new_h = calculate_texture_size(h, &max_texture_size);
00069 int new_components = cmodel_components(colormodel);
00070
00071
00072 if(new_w < w || new_h < h)
00073 {
00074 printf("BC_Texture::create_texture frame size %dx%d bigger than maximum texture %dx%d.\n",
00075 w,
00076 h,
00077 max_texture_size,
00078 max_texture_size);
00079 }
00080
00081
00082 if(texture_id >= 0 &&
00083 (new_h != texture_h ||
00084 new_w != texture_w ||
00085 new_components != texture_components ||
00086 BC_WindowBase::get_synchronous()->current_window->get_id() != window_id))
00087 {
00088
00089
00090
00091 BC_WindowBase::get_synchronous()->release_texture(
00092 window_id,
00093 texture_id);
00094 texture_id = -1;
00095 window_id = -1;
00096 }
00097
00098
00099 texture_w = new_w;
00100 texture_h = new_h;
00101 texture_components = new_components;
00102
00103
00104 if(texture_id < 0)
00105 {
00106 texture_id = BC_WindowBase::get_synchronous()->get_texture(
00107 texture_w,
00108 texture_h,
00109 texture_components);
00110
00111 if(texture_id >= 0)
00112 window_id = BC_WindowBase::get_synchronous()->current_window->get_id();
00113 }
00114
00115
00116
00117
00118 if(texture_id < 0)
00119 {
00120 glGenTextures(1, (GLuint*)&texture_id);
00121 glBindTexture(GL_TEXTURE_2D, (GLuint)texture_id);
00122 glEnable(GL_TEXTURE_2D);
00123 if(texture_components == 4)
00124 glTexImage2D(GL_TEXTURE_2D,
00125 0,
00126 4,
00127 texture_w,
00128 texture_h,
00129 0,
00130 GL_RGBA,
00131 GL_UNSIGNED_BYTE,
00132 0);
00133 else
00134 glTexImage2D(GL_TEXTURE_2D,
00135 0,
00136 3,
00137 texture_w,
00138 texture_h,
00139 0,
00140 GL_RGB,
00141 GL_UNSIGNED_BYTE,
00142 0);
00143
00144 window_id = BC_WindowBase::get_synchronous()->current_window->get_id();
00145 BC_WindowBase::get_synchronous()->put_texture(texture_id,
00146 texture_w,
00147 texture_h,
00148 texture_components);
00149
00150
00151
00152 }
00153 else
00154 {
00155 glBindTexture(GL_TEXTURE_2D, (GLuint)texture_id);
00156 glEnable(GL_TEXTURE_2D);
00157 }
00158 #endif
00159 }
00160
00161 int BC_Texture::calculate_texture_size(int w, int *max)
00162 {
00163 int i;
00164 for(i = 2; (max && i <= *max) || (!max && i < w); i *= 2)
00165 {
00166 if(i >= w)
00167 {
00168 return i;
00169 break;
00170 }
00171 }
00172 if(max && i > *max) return 16;
00173 return i;
00174 }
00175
00176 int BC_Texture::get_texture_id()
00177 {
00178 return texture_id;
00179 }
00180
00181 int BC_Texture::get_texture_w()
00182 {
00183 return texture_w;
00184 }
00185
00186 int BC_Texture::get_texture_h()
00187 {
00188 return texture_h;
00189 }
00190
00191 int BC_Texture::get_texture_components()
00192 {
00193 return texture_components;
00194 }
00195
00196 int BC_Texture::get_window_id()
00197 {
00198 return window_id;
00199 }
00200
00201
00202 void BC_Texture::bind(int texture_unit)
00203 {
00204 #ifdef HAVE_GL
00205
00206 if(texture_id >= 0)
00207 {
00208 if(texture_unit >= 0) glActiveTexture(GL_TEXTURE0 + texture_unit);
00209 glBindTexture(GL_TEXTURE_2D, texture_id);
00210 glEnable(GL_TEXTURE_2D);
00211 if(texture_unit >= 0)
00212 {
00213 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00214 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00215
00216
00217
00218 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00219 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00220
00221
00222 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00223 }
00224 }
00225 #endif
00226 }
00227