SampleShip.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * Copyright 2015 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "include/core/SkCanvas.h"
  8. #include "include/core/SkFont.h"
  9. #include "include/core/SkRSXform.h"
  10. #include "include/core/SkSurface.h"
  11. #include "samplecode/Sample.h"
  12. #include "tools/Resources.h"
  13. #include "tools/timer/Timer.h"
  14. #include <stdio.h>
  15. static const int kGrid = 100;
  16. static const int kWidth = 960;
  17. static const int kHeight = 640;
  18. typedef void (*DrawAtlasProc)(SkCanvas*, SkImage*, const SkRSXform[], const SkRect[],
  19. const SkColor[], int, const SkRect*, const SkPaint*);
  20. static void draw_atlas(SkCanvas* canvas, SkImage* atlas, const SkRSXform xform[],
  21. const SkRect tex[], const SkColor colors[], int count, const SkRect* cull,
  22. const SkPaint* paint) {
  23. canvas->drawAtlas(atlas, xform, tex, colors, count, SkBlendMode::kModulate, cull, paint);
  24. }
  25. static void draw_atlas_sim(SkCanvas* canvas, SkImage* atlas, const SkRSXform xform[],
  26. const SkRect tex[], const SkColor colors[], int count, const SkRect* cull,
  27. const SkPaint* paint) {
  28. for (int i = 0; i < count; ++i) {
  29. SkMatrix matrix;
  30. matrix.setRSXform(xform[i]);
  31. canvas->save();
  32. canvas->concat(matrix);
  33. canvas->drawImageRect(atlas, tex[i], tex[i].makeOffset(-tex[i].x(), -tex[i].y()), paint,
  34. SkCanvas::kFast_SrcRectConstraint);
  35. canvas->restore();
  36. }
  37. }
  38. class DrawShipView : public Sample {
  39. public:
  40. DrawShipView(const char name[], DrawAtlasProc proc) : fName(name), fProc(proc) {
  41. fAtlas = GetResourceAsImage("images/ship.png");
  42. if (!fAtlas) {
  43. SkDebugf("\nCould not decode file ship.png. Falling back to penguin mode.\n");
  44. fAtlas = GetResourceAsImage("images/baby_tux.png");
  45. if (!fAtlas) {
  46. SkDebugf("\nCould not decode file baby_tux.png. Did you forget"
  47. " to set the resourcePath?\n");
  48. return;
  49. }
  50. }
  51. SkScalar anchorX = fAtlas->width()*0.5f;
  52. SkScalar anchorY = fAtlas->height()*0.5f;
  53. int currIndex = 0;
  54. for (int x = 0; x < kGrid; x++) {
  55. for (int y = 0; y < kGrid; y++) {
  56. float xPos = (x / (kGrid - 1.0f)) * kWidth;
  57. float yPos = (y / (kGrid - 1.0f)) * kWidth;
  58. fTex[currIndex] = SkRect::MakeLTRB(0.0f, 0.0f,
  59. SkIntToScalar(fAtlas->width()),
  60. SkIntToScalar(fAtlas->height()));
  61. fXform[currIndex] = SkRSXform::MakeFromRadians(0.1f, SK_ScalarPI*0.5f,
  62. xPos, yPos, anchorX, anchorY);
  63. currIndex++;
  64. }
  65. }
  66. fTex[currIndex] = SkRect::MakeLTRB(0.0f, 0.0f,
  67. SkIntToScalar(fAtlas->width()),
  68. SkIntToScalar(fAtlas->height()));
  69. fXform[currIndex] = SkRSXform::MakeFromRadians(0.5f, SK_ScalarPI*0.5f,
  70. kWidth*0.5f, kHeight*0.5f, anchorX, anchorY);
  71. }
  72. ~DrawShipView() override {}
  73. protected:
  74. SkString name() override { return SkString(fName); }
  75. void onDrawContent(SkCanvas* canvas) override {
  76. const float kCosDiff = 0.99984769515f;
  77. const float kSinDiff = 0.01745240643f;
  78. if (!fAtlas) {
  79. return;
  80. }
  81. SkPaint paint;
  82. paint.setFilterQuality(kLow_SkFilterQuality);
  83. paint.setColor(SK_ColorWHITE);
  84. SkScalar anchorX = fAtlas->width()*0.5f;
  85. SkScalar anchorY = fAtlas->height()*0.5f;
  86. for (int i = 0; i < kGrid*kGrid+1; ++i) {
  87. SkScalar c = fXform[i].fSCos;
  88. SkScalar s = fXform[i].fSSin;
  89. SkScalar dx = c*anchorX - s*anchorY;
  90. SkScalar dy = s*anchorX + c*anchorY;
  91. fXform[i].fSCos = kCosDiff*c - kSinDiff*s;
  92. fXform[i].fSSin = kSinDiff*c + kCosDiff*s;
  93. dx -= fXform[i].fSCos*anchorX - fXform[i].fSSin*anchorY;
  94. dy -= fXform[i].fSSin*anchorX + fXform[i].fSCos*anchorY;
  95. fXform[i].fTx += dx;
  96. fXform[i].fTy += dy;
  97. }
  98. fProc(canvas, fAtlas.get(), fXform, fTex, nullptr, kGrid*kGrid+1, nullptr, &paint);
  99. }
  100. bool onAnimate(double nanos) override {
  101. //TODO: use nanos
  102. //SkScalar angle = SkDoubleToScalar(fmod(1e-9 * nanos * 360 / 24, 360));
  103. //fAnimatingDrawable->setSweep(angle);
  104. return true;
  105. }
  106. private:
  107. const char* fName;
  108. DrawAtlasProc fProc;
  109. sk_sp<SkImage> fAtlas;
  110. SkRSXform fXform[kGrid*kGrid+1];
  111. SkRect fTex[kGrid*kGrid+1];
  112. typedef Sample INHERITED;
  113. };
  114. //////////////////////////////////////////////////////////////////////////////
  115. DEF_SAMPLE( return new DrawShipView("DrawShip", draw_atlas); )
  116. DEF_SAMPLE( return new DrawShipView("DrawShipSim", draw_atlas_sim); )