Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlVG/VectorGraphics.cpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.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 #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   // fill the vertex position array
00055   ref<Geometry> geom = prepareGeometry(ln);
00056   // generate texture coords
00057   if (mState.mImage)
00058   {
00059     ref<ArrayFloat2> tex_array = new ArrayFloat2;
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) = fvec2(u1, 0);
00066       tex_array->at(i+1) = fvec2(u2, 0);
00067     }
00068     // generate geometry
00069     geom->setTexCoordArray(0, tex_array.get());
00070   }
00071   // issue the primitive
00072   geom->drawCalls()->push_back( new DrawArrays(PT_LINES, 0, (int)ln.size()) );
00073   // add the actor
00074   return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00075 }
00076 //-----------------------------------------------------------------------------
00077 Actor* VectorGraphics::drawLineStrip(const std::vector<dvec2>& ln)
00078 {
00079   // fill the vertex position array
00080   ref<Geometry> geom = prepareGeometry(ln);
00081   // generate texture coords
00082   generateLinearTexCoords(geom.get());
00083   // issue the primitive
00084   geom->drawCalls()->push_back( new DrawArrays(PT_LINE_STRIP, 0, (int)ln.size()) );
00085   // add the actor
00086   return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00087 }
00088 //-----------------------------------------------------------------------------
00089 Actor* VectorGraphics::drawLineLoop(const std::vector<dvec2>& ln)
00090 {
00091   // fill the vertex position array
00092   ref<Geometry> geom = prepareGeometry(ln);
00093   // generate texture coords
00094   generateLinearTexCoords(geom.get());
00095   // issue the primitive
00096   geom->drawCalls()->push_back( new DrawArrays(PT_LINE_LOOP, 0, (int)ln.size()) );
00097   // add the actor
00098   return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00099 }
00100 //-----------------------------------------------------------------------------
00101 Actor* VectorGraphics::fillPolygon(const std::vector<dvec2>& poly)
00102 {
00103   // fill the vertex position array
00104   ref<Geometry> geom = prepareGeometryPolyToTriangles(poly);
00105   // generate texture coords
00106   generatePlanarTexCoords(geom.get(), poly);
00107   // issue the primitive
00108   geom->drawCalls()->push_back( new DrawArrays(PT_TRIANGLES, 0, (int)geom->vertexArray()->size()) );
00109   // add the actor
00110   return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00111 }
00112 //-----------------------------------------------------------------------------
00113 Actor* VectorGraphics::fillTriangles(const std::vector<dvec2>& triangles)
00114 {
00115   // fill the vertex position array
00116   ref<Geometry> geom = prepareGeometry(triangles);
00117   // generate texture coords
00118   generatePlanarTexCoords(geom.get(), triangles);
00119   // issue the primitive
00120   geom->drawCalls()->push_back( new DrawArrays(PT_TRIANGLES, 0, (int)triangles.size()) );
00121   // add the actor
00122   return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00123 }
00124 //-----------------------------------------------------------------------------
00125 Actor* VectorGraphics::fillTriangleFan(const std::vector<dvec2>& fan)
00126 {
00127   // fill the vertex position array
00128   ref<Geometry> geom = prepareGeometry(fan);
00129   // generate texture coords
00130   generatePlanarTexCoords(geom.get(), fan);
00131   // issue the primitive
00132   geom->drawCalls()->push_back( new DrawArrays(PT_TRIANGLE_FAN, 0, (int)fan.size()) );
00133   // add the actor
00134   return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00135 }
00136 //-----------------------------------------------------------------------------
00137 Actor* VectorGraphics::fillTriangleStrip(const std::vector<dvec2>& strip)
00138 {
00139   // fill the vertex position array
00140   ref<Geometry> geom = prepareGeometry(strip);
00141   // generate texture coords
00142   generatePlanarTexCoords(geom.get(), strip);
00143   // issue the primitive
00144   geom->drawCalls()->push_back( new DrawArrays(PT_TRIANGLE_STRIP, 0, (int)strip.size()) );
00145   // add the actor
00146   return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00147 }
00148 //-----------------------------------------------------------------------------
00149 Actor* VectorGraphics::fillQuads(const std::vector<dvec2>& quads)
00150 {
00151   // fill the vertex position array
00152   ref<Geometry> geom = prepareGeometry(quads);
00153   // generate texture coords
00154   generateQuadsTexCoords(geom.get(), quads);
00155   // issue the primitive
00156   geom->drawCalls()->push_back( new DrawArrays(PT_QUADS, 0, (int)quads.size()) );
00157   // add the actor
00158   return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00159 }
00160 //-----------------------------------------------------------------------------
00161 Actor* VectorGraphics::fillQuadStrip(const std::vector<dvec2>& quad_strip)
00162 {
00163   // fill the vertex position array
00164   ref<Geometry> geom = prepareGeometry(quad_strip);
00165   // generate texture coords
00166   generatePlanarTexCoords(geom.get(), quad_strip);
00167   // issue the primitive
00168   geom->drawCalls()->push_back( new DrawArrays(PT_QUAD_STRIP, 0, (int)quad_strip.size()) );
00169   // add the actor
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   // transform the points
00183   ref<ArrayFloat3> pos_array = new ArrayFloat3;
00184   pos_array->resize(pt.size());
00185   // transform done using high precision
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     // needed for pixel/perfect rendering
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   // generate geometry
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   // add the actor
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   // fill the vertex position array
00246   ref<Geometry> geom = prepareGeometry(quad);
00247   // generate texture coords
00248   generateQuadsTexCoords(geom.get(), quad);
00249   // issue the primitive
00250   geom->drawCalls()->push_back( new DrawArrays(PT_TRIANGLE_FAN, 0, (int)quad.size()) );
00251   // add the actor
00252   return addActor( new Actor(geom.get(), currentEffect(), NULL) );
00253 }
00254 //-----------------------------------------------------------------------------
00255 void VectorGraphics::continueDrawing()
00256 {
00257   /*mActors.clear();*/ // keep the currently drawn actors
00258 
00259   /*mVGToEffectMap.clear();*/      // keeps cached resources
00260   /*mImageToTextureMap.clear();*/  // keeps cached resources
00261   /*mRectToScissorMap.clear();*/   // keeps cached resources
00262 
00263   // restore the default states
00264   mState  = State();
00265   mMatrix = dmat4();
00266   mMatrixStack.clear();
00267   mStateStack.clear();
00268 }
00269 //-----------------------------------------------------------------------------
00270 void VectorGraphics::endDrawing(bool release_cache)
00271 {
00272   if (release_cache)
00273   {
00274     mVGToEffectMap.clear();
00275     mImageToTextureMap.clear();
00276     mRectToScissorMap.clear();
00277   }
00278   /*mState  = State();
00279   mMatrix = dmat4();*/
00280   mMatrixStack.clear();
00281   mStateStack.clear();
00282 }
00283 //-----------------------------------------------------------------------------
00284 void VectorGraphics::clear()
00285 {
00286   // remove all the actors
00287   mActors.clear();
00288 
00289   // reset everything
00290   mVGToEffectMap.clear();
00291   mImageToTextureMap.clear();
00292   mRectToScissorMap.clear();
00293 
00294   // restore the default states
00295   mState  = State();
00296   mMatrix = dmat4();
00297   mMatrixStack.clear();
00298   mStateStack.clear();
00299 }
00300 //-----------------------------------------------------------------------------
00301 void VectorGraphics::setLineStipple(ELineStipple stipple) 
00302 {
00303   switch(stipple)
00304   {
00305     case LineStipple_Solid: mState.mLineStipple = 0xFFFF; break;
00306     case LineStipple_Dot:   mState.mLineStipple = 0xAAAA; break;
00307     case LineStipple_Dash:  mState.mLineStipple = 0xCCCC; break;
00308     case LineStipple_Dash4: mState.mLineStipple = 0xF0F0; break;
00309     case LineStipple_Dash8: mState.mLineStipple = 0xFF00; break;
00310     case LineStipple_DashDot: mState.mLineStipple = 0xF840; break;
00311     case LineStipple_DashDotDot: mState.mLineStipple = 0xF888; break;
00312   }
00313 }
00314 //-----------------------------------------------------------------------------
00315 void VectorGraphics::setPolygonStipple(EPolygonStipple stipple) 
00316 {
00317   unsigned char solid_stipple[] = {
00318     0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 
00319     0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 
00320     0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 
00321     0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 
00322     0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 
00323     0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 
00324     0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 
00325     0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF };
00326   unsigned char hline_stipple[] = {
00327     0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 
00328     0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 
00329     0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 
00330     0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 
00331     0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 
00332     0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 
00333     0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 
00334     0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00 };
00335   unsigned char vline_stipple[] = {
00336     0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 
00337     0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 
00338     0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 
00339     0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 
00340     0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 
00341     0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 
00342     0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 
00343     0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA };
00344   unsigned char chain_stipple[] = {
00345     0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 
00346     0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 
00347     0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 
00348     0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 
00349     0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 
00350     0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 
00351     0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 0xAA,0xAA,0xAA,0xAA, 
00352     0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55 };
00353   unsigned char dot_stipple[] = {
00354     0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 
00355     0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 
00356     0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 
00357     0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 
00358     0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 
00359     0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 
00360     0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 
00361     0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA, 0x55,0x55,0x55,0x55 };
00362   switch(stipple)
00363   {
00364     case PolygonStipple_Solid: setPolygonStipple(solid_stipple); break;
00365     case PolygonStipple_Dot: setPolygonStipple(dot_stipple); break;
00366     case PolygonStipple_Chain: setPolygonStipple(chain_stipple); break;
00367     case PolygonStipple_HLine: setPolygonStipple(hline_stipple); break;
00368     case PolygonStipple_VLine: setPolygonStipple(vline_stipple); break;
00369   }
00370 }
00371 //-----------------------------------------------------------------------------
00372 void VectorGraphics::setBlendFunc(EBlendFactor src_rgb, EBlendFactor dst_rgb, EBlendFactor src_alpha, EBlendFactor dst_alpha)
00373 {
00374   mState.mBlendFactorSrcRGB   = src_rgb;
00375   mState.mBlendFactorDstRGB   = dst_rgb;
00376   mState.mBlendFactorSrcAlpha = src_alpha;
00377   mState.mBlendFactorDstAlpha = dst_alpha;
00378 }
00379 //-----------------------------------------------------------------------------
00380 void VectorGraphics::getBlendFunc(EBlendFactor& src_rgb, EBlendFactor& dst_rgb, EBlendFactor& src_alpha, EBlendFactor& dst_alpha) const
00381 {
00382   src_rgb   = mState.mBlendFactorSrcRGB;
00383   dst_rgb   = mState.mBlendFactorDstRGB;
00384   src_alpha = mState.mBlendFactorSrcAlpha;
00385   dst_alpha = mState.mBlendFactorDstAlpha;
00386 }
00387 //-----------------------------------------------------------------------------
00388 void VectorGraphics::setBlendEquation( EBlendEquation rgb_eq, EBlendEquation alpha_eq ) 
00389 {
00390   mState.mBlendEquationRGB   = rgb_eq;
00391   mState.mBlendEquationAlpha = alpha_eq;
00392 }//-----------------------------------------------------------------------------
00393 
00394 void VectorGraphics::getBlendEquation( EBlendEquation& rgb_eq, EBlendEquation& alpha_eq ) const
00395 {
00396   rgb_eq   = mState.mBlendEquationRGB;
00397   alpha_eq = mState.mBlendEquationAlpha;
00398 }
00399 //-----------------------------------------------------------------------------
00400 void VectorGraphics::setStencilOp(EStencilOp sfail, EStencilOp dpfail, EStencilOp dppass)
00401 {
00402   mState.mStencil_SFail  = sfail;
00403   mState.mStencil_DpFail = dpfail;
00404   mState.mStencil_DpPass = dppass;
00405 }
00406 //-----------------------------------------------------------------------------
00407 void VectorGraphics::getStencilOp(EStencilOp& sfail, EStencilOp& dpfail, EStencilOp& dppass)
00408 {
00409   sfail  = mState.mStencil_SFail;
00410   dpfail = mState.mStencil_DpFail;
00411   dppass = mState.mStencil_DpPass;
00412 }
00413 //-----------------------------------------------------------------------------
00414 void VectorGraphics::setStencilFunc(EFunction func, int refval, unsigned int mask)
00415 {
00416   mState.mStencil_Function     = func;
00417   mState.mStencil_RefValue     = refval;
00418   mState.mStencil_FunctionMask = mask;
00419 }
00420 //-----------------------------------------------------------------------------
00421 void VectorGraphics::getStencilFunc(EFunction& func, int& refval, unsigned int& mask)
00422 {
00423   func   = mState.mStencil_Function;
00424   refval = mState.mStencil_RefValue;
00425   mask   = mState.mStencil_FunctionMask;
00426 }
00427 //-----------------------------------------------------------------------------
00428 Actor* VectorGraphics::clearColor(const fvec4& color, int x, int y, int w, int h)
00429 {
00430   ref<Clear> clear = new Clear;
00431   clear->setClearColorBuffer(true);
00432   clear->setClearColorValue(color);
00433   clear->setScissorBox(x,y,w,h);
00434   return addActor( new Actor( clear.get(), /*mDefaultEffect.get()*/currentEffect(), NULL) );
00435 }
00436 //-----------------------------------------------------------------------------
00437 Actor* VectorGraphics::clearStencil(int clear_val, int x, int y, int w, int h)
00438 {
00439   ref<Clear> clear = new Clear;
00440   clear->setClearStencilBuffer(true);
00441   clear->setClearStencilValue(clear_val);
00442   clear->setScissorBox(x,y,w,h);
00443   return addActor( new Actor( clear.get(), /*mDefaultEffect.get()*/currentEffect(), NULL) );
00444 }
00445 //-----------------------------------------------------------------------------
00446 Actor* VectorGraphics::drawText(Text* text)
00447 {
00448   if (text->font() == NULL)
00449     text->setFont(mState.mFont.get());
00450   return addActor( new Actor(text, /*mDefaultEffect.get()*/currentEffect(), NULL) );
00451 }
00452 //-----------------------------------------------------------------------------
00453 Actor* VectorGraphics::drawText(int x, int y, const String& text, int alignment)
00454 {
00455   pushMatrix();
00456   mMatrix = dmat4::getTranslation(x,y,0) * mMatrix;
00457   Actor* act = drawText(text, alignment);
00458   popMatrix();
00459   return act;
00460 }
00461 //-----------------------------------------------------------------------------
00462 Actor* VectorGraphics::drawText(const String& text, int alignment)
00463 {
00464   ref<Text> t = new Text;
00465   t->setText( text );
00466   t->setAlignment(alignment);
00467   t->setViewportAlignment(AlignBottom|AlignLeft);
00468   t->setColor( mState.mColor );
00469   t->setMatrix( (fmat4)matrix() );
00470   return drawText(t.get());
00471 }
00472 //-----------------------------------------------------------------------------
00473 Actor* VectorGraphics::drawActor(Actor* actor, Transform* transform, bool keep_effect)
00474 {
00475   VL_CHECK(actor->effect())
00476   if (!keep_effect || !actor->effect())
00477     actor->setEffect(currentEffect());
00478   if (transform != NULL)
00479     actor->setTransform(transform);
00480   return addActor(actor);
00481 }
00482 //-----------------------------------------------------------------------------
00483 Actor* VectorGraphics::drawActorCopy(Actor* actor, Transform* transform)
00484 {
00485   ref<Actor> copy = new Actor(*actor);
00486   copy->setTransform(transform);
00487   drawActor(copy.get());
00488   return copy.get();
00489 }
00490 //-----------------------------------------------------------------------------
00491 void VectorGraphics::rotate(double deg) 
00492 { 
00493   mMatrix = mMatrix * dmat4::getRotation(deg, 0,0,1.0); 
00494 }
00495 //-----------------------------------------------------------------------------
00496 void VectorGraphics::translate(double x, double y, double z)
00497 { 
00498   mMatrix = mMatrix * dmat4::getTranslation(x,y,z); 
00499 }
00500 //-----------------------------------------------------------------------------
00501 void VectorGraphics::scale(double x, double y, double z) 
00502 { 
00503   mMatrix = mMatrix * dmat4::getScaling(x,y,z); 
00504 }
00505 //-----------------------------------------------------------------------------
00506 void VectorGraphics::popMatrix() 
00507 { 
00508   if (mMatrixStack.empty())
00509   {
00510     Log::error("VectorGraphics::popMatrix() matrix stack underflow!\n");
00511     return;
00512   }
00513   setMatrix(mMatrixStack.back());
00514   mMatrixStack.pop_back();
00515 }
00516 //-----------------------------------------------------------------------------
00517 void VectorGraphics::pushState() 
00518 { 
00519   mStateStack.push_back(mState); 
00520   pushMatrix();
00521 }
00522 //-----------------------------------------------------------------------------
00523 void VectorGraphics::popState() 
00524 { 
00525   popMatrix();
00526   if (mStateStack.empty())
00527   {
00528     Log::error("VectorGraphics::popState() matrix stack underflow!\n");
00529     return;
00530   }
00531   mState = mStateStack.back();
00532   mStateStack.pop_back();
00533 }
00534 //-----------------------------------------------------------------------------
00535 void VectorGraphics::pushScissor(int x, int y, int w, int h) 
00536 {
00537   mScissorStack.push_back(mScissor.get()); 
00538   RectI newscissor = mScissor ? mScissor->scissorRect().intersected(RectI(x,y,w,h)) : RectI(x,y,w,h);
00539   setScissor(newscissor.x(), newscissor.y(), newscissor.width(), newscissor.height());
00540 }
00541 //-----------------------------------------------------------------------------
00542 void VectorGraphics::popScissor() 
00543 { 
00544   if (mScissorStack.empty())
00545   {
00546     Log::error("VectorGraphics::popScissor() scissor stack underflow!\n");
00547     return;
00548   }
00549   mScissor = mScissorStack.back();
00550   mScissorStack.pop_back();
00551 }
00552 //-----------------------------------------------------------------------------
00553 void VectorGraphics::generateQuadsTexCoords(Geometry* geom, const std::vector<dvec2>& points)
00554 {
00555   // generate only if there is an image active
00556   if (mState.mImage)
00557   {
00558     ref<ArrayFloat2> tex_array = new ArrayFloat2;
00559     tex_array->resize(geom->vertexArray()->size());
00560     geom->setTexCoordArray(0, tex_array.get());
00561     if (mState.mTextureMode == TextureMode_Clamp)
00562     {
00563       float du = 1.0f / mState.mImage->width()  / 2.0f;
00564       float dv = mState.mImage->height() ? (1.0f / mState.mImage->height() / 2.0f) : 0.5f;
00565       //  1----2
00566       //  |    |
00567       //  |    |
00568       //  0    3
00569       fvec2 texc[] = { fvec2(du,dv), fvec2(du,1.0f-dv), fvec2(1.0f-du,1.0f-dv), fvec2(1.0f-du,dv) };
00570       for(unsigned i=0; i<points.size(); ++i)
00571       {
00572         float s = texc[i%4].s();
00573         float t = texc[i%4].t();
00574         tex_array->at(i).s() = s;
00575         tex_array->at(i).t() = t;
00576       }
00577     }
00578     else
00579     {
00580       AABB aabb;
00581       for(unsigned i=0; i<points.size(); ++i)
00582         aabb.addPoint( geom->vertexArray()->getAsVec3(i) );
00583       for(unsigned i=0; i<points.size(); ++i)
00584       {
00585         vec4 v = geom->vertexArray()->getAsVec4(i);
00586         double s = (v.s()-aabb.minCorner().s()) / (mState.mImage->width() );
00587         double t = (v.t()-aabb.minCorner().t()) / (mState.mImage->height());
00588         tex_array->at(i).s() = (float)s;
00589         tex_array->at(i).t() = (float)t;
00590       }
00591     }
00592   }
00593 }
00594 //-----------------------------------------------------------------------------
00595 void VectorGraphics::generatePlanarTexCoords(Geometry* geom, const std::vector<dvec2>& points)
00596 {
00597   // generate only if there is an image active
00598   if (mState.mImage)
00599   {
00600     // generate uv coordinates based on the aabb
00601     ref<ArrayFloat2> tex_array = new ArrayFloat2;
00602     tex_array->resize(geom->vertexArray()->size());
00603     geom->setTexCoordArray(0, tex_array.get());
00604     if (mState.mTextureMode == TextureMode_Clamp)
00605     {
00606       // compute aabb
00607       AABB aabb;
00608       for(unsigned i=0; i<points.size(); ++i)
00609         aabb.addPoint( (vec3)dvec3(points[i],0.0) );
00610       for(unsigned i=0; i<points.size(); ++i)
00611       {
00612         float s = float((points[i].x() - aabb.minCorner().x()) / aabb.width() );
00613         float t = float((points[i].y() - aabb.minCorner().y()) / aabb.height());
00614         tex_array->at(i).s() = s;
00615         tex_array->at(i).t() = t;
00616       }
00617     }
00618     else
00619     {
00620       AABB aabb;
00621       for(unsigned i=0; i<points.size(); ++i)
00622         aabb.addPoint( geom->vertexArray()->getAsVec3(i)+vec3(0.5f,0.5f,0.0f) );
00623       for(unsigned i=0; i<points.size(); ++i)
00624       {
00625         vec4 v = geom->vertexArray()->getAsVec4(i);
00626         double s = (v.s()-aabb.minCorner().s()) / mState.mImage->width();
00627         double t = (v.t()-aabb.minCorner().t()) / mState.mImage->height();
00628         tex_array->at(i).s() = (float)s;
00629         tex_array->at(i).t() = (float)t;
00630       }
00631     }
00632   }
00633 }
00634 //-----------------------------------------------------------------------------
00635 void VectorGraphics::generateLinearTexCoords(Geometry* geom)
00636 {
00637   if (mState.mImage)
00638   {
00639     ref<ArrayFloat2> tex_array = new ArrayFloat2;
00640     tex_array->resize(geom->vertexArray()->size());
00641     float u1 = 1.0f / mState.mImage->width() * 0.5f;
00642     float u2 = 1.0f - 1.0f / mState.mImage->width() * 0.5f;
00643     for(size_t i=0; i<tex_array->size(); ++i)
00644     {
00645       float t = (float)i/(tex_array->size()-1);
00646       tex_array->at(i).s() = u1 * (1.0f-t) + u2 * t;
00647       tex_array->at(i).t() = 0;
00648     }
00649     // generate geometry
00650     geom->setTexCoordArray(0, tex_array.get());
00651   }
00652 }
00653 //-----------------------------------------------------------------------------
00654 ref<Geometry> VectorGraphics::prepareGeometryPolyToTriangles(const std::vector<dvec2>& ln)
00655 {
00656   // transform the lines
00657   ref<ArrayFloat3> pos_array = new ArrayFloat3;
00658   pos_array->resize( (ln.size()-2) * 3 );
00659   // transform done using high precision
00660   for(unsigned i=0, itri=0; i<ln.size()-2; ++i, itri+=3)
00661   {
00662     pos_array->at(itri+0) = (fvec3)(matrix() * dvec3(ln[0].x(), ln[0].y(), 0));
00663     pos_array->at(itri+1) = (fvec3)(matrix() * dvec3(ln[i+1].x(), ln[i+1].y(), 0));
00664     pos_array->at(itri+2) = (fvec3)(matrix() * dvec3(ln[i+2].x(), ln[i+2].y(), 0));
00665   }
00666   // generate geometry
00667   ref< Geometry > geom = new Geometry;
00668   geom->setVertexArray(pos_array.get());
00669   return geom;
00670 }
00671 //-----------------------------------------------------------------------------
00672 ref<Geometry> VectorGraphics::prepareGeometry(const std::vector<dvec2>& ln)
00673 {
00674   // transform the lines
00675   ref<ArrayFloat3> pos_array = new ArrayFloat3;
00676   pos_array->resize(ln.size());
00677   // transform done using high precision
00678   for(unsigned i=0; i<ln.size(); ++i)
00679     pos_array->at(i) = (fvec3)(matrix() * dvec3(ln[i].x(), ln[i].y(), 0));
00680   // generate geometry
00681   ref< Geometry > geom = new Geometry;
00682   geom->setVertexArray(pos_array.get());
00683   return geom;
00684 }
00685 //-----------------------------------------------------------------------------
00686 Scissor* VectorGraphics::resolveScissor(int x, int y, int width, int height)
00687 {
00688   ref<Scissor> scissor = mRectToScissorMap[RectI(x,y,width,height)];
00689   if (!scissor)
00690   {
00691     scissor = new Scissor(x,y,width,height);
00692     mRectToScissorMap[RectI(x,y,width,height)] = scissor;
00693   }
00694   return scissor.get();
00695 }
00696 //-----------------------------------------------------------------------------
00697 Texture* VectorGraphics::resolveTexture(const Image* image)
00698 {
00699   Texture* texture = mImageToTextureMap[ImageState(image,mState.mTextureMode)].get();
00700   if (!texture)
00701   {
00702     texture = new Texture( image, TF_RGBA, true, false);
00703     texture->getTexParameter()->setMinFilter(TPF_LINEAR_MIPMAP_LINEAR);
00704     texture->getTexParameter()->setMagFilter(TPF_LINEAR);
00705     #if 0
00706       texture->getTexParameter()->setBorderColor(fvec4(1,0,1,1)); // for debuggin purposes
00707     #else
00708       texture->getTexParameter()->setBorderColor(fvec4(1,1,1,0)); // transparent white
00709     #endif
00710     if (mState.mTextureMode == vl::TextureMode_Repeat)
00711     {
00712       texture->getTexParameter()->setWrapS(TPW_REPEAT);
00713       texture->getTexParameter()->setWrapT(TPW_REPEAT);
00714     }
00715     else
00716     {
00717       texture->getTexParameter()->setWrapS(TPW_CLAMP);
00718       texture->getTexParameter()->setWrapT(TPW_CLAMP);
00719     }
00720     mImageToTextureMap[ImageState(image,mState.mTextureMode)] = texture;
00721   }
00722   return texture;
00723 }
00724 //-----------------------------------------------------------------------------
00725 Effect* VectorGraphics::currentEffect(const State& vgs)
00726 {
00727   Effect* effect = mVGToEffectMap[vgs].get();
00728   // create a Shader reflecting the current VectorGraphics state machine state
00729   if (!effect)
00730   {
00731     effect = new Effect;
00732     mVGToEffectMap[vgs] = effect;
00733     Shader* shader = effect->shader();
00734     /*shader->disable(EN_DEPTH_TEST);*/
00735     shader->enable(EN_BLEND);
00736     // color
00737     shader->enable(EN_LIGHTING);
00738     shader->gocMaterial()->setFlatColor(vgs.mColor);
00739     // point size
00740     shader->gocPointSize()->set((float)vgs.mPointSize);
00741     // logicop
00742     if (vgs.mLogicOp != LO_COPY)
00743     {
00744       shader->gocLogicOp()->set(vgs.mLogicOp);
00745       shader->enable(EN_COLOR_LOGIC_OP);
00746     }
00747     // line stipple
00748     if ( vgs.mLineStipple != 0xFFFF )
00749     {
00750 #if defined(VL_OPENGL)
00751       shader->gocLineStipple()->set(1, vgs.mLineStipple);
00752       shader->enable(EN_LINE_STIPPLE);
00753 #else
00754       Log::error("vl::VectorGraphics: line stipple not supported under OpenGL ES. Try using a stipple texture instead.\n");
00755 #endif
00756     }
00757     // line width
00758     if (vgs.mLineWidth != 1.0f)
00759       shader->gocLineWidth()->set(vgs.mLineWidth);
00760     // point smooth
00761     if (vgs.mPointSmoothing)
00762     {
00763       shader->gocHint()->setPointSmoothHint(HM_NICEST);
00764       shader->enable(EN_POINT_SMOOTH);
00765     }
00766     // line smooth
00767     if (vgs.mLineSmoothing)
00768     {
00769       shader->gocHint()->setLineSmoothHint(HM_NICEST);
00770       shader->enable(EN_LINE_SMOOTH);
00771     }
00772     // polygon smooth
00773     if (vgs.mPolygonSmoothing)
00774     {
00775       shader->gocHint()->setPolygonSmoohtHint(HM_NICEST);
00776       shader->enable(EN_POLYGON_SMOOTH);
00777     }
00778     // poly stipple
00779     unsigned char solid_stipple[] = {
00780       0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 
00781       0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 
00782       0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 
00783       0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 
00784       0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 
00785       0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 
00786       0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 
00787       0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF
00788     };
00789     if ( memcmp(vgs.mPolyStipple, solid_stipple, 32*32/8) != 0 )
00790     {
00791 #if defined(VL_OPENGL)
00792       shader->gocPolygonStipple()->set(vgs.mPolyStipple);
00793       shader->enable(EN_POLYGON_STIPPLE);
00794 #else
00795       Log::error("vl::VectorGraphics: polygon stipple not supported under OpenGL ES. Try using a stipple texture instead.\n");
00796 #endif
00797     }
00798     // blending equation and function
00799     shader->gocBlendEquation()->set(vgs.mBlendEquationRGB, vgs.mBlendEquationAlpha);
00800     shader->gocBlendFunc()->set(vgs.mBlendFactorSrcRGB, vgs.mBlendFactorDstRGB, vgs.mBlendFactorSrcAlpha, vgs.mBlendFactorDstAlpha);
00801     if (vgs.mAlphaFunc != FU_ALWAYS)
00802     {
00803       shader->enable(EN_ALPHA_TEST);
00804       shader->gocAlphaFunc()->set(vgs.mAlphaFunc, vgs.mAlphaFuncRefValue);
00805     }
00806     // masks (by default they are all 'true')
00807     if (vgs.mColorMask != ivec4(1,1,1,1) )
00808       shader->gocColorMask()->set(vgs.mColorMask.r()?true:false,vgs.mColorMask.g()?true:false,vgs.mColorMask.b()?true:false,vgs.mColorMask.a()?true:false);
00809     // stencil
00810     if (vgs.mStencilTestEnabled)
00811     {
00812       shader->enable(EN_STENCIL_TEST);
00813       shader->gocStencilMask()->set(PF_FRONT_AND_BACK, vgs.mStencilMask);
00814       shader->gocStencilOp()->set(PF_FRONT_AND_BACK, vgs.mStencil_SFail, vgs.mStencil_DpFail, vgs.mStencil_DpPass);
00815       shader->gocStencilFunc()->set(PF_FRONT_AND_BACK, vgs.mStencil_Function, vgs.mStencil_RefValue, vgs.mStencil_FunctionMask);
00816     }
00817     /*if (!vgs.mDepthMask)
00818       shader->gocDepthMask()->set(false);*/
00819     // texture
00820     if (vgs.mImage)
00821     {
00822       shader->gocTextureSampler(0)->setTexture( resolveTexture(vgs.mImage.get()) );
00823       if (Has_Point_Sprite)
00824       {
00825         shader->gocTexEnv(0)->setPointSpriteCoordReplace(true);
00826         shader->enable(EN_POINT_SPRITE);
00827       }
00828       else
00829         Log::error("GL_ARB_point_sprite not supported.\n");
00830     }
00831   }
00832   return effect;
00833 }
00834 //-----------------------------------------------------------------------------
00835 Actor* VectorGraphics::addActor(Actor* actor) 
00836 { 
00837   actor->setScissor(mScissor.get());
00838   mActors.push_back(actor);
00839   return actor;
00840 }
00841 //-----------------------------------------------------------------------------

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:43.
Permission is granted to use this page to write and publish articles regarding Visualization Library.