skia2/samplecode/PerlinPatch.cpp
Ben Wagner a93a14a998 Convert NULL and 0 to nullptr.
This was created by looking at warnings produced by clang's
-Wzero-as-null-pointer-constant. This updates most issues in
Skia code. However, there are places where GL and Vulkan want
pointer values which are explicitly 0, external headers which
use NULL directly, and possibly more uses in un-compiled
sources (for other platforms).

Change-Id: Id22fbac04d5c53497a53d734f0896b4f06fe8345
Reviewed-on: https://skia-review.googlesource.com/39521
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
2017-08-28 17:48:57 +00:00

219 lines
7.4 KiB
C++

/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SampleCode.h"
#include "SkAnimTimer.h"
#include "SkCanvas.h"
#include "SkGradientShader.h"
#include "SkPatchUtils.h"
#include "SkPerlinNoiseShader.h"
static void draw_control_points(SkCanvas* canvas, const SkPoint cubics[12]) {
//draw control points
SkPaint paint;
SkPoint bottom[SkPatchUtils::kNumPtsCubic];
SkPatchUtils::GetBottomCubic(cubics, bottom);
SkPoint top[SkPatchUtils::kNumPtsCubic];
SkPatchUtils::GetTopCubic(cubics, top);
SkPoint left[SkPatchUtils::kNumPtsCubic];
SkPatchUtils::GetLeftCubic(cubics, left);
SkPoint right[SkPatchUtils::kNumPtsCubic];
SkPatchUtils::GetRightCubic(cubics, right);
paint.setColor(SK_ColorBLACK);
paint.setStrokeWidth(0.5f);
SkPoint corners[4] = { bottom[0], bottom[3], top[0], top[3] };
canvas->drawPoints(SkCanvas::kLines_PointMode, 4, bottom, paint);
canvas->drawPoints(SkCanvas::kLines_PointMode, 2, bottom + 1, paint);
canvas->drawPoints(SkCanvas::kLines_PointMode, 4, top, paint);
canvas->drawPoints(SkCanvas::kLines_PointMode, 4, left, paint);
canvas->drawPoints(SkCanvas::kLines_PointMode, 4, right, paint);
canvas->drawPoints(SkCanvas::kLines_PointMode, 2, top + 1, paint);
canvas->drawPoints(SkCanvas::kLines_PointMode, 2, left + 1, paint);
canvas->drawPoints(SkCanvas::kLines_PointMode, 2, right + 1, paint);
paint.setStrokeWidth(2);
paint.setColor(SK_ColorRED);
canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, corners, paint);
paint.setColor(SK_ColorBLUE);
canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, bottom + 1, paint);
paint.setColor(SK_ColorCYAN);
canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, top + 1, paint);
paint.setColor(SK_ColorYELLOW);
canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, left + 1, paint);
paint.setColor(SK_ColorGREEN);
canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, right + 1, paint);
}
// These are actually half the total width and hieghts
const SkScalar TexWidth = 100.0f;
const SkScalar TexHeight = 100.0f;
class PerlinPatchView : public SampleView {
sk_sp<SkShader> fShader0;
sk_sp<SkShader> fShader1;
sk_sp<SkShader> fShaderCompose;
SkScalar fXFreq;
SkScalar fYFreq;
SkScalar fSeed;
SkPoint fPts[SkPatchUtils::kNumCtrlPts];
SkScalar fTexX;
SkScalar fTexY;
SkScalar fTexScale;
SkMatrix fInvMatrix;
bool fShowGrid = false;
public:
PerlinPatchView() : fXFreq(0.025f), fYFreq(0.025f), fSeed(0.0f),
fTexX(100.0), fTexY(50.0), fTexScale(1.0f) {
const SkScalar s = 2;
// The order of the colors and points is clockwise starting at upper-left corner.
//top points
fPts[0].set(100 * s, 100 * s);
fPts[1].set(150 * s, 50 * s);
fPts[2].set(250 * s, 150 * s);
fPts[3].set(300 * s, 100 * s);
//right points
fPts[4].set(275 * s, 150 * s);
fPts[5].set(350 * s, 250 * s);
//bottom points
fPts[6].set(300 * s, 300 * s);
fPts[7].set(250 * s, 250 * s);
//left points
fPts[8].set(150 * s, 350 * s);
fPts[9].set(100 * s, 300 * s);
fPts[10].set(50 * s, 250 * s);
fPts[11].set(150 * s, 150 * s);
const SkColor colors[SkPatchUtils::kNumCorners] = {
0xFF5555FF, 0xFF8888FF, 0xFFCCCCFF
};
const SkPoint points[2] = { SkPoint::Make(0.0f, 0.0f),
SkPoint::Make(100.0f, 100.0f) };
fShader0 = SkGradientShader::MakeLinear(points,
colors,
nullptr,
3,
SkShader::kMirror_TileMode,
0,
nullptr);
}
protected:
// overrides from SkEventSink
bool onQuery(SkEvent* evt) override {
if (SampleCode::TitleQ(*evt)) {
SampleCode::TitleR(evt, "PerlinPatch");
return true;
}
SkUnichar uni;
if (SampleCode::CharQ(*evt, &uni)) {
switch (uni) {
case 'g': fShowGrid = !fShowGrid; this->inval(nullptr); return true;
default: break;
}
}
return this->INHERITED::onQuery(evt);
}
bool onAnimate(const SkAnimTimer& timer) override {
fSeed += 0.005f;
return true;
}
void onDrawContent(SkCanvas* canvas) override {
if (!canvas->getTotalMatrix().invert(&fInvMatrix)) {
return;
}
SkPaint paint;
SkScalar texWidth = fTexScale * TexWidth;
SkScalar texHeight = fTexScale * TexHeight;
const SkPoint texCoords[SkPatchUtils::kNumCorners] = {
{ fTexX - texWidth, fTexY - texHeight},
{ fTexX + texWidth, fTexY - texHeight},
{ fTexX + texWidth, fTexY + texHeight},
{ fTexX - texWidth, fTexY + texHeight}}
;
SkScalar scaleFreq = 2.0;
fShader1 = SkPerlinNoiseShader::MakeImprovedNoise(fXFreq/scaleFreq, fYFreq/scaleFreq, 4,
fSeed);
fShaderCompose = SkShader::MakeComposeShader(fShader0, fShader1, SkBlendMode::kSrcOver);
paint.setShader(fShaderCompose);
const SkPoint* tex = texCoords;
if (fShowGrid) {
tex = nullptr;
}
canvas->drawPatch(fPts, nullptr, tex, SkBlendMode::kSrc, paint);
draw_control_points(canvas, fPts);
}
class PtClick : public Click {
public:
int fIndex;
PtClick(SkView* view, int index) : Click(view), fIndex(index) {}
};
static bool hittest(const SkPoint& pt, SkScalar x, SkScalar y) {
return SkPoint::Length(pt.fX - x, pt.fY - y) < SkIntToScalar(5);
}
SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override {
// holding down shift
if (1 == modi) {
return new PtClick(this, -1);
}
// holding down ctrl
if (2 == modi) {
return new PtClick(this, -2);
}
SkPoint clickPoint = {x, y};
fInvMatrix.mapPoints(&clickPoint, 1);
for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); i++) {
if (hittest(fPts[i], clickPoint.fX, clickPoint.fY)) {
return new PtClick(this, (int)i);
}
}
return this->INHERITED::onFindClickHandler(x, y, modi);
}
bool onClick(Click* click) override {
PtClick* ptClick = (PtClick*)click;
if (ptClick->fIndex >= 0) {
fPts[ptClick->fIndex].set(click->fCurr.fX , click->fCurr.fY );
} else if (-1 == ptClick->fIndex) {
SkScalar xDiff = click->fPrev.fX - click->fCurr.fX;
SkScalar yDiff = click->fPrev.fY - click->fCurr.fY;
fTexX += xDiff * fTexScale;
fTexY += yDiff * fTexScale;
} else if (-2 == ptClick->fIndex) {
SkScalar yDiff = click->fCurr.fY - click->fPrev.fY;
fTexScale += yDiff / 10.0f;
fTexScale = SkTMax(0.1f, SkTMin(20.f, fTexScale));
}
this->inval(nullptr);
return true;
}
private:
typedef SampleView INHERITED;
};
DEF_SAMPLE( return new PerlinPatchView(); )