diff options
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/Package_opengl.mk | 2 | ||||
-rw-r--r-- | vcl/inc/opengl/program.hxx | 4 | ||||
-rw-r--r-- | vcl/inc/openglgdiimpl.hxx | 4 | ||||
-rw-r--r-- | vcl/opengl/gdiimpl.cxx | 364 | ||||
-rw-r--r-- | vcl/opengl/lineFragmentShader.glsl | 36 | ||||
-rw-r--r-- | vcl/opengl/lineVertexShader.glsl | 37 | ||||
-rw-r--r-- | vcl/opengl/program.cxx | 10 |
7 files changed, 407 insertions, 50 deletions
diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk index b8851df57625..a0f6e9a27128 100644 --- a/vcl/Package_opengl.mk +++ b/vcl/Package_opengl.mk @@ -21,6 +21,8 @@ $(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\ invert50FragmentShader.glsl \ convolutionFragmentShader.glsl \ linearGradientFragmentShader.glsl \ + lineFragmentShader.glsl \ + lineVertexShader.glsl \ maskFragmentShader.glsl \ maskedTextureVertexShader.glsl \ maskedTextureFragmentShader.glsl \ diff --git a/vcl/inc/opengl/program.hxx b/vcl/inc/opengl/program.hxx index 5de3c1bdbe5f..780cba72380f 100644 --- a/vcl/inc/opengl/program.hxx +++ b/vcl/inc/opengl/program.hxx @@ -37,6 +37,7 @@ private: GLuint mnTexCoordAttrib; GLuint mnAlphaCoordAttrib; GLuint mnMaskCoordAttrib; + GLuint mnNormalAttrib; TextureList maTextures; bool mbBlending; @@ -59,6 +60,7 @@ public: void SetTextureCoord( const GLvoid* pData ); void SetAlphaCoord( const GLvoid* pData ); void SetMaskCoord(const GLvoid* pData); + void SetExtrusionVectors(const GLvoid* pData); void SetUniform1f( const OString& rName, GLfloat v1 ); void SetUniform2f( const OString& rName, GLfloat v1, GLfloat v2 ); @@ -80,7 +82,7 @@ public: bool DrawTexture( const OpenGLTexture& rTexture ); protected: - void SetVertexAttrib( GLuint& rAttrib, const OString& rName, const GLvoid* pData ); + void SetVertexAttrib( GLuint& rAttrib, const OString& rName, const GLvoid* pData, GLint nSize = 2 ); GLuint GetUniformLocation( const OString& rName ); }; diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 3b629005c712..f3247f9f8d22 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -113,6 +113,7 @@ public: bool UseSolid( SalColor nColor ); bool UseSolidAA( SalColor nColor, double fTransparency ); bool UseSolidAA( SalColor nColor ); + bool UseLine(SalColor nColor, double fTransparency, GLfloat fLineWidth, bool bUseAA); bool UseInvert50(); bool UseInvert(SalInvert nFlags); @@ -127,6 +128,9 @@ public: void DrawRect( long nX, long nY, long nWidth, long nHeight ); void DrawRect( const Rectangle& rRect ); void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ); + void DrawLineSegment(float x1, float y1, float x2, float y2); + void DrawLineCap(float x1, float y1, float x2, float y2, css::drawing::LineCap eLineCap, float fLineWidth); + void DrawPolyLine( const basegfx::B2DPolygon& rPolygon, float fLineWidth, basegfx::B2DLineJoin eLineJoin, css::drawing::LineCap eLineCap); void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon, bool blockAA = false ); void DrawRegionBand( const RegionBand& rRegion ); void DrawTextureRect( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false ); diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 6828efb9b49d..2efac9741908 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -37,6 +37,9 @@ #include <vector> +#include <glm/gtc/type_ptr.hpp> +#include <glm/gtx/norm.hpp> + #include <stdlib.h> class OpenGLFlushIdle : public Idle @@ -624,6 +627,311 @@ void OpenGLSalGraphicsImpl::DrawLine( double nX1, double nY1, double nX2, double CHECK_GL_ERROR(); } +namespace +{ + +inline void addVertex(std::vector<GLfloat>& rVertices, std::vector<GLfloat>& rExtrusionVectors, glm::vec2 point, glm::vec2 extrusionVector, float length) +{ + rVertices.push_back(point.x); + rVertices.push_back(point.y); + + rExtrusionVectors.push_back(extrusionVector.x); + rExtrusionVectors.push_back(extrusionVector.y); + rExtrusionVectors.push_back(length); +} + +inline void addVertexPair(std::vector<GLfloat>& rVertices, std::vector<GLfloat>& rExtrusionVectors, glm::vec2 point, glm::vec2 extrusionVector, float length) +{ + addVertex(rVertices, rExtrusionVectors, point, -extrusionVector, -length); + addVertex(rVertices, rExtrusionVectors, point, extrusionVector, length); +} + +inline glm::vec2 normalize(const glm::vec2& vector) +{ + if (glm::length(vector) > 0.0) + return glm::normalize(vector); + return vector; +} + +} // end anonymous namespace + +void OpenGLSalGraphicsImpl::DrawLineCap(float x1, float y1, float x2, float y2, css::drawing::LineCap eLineCap, float fLineWidth) +{ + if (eLineCap != css::drawing::LineCap_ROUND && eLineCap != css::drawing::LineCap_SQUARE) + return; + + OpenGLZone aZone; + + const int nRoundCapIteration = 12; + + std::vector<GLfloat> aVertices; + std::vector<GLfloat> aExtrusionVectors; + + glm::vec2 p1(x1, y1); + glm::vec2 p2(x2, y2); + glm::vec2 lineVector = normalize(p2 - p1); + glm::vec2 normal = glm::vec2(-lineVector.y, lineVector.x); + + if (eLineCap == css::drawing::LineCap_ROUND) + { + for (int nFactor = 0; nFactor <= nRoundCapIteration; nFactor++) + { + float angle = float(nFactor) * (M_PI / float(nRoundCapIteration)); + glm::vec2 roundNormal(normal.x * glm::cos(angle) - normal.y * glm::sin(angle), + normal.x * glm::sin(angle) + normal.y * glm::cos(angle)); + + addVertexPair(aVertices, aExtrusionVectors, p1, roundNormal, 1.0f); + } + } + else if (eLineCap == css::drawing::LineCap_SQUARE) + { + glm::vec2 extrudedPoint = p1 + -lineVector * (fLineWidth / 2.0f); + + addVertexPair(aVertices, aExtrusionVectors, extrudedPoint, normal, 1.0f); + addVertexPair(aVertices, aExtrusionVectors, p1, normal, 1.0f); + } + + ApplyProgramMatrices(0.0f); + mpProgram->SetExtrusionVectors(aExtrusionVectors.data()); + mpProgram->SetVertices(aVertices.data()); + glDrawArrays(GL_TRIANGLE_STRIP, 0, aVertices.size() / 2); + + CHECK_GL_ERROR(); +} + +void OpenGLSalGraphicsImpl::DrawLineSegment(float x1, float y1, float x2, float y2) +{ + glm::vec2 p1(x1, y1); + glm::vec2 p2(x2, y2); + + if (p1.x == p2.x && p1.y == p2.y) + return; + + std::vector<GLfloat> aPoints; + std::vector<GLfloat> aExtrusionVectors; + + OpenGLZone aZone; + + glm::vec2 lineVector = normalize(p2 - p1); + glm::vec2 normal = glm::vec2(-lineVector.y, lineVector.x); + + addVertexPair(aPoints, aExtrusionVectors, p1, normal, 1.0f); + addVertexPair(aPoints, aExtrusionVectors, p2, normal, 1.0f); + + ApplyProgramMatrices(0.0f); + mpProgram->SetExtrusionVectors(aExtrusionVectors.data()); + mpProgram->SetVertices(aPoints.data()); + glDrawArrays(GL_TRIANGLE_STRIP, 0, aPoints.size() / 2); + + CHECK_GL_ERROR(); +} + +/** Draw a simple (non bezier) polyline + * + * OpenGL polyline drawing algorithm inspired by: + * - http://mattdesl.svbtle.com/drawing-lines-is-hard + * - https://www.mapbox.com/blog/drawing-antialiased-lines/ + * - https://cesiumjs.org/2013/04/22/Robust-Polyline-Rendering-with-WebGL/ + * - http://artgrammer.blogspot.si/2011/05/drawing-nearly-perfect-2d-line-segments.html + * - http://artgrammer.blogspot.si/2011/07/drawing-polylines-by-tessellation.html + * + */ +void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, float fLineWidth, basegfx::B2DLineJoin eLineJoin, css::drawing::LineCap eLineCap) +{ + sal_uInt32 nPoints = rPolygon.count(); + bool bClosed = rPolygon.isClosed(); + + if (!bClosed && nPoints >= 2) + { + // draw begin cap + { + glm::vec2 p1(rPolygon.getB2DPoint(0).getX(), rPolygon.getB2DPoint(0).getY()); + glm::vec2 p2(rPolygon.getB2DPoint(1).getX(), rPolygon.getB2DPoint(1).getY()); + DrawLineCap(p1.x, p1.y, p2.x, p2.y, eLineCap, fLineWidth); + } + + // draw end cap + { + glm::vec2 p1(rPolygon.getB2DPoint(nPoints - 1).getX(), rPolygon.getB2DPoint(nPoints - 1).getY()); + glm::vec2 p2(rPolygon.getB2DPoint(nPoints - 2).getX(), rPolygon.getB2DPoint(nPoints - 2).getY()); + DrawLineCap(p1.x, p1.y, p2.x, p2.y, eLineCap, fLineWidth); + } + } + + if (nPoints == 2 || eLineJoin == basegfx::B2DLineJoin::NONE) + { + // If line joint is NONE or a simple line with 2 points, draw the polyline + // each line segment separatly. + for (int i = 0; i < int(nPoints) - 1; ++i) + { + glm::vec2 p1(rPolygon.getB2DPoint(i+0).getX(), rPolygon.getB2DPoint(i+0).getY()); + glm::vec2 p2(rPolygon.getB2DPoint(i+1).getX(), rPolygon.getB2DPoint(i+1).getY()); + DrawLineSegment(p1.x, p1.y, p2.x, p2.y); + } + if (bClosed) + { + glm::vec2 p1(rPolygon.getB2DPoint(nPoints - 1).getX(), rPolygon.getB2DPoint(nPoints - 1).getY()); + glm::vec2 p2(rPolygon.getB2DPoint(0).getX(), rPolygon.getB2DPoint(0).getY()); + DrawLineSegment(p1.x, p1.y, p2.x, p2.y); + } + } + else if (nPoints > 2) + { + OpenGLZone aZone; + + int i = 0; + int lastPoint = int(nPoints); + + std::vector<GLfloat> aVertices; + std::vector<GLfloat> aExtrusionVectors; + + // First guess on the size, but we could know relatively exactly + // how much vertices we need. + aVertices.reserve(nPoints * 4); + aExtrusionVectors.reserve(nPoints * 6); + + // Handle first point + + glm::vec2 nextLineVector; + glm::vec2 previousLineVector; + glm::vec2 normal; // perpendicular to the line vector + + glm::vec2 p0(rPolygon.getB2DPoint(nPoints - 1).getX(), rPolygon.getB2DPoint(nPoints - 1).getY()); + glm::vec2 p1(rPolygon.getB2DPoint(0).getX(), rPolygon.getB2DPoint(0).getY()); + glm::vec2 p2(rPolygon.getB2DPoint(1).getX(), rPolygon.getB2DPoint(1).getY()); + + nextLineVector = normalize(p2 - p1); + + if (!bClosed) + { + normal = glm::vec2(-nextLineVector.y, nextLineVector.x); // make perpendicular + addVertexPair(aVertices, aExtrusionVectors, p1, normal, 1.0f); + + i++; // first point done already + lastPoint--; // last point will be calculated separatly from the loop + + p0 = p1; + previousLineVector = nextLineVector; + } + else + { + lastPoint++; // we need to connect last point to first point so one more line segment to calculate + + previousLineVector = normalize(p1 - p0); + } + + for (; i < lastPoint; ++i) + { + int index1 = (i + 0) % nPoints; // loop indices - important when polyline is closed + int index2 = (i + 1) % nPoints; + + p1 = glm::vec2(rPolygon.getB2DPoint(index1).getX(), rPolygon.getB2DPoint(index1).getY()); + p2 = glm::vec2(rPolygon.getB2DPoint(index2).getX(), rPolygon.getB2DPoint(index2).getY()); + + if (p1 == p2) // skip equal points, normals could div-by-0 + continue; + + nextLineVector = normalize(p2 - p1); + + if (eLineJoin == basegfx::B2DLineJoin::Miter) + { + // With miter join we calculate the extrusion vector by adding normals of + // previous and next line segment. The vector shows the way but we also + // need the length (otherwise the line will be deformed). Length factor is + // calculated as dot product of extrusion vector and one of the normals. + // The value we get is the inverse length (used in the shader): + // length = line_width / dot(extrusionVector, normal) + + normal = glm::vec2(-previousLineVector.y, previousLineVector.x); + + glm::vec2 tangent = normalize(nextLineVector + previousLineVector); + glm::vec2 extrusionVector(-tangent.y, tangent.x); + GLfloat length = glm::dot(extrusionVector, normal); + + addVertexPair(aVertices, aExtrusionVectors, p1, extrusionVector, length); + } + else if (eLineJoin == basegfx::B2DLineJoin::Bevel) + { + // For bevel join we just add 2 additional vertices and use previous + // line segment normal and next line segment normal as extrusion vector. + // All the magic is done by the fact that we draw triangle strips, so we + // cover the joins correctly. + + glm::vec2 previousNormal = glm::vec2(-previousLineVector.y, previousLineVector.x); + glm::vec2 nextNormal = glm::vec2(-nextLineVector.y, nextLineVector.x); + + addVertexPair(aVertices, aExtrusionVectors, p1, previousNormal, 1.0f); + addVertexPair(aVertices, aExtrusionVectors, p1, nextNormal, 1.0f); + } + else if (eLineJoin == basegfx::B2DLineJoin::Round) + { + // For round join we do a similar thing as in bevel, we add more intermediate + // vertices and add normals to get extrusion vectors in the between the + // both normals. + + // 3 additional extrusion vectors + normals are enough to make most + // line joins look round. Ideally the number of vectors could be + // calculated. + + glm::vec2 previousNormal = glm::vec2(-previousLineVector.y, previousLineVector.x); + glm::vec2 nextNormal = glm::vec2(-nextLineVector.y, nextLineVector.x); + + glm::vec2 middle = normalize(previousNormal + nextNormal); + glm::vec2 middleLeft = normalize(previousNormal + middle); + glm::vec2 middleRight = normalize(middle + nextNormal); + + addVertexPair(aVertices, aExtrusionVectors, p1, previousNormal, 1.0f); + addVertexPair(aVertices, aExtrusionVectors, p1, middleLeft, 1.0f); + addVertexPair(aVertices, aExtrusionVectors, p1, middle, 1.0f); + addVertexPair(aVertices, aExtrusionVectors, p1, middleRight, 1.0f); + addVertexPair(aVertices, aExtrusionVectors, p1, nextNormal, 1.0f); + } + p0 = p1; + previousLineVector = nextLineVector; + } + + if (!bClosed) + { + // Create vertices for the last point. There is no line join so just + // use the last line segment normal as the extrusion vector. + + p1 = glm::vec2(rPolygon.getB2DPoint(nPoints - 1).getX(), rPolygon.getB2DPoint(nPoints - 1).getY()); + + normal = glm::vec2(-previousLineVector.y, previousLineVector.x); + + addVertexPair(aVertices, aExtrusionVectors, p1, normal, 1.0f); + } + + ApplyProgramMatrices(0.0f); + mpProgram->SetExtrusionVectors(aExtrusionVectors.data()); + mpProgram->SetVertices(aVertices.data()); + glDrawArrays(GL_TRIANGLE_STRIP, 0, aVertices.size() / 2); + + CHECK_GL_ERROR(); + } +} + +bool OpenGLSalGraphicsImpl::UseLine(SalColor nColor, double fTransparency, GLfloat fLineWidth, bool bUseAA) +{ + if( nColor == SALCOLOR_NONE ) + return false; + if( !UseProgram( "lineVertexShader", "lineFragmentShader" ) ) + return false; + mpProgram->SetColorf("color", nColor, fTransparency); + mpProgram->SetUniform1f("line_width", fLineWidth); + // The width of the feather - area we make lineary transparent in VS. + // Good AA value is 0.5, 0.0 means the no AA will be done. + mpProgram->SetUniform1f("feather", bUseAA ? 0.5f : 0.0f); + // We need blending or AA won't work correctly + mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); +#ifdef DBG_UTIL + mProgramIsSolidColor = true; +#endif + mProgramSolidColor = nColor; + mProgramSolidTransparency = fTransparency; + return true; +} + void OpenGLSalGraphicsImpl::DrawLineAA( double nX1, double nY1, double nX2, double nY2 ) { OpenGLZone aZone; @@ -1539,58 +1847,20 @@ bool OpenGLSalGraphicsImpl::drawPolyLine( return true; const bool bIsHairline = (rLineWidth.getX() == rLineWidth.getY()) && (rLineWidth.getX() <= 1.2); + const float fLineWidth = bIsHairline ? 1.0f : rLineWidth.getX(); - // #i101491# - if( !bIsHairline && (rPolygon.count() > 1000) ) - { - // the used basegfx::tools::createAreaGeometry is simply too - // expensive with very big polygons; fallback to caller (who - // should use ImplLineConverter normally) - // AW: ImplLineConverter had to be removed since it does not even - // know LineJoins, so the fallback will now prepare the line geometry - // the same way. - return false; - } - - // shortcut for hairline drawing to improve performance - if (bIsHairline) - { - // Let's just leave it to OutputDevice to do the bezier subdivision, - // drawPolyLine(sal_uInt32 nPoints, const SalPoint* pPtAry) will be - // called with the result. - return false; - } - - // #i11575#desc5#b adjust B2D tesselation result to raster positions - basegfx::B2DPolygon aPolygon = rPolygon; - const double fHalfWidth = 0.5 * rLineWidth.getX(); + PreDraw(XOROption::IMPLEMENT_XOR); - // get the area polygon for the line polygon - if( (rLineWidth.getX() != rLineWidth.getY()) - && !basegfx::fTools::equalZero( rLineWidth.getY() ) ) + if (UseLine(mnLineColor, 0.0f, fLineWidth, true)) { - // prepare for createAreaGeometry() with anisotropic linewidth - aPolygon.transform( basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getX() / rLineWidth.getY())); - } - - // create the area-polygon for the line - const basegfx::B2DPolyPolygon aAreaPolyPoly( basegfx::tools::createAreaGeometry(aPolygon, fHalfWidth, eLineJoin, eLineCap) ); + basegfx::B2DPolygon aPolygon(rPolygon); - if( (rLineWidth.getX() != rLineWidth.getY()) - && !basegfx::fTools::equalZero( rLineWidth.getX() ) ) - { - // postprocess createAreaGeometry() for anisotropic linewidth - aPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getY() / rLineWidth.getX())); - } + if (aPolygon.areControlPointsUsed()) + aPolygon = basegfx::tools::polygonSubdivide(aPolygon, 5 * F_PI180); + else + aPolygon.removeDoublePoints(); - PreDraw( XOROption::IMPLEMENT_XOR ); - if( UseSolid( mnLineColor, fTransparency ) ) - { - for( sal_uInt32 i = 0; i < aAreaPolyPoly.count(); i++ ) - { - const basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( i ) ); - DrawPolyPolygon( aOnePoly ); - } + DrawPolyLine(aPolygon, fLineWidth, eLineJoin, eLineCap); } PostDraw(); diff --git a/vcl/opengl/lineFragmentShader.glsl b/vcl/opengl/lineFragmentShader.glsl new file mode 100644 index 000000000000..a8c73d6b80cc --- /dev/null +++ b/vcl/opengl/lineFragmentShader.glsl @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +varying float fade_factor; // 0->1 fade factor used for AA +uniform vec4 color; + +uniform float line_width; +uniform float feather; + +void main() +{ + float start = (line_width / 2.0) - feather; // where we start to apply alpha + float end = (line_width / 2.0) + feather; // where we end to apply alpha + + // Calculate the multiplier so we can transform the 0->1 fade factor + // to take feather and line width into account. + float multiplied = 1.0 / (1.0 - (start / end)); + + float dist = (1.0 - abs(fade_factor)) * multiplied; + + float alpha = clamp(dist, 0.0, 1.0); + + // modify the alpha chanel only + vec4 result_color = color; + result_color.a = result_color.a * alpha; + + gl_FragColor = result_color; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/lineVertexShader.glsl b/vcl/opengl/lineVertexShader.glsl new file mode 100644 index 000000000000..0adcb4908201 --- /dev/null +++ b/vcl/opengl/lineVertexShader.glsl @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +attribute vec2 position; +attribute vec4 extrusion_vectors; + +varying float fade_factor; // fade factor for anti-aliasing + +uniform float line_width; +uniform float feather; // width where we fade the line + +uniform mat4 mvp; + +void main() +{ + vec2 extrusion_vector = extrusion_vectors.xy; + // miter factor to additionaly lenghten the distance of vertex (needed for miter) + // if 1.0 - miter_factor has no effect + float miter_factor = 1.0f / abs(extrusion_vectors.z); + // fade factor is always -1.0 or 1.0 -> we transport that info together with length + fade_factor = sign(extrusion_vectors.z); + + float rendered_thickness = (line_width + feather * 2.0) * miter_factor; + + // lengthen the vertex in directon of the extrusion vector by line width. + vec4 position = vec4(position + (extrusion_vector * (rendered_thickness / 2.0) ), 0.0, 1.0); + + gl_Position = mvp * position; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/program.cxx b/vcl/opengl/program.cxx index 588700b537d9..340b10f6bb8f 100644 --- a/vcl/opengl/program.cxx +++ b/vcl/opengl/program.cxx @@ -22,6 +22,7 @@ OpenGLProgram::OpenGLProgram() : mnTexCoordAttrib( SAL_MAX_UINT32 ), mnAlphaCoordAttrib( SAL_MAX_UINT32 ), mnMaskCoordAttrib( SAL_MAX_UINT32 ), + mnNormalAttrib( SAL_MAX_UINT32 ), mbBlending( false ), mfLastWidth(0.0), mfLastHeight(0.0), @@ -100,7 +101,7 @@ bool OpenGLProgram::Clean() return true; } -void OpenGLProgram::SetVertexAttrib( GLuint& rAttrib, const OString& rName, const GLvoid* pData ) +void OpenGLProgram::SetVertexAttrib( GLuint& rAttrib, const OString& rName, const GLvoid* pData, GLint nSize ) { if( rAttrib == SAL_MAX_UINT32 ) { @@ -113,7 +114,7 @@ void OpenGLProgram::SetVertexAttrib( GLuint& rAttrib, const OString& rName, cons CHECK_GL_ERROR(); mnEnabledAttribs |= ( 1 << rAttrib ); } - glVertexAttribPointer( rAttrib, 2, GL_FLOAT, GL_FALSE, 0, pData ); + glVertexAttribPointer( rAttrib, nSize, GL_FLOAT, GL_FALSE, 0, pData ); CHECK_GL_ERROR(); } @@ -137,6 +138,11 @@ void OpenGLProgram::SetMaskCoord(const GLvoid* pData) SetVertexAttrib(mnMaskCoordAttrib, "mask_coord_in", pData); } +void OpenGLProgram::SetExtrusionVectors(const GLvoid* pData) +{ + SetVertexAttrib(mnNormalAttrib, "extrusion_vectors", pData, 3); +} + GLuint OpenGLProgram::GetUniformLocation( const OString& rName ) { auto it = maUniformLocations.find( rName ); |