1 #define GL_GLEXT_PROTOTYPES
3 #include "bcsynchronous.h"
5 #include "bcwindowbase.h"
6 #include "colormodels.h"
9 BC_Texture::BC_Texture(int w, int h, int colormodel)
13 this->colormodel = colormodel;
18 texture_components = 0;
20 create_texture(w, h, colormodel);
24 BC_Texture::~BC_Texture()
29 void BC_Texture::clear_objects()
31 if(get_texture_id() >= 0)
33 // printf("VFrame::clear_objects %p window_id=%d texture_id=%d w=%d h=%d\n",
34 // this, window_id, texture_id, texture_w, texture_h);
35 BC_WindowBase::get_synchronous()->release_texture(
42 void BC_Texture::new_texture(BC_Texture **texture,
49 (*texture) = new BC_Texture(w, h, colormodel);
53 (*texture)->create_texture(w, h, colormodel);
57 void BC_Texture::create_texture(int w, int h, int colormodel)
61 // Get max texture size from the server.
62 // Maximum size was 4096 on the earliest cards that could do video.
63 int max_texture_size = 0;
64 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
66 // Calculate dimensions of texture
67 int new_w = calculate_texture_size(w, &max_texture_size);
68 int new_h = calculate_texture_size(h, &max_texture_size);
69 int new_components = cmodel_components(colormodel);
72 if(new_w < w || new_h < h)
74 printf("BC_Texture::create_texture frame size %dx%d bigger than maximum texture %dx%d.\n",
81 // Delete existing texture
83 (new_h != texture_h ||
85 new_components != texture_components ||
86 BC_WindowBase::get_synchronous()->current_window->get_id() != window_id))
88 // printf("BC_Texture::create_texture released window_id=%d texture_id=%d\n",
89 // BC_WindowBase::get_synchronous()->current_window->get_id(),
91 BC_WindowBase::get_synchronous()->release_texture(
101 texture_components = new_components;
103 // Get matching texture
106 texture_id = BC_WindowBase::get_synchronous()->get_texture(
110 // A new VFrame has no window_id, so it must read it from the matching texture.
112 window_id = BC_WindowBase::get_synchronous()->current_window->get_id();
116 // No matching texture exists.
117 // Create new texture with the proper dimensions
120 glGenTextures(1, (GLuint*)&texture_id);
121 glBindTexture(GL_TEXTURE_2D, (GLuint)texture_id);
122 glEnable(GL_TEXTURE_2D);
123 if(texture_components == 4)
124 glTexImage2D(GL_TEXTURE_2D,
134 glTexImage2D(GL_TEXTURE_2D,
144 window_id = BC_WindowBase::get_synchronous()->current_window->get_id();
145 BC_WindowBase::get_synchronous()->put_texture(texture_id,
149 // printf("VFrame::new_texture created texture_id=%d window_id=%d\n",
155 glBindTexture(GL_TEXTURE_2D, (GLuint)texture_id);
156 glEnable(GL_TEXTURE_2D);
161 int BC_Texture::calculate_texture_size(int w, int *max)
164 for(i = 2; (max && i <= *max) || (!max && i < w); i *= 2)
172 if(max && i > *max) return 16;
176 int BC_Texture::get_texture_id()
181 int BC_Texture::get_texture_w()
186 int BC_Texture::get_texture_h()
191 int BC_Texture::get_texture_components()
193 return texture_components;
196 int BC_Texture::get_window_id()
202 void BC_Texture::bind(int texture_unit)
208 if(texture_unit >= 0) glActiveTexture(GL_TEXTURE0 + texture_unit);
209 glBindTexture(GL_TEXTURE_2D, texture_id);
210 glEnable(GL_TEXTURE_2D);
211 if(texture_unit >= 0)
213 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
214 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
216 // GL_REPEAT in this case causes the upper left corners of the masks
218 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
219 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
221 // Get the texture to alpha blend
222 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);