4 // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #include <SDL_image.h>
32 #include "gameconfig.hpp"
33 #include "physfs/physfs_sdl.hpp"
34 #include "video/surface.hpp"
35 #include "video/drawing_context.hpp"
36 #include "video/color.hpp"
37 #include "image_texture.hpp"
38 #include "texture_manager.hpp"
40 Surface::Surface(const std::string& file)
42 texture = texture_manager->get(file);
46 uv_right = texture->get_uv_right();
47 uv_bottom = texture->get_uv_bottom();
49 width = texture->get_image_width();
50 height = texture->get_image_height();
53 Surface::Surface(const std::string& file, int x, int y, int w, int h)
55 texture = texture_manager->get(file);
58 float tex_w = static_cast<float> (texture->get_width());
59 float tex_h = static_cast<float> (texture->get_height());
60 uv_left = static_cast<float>(x) / tex_w;
61 uv_top = static_cast<float>(y) / tex_h;
62 uv_right = static_cast<float>(x+w) / tex_w;
63 uv_bottom = static_cast<float>(y+h) / tex_h;
69 Surface::Surface(const Surface& other)
71 texture = other.texture;
74 uv_left = other.uv_left;
75 uv_top = other.uv_top;
76 uv_right = other.uv_right;
77 uv_bottom = other.uv_bottom;
79 height = other.height;
83 Surface::operator= (const Surface& other)
87 texture = other.texture;
89 uv_left = other.uv_left;
90 uv_top = other.uv_top;
91 uv_right = other.uv_right;
92 uv_bottom = other.uv_bottom;
94 height = other.height;
107 std::swap(uv_left, uv_right);
110 static inline void intern_draw(float left, float top, float right, float bottom, float uv_left, float uv_top,
111 float uv_right, float uv_bottom,
112 DrawingEffect effect)
114 if(effect & HORIZONTAL_FLIP)
115 std::swap(uv_left, uv_right);
116 if(effect & VERTICAL_FLIP) {
117 std::swap(uv_top, uv_bottom);
121 glTexCoord2f(uv_left, uv_top);
122 glVertex2f(left, top);
124 glTexCoord2f(uv_right, uv_top);
125 glVertex2f(right, top);
127 glTexCoord2f(uv_right, uv_bottom);
128 glVertex2f(right, bottom);
130 glTexCoord2f(uv_left, uv_bottom);
131 glVertex2f(left, bottom);
135 static inline void intern_draw2(float left, float top, float right, float bottom,
136 float uv_left, float uv_top,
137 float uv_right, float uv_bottom,
141 DrawingEffect effect)
143 if(effect & HORIZONTAL_FLIP)
144 std::swap(uv_left, uv_right);
145 if(effect & VERTICAL_FLIP) {
146 std::swap(uv_top, uv_bottom);
149 float center_x = (left + right) / 2;
150 float center_y = (top + bottom) / 2;
152 float sa = sinf(angle/180.0f*M_PI);
153 float ca = cosf(angle/180.0f*M_PI);
161 glBlendFunc(blend.sfactor, blend.dfactor);
162 glColor4f(color.red, color.green, color.blue, color.alpha);
164 glTexCoord2f(uv_left, uv_top);
165 glVertex2f(left*ca - top*sa + center_x,
166 left*sa + top*ca + center_y);
168 glTexCoord2f(uv_right, uv_top);
169 glVertex2f(right*ca - top*sa + center_x,
170 right*sa + top*ca + center_y);
172 glTexCoord2f(uv_right, uv_bottom);
173 glVertex2f(right*ca - bottom*sa + center_x,
174 right*sa + bottom*ca + center_y);
176 glTexCoord2f(uv_left, uv_bottom);
177 glVertex2f(left*ca - bottom*sa + center_x,
178 left*sa + bottom*ca + center_y);
181 // FIXME: find a better way to restore the blend mode
182 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
183 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
187 Surface::draw(float x, float y, float alpha, float angle, const Color& color, const Blend& blend, DrawingEffect effect) const
189 glColor4f(1.0f, 1.0f, 1.0f, alpha);
190 glBindTexture(GL_TEXTURE_2D, texture->get_handle());
193 x + width, y + height,
194 uv_left, uv_top, uv_right, uv_bottom,
202 Surface::draw(float x, float y, float alpha, DrawingEffect effect) const
204 glColor4f(1.0f, 1.0f, 1.0f, alpha);
205 glBindTexture(GL_TEXTURE_2D, texture->get_handle());
208 x + width, y + height,
209 uv_left, uv_top, uv_right, uv_bottom, effect);
213 Surface::draw_part(float src_x, float src_y, float dst_x, float dst_y,
214 float width, float height, float alpha,
215 DrawingEffect effect) const
217 float uv_width = uv_right - uv_left;
218 float uv_height = uv_bottom - uv_top;
220 float uv_left = this->uv_left + (uv_width * src_x) / this->width;
221 float uv_top = this->uv_top + (uv_height * src_y) / this->height;
222 float uv_right = this->uv_left + (uv_width * (src_x + width)) / this->width;
223 float uv_bottom = this->uv_top + (uv_height * (src_y + height)) / this->height;
225 glColor4f(1.0f, 1.0f, 1.0f, alpha);
226 glBindTexture(GL_TEXTURE_2D, texture->get_handle());
228 intern_draw(dst_x, dst_y,
229 dst_x + width, dst_y + height,
230 uv_left, uv_top, uv_right, uv_bottom, effect);