00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "xrb_engine2_sprite.hpp"
00012
00013 #include "xrb_gl.hpp"
00014 #include "xrb_render.hpp"
00015 #include "xrb_serializer.hpp"
00016
00017 namespace Xrb
00018 {
00019
00020 Engine2::Sprite *Engine2::Sprite::Create (std::string const &texture_path)
00021 {
00022 Resource<GLTexture> texture =
00023 Singleton::ResourceLibrary().LoadPath<GLTexture>(
00024 GLTexture::Create,
00025 texture_path);
00026 if (!texture.IsValid())
00027 return NULL;
00028
00029 return new Sprite(texture);
00030 }
00031
00032 Engine2::Sprite *Engine2::Sprite::Create (Serializer &serializer)
00033 {
00034 Sprite *retval = new Sprite(Resource<GLTexture>());
00035
00036
00037 retval->Object::ReadClassSpecific(serializer);
00038 retval->Sprite::ReadClassSpecific(serializer);
00039
00040 return retval;
00041 }
00042
00043 void Engine2::Sprite::Write (Serializer &serializer) const
00044 {
00045 WriteObjectType(serializer);
00046
00047 Object::WriteClassSpecific(serializer);
00048 Sprite::WriteClassSpecific(serializer);
00049 }
00050
00051 void Engine2::Sprite::Draw (
00052 Engine2::Object::DrawData const &draw_data,
00053 Float const alpha_mask) const
00054 {
00055 if (draw_data.GetRenderContext().MaskAndBiasWouldResultInNoOp())
00056 return;
00057
00058
00059 if (!m_texture.IsValid())
00060 return;
00061
00062
00063 glMatrixMode(GL_MODELVIEW);
00064
00065
00066
00067 glPushMatrix();
00068
00069
00070
00071 glTranslatef(
00072 Translation()[Dim::X],
00073 Translation()[Dim::Y],
00074 ZDepth());
00075 glRotatef(Angle(), 0.0f, 0.0f, 1.0f);
00076 glScalef(
00077 ScaleFactors()[Dim::X],
00078 ScaleFactors()[Dim::Y],
00079 1.0f);
00080
00081
00082 Color color_bias(draw_data.GetRenderContext().BlendedColorBias(ColorBias()));
00083
00084 Color color_mask(draw_data.GetRenderContext().MaskedColor(ColorMask()));
00085 color_mask[Dim::A] *= alpha_mask;
00086
00087 Render::SetupTextureUnits(m_texture->Handle(), color_mask, color_bias);
00088
00089
00090 {
00091 static FloatVector2 const s_texture_coord_array[4] =
00092 {
00093 FloatVector2(0.0f, 1.0f),
00094 FloatVector2(1.0f, 1.0f),
00095 FloatVector2(0.0f, 0.0f),
00096 FloatVector2(1.0f, 0.0f)
00097 };
00098 static FloatVector2 const s_vertex_array[4] =
00099 {
00100 FloatVector2(-1.0f, -1.0f),
00101 FloatVector2( 1.0f, -1.0f),
00102 FloatVector2(-1.0f, 1.0f),
00103 FloatVector2( 1.0f, 1.0f)
00104 };
00105
00106 glEnableClientState(GL_VERTEX_ARRAY);
00107 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00108
00109 glVertexPointer(2, GL_FLOAT, 0, s_vertex_array);
00110
00111 glClientActiveTexture(GL_TEXTURE0);
00112 glTexCoordPointer(2, GL_FLOAT, 0, s_texture_coord_array);
00113 glClientActiveTexture(GL_TEXTURE1);
00114 glTexCoordPointer(2, GL_FLOAT, 0, s_texture_coord_array);
00115
00116 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
00117
00118
00119 glDisableClientState(GL_VERTEX_ARRAY);
00120 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00121 }
00122
00123 glPopMatrix();
00124 }
00125
00126 void Engine2::Sprite::SetPhysicalSizeRatios (FloatVector2 const &physical_size_ratios)
00127 {
00128 ASSERT1(physical_size_ratios[Dim::X] > 0.0f);
00129 ASSERT1(physical_size_ratios[Dim::Y] > 0.0f);
00130 m_physical_size_ratios = physical_size_ratios;
00131 IndicateRadiiNeedToBeRecalculated();
00132 }
00133
00134 void Engine2::Sprite::SetPhysicalSizeRatio (Float const physical_size_ratio)
00135 {
00136 m_physical_size_ratios.SetComponents(physical_size_ratio, physical_size_ratio);
00137 IndicateRadiiNeedToBeRecalculated();
00138 }
00139
00140 Engine2::Sprite::Sprite (Resource<GLTexture> const &texture)
00141 :
00142 Object(OT_SPRITE),
00143 m_physical_size_ratios(1.0f, 1.0f)
00144 {
00145 m_texture = texture;
00146 m_is_round = true;
00147 }
00148
00149 void Engine2::Sprite::ReadClassSpecific (Serializer &serializer)
00150 {
00151
00152 m_texture =
00153 Singleton::ResourceLibrary().LoadPath<GLTexture>(
00154 GLTexture::Create,
00155 serializer.ReadStdString());
00156 m_is_round = serializer.ReadBool();
00157 serializer.ReadFloatVector2(&m_physical_size_ratios);
00158 IndicateRadiiNeedToBeRecalculated();
00159
00160 ASSERT1(m_texture.IsValid());
00161 }
00162
00163 void Engine2::Sprite::WriteClassSpecific (Serializer &serializer) const
00164 {
00165 ASSERT1(m_texture.IsValid());
00166
00167
00168 serializer.WriteStdString(m_texture.Path());
00169 serializer.WriteBool(m_is_round);
00170 serializer.WriteFloatVector2(m_physical_size_ratios);
00171 }
00172
00173 void Engine2::Sprite::CalculateRadius (QuadTreeType const quad_tree_type) const
00174 {
00175 switch (quad_tree_type)
00176 {
00177 case QTT_VISIBILITY:
00178 if (m_is_round)
00179 m_radius[quad_tree_type] = Max(ScaleFactors()[Dim::X], ScaleFactors()[Dim::Y]);
00180 else
00181 m_radius[quad_tree_type] = ScaleFactors().Length();
00182 break;
00183
00184 case QTT_PHYSICS_HANDLER:
00185 if (m_is_round)
00186 m_radius[quad_tree_type] =
00187 Max(ScaleFactors()[Dim::X] * m_physical_size_ratios[Dim::X],
00188 ScaleFactors()[Dim::Y] * m_physical_size_ratios[Dim::Y]);
00189 else
00190 m_radius[quad_tree_type] = (ScaleFactors() * m_physical_size_ratios).Length();
00191 break;
00192
00193 default:
00194 ASSERT0(false && "Invalid QuadTreeType");
00195 break;
00196 }
00197 }
00198
00199 void Engine2::Sprite::CloneProperties (Engine2::Object const *const object)
00200 {
00201 ASSERT1(object->GetObjectType() == OT_SPRITE);
00202 Sprite const *sprite = DStaticCast<Sprite const *>(object);
00203 ASSERT1(sprite != NULL);
00204
00205 m_texture = sprite->m_texture;
00206 m_is_round = sprite->m_is_round;
00207 m_physical_size_ratios = sprite->m_physical_size_ratios;
00208 IndicateRadiiNeedToBeRecalculated();
00209 }
00210
00211 }