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