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 #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 //-----------------------------------------------------------------------------