/* Copyright 2010 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef GrSamplerState_DEFINED #define GrSamplerState_DEFINED #include "GrTypes.h" #include "GrMatrix.h" class GrSamplerState { public: /** * The intepretation of the texture matrix depends on the sample mode. The * texture matrix is applied both when the texture coordinates are explicit * and when vertex positions are used as texture coordinates. In the latter * case the texture matrix is applied to the pre-view-matrix position * values. * * kNormal_SampleMode * The post-matrix texture coordinates are in normalize space with (0,0) at * the top-left and (1,1) at the bottom right. * kRadial_SampleMode * The matrix specifies the radial gradient parameters. * (0,0) in the post-matrix space is center of the radial gradient. * kRadial2_SampleMode * Matrix transforms to space where first circle is centered at the * origin. The second circle will be centered (x, 0) where x may be * 0 and is provided by setRadial2Params. The post-matrix space is * normalized such that 1 is the second radius - first radius. * kSweepSampleMode * The angle from the origin of texture coordinates in post-matrix space * determines the gradient value. */ enum SampleMode { kNormal_SampleMode, //!< sample color directly kRadial_SampleMode, //!< treat as radial gradient kRadial2_SampleMode, //!< treat as 2-point radial gradient kSweep_SampleMode, //!< treat as sweep gradient }; /** * Describes how a texture is sampled when coordinates are outside the * texture border */ enum WrapMode { kClamp_WrapMode, kRepeat_WrapMode, kMirror_WrapMode }; /** * Default sampler state is set to clamp, use normal sampling mode, be * unfiltered, and use identity matrix. */ GrSamplerState() { this->setClampNoFilter(); } explicit GrSamplerState(bool filter) { fWrapX = kClamp_WrapMode; fWrapY = kClamp_WrapMode; fSampleMode = kNormal_SampleMode; fFilter = filter; fMatrix.setIdentity(); } GrSamplerState(WrapMode wx, WrapMode wy, bool filter) { fWrapX = wx; fWrapY = wy; fSampleMode = kNormal_SampleMode; fFilter = filter; fMatrix.setIdentity(); } GrSamplerState(WrapMode wx, WrapMode wy, const GrMatrix& matrix, bool filter) { fWrapX = wx; fWrapY = wy; fSampleMode = kNormal_SampleMode; fFilter = filter; fMatrix = matrix; } GrSamplerState(WrapMode wx, WrapMode wy, SampleMode sample, const GrMatrix& matrix, bool filter) { fWrapX = wx; fWrapY = wy; fSampleMode = sample; fMatrix = matrix; fFilter = filter; } WrapMode getWrapX() const { return fWrapX; } WrapMode getWrapY() const { return fWrapY; } SampleMode getSampleMode() const { return fSampleMode; } const GrMatrix& getMatrix() const { return fMatrix; } bool isFilter() const { return fFilter; } bool isGradient() const { return kRadial_SampleMode == fSampleMode || kRadial2_SampleMode == fSampleMode || kSweep_SampleMode == fSampleMode; } void setWrapX(WrapMode mode) { fWrapX = mode; } void setWrapY(WrapMode mode) { fWrapY = mode; } void setSampleMode(SampleMode mode) { fSampleMode = mode; } /** * Sets the sampler's matrix. See SampleMode for explanation of * relationship between the matrix and sample mode. * @param matrix the matrix to set */ void setMatrix(const GrMatrix& matrix) { fMatrix = matrix; } /** * Multiplies the current sampler matrix a matrix * * After this call M' = M*m where M is the old matrix, m is the parameter * to this function, and M' is the new matrix. (We consider points to * be column vectors so tex cood vector t is transformed by matrix X as * t' = X*t.) * * @param matrix the matrix used to modify the matrix. */ void preConcatMatrix(const GrMatrix& matrix) { fMatrix.preConcat(matrix); } /** * Enables or disables filtering. * @param filter indicates whether filtering is applied. */ void setFilter(bool filter) { fFilter = filter; } void setClampNoFilter() { fWrapX = kClamp_WrapMode; fWrapY = kClamp_WrapMode; fSampleMode = kNormal_SampleMode; fFilter = false; fMatrix.setIdentity(); } GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; } GrScalar getRadial2Radius0() const { return fRadial2Radius0; } bool isRadial2PosRoot() const { return fRadial2PosRoot; } /** * Sets the parameters for kRadial2_SampleMode. The texture * matrix must be set so that the first point is at (0,0) and the second * point lies on the x-axis. The second radius minus the first is 1 unit. * The additional parameters to define the gradient are specified by this * function. */ void setRadial2Params(GrScalar centerX1, GrScalar radius0, bool posRoot) { fRadial2CenterX1 = centerX1; fRadial2Radius0 = radius0; fRadial2PosRoot = posRoot; } static const GrSamplerState& ClampNoFilter() { return gClampNoFilter; } private: WrapMode fWrapX; WrapMode fWrapY; SampleMode fSampleMode; bool fFilter; GrMatrix fMatrix; // these are undefined unless fSampleMode == kRadial2_SampleMode GrScalar fRadial2CenterX1; GrScalar fRadial2Radius0; bool fRadial2PosRoot; static const GrSamplerState gClampNoFilter; }; #endif