1 /*
2 * client/Graphic.cpp
3 *
4 * This file is part of Leges Motus, a networked, 2D shooter set in zero gravity.
5 *
6 * Copyright 2009-2010 Andrew Ayer, Nathan Partlan, Jeffrey Pfau
7 *
8 * Leges Motus is free and open source software. You may redistribute it and/or
9 * modify it under the terms of version 2, or (at your option) version 3, of the
10 * GNU General Public License (GPL), as published by the Free Software Foundation.
11 *
12 * Leges Motus is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
14 * PARTICULAR PURPOSE. See the full text of the GNU General Public License for
15 * further detail.
16 *
17 * For a full copy of the GNU General Public License, please see the COPYING file
18 * in the root of the source code tree. You may also retrieve a copy from
19 * <http://www.gnu.org/licenses/gpl-2.0.txt>, or request a copy by writing to the
20 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 *
23 */
24
25 #include "Graphic.hpp"
26 #include "SDL_image.h"
27 #include "common/Exception.hpp"
28 #include "common/math.hpp"
29
30 using namespace LM;
31
Graphic()32 Graphic::Graphic() {
33 init(NULL);
34 }
35
Graphic(SDL_Surface * image)36 Graphic::Graphic(SDL_Surface* image) {
37 init(image);
38 }
39
Graphic(const char * filename)40 Graphic::Graphic(const char* filename) {
41 SDL_Surface* loaded = IMG_Load(filename);
42 init(loaded);
43 SDL_FreeSurface(loaded);
44 }
45
Graphic(const Graphic & other)46 Graphic::Graphic(const Graphic& other) {
47 m_x = other.m_x;
48 m_y = other.m_y;
49 m_invisible = other.m_invisible;
50 m_center_x = other.m_center_x;
51 m_center_y = other.m_center_y;
52 m_rotation = other.m_rotation;
53 m_scale_x = other.m_scale_x;
54 m_scale_y = other.m_scale_y;
55 m_priority = other.m_priority;
56 m_image_width = other.m_image_width;
57 m_image_height = other.m_image_height;
58 m_tex_id = other.m_tex_id;
59 m_tex_count = other.m_tex_count;
60 if (m_tex_count != NULL) {
61 ++*m_tex_count;
62 }
63 }
64
~Graphic()65 Graphic::~Graphic() {
66 if (m_tex_count != NULL) {
67 if(*m_tex_count <= 1) {
68 glDeleteTextures(1, &m_tex_id);
69 delete m_tex_count;
70 } else {
71 --*m_tex_count;
72 }
73 }
74 }
75
init(SDL_Surface * image)76 void Graphic::init(SDL_Surface* image) {
77 m_image_width = 0;
78 m_image_height = 0;
79 m_center_x = 0.0;
80 m_center_y = 0.0;
81 m_invisible = false;
82 m_tex_count = NULL;
83 m_priority = 0;
84 m_x = 0;
85 m_y = 0;
86 m_scale_x = 1.0;
87 m_scale_y = 1.0;
88 m_rotation = 0;
89
90 if (image == NULL) {
91 return;
92 }
93
94 m_image_width = image->w;
95 m_image_height = image->h;
96 int width = to_pow_2(image->w);
97 int height = to_pow_2(image->h);
98 SDL_Surface *hw_image = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
99 SDL_SetAlpha(image, 0, SDL_ALPHA_OPAQUE);
100 SDL_BlitSurface(image, NULL, hw_image, NULL);
101 m_tex_count = new int;
102 *m_tex_count = 1;
103 glGenTextures(1, &m_tex_id);
104 glBindTexture(GL_TEXTURE_2D, m_tex_id);
105 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
106 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
107 glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, hw_image->pixels);
108 SDL_FreeSurface(hw_image);
109 }
110
get_texture_id() const111 GLuint Graphic::get_texture_id() const {
112 return m_tex_id;
113 }
114
transform_gl() const115 void Graphic::transform_gl() const {
116 glTranslated(round(m_x), round(m_y), 0.0); //TODO find alternative method
117 glRotated(m_rotation, 0.0, 0.0, 1.0);
118 glScaled(m_scale_x, m_scale_y, 1.0);
119 glTranslated(-round(m_center_x), -round(m_center_y), 0.0);
120 }
121
draw_rect(double x0,double y0,double x1,double y1) const122 void Graphic::draw_rect(double x0, double y0, double x1, double y1) const {
123 GLdouble vertices[8] = {
124 x0, y0,
125 x1, y0,
126 x1, y1,
127 x0, y1
128 };
129 glVertexPointer(2, GL_DOUBLE, 0, vertices);
130 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
131 }
132
get_image_width() const133 double Graphic::get_image_width() const {
134 return m_image_width;
135 }
136
get_image_height() const137 double Graphic::get_image_height() const {
138 return m_image_height;
139 }
140
get_x() const141 double Graphic::get_x() const {
142 return m_x;
143 }
144
get_y() const145 double Graphic::get_y() const {
146 return m_y;
147 }
148
get_scale_x() const149 double Graphic::get_scale_x() const {
150 return m_scale_x;
151 }
152
get_scale_y() const153 double Graphic::get_scale_y() const {
154 return m_scale_y;
155 }
156
get_rotation() const157 double Graphic::get_rotation() const {
158 return m_rotation;
159 }
160
get_priority() const161 int Graphic::get_priority() const {
162 return m_priority;
163 }
164
set_priority(int priority)165 void Graphic::set_priority(int priority) {
166 m_priority = priority;
167 }
168
set_x(double x)169 void Graphic::set_x(double x) {
170 m_x = x;
171 }
172
set_y(double y)173 void Graphic::set_y(double y) {
174 m_y = y;
175 }
176
set_scale_x(double scale_x)177 void Graphic::set_scale_x(double scale_x) {
178 m_scale_x = scale_x;
179 }
180
set_scale_y(double scale_y)181 void Graphic::set_scale_y(double scale_y) {
182 m_scale_y = scale_y;
183 }
184
set_rotation(double rotation)185 void Graphic::set_rotation(double rotation) {
186 m_rotation = rotation;
187 }
188
get_center_x() const189 double Graphic::get_center_x() const {
190 return m_center_x;
191 }
192
get_center_y() const193 double Graphic::get_center_y() const {
194 return m_center_y;
195 }
196
set_center_x(double center_x)197 void Graphic::set_center_x(double center_x) {
198 m_center_x = center_x;
199 }
200
set_center_y(double center_y)201 void Graphic::set_center_y(double center_y) {
202 m_center_y = center_y;
203 }
204
set_color_intensity(const Color & color)205 void Graphic::set_color_intensity(const Color& color) {
206 set_red_intensity(color.r);
207 set_red_intensity(color.g);
208 set_red_intensity(color.b);
209 }
210
is_invisible() const211 bool Graphic::is_invisible() const {
212 return m_invisible;
213 }
214
set_invisible(bool invisible)215 void Graphic::set_invisible(bool invisible) {
216 m_invisible = invisible;
217 }
218
is_over(int x,int y) const219 bool Graphic::is_over(int x, int y) const {
220 double left = get_x() - get_center_x();
221 double top = get_y() - get_center_y();
222 return (x >= left && x <= left + get_image_width() && y >= top && y <= top + get_image_height());
223 }
224