1 // Copyright Timothy Goya 2007.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
7 #include <unison/video/Surface.hpp>
8 #include <unison/video/Window.hpp>
9 #include <unison/video/Renderers.hpp>
10 #include <unison/video/backend/Renderer.hpp>
17 int next_power_of_two(int val)
32 Texture::Texture(const Surface &surface) :
33 Backend::Texture(surface),
38 /*Texture::Texture(const Surface &surface, const std::string &name) :
39 Backend::Texture(surface, name),
44 Texture::Texture(Backend::Texture *texture) :
45 Backend::Texture(texture),
52 for(std::vector<Handle>::iterator iter = handles.begin(), end = handles.end();iter != end;++iter)
54 glDeleteTextures(1, &iter->texture);
58 const Surface Texture::get_surface()
60 if(surface.get_size() == Area())
62 assert(!handles.empty());
63 surface = Surface(size);
64 for(std::vector<Handle>::iterator iter = handles.begin(), end = handles.end();iter != end;++iter)
66 Surface section(iter->rect.size);
67 glBindTexture(GL_TEXTURE_2D, iter->texture);
68 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, section.get_pixels());
69 surface.blit(section, iter->rect.pos, Rect(), BLEND_NONE);
71 assert(!glGetError());
79 for(std::vector<Handle>::iterator iter = handles.begin(), end = handles.end();iter != end;++iter)
81 glDeleteTextures(1, &iter->texture);
86 void Texture::blit(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
89 Renderers::get().get_renderer().blit(src, src_rect, surface, dst_pos, options);
92 void Texture::blit(const Video::Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
95 Texture *texture = dynamic_cast<Texture *>(Backend::Texture::get_texture(src.get_id()));
96 Renderers::get().get_renderer().blit(texture, src_rect, surface, dst_pos, options);
99 void Texture::fill(const Color &color, const Rect &rect)
102 Renderers::get().get_renderer().fill(surface, color, rect);
105 void Texture::fill_blend(const Color &color, const Rect &rect)
108 Renderers::get().get_renderer().fill_blend(surface, color, rect);
111 void Texture::blit_draw_buffer(const Rect &src_rect, const Point &dst_pos, const RenderOptions &options)
115 assert(surface.get_size() != Area());
117 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_size);
118 for(unsigned int y = 0;y < surface.get_size().y;y += max_size)
120 for(unsigned int x = 0;x < surface.get_size().x;x += max_size)
125 rect.size.x = std::min(surface.get_size().x - x, (unsigned int)max_size);
126 rect.size.y = std::min(surface.get_size().y - y, (unsigned int)max_size);
127 handles.push_back(create_handle(surface, rect));
133 glColor4ub(options.color.red, options.color.green, options.color.blue, options.alpha);
134 switch(options.blend)
138 //glBlendFunc(GL_ONE, GL_ZERO);
141 assert(0 && "Mask blending not implemented");
145 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
149 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
153 glBlendFunc(GL_ZERO, GL_SRC_COLOR);
156 assert(0 && "Unrecognized blend mode");
162 glTranslatef(dst_pos.x - src_rect.pos.x, dst_pos.y - src_rect.pos.y, 0);
164 for(std::vector<Handle>::iterator iter = handles.begin(), end = handles.end();iter != end;++iter)
166 Rect overlap = iter->rect.get_overlap(src_rect);
167 if(overlap != Rect())
169 GLfloat uv_left = GLfloat(overlap.get_left()) / iter->rect.size.x;
170 GLfloat uv_top = GLfloat(overlap.get_top()) / iter->rect.size.y;
171 GLfloat uv_right = GLfloat(overlap.get_right()) / iter->rect.size.x;
172 GLfloat uv_bottom = GLfloat(overlap.get_bottom()) / iter->rect.size.y;
176 std::swap(uv_left, uv_right);
181 std::swap(uv_top, uv_bottom);
186 glTranslatef(overlap.pos.x, overlap.pos.y, 0);
188 glBindTexture(GL_TEXTURE_2D, iter->texture);
190 glTexCoord2f(uv_left, uv_top);
193 glTexCoord2f(uv_right, uv_top);
194 glVertex2i(overlap.size.x, 0);
196 glTexCoord2f(uv_right, uv_bottom);
197 glVertex2i(overlap.size.x, overlap.size.y);
199 glTexCoord2f(uv_left, uv_bottom);
200 glVertex2i(0, overlap.size.y);
209 //glColor4ub(0xff, 0xff, 0xff, 0xff);
210 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
213 Texture::Handle Texture::create_handle(const Surface &surface, const Rect &rect)
215 Texture::Handle handle;
217 handle.rect.size.x = next_power_of_two(rect.size.x);
218 handle.rect.size.y = next_power_of_two(rect.size.y);
219 Surface convert(handle.rect.size);
220 convert.blit(surface, Point(), rect, BLEND_NONE);
223 glGenTextures(1, &handle.texture);
224 assert(!glGetError());
227 glBindTexture(GL_TEXTURE_2D, handle.texture);
228 //glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
231 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
232 handle.rect.size.x, handle.rect.size.y,
233 0, GL_RGBA, GL_UNSIGNED_BYTE, convert.get_pixels());
236 assert(!glGetError());
238 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
239 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
240 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
241 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
245 glDeleteTextures(1, &handle.texture);