xref: /aosp_15_r20/external/skia/gm/3d.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2020 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 
8 #include "gm/gm.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkData.h"
11 #include "include/core/SkPicture.h"
12 #include "include/core/SkPictureRecorder.h"
13 
14 #include <cmath>
15 
16 struct Info {
17     float   fNear = 0.05f;
18     float   fFar = 4;
19     float   fAngle = SK_ScalarPI / 4;
20 
21     SkV3    fEye { 0, 0, 1.0f/std::tan(fAngle/2) - 1 };
22     SkV3    fCOA { 0, 0, 0 };
23     SkV3    fUp  { 0, 1, 0 };
24 };
25 
inv(const SkM44 & m)26 static SkM44 inv(const SkM44& m) {
27     SkM44 inverse(SkM44::kUninitialized_Constructor);
28     if (!m.invert(&inverse)) {
29         inverse.setIdentity();
30     }
31     return inverse;
32 }
33 
make_ctm(const Info & info,const SkM44 & model,SkSize size)34 static SkM44 make_ctm(const Info& info, const SkM44& model, SkSize size) {
35     SkM44  camera, perspective, viewport;
36 
37     SkScalar w = size.width();
38     SkScalar h = size.height();
39 
40     perspective = SkM44::Perspective(info.fNear, info.fFar, info.fAngle);
41     camera = SkM44::LookAt(info.fEye, info.fCOA, info.fUp);
42     viewport.setScale(w*0.5f, h*0.5f, 1);//.postTranslate(r.centerX(), r.centerY(), 0);
43 
44     return viewport * perspective * camera * model * inv(viewport);
45 }
46 
do_draw(SkCanvas * canvas,SkColor color)47 static void do_draw(SkCanvas* canvas, SkColor color) {
48     SkAutoCanvasRestore acr(canvas, true);
49 
50     Info info;
51 
52     SkM44 m = SkM44::Rotate({0, 1, 0}, SK_ScalarPI/6);
53 
54     canvas->concat(make_ctm(info, m, {300, 300}));
55 
56     canvas->translate(150, 150);
57     SkPaint paint;
58     paint.setColor(color);
59     canvas->drawRect({-100, -100, 100, 100}, paint);
60 }
61 
62 /*
63  *  Test calling drawables w/ translate and matrices
64  */
65 DEF_SIMPLE_GM(sk3d_simple, real_canvas, 300, 300) {
66     do_draw(real_canvas, 0xFFFF0000);
67 
68     SkPictureRecorder recorder;
69     SkCanvas* canvas = recorder.beginRecording(300, 300);
70 
71     do_draw(canvas, 0x880000FF);
72 
73     auto pic = recorder.finishRecordingAsPicture();
74     real_canvas->drawPicture(pic);
75 }
76