00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <vlVG/VectorGraphics.hpp>
00033
00034 using namespace vl;
00035
00036
00037 VectorGraphics::VectorGraphics()
00038 {
00039 mDefaultEffect = new Effect;
00040 mDefaultEffect->shader()->enable(EN_BLEND);
00041 mActors.setAutomaticDelete(false);
00042 }
00043
00044 Actor* VectorGraphics::drawLine(double x1, double y1, double x2, double y2)
00045 {
00046 std::vector<dvec2> ln;
00047 ln.push_back(dvec2(x1,y1));
00048 ln.push_back(dvec2(x2,y2));
00049 return drawLines(ln);
00050 }
00051
00052 Actor* VectorGraphics::drawLines(const std::vector<dvec2>& ln)
00053 {
00054
00055 ref<Geometry> geom = prepareGeometry(ln);
00056
00057 if (mState.mImage)
00058 {
00059 ref<ArrayFloat1> tex_array = new ArrayFloat1;
00060 tex_array->resize(geom->vertexArray()->size());
00061 float u1 = 1.0f / mState.mImage->width() * 0.5f;
00062 float u2 = 1.0f - 1.0f / mState.mImage->width() * 0.5f;
00063 for(size_t i=0; i<tex_array->size(); i+=2)
00064 {
00065 tex_array->at(i+0) = u1;
00066 tex_array->at(i+1) = u2;
00067 }
00068
00069 geom->setTexCoordArray(0, tex_array.get());
00070 }
00071
00072 geom->drawCalls()->push_back( new DrawArrays(PT_LINES, 0, (int)ln.size()) );
00073
00074 return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00075 }
00076
00077 Actor* VectorGraphics::drawLineStrip(const std::vector<dvec2>& ln)
00078 {
00079
00080 ref<Geometry> geom = prepareGeometry(ln);
00081
00082 generateLinearTexCoords(geom.get());
00083
00084 geom->drawCalls()->push_back( new DrawArrays(PT_LINE_STRIP, 0, (int)ln.size()) );
00085
00086 return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00087 }
00088
00089 Actor* VectorGraphics::drawLineLoop(const std::vector<dvec2>& ln)
00090 {
00091
00092 ref<Geometry> geom = prepareGeometry(ln);
00093
00094 generateLinearTexCoords(geom.get());
00095
00096 geom->drawCalls()->push_back( new DrawArrays(PT_LINE_LOOP, 0, (int)ln.size()) );
00097
00098 return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00099 }
00100
00101 Actor* VectorGraphics::fillPolygon(const std::vector<dvec2>& poly)
00102 {
00103
00104 ref<Geometry> geom = prepareGeometry(poly);
00105
00106 generatePlanarTexCoords(geom.get(), poly);
00107
00108 geom->drawCalls()->push_back( new DrawArrays(PT_POLYGON, 0, (int)poly.size()) );
00109
00110 return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00111 }
00112
00113 Actor* VectorGraphics::fillTriangles(const std::vector<dvec2>& triangles)
00114 {
00115
00116 ref<Geometry> geom = prepareGeometry(triangles);
00117
00118 generatePlanarTexCoords(geom.get(), triangles);
00119
00120 geom->drawCalls()->push_back( new DrawArrays(PT_TRIANGLES, 0, (int)triangles.size()) );
00121
00122 return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00123 }
00124
00125 Actor* VectorGraphics::fillTriangleFan(const std::vector<dvec2>& fan)
00126 {
00127
00128 ref<Geometry> geom = prepareGeometry(fan);
00129
00130 generatePlanarTexCoords(geom.get(), fan);
00131
00132 geom->drawCalls()->push_back( new DrawArrays(PT_TRIANGLE_FAN, 0, (int)fan.size()) );
00133
00134 return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00135 }
00136
00137 Actor* VectorGraphics::fillTriangleStrip(const std::vector<dvec2>& strip)
00138 {
00139
00140 ref<Geometry> geom = prepareGeometry(strip);
00141
00142 generatePlanarTexCoords(geom.get(), strip);
00143
00144 geom->drawCalls()->push_back( new DrawArrays(PT_TRIANGLE_STRIP, 0, (int)strip.size()) );
00145
00146 return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00147 }
00148
00149 Actor* VectorGraphics::fillQuads(const std::vector<dvec2>& quads)
00150 {
00151
00152 ref<Geometry> geom = prepareGeometry(quads);
00153
00154 generateQuadsTexCoords(geom.get(), quads);
00155
00156 geom->drawCalls()->push_back( new DrawArrays(PT_QUADS, 0, (int)quads.size()) );
00157
00158 return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00159 }
00160
00161 Actor* VectorGraphics::fillQuadStrip(const std::vector<dvec2>& quad_strip)
00162 {
00163
00164 ref<Geometry> geom = prepareGeometry(quad_strip);
00165
00166 generatePlanarTexCoords(geom.get(), quad_strip);
00167
00168 geom->drawCalls()->push_back( new DrawArrays(PT_QUAD_STRIP, 0, (int)quad_strip.size()) );
00169
00170 return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00171 }
00172
00173 Actor* VectorGraphics::drawPoint(double x, double y)
00174 {
00175 std::vector<dvec2> pt;
00176 pt.push_back(dvec2(x,y));
00177 return drawPoints(pt);
00178 }
00179
00180 Actor* VectorGraphics::drawPoints(const std::vector<dvec2>& pt)
00181 {
00182
00183 ref<ArrayFloat3> pos_array = new ArrayFloat3;
00184 pos_array->resize(pt.size());
00185
00186 for(unsigned i=0; i<pt.size(); ++i)
00187 {
00188 pos_array->at(i) = (fvec3)(matrix() * dvec3(pt[i].x(), pt[i].y(), 0));
00189
00190 if (mState.mPointSize % 2 == 0)
00191 {
00192 pos_array->at(i).s() += 0.5;
00193 pos_array->at(i).t() += 0.5;
00194 }
00195 }
00196
00197 ref< Geometry > geom = new Geometry;
00198 geom->setVertexArray(pos_array.get());
00199 geom->drawCalls()->push_back( new DrawArrays(PT_POINTS, 0, (int)pos_array->size()) );
00200
00201 return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00202 }
00203
00204 Actor* VectorGraphics::drawEllipse(double origx, double origy, double xaxis, double yaxis, int segments)
00205 {
00206 std::vector<dvec2> points;
00207 points.resize(segments);
00208 for(int i=0; i<segments; ++i)
00209 {
00210 double t = (double)i/(segments-1) * dPi * 2.0 + dPi * 0.5;
00211 points[i] = dvec2(cos(t)*xaxis*0.5+origx, sin(t)*yaxis*0.5+origy);
00212 }
00213 return drawLineStrip(points);
00214 }
00215
00216 Actor* VectorGraphics::fillEllipse(double origx, double origy, double xaxis, double yaxis, int segments)
00217 {
00218 std::vector<dvec2> points;
00219 points.resize(segments);
00220 for(int i=0; i<segments; ++i)
00221 {
00222 double t = (double)i/segments * dPi * 2.0 + dPi * 0.5;
00223 points[i] = dvec2(cos(t)*xaxis*0.5+origx, sin(t)*yaxis*0.5+origy);
00224 }
00225 return fillPolygon(points);
00226 }
00227
00228 Actor* VectorGraphics::drawQuad(double left, double bottom, double right, double top)
00229 {
00230 std::vector<dvec2> quad;
00231 quad.push_back(dvec2(left,bottom));
00232 quad.push_back(dvec2(left,top));
00233 quad.push_back(dvec2(right,top));
00234 quad.push_back(dvec2(right,bottom));
00235 return drawLineLoop(quad);
00236 }
00237
00238 Actor* VectorGraphics::fillQuad(double left, double bottom, double right, double top)
00239 {
00240 std::vector<dvec2> quad;
00241 quad.push_back(dvec2(left,bottom));
00242 quad.push_back(dvec2(left,top));
00243 quad.push_back(dvec2(right,top));
00244 quad.push_back(dvec2(right,bottom));
00245 return fillQuads(quad);
00246 }
00247
00248 void VectorGraphics::continueDrawing()
00249 {
00250
00251
00252
00253
00254
00255
00256
00257 mState = State();
00258 mMatrix = dmat4();
00259 mMatrixStack.clear();
00260 mStateStack.clear();
00261 }
00262
00263 void VectorGraphics::endDrawing(bool release_cache)
00264 {
00265 if (release_cache)
00266 {
00267 mVGToEffectMap.clear();
00268 mImageToTextureMap.clear();
00269 mRectToScissorMap.clear();
00270 }
00271
00272
00273 mMatrixStack.clear();
00274 mStateStack.clear();
00275 }
00276
00277 void VectorGraphics::clear()
00278 {
00279
00280 mActors.clear();
00281
00282
00283 mVGToEffectMap.clear();
00284 mImageToTextureMap.clear();
00285 mRectToScissorMap.clear();
00286
00287
00288 mState = State();
00289 mMatrix = dmat4();
00290 mMatrixStack.clear();
00291 mStateStack.clear();
00292 }
00293
00294 void VectorGraphics::setLineStipple(ELineStipple stipple)
00295 {
00296 switch(stipple)
00297 {
00298 case LineStipple_Solid: mState.mLineStipple = 0xFFFF; break;
00299 case LineStipple_Dot: mState.mLineStipple = 0xAAAA; break;
00300 case LineStipple_Dash: mState.mLineStipple = 0xCCCC; break;
00301 case LineStipple_Dash4: mState.mLineStipple = 0xF0F0; break;
00302 case LineStipple_Dash8: mState.mLineStipple = 0xFF00; break;
00303 case LineStipple_DashDot: mState.mLineStipple = 0xF840; break;
00304 case LineStipple_DashDotDot: mState.mLineStipple = 0xF888; break;
00305 }
00306 }
00307
00308 void VectorGraphics::setPolygonStipple(EPolygonStipple stipple)
00309 {
00310 unsigned char solid_stipple[] = {
00311 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
00312 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
00313 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
00314 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
00315 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
00316 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
00317 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
00318 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF };
00319 unsigned char hline_stipple[] = {
00320 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00,
00321 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00,
00322 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00,
00323 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00,
00324 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00,
00325 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00,
00326 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00,
00327 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00 };
00328 unsigned char vline_stipple[] = {
00329 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA,
00330 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA,
00331 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA,
00332 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA,
00333 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA,
00334 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA,
00335 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA,
00336 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA };
00337 unsigned char chain_stipple[] = {
00338 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA,
00339 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55,
00340 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA,
00341 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55,
00342 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA,
00343 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55,
00344 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA,
00345 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55 };
00346 unsigned char dot_stipple[] = {
00347 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55,
00348 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55,
00349 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55,
00350 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55,
00351 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55,
00352 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55,
00353 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55,
00354 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55 };
00355 switch(stipple)
00356 {
00357 case PolygonStipple_Solid: setPolygonStipple(solid_stipple); break;
00358 case PolygonStipple_Dot: setPolygonStipple(dot_stipple); break;
00359 case PolygonStipple_Chain: setPolygonStipple(chain_stipple); break;
00360 case PolygonStipple_HLine: setPolygonStipple(hline_stipple); break;
00361 case PolygonStipple_VLine: setPolygonStipple(vline_stipple); break;
00362 }
00363 }
00364
00365 void VectorGraphics::setBlendFunc(EBlendFactor src_rgb, EBlendFactor dst_rgb, EBlendFactor src_alpha, EBlendFactor dst_alpha)
00366 {
00367 mState.mBlendFactorSrcRGB = src_rgb;
00368 mState.mBlendFactorDstRGB = dst_rgb;
00369 mState.mBlendFactorSrcAlpha = src_alpha;
00370 mState.mBlendFactorDstAlpha = dst_alpha;
00371 }
00372
00373 void VectorGraphics::getBlendFunc(EBlendFactor& src_rgb, EBlendFactor& dst_rgb, EBlendFactor& src_alpha, EBlendFactor& dst_alpha) const
00374 {
00375 src_rgb = mState.mBlendFactorSrcRGB;
00376 dst_rgb = mState.mBlendFactorDstRGB;
00377 src_alpha = mState.mBlendFactorSrcAlpha;
00378 dst_alpha = mState.mBlendFactorDstAlpha;
00379 }
00380
00381 void VectorGraphics::setBlendEquation( EBlendEquation rgb_eq, EBlendEquation alpha_eq )
00382 {
00383 mState.mBlendEquationRGB = rgb_eq;
00384 mState.mBlendEquationAlpha = alpha_eq;
00385 }
00386
00387 void VectorGraphics::getBlendEquation( EBlendEquation& rgb_eq, EBlendEquation& alpha_eq ) const
00388 {
00389 rgb_eq = mState.mBlendEquationRGB;
00390 alpha_eq = mState.mBlendEquationAlpha;
00391 }
00392
00393 void VectorGraphics::setStencilOp(EStencilOp sfail, EStencilOp dpfail, EStencilOp dppass)
00394 {
00395 mState.mStencil_SFail = sfail;
00396 mState.mStencil_DpFail = dpfail;
00397 mState.mStencil_DpPass = dppass;
00398 }
00399
00400 void VectorGraphics::getStencilOp(EStencilOp& sfail, EStencilOp& dpfail, EStencilOp& dppass)
00401 {
00402 sfail = mState.mStencil_SFail;
00403 dpfail = mState.mStencil_DpFail;
00404 dppass = mState.mStencil_DpPass;
00405 }
00406
00407 void VectorGraphics::setStencilFunc(EFunction func, int refval, unsigned int mask)
00408 {
00409 mState.mStencil_Function = func;
00410 mState.mStencil_RefValue = refval;
00411 mState.mStencil_FunctionMask = mask;
00412 }
00413
00414 void VectorGraphics::getStencilFunc(EFunction& func, int& refval, unsigned int& mask)
00415 {
00416 func = mState.mStencil_Function;
00417 refval = mState.mStencil_RefValue;
00418 mask = mState.mStencil_FunctionMask;
00419 }
00420
00421 Actor* VectorGraphics::clearColor(const fvec4& color, int x, int y, int w, int h)
00422 {
00423 ref<Clear> clear = new Clear;
00424 clear->setClearColorBuffer(true);
00425 clear->setClearColorValue(color);
00426 clear->setScissorBox(x,y,w,h);
00427 return addActor( new Actor( clear.get(), currentEffect(), NULL) );
00428 }
00429
00430 Actor* VectorGraphics::clearStencil(int clear_val, int x, int y, int w, int h)
00431 {
00432 ref<Clear> clear = new Clear;
00433 clear->setClearStencilBuffer(true);
00434 clear->setClearStencilValue(clear_val);
00435 clear->setScissorBox(x,y,w,h);
00436 return addActor( new Actor( clear.get(), currentEffect(), NULL) );
00437 }
00438
00439 Actor* VectorGraphics::drawText(Text* text)
00440 {
00441 if (text->font() == NULL)
00442 text->setFont(mState.mFont.get());
00443 return addActor( new Actor(text, currentEffect(), NULL) );
00444 }
00445
00446 Actor* VectorGraphics::drawText(int x, int y, const String& text, int alignment)
00447 {
00448 pushMatrix();
00449 mMatrix = dmat4::getTranslation(x,y,0) * mMatrix;
00450 Actor* act = drawText(text, alignment);
00451 popMatrix();
00452 return act;
00453 }
00454
00455 Actor* VectorGraphics::drawText(const String& text, int alignment)
00456 {
00457 ref<Text> t = new Text;
00458 t->setText( text );
00459 t->setAlignment(alignment);
00460 t->setViewportAlignment(AlignBottom|AlignLeft);
00461 t->setColor( mState.mColor );
00462 t->setMatrix( (fmat4)matrix() );
00463 return drawText(t.get());
00464 }
00465
00466 Actor* VectorGraphics::drawActor(Actor* actor, Transform* transform, bool keep_effect)
00467 {
00468 VL_CHECK(actor->effect())
00469 if (!keep_effect || !actor->effect())
00470 actor->setEffect(currentEffect());
00471 if (transform != NULL)
00472 actor->setTransform(transform);
00473 return addActor(actor);
00474 }
00475
00476 Actor* VectorGraphics::drawActorCopy(Actor* actor, Transform* transform)
00477 {
00478 ref<Actor> copy = new Actor(*actor);
00479 copy->setTransform(transform);
00480 drawActor(copy.get());
00481 return copy.get();
00482 }
00483
00484 void VectorGraphics::rotate(double deg)
00485 {
00486 mMatrix = mMatrix * dmat4::getRotation(deg, 0,0,1.0);
00487 }
00488
00489 void VectorGraphics::translate(double x, double y, double z)
00490 {
00491 mMatrix = mMatrix * dmat4::getTranslation(x,y,z);
00492 }
00493
00494 void VectorGraphics::scale(double x, double y, double z)
00495 {
00496 mMatrix = mMatrix * dmat4::getScaling(x,y,z);
00497 }
00498
00499 void VectorGraphics::popMatrix()
00500 {
00501 if (mMatrixStack.empty())
00502 {
00503 Log::error("VectorGraphics::popMatrix() matrix stack underflow!\n");
00504 return;
00505 }
00506 setMatrix(mMatrixStack.back());
00507 mMatrixStack.pop_back();
00508 }
00509
00510 void VectorGraphics::pushState()
00511 {
00512 mStateStack.push_back(mState);
00513 pushMatrix();
00514 }
00515
00516 void VectorGraphics::popState()
00517 {
00518 popMatrix();
00519 if (mStateStack.empty())
00520 {
00521 Log::error("VectorGraphics::popState() matrix stack underflow!\n");
00522 return;
00523 }
00524 mState = mStateStack.back();
00525 mStateStack.pop_back();
00526 }
00527
00528 void VectorGraphics::pushScissor(int x, int y, int w, int h)
00529 {
00530 mScissorStack.push_back(mScissor.get());
00531 RectI newscissor = mScissor ? mScissor->scissorRect().intersected(RectI(x,y,w,h)) : RectI(x,y,w,h);
00532 setScissor(newscissor.x(), newscissor.y(), newscissor.width(), newscissor.height());
00533 }
00534
00535 void VectorGraphics::popScissor()
00536 {
00537 if (mScissorStack.empty())
00538 {
00539 Log::error("VectorGraphics::popScissor() scissor stack underflow!\n");
00540 return;
00541 }
00542 mScissor = mScissorStack.back();
00543 mScissorStack.pop_back();
00544 }
00545
00546 void VectorGraphics::generateQuadsTexCoords(Geometry* geom, const std::vector<dvec2>& points)
00547 {
00548
00549 if (mState.mImage)
00550 {
00551 ref<ArrayFloat2> tex_array = new ArrayFloat2;
00552 tex_array->resize(geom->vertexArray()->size());
00553 geom->setTexCoordArray(0, tex_array.get());
00554 if (mState.mTextureMode == TextureMode_Clamp)
00555 {
00556 float du = 1.0f / mState.mImage->width() / 2.0f;
00557 float dv = mState.mImage->height() ? (1.0f / mState.mImage->height() / 2.0f) : 0.5f;
00558
00559
00560
00561
00562 fvec2 texc[] = { fvec2(du,dv), fvec2(du,1.0f-dv), fvec2(1.0f-du,1.0f-dv), fvec2(1.0f-du,dv) };
00563 for(unsigned i=0; i<points.size(); ++i)
00564 {
00565 float s = texc[i%4].s();
00566 float t = texc[i%4].t();
00567 tex_array->at(i).s() = s;
00568 tex_array->at(i).t() = t;
00569 }
00570 }
00571 else
00572 {
00573 AABB aabb;
00574 for(unsigned i=0; i<points.size(); ++i)
00575 aabb.addPoint( (vec3)geom->vertexArray()->vectorAsVec4(i).xyz() );
00576 for(unsigned i=0; i<points.size(); ++i)
00577 {
00578 vec4 v = geom->vertexArray()->vectorAsVec4(i);
00579 double s = (geom->vertexArray()->vectorAsVec4(i).s()-aabb.minCorner().s()) / (mState.mImage->width() );
00580 double t = (geom->vertexArray()->vectorAsVec4(i).t()-aabb.minCorner().t()) / (mState.mImage->height());
00581 tex_array->at(i).s() = (float)s;
00582 tex_array->at(i).t() = (float)t;
00583 }
00584 }
00585 }
00586 }
00587
00588 void VectorGraphics::generatePlanarTexCoords(Geometry* geom, const std::vector<dvec2>& points)
00589 {
00590
00591 if (mState.mImage)
00592 {
00593
00594 ref<ArrayFloat2> tex_array = new ArrayFloat2;
00595 tex_array->resize(geom->vertexArray()->size());
00596 geom->setTexCoordArray(0, tex_array.get());
00597 if (mState.mTextureMode == TextureMode_Clamp)
00598 {
00599
00600 AABB aabb;
00601 for(unsigned i=0; i<points.size(); ++i)
00602 aabb.addPoint( (vec3)dvec3(points[i],0.0) );
00603 for(unsigned i=0; i<points.size(); ++i)
00604 {
00605 float s = float((points[i].x() - aabb.minCorner().x()) / aabb.width() );
00606 float t = float((points[i].y() - aabb.minCorner().y()) / aabb.height());
00607 tex_array->at(i).s() = s;
00608 tex_array->at(i).t() = t;
00609 }
00610 }
00611 else
00612 {
00613 AABB aabb;
00614 for(unsigned i=0; i<points.size(); ++i)
00615 aabb.addPoint( (vec3)geom->vertexArray()->vectorAsVec4(i).xyz()+vec3(0.5f,0.5f,0.0f) );
00616 for(unsigned i=0; i<points.size(); ++i)
00617 {
00618 vec4 v = geom->vertexArray()->vectorAsVec4(i);
00619 double s = (geom->vertexArray()->vectorAsVec4(i).s()-aabb.minCorner().s()) / mState.mImage->width();
00620 double t = (geom->vertexArray()->vectorAsVec4(i).t()-aabb.minCorner().t()) / mState.mImage->height();
00621 tex_array->at(i).s() = (float)s;
00622 tex_array->at(i).t() = (float)t;
00623 }
00624 }
00625 }
00626 }
00627
00628 void VectorGraphics::generateLinearTexCoords(Geometry* geom)
00629 {
00630 if (mState.mImage)
00631 {
00632 ref<ArrayFloat1> tex_array = new ArrayFloat1;
00633 tex_array->resize(geom->vertexArray()->size());
00634 float u1 = 1.0f / mState.mImage->width() * 0.5f;
00635 float u2 = 1.0f - 1.0f / mState.mImage->width() * 0.5f;
00636 for(size_t i=0; i<tex_array->size(); ++i)
00637 {
00638 float t = (float)i/(tex_array->size()-1);
00639 tex_array->at(i) = u1 * (1.0f-t) + u2 * t;
00640 }
00641
00642 geom->setTexCoordArray(0, tex_array.get());
00643 }
00644 }
00645
00646 ref<Geometry> VectorGraphics::prepareGeometry(const std::vector<dvec2>& ln)
00647 {
00648
00649 ref<ArrayFloat3> pos_array = new ArrayFloat3;
00650 pos_array->resize(ln.size());
00651
00652 for(unsigned i=0; i<ln.size(); ++i)
00653 pos_array->at(i) = (fvec3)(matrix() * dvec3(ln[i].x(), ln[i].y(), 0));
00654
00655 ref< Geometry > geom = new Geometry;
00656 geom->setVertexArray(pos_array.get());
00657 return geom;
00658 }
00659
00660 Scissor* VectorGraphics::resolveScissor(int x, int y, int width, int height)
00661 {
00662 ref<Scissor> scissor = mRectToScissorMap[RectI(x,y,width,height)];
00663 if (!scissor)
00664 {
00665 scissor = new Scissor(x,y,width,height);
00666 mRectToScissorMap[RectI(x,y,width,height)] = scissor;
00667 }
00668 return scissor.get();
00669 }
00670
00671 Texture* VectorGraphics::resolveTexture(Image* image)
00672 {
00673 Texture* texture = mImageToTextureMap[ImageState(image,mState.mTextureMode)].get();
00674 if (!texture)
00675 {
00676 texture = new Texture( image, TF_RGBA, true, false);
00677 texture->getTexParameter()->setMinFilter(TPF_LINEAR_MIPMAP_LINEAR);
00678 texture->getTexParameter()->setMagFilter(TPF_LINEAR);
00679 #if 0
00680 texture->getTexParameter()->setBorderColor(fvec4(1,0,1,1));
00681 #else
00682 texture->getTexParameter()->setBorderColor(fvec4(1,1,1,0));
00683 #endif
00684 if (mState.mTextureMode == vl::TextureMode_Repeat)
00685 {
00686 texture->getTexParameter()->setWrapS(TPW_REPEAT);
00687 texture->getTexParameter()->setWrapT(TPW_REPEAT);
00688 }
00689 else
00690 {
00691 texture->getTexParameter()->setWrapS(TPW_CLAMP);
00692 texture->getTexParameter()->setWrapT(TPW_CLAMP);
00693 }
00694 mImageToTextureMap[ImageState(image,mState.mTextureMode)] = texture;
00695 }
00696 return texture;
00697 }
00698
00699 Effect* VectorGraphics::currentEffect(const State& vgs)
00700 {
00701 Effect* effect = mVGToEffectMap[vgs].get();
00702
00703 if (!effect)
00704 {
00705 effect = new Effect;
00706 mVGToEffectMap[vgs] = effect;
00707 Shader* shader = effect->shader();
00708
00709 shader->enable(EN_BLEND);
00710
00711 shader->enable(EN_LIGHTING);
00712 shader->gocMaterial()->setFlatColor(vgs.mColor);
00713
00714 shader->gocPointSize()->set((float)vgs.mPointSize);
00715
00716 if (vgs.mLogicOp != LO_COPY)
00717 {
00718 shader->gocLogicOp()->set(vgs.mLogicOp);
00719 shader->enable(EN_COLOR_LOGIC_OP);
00720 }
00721
00722 if ( vgs.mLineStipple != 0xFFFF )
00723 {
00724 shader->gocLineStipple()->set(1, vgs.mLineStipple);
00725 shader->enable(EN_LINE_STIPPLE);
00726 }
00727
00728 if (vgs.mLineWidth != 1.0f)
00729 shader->gocLineWidth()->set(vgs.mLineWidth);
00730
00731 if (vgs.mPointSmoothing)
00732 {
00733 shader->gocHint()->setPointSmoothHint(HM_NICEST);
00734 shader->enable(EN_POINT_SMOOTH);
00735 }
00736
00737 if (vgs.mLineSmoothing)
00738 {
00739 shader->gocHint()->setLineSmoothHint(HM_NICEST);
00740 shader->enable(EN_LINE_SMOOTH);
00741 }
00742
00743 if (vgs.mPolygonSmoothing)
00744 {
00745 shader->gocHint()->setPolygonSmoohtHint(HM_NICEST);
00746 shader->enable(EN_POLYGON_SMOOTH);
00747 }
00748
00749 unsigned char solid_stipple[] = {
00750 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
00751 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
00752 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
00753 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
00754 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
00755 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
00756 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,
00757 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF
00758 };
00759 if ( memcmp(vgs.mPolyStipple, solid_stipple, 32*32/8) != 0 )
00760 {
00761 shader->gocPolygonStipple()->set(vgs.mPolyStipple);
00762 shader->enable(EN_POLYGON_STIPPLE);
00763 }
00764
00765 shader->gocBlendEquation()->set(vgs.mBlendEquationRGB, vgs.mBlendEquationAlpha);
00766 shader->gocBlendFunc()->set(vgs.mBlendFactorSrcRGB, vgs.mBlendFactorDstRGB, vgs.mBlendFactorSrcAlpha, vgs.mBlendFactorDstAlpha);
00767 if (vgs.mAlphaFunc != FU_ALWAYS)
00768 {
00769 shader->enable(EN_ALPHA_TEST);
00770 shader->gocAlphaFunc()->set(vgs.mAlphaFunc, vgs.mAlphaFuncRefValue);
00771 }
00772
00773 if (vgs.mColorMask != ivec4(1,1,1,1) )
00774 shader->gocColorMask()->set(vgs.mColorMask.r()?true:false,vgs.mColorMask.g()?true:false,vgs.mColorMask.b()?true:false,vgs.mColorMask.a()?true:false);
00775
00776 if (vgs.mStencilTestEnabled)
00777 {
00778 shader->enable(EN_STENCIL_TEST);
00779 shader->gocStencilMask()->set(PF_FRONT_AND_BACK, vgs.mStencilMask);
00780 shader->gocStencilOp()->set(PF_FRONT_AND_BACK, vgs.mStencil_SFail, vgs.mStencil_DpFail, vgs.mStencil_DpPass);
00781 shader->gocStencilFunc()->set(PF_FRONT_AND_BACK, vgs.mStencil_Function, vgs.mStencil_RefValue, vgs.mStencil_FunctionMask);
00782 }
00783
00784
00785
00786 if (vgs.mImage)
00787 {
00788 shader->gocTextureUnit(0)->setTexture( resolveTexture(vgs.mImage.get()) );
00789 if (GLEW_ARB_point_sprite || GLEW_VERSION_2_0)
00790 {
00791 shader->gocTexEnv(0)->setPointSpriteCoordReplace(true);
00792 shader->enable(EN_POINT_SPRITE);
00793 }
00794 else
00795 Log::error("GL_ARB_point_sprite not supported.\n");
00796 }
00797 }
00798 return effect;
00799 }
00800
00801 Actor* VectorGraphics::addActor(Actor* actor)
00802 {
00803 actor->setScissor(mScissor.get());
00804 mActors.push_back(actor);
00805 return actor;
00806 }
00807