Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://visualizationlibrary.org */ 00005 /* */ 00006 /* Copyright (c) 2005-2010, Michele Bosi */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without modification, */ 00010 /* are permitted provided that the following conditions are met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, this */ 00013 /* list of conditions and the following disclaimer. */ 00014 /* */ 00015 /* - Redistributions in binary form must reproduce the above copyright notice, this */ 00016 /* list of conditions and the following disclaimer in the documentation and/or */ 00017 /* other materials provided with the distribution. */ 00018 /* */ 00019 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ 00020 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ 00021 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ 00022 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ 00023 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ 00024 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ 00025 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ 00026 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 00027 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ 00028 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 00029 /* */ 00030 /**************************************************************************************/ 00031 00032 #ifndef VectorGraphics_INCLUDE_ONCE 00033 #define VectorGraphics_INCLUDE_ONCE 00034 00035 #include <vlVG/link_config.hpp> 00036 #include <vlCore/Image.hpp> 00037 #include <vlCore/VisualizationLibrary.hpp> 00038 #include <vlGraphics/Actor.hpp> 00039 #include <vlGraphics/Text.hpp> 00040 #include <vlGraphics/FontManager.hpp> 00041 #include <vlGraphics/Effect.hpp> 00042 #include <vlGraphics/SceneManager.hpp> 00043 #include <vlGraphics/Clear.hpp> 00044 #include <vlGraphics/Scissor.hpp> 00045 #include <vlGraphics/Geometry.hpp> 00046 #include <vlGraphics/FontManager.hpp> 00047 00048 namespace vl 00049 { 00051 typedef enum 00052 { 00054 TextureMode_Clamp, 00056 TextureMode_Repeat 00057 } ETextureMode; 00058 00060 typedef enum 00061 { 00063 PolygonStipple_Solid, 00064 PolygonStipple_Dot, 00065 PolygonStipple_Chain, 00066 PolygonStipple_HLine, 00067 PolygonStipple_VLine 00068 } EPolygonStipple; 00069 00071 typedef enum 00072 { 00074 LineStipple_Solid, 00075 LineStipple_Dot, 00076 LineStipple_Dash, 00077 LineStipple_Dash4, 00078 LineStipple_Dash8, 00079 LineStipple_DashDot, 00080 LineStipple_DashDotDot 00081 } ELineStipple; 00082 00083 //------------------------------------------------------------------------------------------------------------------------------------------- 00084 // VectorGraphics 00085 //------------------------------------------------------------------------------------------------------------------------------------------- 00106 class VLVG_EXPORT VectorGraphics: public Object 00107 { 00108 VL_INSTRUMENT_CLASS(vl::VectorGraphics, Object) 00109 00110 private: 00111 //------------------------------------------------------------------------- start internal 00113 class ImageState 00114 { 00115 public: 00116 ImageState(const Image* img, ETextureMode mode): mImage(img), mTextureMode(mode) {} 00117 00118 bool operator<(const ImageState& other) const 00119 { 00120 if (mImage != other.mImage) 00121 return mImage < other.mImage; 00122 else 00123 if (mTextureMode != other.mTextureMode) 00124 return mTextureMode < other.mTextureMode; 00125 else 00126 return false; 00127 } 00128 protected: 00129 const Image* mImage; 00130 ETextureMode mTextureMode; 00131 }; 00132 //------------------------------------------------------------------------- start internal 00134 class State 00135 { 00136 public: 00137 State() 00138 { 00139 mColor = white; 00140 mPointSize = 5; 00141 mImage = NULL; 00142 mTextureMode = TextureMode_Clamp; 00143 mLogicOp = LO_COPY; 00144 mPointSmoothing= true; 00145 mLineSmoothing = true; 00146 mPolygonSmoothing = false; 00147 mLineWidth = 1.0; 00148 mLineStipple = 0xFFFF; 00149 memset(mPolyStipple, 0xFF, 32*32/8); 00150 00151 // blend equation 00152 mBlendEquationRGB = BE_FUNC_ADD; 00153 mBlendEquationAlpha = BE_FUNC_ADD; 00154 // blend factor 00155 mBlendFactorSrcRGB = BF_SRC_ALPHA; 00156 mBlendFactorDstRGB = BF_ONE_MINUS_SRC_ALPHA; 00157 mBlendFactorSrcAlpha = BF_SRC_ALPHA; 00158 mBlendFactorDstAlpha = BF_ONE_MINUS_SRC_ALPHA; 00159 // alpha func 00160 mAlphaFuncRefValue = 0.0f; 00161 mAlphaFunc = FU_ALWAYS; 00162 // font 00163 mFont = defFontManager()->acquireFont("/font/bitstream-vera/VeraMono.ttf", 10, false); 00164 // masks 00165 /*mDepthMask = true;*/ 00166 mColorMask = ivec4(1,1,1,1); 00167 // stencil 00168 mStencilMask = 0xFFFFFFFF; 00169 mStencilTestEnabled = false; 00170 mStencil_SFail = SO_KEEP; 00171 mStencil_SFail = SO_KEEP; 00172 mStencil_DpFail = SO_KEEP; 00173 mStencil_Function = FU_ALWAYS; 00174 mStencil_RefValue = 0; 00175 mStencil_FunctionMask = ~(unsigned int)0; 00176 } 00177 00178 fvec4 mColor; 00179 int mPointSize; 00180 ref<Image> mImage; 00181 ETextureMode mTextureMode; 00182 ELogicOp mLogicOp; 00183 float mLineWidth; 00184 bool mPointSmoothing; 00185 bool mLineSmoothing; 00186 bool mPolygonSmoothing; 00187 unsigned short mLineStipple; 00188 unsigned char mPolyStipple[32*32/8]; 00189 EBlendEquation mBlendEquationRGB; 00190 EBlendEquation mBlendEquationAlpha; 00191 EBlendFactor mBlendFactorSrcRGB; 00192 EBlendFactor mBlendFactorDstRGB; 00193 EBlendFactor mBlendFactorSrcAlpha; 00194 EBlendFactor mBlendFactorDstAlpha; 00195 float mAlphaFuncRefValue; 00196 EFunction mAlphaFunc; 00197 ref<Font> mFont; 00198 /*bool mDepthMask;*/ 00199 ivec4 mColorMask; 00200 // stencil 00201 bool mStencilTestEnabled; 00202 unsigned int mStencilMask; 00203 EStencilOp mStencil_SFail; 00204 EStencilOp mStencil_DpFail; 00205 EStencilOp mStencil_DpPass; 00206 EFunction mStencil_Function; 00207 int mStencil_RefValue; 00208 unsigned int mStencil_FunctionMask; 00209 00210 bool operator<(const State& other) const 00211 { 00212 // lexicographic sorting 00213 if (mColor.r() != other.mColor.r()) 00214 return mColor.r() < other.mColor.r(); 00215 else 00216 if (mColor.g() != other.mColor.g()) 00217 return mColor.g() < other.mColor.g(); 00218 else 00219 if (mColor.b() != other.mColor.b()) 00220 return mColor.b() < other.mColor.b(); 00221 else 00222 if (mColor.a() != other.mColor.a()) 00223 return mColor.a() < other.mColor.a(); 00224 else 00225 if(mPointSize != other.mPointSize) 00226 return mPointSize < other.mPointSize; 00227 else 00228 if(mImage != other.mImage) 00229 return mImage < other.mImage; 00230 else 00231 if (mTextureMode != other.mTextureMode) 00232 return mTextureMode < other.mTextureMode; 00233 else 00234 if (mPolygonSmoothing != other.mPolygonSmoothing) 00235 return mPolygonSmoothing < other.mPolygonSmoothing; 00236 else 00237 if (mPointSmoothing!= other.mPointSmoothing) 00238 return mPointSmoothing < other.mPointSmoothing; 00239 else 00240 if (mLineSmoothing!= other.mLineSmoothing) 00241 return mLineSmoothing < other.mLineSmoothing; 00242 else 00243 if (mLineWidth != other.mLineWidth) 00244 return mLineWidth < other.mLineWidth; 00245 else 00246 if (mLineStipple != other.mLineStipple) 00247 return mLineStipple < other.mLineStipple; 00248 else 00249 if (mLogicOp != other.mLogicOp) 00250 return mLogicOp < other.mLogicOp; 00251 else 00252 if ( memcmp(mPolyStipple, other.mPolyStipple, 32*32/8) != 0 ) 00253 return memcmp(mPolyStipple, other.mPolyStipple, 32*32/8) < 0; 00254 else 00255 if ( mBlendEquationRGB != other.mBlendEquationRGB) 00256 return mBlendEquationRGB < other.mBlendEquationRGB; 00257 else 00258 if ( mBlendEquationAlpha != other.mBlendEquationAlpha) 00259 return mBlendEquationAlpha < other.mBlendEquationAlpha; 00260 else 00261 if ( mBlendFactorSrcRGB != other.mBlendFactorSrcRGB) 00262 return mBlendFactorSrcRGB < other.mBlendFactorSrcRGB; 00263 else 00264 if ( mBlendFactorDstRGB != other.mBlendFactorDstRGB) 00265 return mBlendFactorDstRGB < other.mBlendFactorDstRGB; 00266 else 00267 if ( mBlendFactorSrcAlpha != other.mBlendFactorSrcAlpha) 00268 return mBlendFactorSrcAlpha < other.mBlendFactorSrcAlpha; 00269 else 00270 if ( mBlendFactorDstAlpha != other.mBlendFactorDstAlpha) 00271 return mBlendFactorDstAlpha < other.mBlendFactorDstAlpha; 00272 else 00273 if ( mAlphaFuncRefValue != other.mAlphaFuncRefValue) 00274 return mAlphaFuncRefValue < other.mAlphaFuncRefValue; 00275 else 00276 if ( mAlphaFunc != other.mAlphaFunc) 00277 return mAlphaFunc < other.mAlphaFunc; 00278 else 00279 if ( mFont != other.mFont) 00280 return mFont < other.mFont; 00281 else 00282 /*if ( mDepthMask != other.mDepthMask) 00283 return mDepthMask < other.mDepthMask; 00284 else*/ 00285 if ( mColorMask.r() != other.mColorMask.r()) 00286 return mColorMask.r() < other.mColorMask.r(); 00287 else 00288 if ( mColorMask.g() != other.mColorMask.g()) 00289 return mColorMask.g() < other.mColorMask.g(); 00290 else 00291 if ( mColorMask.b() != other.mColorMask.b()) 00292 return mColorMask.b() < other.mColorMask.b(); 00293 else 00294 if ( mColorMask.a() != other.mColorMask.a()) 00295 return mColorMask.a() < other.mColorMask.a(); 00296 else 00297 if ( mStencilMask != other.mStencilMask) 00298 return mStencilMask < other.mStencilMask; 00299 else 00300 if ( mStencilTestEnabled != other.mStencilTestEnabled) 00301 return mStencilTestEnabled < other.mStencilTestEnabled; 00302 else 00303 if ( mStencil_SFail != other.mStencil_SFail ) 00304 return mStencil_SFail < other.mStencil_SFail; 00305 else 00306 if ( mStencil_DpFail != other.mStencil_DpFail ) 00307 return mStencil_DpFail < other.mStencil_DpFail; 00308 else 00309 if ( mStencil_DpPass != other.mStencil_DpPass ) 00310 return mStencil_DpPass < other.mStencil_DpPass; 00311 else 00312 if ( mStencil_Function != other.mStencil_Function ) 00313 return mStencil_Function < other.mStencil_Function; 00314 else 00315 if ( mStencil_RefValue != other.mStencil_RefValue ) 00316 return mStencil_RefValue < other.mStencil_RefValue; 00317 else 00318 if ( mStencil_FunctionMask != other.mStencil_FunctionMask ) 00319 return mStencil_FunctionMask < other.mStencil_FunctionMask; 00320 else 00321 return false; 00322 } 00323 }; 00324 //------------------------------------------------------------------------- end internal 00325 00326 public: 00327 VectorGraphics(); 00328 00330 const ActorCollection* actors() const { return &mActors; } 00331 00333 ActorCollection* actors() { return &mActors; } 00334 00336 Actor* drawLine(double x1, double y1, double x2, double y2); 00337 00339 Actor* drawLines(const std::vector<dvec2>& ln); 00340 00342 Actor* drawLineStrip(const std::vector<dvec2>& ln); 00343 00345 Actor* drawLineLoop(const std::vector<dvec2>& ln); 00346 00348 Actor* fillPolygon(const std::vector<dvec2>& poly); 00349 00351 Actor* fillTriangles(const std::vector<dvec2>& triangles); 00352 00354 Actor* fillTriangleFan(const std::vector<dvec2>& fan); 00355 00357 Actor* fillTriangleStrip(const std::vector<dvec2>& strip); 00358 00360 Actor* fillQuads(const std::vector<dvec2>& quads); 00361 00363 Actor* fillQuadStrip(const std::vector<dvec2>& quad_strip); 00364 00366 Actor* drawPoint(double x, double y); 00367 00369 Actor* drawPoints(const std::vector<dvec2>& pt); 00370 00372 Actor* drawEllipse(double origx, double origy, double xaxis, double yaxis, int segments = 64); 00373 00375 Actor* fillEllipse(double origx, double origy, double xaxis, double yaxis, int segments = 64); 00376 00378 Actor* drawQuad(double left, double bottom, double right, double top); 00379 00381 Actor* fillQuad(double left, double bottom, double right, double top); 00382 00385 void startDrawing() { clear(); } 00386 00389 void continueDrawing(); 00390 00393 void endDrawing(bool release_cache=true); 00394 00396 void clear(); 00397 00399 void setColor(const fvec4& color) { mState.mColor = color; } 00400 00402 const fvec4& color() const { return mState.mColor; } 00403 00405 void setPointSize(int size) { mState.mPointSize = size; } 00406 00408 int pointSize() const { return mState.mPointSize; } 00409 00411 void setImage(Image* image) { mState.mImage = image; } 00412 00414 const Image* image() const { return mState.mImage.get(); } 00415 00417 Image* image() { return mState.mImage.get(); } 00418 00420 void setPoint(Image* image) { setImage(image); setPointSize(image->width()); } 00421 00423 void setTextureMode(ETextureMode mode) { mState.mTextureMode = mode; } 00424 00426 ETextureMode textureMode() const { return mState.mTextureMode; } 00427 00429 void setLogicOp(ELogicOp op) { mState.mLogicOp = op; } 00430 00432 ELogicOp logicOp() const { return mState.mLogicOp; } 00433 00435 void setLineWidth(float width) { mState.mLineWidth = width; } 00436 00438 float lineWidth() const { return mState.mLineWidth; } 00439 00441 void setPointSmoothing(bool smooth) { mState.mPointSmoothing = smooth; } 00442 00444 bool pointSmoothing() const { return mState.mPointSmoothing; } 00445 00447 void setLineSmoothing(bool smooth) { mState.mLineSmoothing = smooth; } 00448 00450 bool lineSmoothing() const { return mState.mLineSmoothing; } 00451 00453 void setPolygonSmoothing(bool smooth) { mState.mPolygonSmoothing = smooth; } 00454 00456 bool polygonSmoothing() const { return mState.mPolygonSmoothing; } 00457 00459 void setLineStipple(ELineStipple stipple) ; 00460 00462 void setLineStipple(unsigned short stipple) { mState.mLineStipple = stipple; } 00463 00465 unsigned short lineStipple() const { return mState.mLineStipple; } 00466 00468 void setPolygonStipple(EPolygonStipple stipple); 00469 00471 void setPolygonStipple(unsigned char* stipple) { memcpy(mState.mPolyStipple, stipple, 32*32/8); } 00472 00474 const unsigned char* polygonStipple() const { return mState.mPolyStipple; } 00475 00477 unsigned char* polygonStipple() { return mState.mPolyStipple; } 00478 00480 void setAlphaFunc(EFunction func, float ref_value) { mState.mAlphaFuncRefValue=ref_value; mState.mAlphaFunc=func; } 00481 00483 void getAlphaFunc(EFunction& func, float& ref_value) const { ref_value=mState.mAlphaFuncRefValue; func=mState.mAlphaFunc; } 00484 00486 void setBlendFunc(EBlendFactor src_rgb, EBlendFactor dst_rgb, EBlendFactor src_alpha, EBlendFactor dst_alpha); 00487 00489 void getBlendFunc(EBlendFactor& src_rgb, EBlendFactor& dst_rgb, EBlendFactor& src_alpha, EBlendFactor& dst_alpha) const; 00490 00492 void setBlendEquation( EBlendEquation rgb_eq, EBlendEquation alpha_eq ); 00493 00495 void getBlendEquation( EBlendEquation& rgb_eq, EBlendEquation& alpha_eq ) const; 00496 00498 void setColorMask(bool r, bool g, bool b, bool a) { mState.mColorMask = ivec4(r?1:0,g?1:0,b?1:0,a?1:0); } 00499 00501 const ivec4& colorMask() const { return mState.mColorMask; } 00502 00503 /*void setDetphMask(bool mask) { mState.mDepthMask = mask; } 00504 bool depthMask() const { return mState.mDepthMask; }*/ 00505 00507 void setStencilTestEnabled(bool enabled) { mState.mStencilTestEnabled = enabled; } 00508 00510 bool stencilTestEnabled() const { return mState.mStencilTestEnabled; } 00511 00513 void setStencilMask(unsigned int mask) { mState.mStencilMask = mask; } 00514 00516 unsigned int stencilMask() const { return mState.mStencilMask; } 00517 00519 void setStencilOp(EStencilOp sfail, EStencilOp dpfail, EStencilOp dppass); 00520 00522 void getStencilOp(EStencilOp& sfail, EStencilOp& dpfail, EStencilOp& dppass); 00523 00525 void setStencilFunc(EFunction func, int refval, unsigned int mask); 00526 00528 void getStencilFunc(EFunction& func, int& refval, unsigned int& mask); 00529 00531 void setFont(const String& name, int size, bool smooth=false) { mState.mFont = defFontManager()->acquireFont(name,size,smooth); } 00532 00534 void setFont(const Font* font) { setFont(font->filePath(),font->size(),font->smooth()); } 00535 00537 void setDefaultFont() { setFont(defFontManager()->acquireFont("/font/bitstream-vera/VeraMono.ttf", 10, false)); } 00538 00540 const Font* font() const { return mState.mFont.get(); } 00541 00546 void setScissor(int x, int y, int width, int height) 00547 { 00548 mScissor = resolveScissor(x,y,width,height); 00549 } 00550 00552 const Scissor* scissor() const { return mScissor.get(); } 00553 00555 void removeScissor() 00556 { 00557 mScissor = NULL; 00558 } 00559 00564 Actor* clearColor(const fvec4& color, int x=0, int y=0, int w=-1, int h=-1); 00565 00570 Actor* clearStencil(int clear_val, int x=0, int y=0, int w=-1, int h=-1); 00571 00573 Actor* drawText(Text* text); 00574 00577 Actor* drawText(int x, int y, const String& text, int alignment = AlignBottom|AlignLeft); 00578 00580 Actor* drawText(const String& text, int alignment = AlignBottom|AlignLeft); 00581 00585 Actor* drawActor(Actor* actor, Transform* transform=NULL, bool keep_effect=false); 00586 00589 Actor* drawActorCopy(Actor* actor, Transform* transform=NULL); 00590 00592 const dmat4& matrix() const { return mMatrix; } 00593 00595 void setMatrix(const dmat4& matrix) { mMatrix = matrix; } 00596 00598 void resetMatrix() { mMatrix.setIdentity(); } 00599 00601 void rotate(double deg); 00602 00604 void translate(double x, double y, double z=0.0); 00605 00607 void scale(double x, double y, double z=1.0); 00608 00610 void pushMatrix() { mMatrixStack.push_back(matrix()); } 00611 00613 void popMatrix(); 00614 00616 const std::vector<dmat4>& matrixStack() const { return mMatrixStack; } 00617 00619 void pushState(); 00620 00622 void popState(); 00623 00624 /*const std::vector<State>& stateStack() const { return mStateStack; }*/ 00625 00629 void pushScissor(int x, int y, int w, int h); 00630 00632 void popScissor(); 00633 00635 const std::vector< ref<Scissor> >& scissorStack() const { return mScissorStack; } 00636 00638 void setTransform(Transform* transform) { for(int i=0; i<actors()->size(); ++i) actors()->at(i)->setTransform(transform); } 00639 00641 Effect* currentEffect() { return currentEffect(mState); } 00642 00643 private: 00644 void generateQuadsTexCoords(Geometry* geom, const std::vector<dvec2>& points); 00645 00646 void generatePlanarTexCoords(Geometry* geom, const std::vector<dvec2>& points); 00647 00648 void generateLinearTexCoords(Geometry* geom); 00649 00650 ref<Geometry> prepareGeometry(const std::vector<dvec2>& ln); 00651 00652 ref<Geometry> prepareGeometryPolyToTriangles(const std::vector<dvec2>& ln); 00653 00654 Scissor* resolveScissor(int x, int y, int width, int height); 00655 00656 Texture* resolveTexture(const Image* image); 00657 00658 Effect* currentEffect(const State& vgs); 00659 00660 Actor* addActor(Actor* actor) ; 00661 00662 private: 00663 // state-machine state variables 00664 State mState; 00665 dmat4 mMatrix; 00666 ref<Scissor> mScissor; 00667 std::vector<State> mStateStack; 00668 std::vector<dmat4> mMatrixStack; 00669 std::vector< ref<Scissor> > mScissorStack; 00670 // state-machine state map 00671 std::map<State, ref<Effect> > mVGToEffectMap; 00672 std::map<ImageState, ref<Texture> > mImageToTextureMap; 00673 std::map<RectI, ref<Scissor> > mRectToScissorMap; 00674 ref<Effect> mDefaultEffect; 00675 ActorCollection mActors; 00676 }; 00677 //------------------------------------------------------------------------------------------------------------------------------------------- 00678 } 00679 00680 #endif