blob: 27eccc250d407c6f76a95dc75206fec81ecb7c4a [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
2 * Copyright 2011 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 */
reed@android.com2ee7c642009-10-28 14:25:34 +00007#include "SkMeshUtils.h"
8#include "SkCanvas.h"
9#include "SkPaint.h"
10
11SkMeshIndices::SkMeshIndices() {
12 sk_bzero(this, sizeof(*this));
13}
14
15SkMeshIndices::~SkMeshIndices() {
16 sk_free(fStorage);
17}
18
19bool SkMeshIndices::init(SkPoint tex[], uint16_t indices[],
20 int texW, int texH, int rows, int cols) {
21 if (rows < 2 || cols < 2) {
22 sk_free(fStorage);
halcanary96fcdcc2015-08-27 07:41:13 -070023 fStorage = nullptr;
24 fTex = nullptr;
25 fIndices = nullptr;
reed@android.com2ee7c642009-10-28 14:25:34 +000026 fTexCount = fIndexCount = 0;
27 return false;
28 }
29
30 sk_free(fStorage);
halcanary96fcdcc2015-08-27 07:41:13 -070031 fStorage = nullptr;
reed@android.com2ee7c642009-10-28 14:25:34 +000032
33 fTexCount = rows * cols;
34 rows -= 1;
35 cols -= 1;
36 fIndexCount = rows * cols * 6;
37
38 if (tex) {
39 fTex = tex;
40 fIndices = indices;
41 } else {
42 fStorage = sk_malloc_throw(fTexCount * sizeof(SkPoint) +
43 fIndexCount * sizeof(uint16_t));
44 fTex = (SkPoint*)fStorage;
45 fIndices = (uint16_t*)(fTex + fTexCount);
46 }
47
48 // compute the indices
49 {
50 uint16_t* idx = fIndices;
51 int index = 0;
52 for (int y = 0; y < cols; y++) {
53 for (int x = 0; x < rows; x++) {
54 *idx++ = index;
55 *idx++ = index + rows + 1;
56 *idx++ = index + 1;
rmistry@google.comd6176b02012-08-23 18:14:13 +000057
reed@android.com2ee7c642009-10-28 14:25:34 +000058 *idx++ = index + 1;
59 *idx++ = index + rows + 1;
60 *idx++ = index + rows + 2;
rmistry@google.comd6176b02012-08-23 18:14:13 +000061
reed@android.com2ee7c642009-10-28 14:25:34 +000062 index += 1;
63 }
64 index += 1;
65 }
66 }
67
68 // compute texture coordinates
69 {
70 SkPoint* tex = fTex;
71 const SkScalar dx = SkIntToScalar(texW) / rows;
72 const SkScalar dy = SkIntToScalar(texH) / cols;
73 for (int y = 0; y <= cols; y++) {
74 for (int x = 0; x <= rows; x++) {
75 tex->set(x*dx, y*dy);
76 tex += 1;
77 }
78 }
79 }
80 return true;
81}
82
83///////////////////////////////////////////////////////////////////////////////
84
85#include "SkShader.h"
86
87void SkMeshUtils::Draw(SkCanvas* canvas, const SkBitmap& bitmap,
88 int rows, int cols, const SkPoint verts[],
89 const SkColor colors[], const SkPaint& paint) {
90 SkMeshIndices idx;
rmistry@google.comd6176b02012-08-23 18:14:13 +000091
reed@android.com2ee7c642009-10-28 14:25:34 +000092 if (idx.init(bitmap.width(), bitmap.height(), rows, cols)) {
93 SkPaint p(paint);
reed8a21c9f2016-03-08 18:50:00 -080094 p.setShader(SkShader::MakeBitmapShader(bitmap,
reed@android.com2ee7c642009-10-28 14:25:34 +000095 SkShader::kClamp_TileMode,
reed8a21c9f2016-03-08 18:50:00 -080096 SkShader::kClamp_TileMode));
reed@android.com2ee7c642009-10-28 14:25:34 +000097 canvas->drawVertices(SkCanvas::kTriangles_VertexMode,
halcanary96fcdcc2015-08-27 07:41:13 -070098 rows * cols, verts, idx.tex(), colors, nullptr,
reed@android.com2ee7c642009-10-28 14:25:34 +000099 idx.indices(), idx.indexCount(), p);
100 }
101}