1// Copyright (C) 2010 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma version(1)
16
17#pragma rs java_package_name(com.android.wallpaper.holospiral)
18
19#include "rs_graphics.rsh"
20
21#pragma rs export_func(resize)
22
23#define FOV 60.0f
24#define SPIRAL_ROTATE_SPEED 15.0f
25#define INNER_ROTATE_SPEED 1.5f
26#define OUTER_ROTATE_SPEED 0.5f
27
28// Vertex Shaders
29rs_program_vertex gPVBackground;
30rs_program_vertex gPVGeometry;
31
32// Fragment Shaders
33rs_program_fragment gPFBackground;
34rs_program_fragment gPFGeometry;
35
36// Blending and Depth testing
37rs_program_store gPSBackground;
38rs_program_store gPSGeometry;
39
40// Meshes
41rs_mesh gInnerGeometry;
42rs_mesh gOuterGeometry;
43rs_mesh gBackgroundMesh;
44
45// Matrices
46static rs_matrix4x4 gProjectionMatrix;
47static rs_matrix4x4 gTransformedModelView;
48
49// Textures
50rs_allocation gPointTexture;
51
52// Misc fields
53float gXOffset;
54float gNearPlane;
55float gFarPlane;
56
57// User defined data types
58typedef struct VertexShaderConstants_s {
59    rs_matrix4x4 modelViewProj;
60    float maxPointSize;
61    float farPlane;
62} VertexShaderConstants;
63VertexShaderConstants* gVSConstants;
64
65typedef struct VertexColor_s {
66    float3 position;
67    float4 color;
68} VertexColor;
69VertexColor* VertexColor_s_dummy;
70
71static float lastTime;
72static float gInnerRotateAngle;
73static float gOuterRotateAngle;
74static float gWidth;
75static float gHeight;
76
77static float modulo360(float val) {
78    static const INVERSE_360 = 1.0f / 360.0f;
79    int multiplier = (int)(val * INVERSE_360);
80    return val - (multiplier * 360.0f);
81}
82
83static void drawBackground() {
84    rsgBindProgramVertex(gPVBackground);
85    rsgBindProgramFragment(gPFBackground);
86    rsgBindProgramStore(gPSBackground);
87
88    rsgDrawMesh(gBackgroundMesh);
89}
90
91static void drawGeometry(float dt) {
92    rsgBindProgramVertex(gPVGeometry);
93    rsgBindProgramFragment(gPFGeometry);
94    rsgBindProgramStore(gPSGeometry);
95
96    rsgBindTexture(gPFGeometry, 0, gPointTexture);
97
98    rs_matrix4x4 modelView;
99    rs_matrix4x4 rotateModelView;
100
101    rsMatrixLoad(&modelView, &gTransformedModelView);
102    rsMatrixRotate(&modelView, gXOffset * -SPIRAL_ROTATE_SPEED, 0.0f, 1.0f, 0.0f);
103
104    rsMatrixLoad(&rotateModelView, &modelView);
105    {
106        rsMatrixRotate(&rotateModelView, -gOuterRotateAngle, 0.0f, 0.0f, 1.0f);
107        rsMatrixLoadMultiply(&gVSConstants->modelViewProj, &gProjectionMatrix, &rotateModelView);
108
109        // Wrap the rotation so we don't go past 360
110        gOuterRotateAngle = modulo360(gOuterRotateAngle + (dt * OUTER_ROTATE_SPEED));
111
112        rsgDrawMesh(gOuterGeometry);
113    }
114
115    rsMatrixLoad(&rotateModelView, &modelView);
116    {
117        rsMatrixRotate(&rotateModelView, gInnerRotateAngle, 0.0f, 0.0f, 1.0f);
118        rsMatrixLoadMultiply(&gVSConstants->modelViewProj, &gProjectionMatrix, &rotateModelView);
119
120        // Wrap the rotation so we don't go past 360
121        gInnerRotateAngle = modulo360(gInnerRotateAngle + (dt * INNER_ROTATE_SPEED));
122
123        rsgDrawMesh(gInnerGeometry);
124    }
125}
126
127void resize(float width, float height) {
128    gWidth = width;
129    gHeight = height;
130    gVSConstants->farPlane = gFarPlane;
131    rsMatrixLoadPerspective(&gProjectionMatrix, FOV, gWidth / gHeight, gNearPlane, gFarPlane);
132}
133
134void init() {
135    gInnerRotateAngle = 0.0f;
136    gOuterRotateAngle = 0.0f;
137
138    gXOffset = 0.0f;
139    lastTime = rsUptimeMillis();
140
141    // Pre-calculate some fixed transformations
142    rsMatrixLoadIdentity(&gTransformedModelView);
143    rsMatrixTranslate(&gTransformedModelView, -3.0f, -5.0f, -18.0f);
144    rsMatrixRotate(&gTransformedModelView, 20.0f, 0.0f, 1.0f, 0.0f);
145    rsMatrixRotate(&gTransformedModelView, -10.0f, 1.0f, 0.0f, 0.0f);
146}
147
148int root(void) {
149    float now = rsUptimeMillis();
150    float elapsed = (now - lastTime) * 0.001f;
151    lastTime = now;
152
153    drawBackground();
154    drawGeometry(elapsed);
155
156    // Around 14 FPS
157    return 70;
158}
159