diff options
author | dvonbeck <dvonbeck@google.com> | 2016-07-20 11:20:30 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-07-20 11:20:30 -0700 |
commit | c526da94e4f2dc0c8521099dad2118c5d6b8da4a (patch) | |
tree | cacbe403042f6a407fc3ae052c0110a88942af09 /gm/lightingshader2.cpp | |
parent | f2944815e5e490c843c5a364fcaae2471526562f (diff) |
SkLS now accepting nullptr for diffuse shader and normal source, now accurately handling alpha
This CL's base is the CL for taking in a diffuse shader into SkLS on the API side: https://codereview.chromium.org/2064153002
BUG=skia:5502,skia:5517
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2132113002
Review-Url: https://codereview.chromium.org/2132113002
Diffstat (limited to 'gm/lightingshader2.cpp')
-rw-r--r-- | gm/lightingshader2.cpp | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/gm/lightingshader2.cpp b/gm/lightingshader2.cpp new file mode 100644 index 0000000000..c2f4d6caac --- /dev/null +++ b/gm/lightingshader2.cpp @@ -0,0 +1,232 @@ +/* + * 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 "SkPoint3.h" +#include "SkShader.h" + +// Create a truncated pyramid normal map +static SkBitmap make_frustum_normalmap(int texSize) { + SkBitmap frustum; + frustum.allocN32Pixels(texSize, texSize); + + sk_tool_utils::create_frustum_normal_map(&frustum, SkIRect::MakeWH(texSize, texSize)); + return frustum; +} + +namespace skiagm { + +// This GM exercises lighting shaders. Specifically, nullptr arguments, scaling when using +// normal maps, and paint transparency. +class LightingShader2GM : public GM { +public: + LightingShader2GM() { + this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); + } + +protected: + SkString onShortName() override { + return SkString("lightingshader2"); + } + + SkISize onISize() override { + return SkISize::Make(kGMSize, kGMSize); + } + + 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 = SkRect::MakeIWH(kTexSize, kTexSize); + SkMatrix matrix; + SkRect bitmapBounds = SkRect::MakeIWH(kTexSize, kTexSize); + matrix.setRectToRect(bitmapBounds, fRect, SkMatrix::kFill_ScaleToFit); + + SkBitmap opaqueDiffuseMap = sk_tool_utils::create_checkerboard_bitmap( + kTexSize, kTexSize, + sk_tool_utils::color_to_565(0x0), + sk_tool_utils::color_to_565(0xFF804020), + 8); + fOpaqueDiffuse = SkMakeBitmapShader(opaqueDiffuseMap, SkShader::kClamp_TileMode, + SkShader::kClamp_TileMode, &matrix, nullptr); + + SkBitmap translucentDiffuseMap = sk_tool_utils::create_checkerboard_bitmap( + kTexSize, kTexSize, + SkColorSetARGB(0x55, 0x00, 0x00, 0x00), + SkColorSetARGB(0x55, 0x80, 0x40, 0x20), + 8); + fTranslucentDiffuse = SkMakeBitmapShader(translucentDiffuseMap, SkShader::kClamp_TileMode, + SkShader::kClamp_TileMode, &matrix, nullptr); + + SkBitmap normalMap = make_frustum_normalmap(kTexSize); + fNormalMapShader = SkMakeBitmapShader(normalMap, SkShader::kClamp_TileMode, + SkShader::kClamp_TileMode, &matrix, nullptr); + + } + + // 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); + } + + static constexpr int NUM_BOOLEAN_PARAMS = 4; + void drawRect(SkCanvas* canvas, SkScalar scaleX, SkScalar scaleY, + SkScalar rotate, bool useNormalSource, bool useDiffuseShader, + bool useTranslucentPaint, bool useTranslucentShader) { + canvas->save(); + + this->positionCTM(canvas, scaleX, scaleY, rotate); + + const SkMatrix& ctm = canvas->getTotalMatrix(); + + SkPaint paint; + sk_sp<SkNormalSource> normalSource = nullptr; + sk_sp<SkShader> diffuseShader = nullptr; + + if (useNormalSource) { + normalSource = SkNormalSource::MakeFromNormalMap(fNormalMapShader, ctm); + } + + if (useDiffuseShader) { + diffuseShader = (useTranslucentShader) ? fTranslucentDiffuse : fOpaqueDiffuse; + } else { + paint.setColor(0xFF00FF00); + } + + if (useTranslucentPaint) { + paint.setAlpha(0x99); + } + + paint.setShader(SkLightingShader::Make(std::move(diffuseShader), std::move(normalSource), + fLights)); + canvas->drawRect(fRect, paint); + + canvas->restore(); + } + + void onDraw(SkCanvas* canvas) override { + + constexpr SkScalar LABEL_SIZE = 10.0f; + SkPaint labelPaint; + labelPaint.setTypeface(sk_tool_utils::create_portable_typeface("sans-serif", + SkFontStyle())); + labelPaint.setAntiAlias(true); + labelPaint.setTextSize(LABEL_SIZE); + + constexpr int GRID_COLUMN_NUM = 4; + constexpr SkScalar GRID_CELL_WIDTH = kTexSize + 20.0f + NUM_BOOLEAN_PARAMS * LABEL_SIZE; + + int gridNum = 0; + + // Running through all possible bool parameter combinations + for (bool useNormalSource : {true, false}) { + for (bool useDiffuseShader : {true, false}) { + for (bool useTranslucentPaint : {true, false}) { + for (bool useTranslucentShader : {true, false}) { + + // Determining position + SkScalar xPos = (gridNum % GRID_COLUMN_NUM) * GRID_CELL_WIDTH; + SkScalar yPos = (gridNum / GRID_COLUMN_NUM) * GRID_CELL_WIDTH; + + canvas->save(); + + canvas->translate(xPos, yPos); + this->drawRect(canvas, 1.0f, 1.0f, 0.f, useNormalSource, useDiffuseShader, + useTranslucentPaint, useTranslucentShader); + // Drawing labels + canvas->translate(0.0f, SkIntToScalar(kTexSize)); + { + canvas->translate(0.0f, LABEL_SIZE); + SkString label; + label.appendf("useNormalSource: %d", useNormalSource); + canvas->drawText(label.c_str(), label.size(), 0.0f, 0.0f, labelPaint); + } + { + canvas->translate(0.0f, LABEL_SIZE); + SkString label; + label.appendf("useDiffuseShader: %d", useDiffuseShader); + canvas->drawText(label.c_str(), label.size(), 0.0f, 0.0f, labelPaint); + } + { + canvas->translate(0.0f, LABEL_SIZE); + SkString label; + label.appendf("useTranslucentPaint: %d", useTranslucentPaint); + canvas->drawText(label.c_str(), label.size(), 0.0f, 0.0f, labelPaint); + } + { + canvas->translate(0.0f, LABEL_SIZE); + SkString label; + label.appendf("useTranslucentShader: %d", useTranslucentShader); + canvas->drawText(label.c_str(), label.size(), 0.0f, 0.0f, labelPaint); + } + + canvas->restore(); + + gridNum++; + } + } + } + } + + + // Rotation/scale test + { + SkScalar xPos = (gridNum % GRID_COLUMN_NUM) * GRID_CELL_WIDTH; + SkScalar yPos = (gridNum / GRID_COLUMN_NUM) * GRID_CELL_WIDTH; + + canvas->save(); + canvas->translate(xPos, yPos); + this->drawRect(canvas, 0.6f, 0.6f, 45.0f, true, true, true, true); + canvas->restore(); + + gridNum++; + } + + // Anisotropic scale test + { + SkScalar xPos = (gridNum % GRID_COLUMN_NUM) * GRID_CELL_WIDTH; + SkScalar yPos = (gridNum / GRID_COLUMN_NUM) * GRID_CELL_WIDTH; + + canvas->save(); + canvas->translate(xPos, yPos); + this->drawRect(canvas, 0.6f, 0.4f, 30.0f, true, true, true, true); + canvas->restore(); + + gridNum++; + } + } + +private: + static const int kTexSize = 96; + static const int kGMSize = 512; + + sk_sp<SkShader> fOpaqueDiffuse; + sk_sp<SkShader> fTranslucentDiffuse; + sk_sp<SkShader> fNormalMapShader; + + SkRect fRect; + sk_sp<SkLights> fLights; + + typedef GM INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +DEF_GM(return new LightingShader2GM;) +} |