diff options
author | dvonbeck <dvonbeck@google.com> | 2016-07-28 08:58:19 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-07-28 08:58:19 -0700 |
commit | bba4cfebcabba3aca5c2452d7df1853258bd701c (patch) | |
tree | f3675119f7a7437c9fdfb5089f9f31f018095b08 /gm | |
parent | 1c58696112a5d7bf1acbcc337099b0bf5eb80650 (diff) |
Added API for Bevel NormalSource.
This CL adds an API for Bevel normal source and a dummy implementation that returns a normal (0, 0, 1) every time.
This CL's base is the CL for accepting nullptrs: https://codereview.chromium.org/2132113002
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2080993002
Review-Url: https://codereview.chromium.org/2080993002
Diffstat (limited to 'gm')
-rw-r--r-- | gm/lightingshaderbevel.cpp | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/gm/lightingshaderbevel.cpp b/gm/lightingshaderbevel.cpp new file mode 100644 index 0000000000..d119a27cbd --- /dev/null +++ b/gm/lightingshaderbevel.cpp @@ -0,0 +1,269 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gm.h" + +#include "SkBitmapProcShader.h" +#include "SkLightingShader.h" +#include "SkNormalSource.h" +#include "SkPath.h" +#include "SkPoint3.h" +#include "SkShader.h" + + +namespace skiagm { + +// This GM exercises lighting shaders when used with bevel SkNormalSource objects. +class LightingShaderBevelGM : public GM { +public: + LightingShaderBevelGM() { + this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); + } + +protected: + SkString onShortName() override { + return SkString("lightingshaderbevel"); + } + + SkISize onISize() override { + return SkISize::Make(SkScalarCeilToInt(GRID_NUM_COLUMNS * GRID_CELL_WIDTH), + SkScalarCeilToInt(GRID_NUM_ROWS * GRID_CELL_WIDTH)); + } + + void onOnceBeforeDraw() override { + SkLights::Builder builder; + const SkVector3 kLightFromUpperRight = SkVector3::Make(0.788f, 0.394f, 0.473f); + + builder.add(SkLights::Light(SkColor3f::Make(1.0f, 1.0f, 1.0f), + kLightFromUpperRight)); + builder.add(SkLights::Light(SkColor3f::Make(0.2f, 0.2f, 0.2f))); + fLights = builder.finish(); + + // fRect is assumed to be square throughout this file + fRect = SkRect::MakeIWH(kTexSize, kTexSize); + SkMatrix matrix; + SkRect bitmapBounds = SkRect::MakeIWH(kTexSize, kTexSize); + matrix.setRectToRect(bitmapBounds, fRect, SkMatrix::kFill_ScaleToFit); + + SkBitmap diffuseMap = sk_tool_utils::create_checkerboard_bitmap( + kTexSize, kTexSize, + sk_tool_utils::color_to_565(0x0), + sk_tool_utils::color_to_565(0xFF804020), + 8); + fDiffuse = SkMakeBitmapShader(diffuseMap, SkShader::kClamp_TileMode, + SkShader::kClamp_TileMode, &matrix, nullptr); + + fConvexPath.moveTo(fRect.width() / 2.0f, 0.0f); + fConvexPath.lineTo(0.0f, fRect.height()); + fConvexPath.lineTo(fRect.width(), fRect.height()); + fConvexPath.close(); + + // Creating concave path + { + SkScalar x = 0.0f; + SkScalar y = fRect.height() / 2.0f; + + const int NUM_SPIKES = 8; + + const SkScalar x0 = x; + const SkScalar dx = fRect.width() / (NUM_SPIKES * 2); + const SkScalar dy = SK_Scalar1 * 10; + + + fConcavePath.moveTo(x, y + dy); + for (int i = 0; i < NUM_SPIKES; i++) { + x += dx; + fConcavePath.lineTo(x, y - dy); + x += dx; + fConcavePath.lineTo(x, y + dy); + } + fConcavePath.lineTo(x, y + (2 * dy)); + fConcavePath.lineTo(x0, y + (2 * dy)); + fConcavePath.close(); + } + } + + // Scales shape around origin, rotates shape around origin, then translates shape to origin + void positionCTM(SkCanvas *canvas, SkScalar scaleX, SkScalar scaleY, SkScalar rotate) const { + canvas->translate(kTexSize/2.0f, kTexSize/2.0f); + canvas->scale(scaleX, scaleY); + canvas->rotate(rotate); + canvas->translate(-kTexSize/2.0f, -kTexSize/2.0f); + } + + enum Shape { + kCircle_Shape, + kRect_Shape, + kRRect_Shape, + kConvexPath_Shape, + kConcavePath_Shape, + + kLast_Shape = kConcavePath_Shape + }; + void drawShape(enum Shape shape, SkCanvas* canvas, SkScalar scaleX, SkScalar scaleY, + SkScalar rotate, SkNormalSource::BevelType bevelType, SkScalar bevelHeight) { + canvas->save(); + + this->positionCTM(canvas, scaleX, scaleY, rotate); + + SkPaint paint; + + SkScalar bevelWidth = 10.0f; + sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeBevel(bevelType, bevelWidth, + bevelHeight); + + paint.setShader(SkLightingShader::Make(fDiffuse, std::move(normalSource), fLights)); + paint.setAntiAlias(true); + switch(shape) { + case kCircle_Shape: + canvas->drawCircle(fRect.centerX(), fRect.centerY(), fRect.width()/2.0f, paint); + break; + case kRect_Shape: + canvas->drawRect(fRect, paint); + break; + case kRRect_Shape: + canvas->drawRoundRect(fRect, 5.0f, 5.0f, paint); + break; + case kConvexPath_Shape: + canvas->drawPath(fConvexPath, paint); + break; + case kConcavePath_Shape: + canvas->drawPath(fConcavePath, paint); + break; + default: + SkDEBUGFAIL("Invalid shape enum for drawShape"); + } + + canvas->restore(); + } + + void onDraw(SkCanvas* canvas) override { + SkPaint labelPaint; + labelPaint.setTypeface(sk_tool_utils::create_portable_typeface("sans-serif", + SkFontStyle())); + labelPaint.setAntiAlias(true); + labelPaint.setTextSize(LABEL_SIZE); + + int gridNum = 0; + + // Running through all possible parameter combinations + for (auto bevelType : {SkNormalSource::BevelType::kLinear, + SkNormalSource::BevelType::kRoundedIn, + SkNormalSource::BevelType::kRoundedOut}) { + for (SkScalar bevelHeight: {-7.0f, 7.0f}) { + for (int shapeInt = 0; shapeInt < NUM_SHAPES; shapeInt++) { + Shape shape = (Shape)shapeInt; + + // Determining position + SkScalar xPos = (gridNum / GRID_NUM_ROWS) * GRID_CELL_WIDTH; + SkScalar yPos = (gridNum % GRID_NUM_ROWS) * GRID_CELL_WIDTH; + + canvas->save(); + + canvas->translate(xPos, yPos); + this->drawShape(shape, canvas, 1.0f, 1.0f, 0.f, bevelType, bevelHeight); + // Drawing labels + canvas->translate(0.0f, SkIntToScalar(kTexSize)); + { + canvas->translate(0.0f, LABEL_SIZE); + SkString label; + label.append("bevelType: "); + switch (bevelType) { + case SkNormalSource::BevelType::kLinear: + label.append("linear"); + break; + case SkNormalSource::BevelType::kRoundedIn: + label.append("roundedIn"); + break; + case SkNormalSource::BevelType::kRoundedOut: + label.append("roundedOut"); + break; + } + canvas->drawText(label.c_str(), label.size(), 0.0f, 0.0f, labelPaint); + } + { + canvas->translate(0.0f, LABEL_SIZE); + SkString label; + label.appendf("bevelHeight: %.1f", bevelHeight); + canvas->drawText(label.c_str(), label.size(), 0.0f, 0.0f, labelPaint); + } + + canvas->restore(); + + gridNum++; + } + } + } + + // Testing rotation + for (int shapeInt = 0; shapeInt < NUM_SHAPES; shapeInt++) { + Shape shape = (Shape)shapeInt; + + // Determining position + SkScalar xPos = (gridNum / GRID_NUM_ROWS) * GRID_CELL_WIDTH; + SkScalar yPos = (gridNum % GRID_NUM_ROWS) * GRID_CELL_WIDTH; + + canvas->save(); + + canvas->translate(xPos, yPos); + this->drawShape(shape, canvas, SK_ScalarRoot2Over2, SK_ScalarRoot2Over2, 45.0f, + SkNormalSource::BevelType::kLinear, 7.0f); + + // Drawing labels + canvas->translate(0.0f, SkIntToScalar(kTexSize)); + { + canvas->translate(0.0f, LABEL_SIZE); + SkString label; + label.appendf("bevelType: linear"); + canvas->drawText(label.c_str(), label.size(), 0.0f, 0.0f, labelPaint); + } + { + canvas->translate(0.0f, LABEL_SIZE); + SkString label; + label.appendf("bevelHeight: %.1f", 7.0f); + canvas->drawText(label.c_str(), label.size(), 0.0f, 0.0f, labelPaint); + } + { + canvas->translate(0.0f, LABEL_SIZE); + SkString label; + label.appendf("rotated"); + canvas->drawText(label.c_str(), label.size(), 0.0f, 0.0f, labelPaint); + } + + canvas->restore(); + + gridNum++; + } + + // Making sure NUM_COMBINATIONS_PER_SHAPE is set correctly + SkASSERT(gridNum == (NUM_COMBINATIONS_PER_SHAPE*NUM_SHAPES)); + } + +private: + static constexpr int kTexSize = 96; + static constexpr int NUM_SHAPES = kLast_Shape + 1; + static constexpr int NUM_COMBINATIONS_PER_SHAPE = 7; + static constexpr int GRID_NUM_ROWS = NUM_SHAPES; + static constexpr int GRID_NUM_COLUMNS = NUM_COMBINATIONS_PER_SHAPE; + static constexpr SkScalar LABEL_SIZE = 10.0f; + static constexpr int NUM_LABELS_PER_CELL = 3; + static constexpr SkScalar GRID_CELL_WIDTH = kTexSize + 10.0f + NUM_LABELS_PER_CELL * LABEL_SIZE; + + sk_sp<SkShader> fDiffuse; + + SkRect fRect; + SkPath fConvexPath; + SkPath fConcavePath; + sk_sp<SkLights> fLights; + + typedef GM INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +DEF_GM(return new LightingShaderBevelGM;) +} |