Home | History | Annotate | Download | only in raw
      1 // Copyright (C) 2009 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 #pragma stateVertex(PVBackground)
     17 #pragma stateRaster(parent)
     18 #pragma stateFragment(PFBackground)
     19 
     20 #define RSID_NOISESRC1 1
     21 #define RSID_NOISESRC2 2
     22 #define RSID_NOISESRC3 3
     23 #define RSID_NOISESRC4 4
     24 #define RSID_NOISESRC5 5
     25 #define RSID_NOISEDST1 6
     26 #define RSID_NOISEDST2 7
     27 #define RSID_NOISEDST3 8
     28 #define RSID_NOISEDST4 9
     29 #define RSID_NOISEDST5 10
     30 
     31 float xshift[5];
     32 float rotation[5];
     33 float scale[5];
     34 float alphafactor;
     35 int currentpreset;
     36 int lastuptime;
     37 float timedelta;
     38 
     39 void drawCloud(float *ident, int id, int idx) {
     40     float mat1[16];
     41     float z = -8.f * idx;
     42     matrixLoadMat(mat1,ident);
     43     matrixTranslate(mat1, -State->mXOffset * 8.f * idx, -State->mTilt * idx / 3.f, 0.f);
     44     matrixRotate(mat1, rotation[idx], 0.f, 0.f, 1.f);
     45     vpLoadModelMatrix(mat1);
     46 
     47     bindTexture(NAMED_PFBackground, 0, id);
     48     drawQuadTexCoords(
     49             -1200.0f, -1200.0f, z,        // space
     50                 0.f + xshift[idx], 0.f,        // texture
     51             1200, -1200.0f, z,            // space
     52                 scale[idx] + xshift[idx], 0.f,         // texture
     53             1200, 1200.0f, z,            // space
     54                 scale[idx] + xshift[idx], scale[idx],         // texture
     55             -1200.0f, 1200.0f, z,        // space
     56                 0.f + xshift[idx], scale[idx]);       // texture
     57 }
     58 
     59 void drawClouds(float* ident) {
     60 
     61     int i;
     62 
     63     float mat1[16];
     64 
     65     matrixLoadMat(mat1,ident);
     66 
     67     if (State->mRotate != 0) {
     68         rotation[0] += 0.10 * timedelta;
     69         rotation[1] += 0.102f * timedelta;
     70         rotation[2] += 0.106f * timedelta;
     71         rotation[3] += 0.114f * timedelta;
     72         rotation[4] += 0.123f * timedelta;
     73     }
     74 
     75     int mask = State->mTextureMask;
     76     if (mask & 1) {
     77         xshift[0] += 0.0010f * timedelta;
     78         if (State->mTextureSwap != 0) {
     79             drawCloud(mat1, NAMED_Tnoise5, 0);
     80         } else {
     81             drawCloud(mat1, NAMED_Tnoise1, 0);
     82         }
     83     }
     84 
     85     if (mask & 2) {
     86         xshift[1] += 0.00106 * timedelta;
     87         drawCloud(mat1, NAMED_Tnoise2, 1);
     88     }
     89 
     90     if (mask & 4) {
     91         xshift[2] += 0.00114f * timedelta;
     92         drawCloud(mat1, NAMED_Tnoise3, 2);
     93     }
     94 
     95     if (mask & 8) {
     96         xshift[3] += 0.00118f * timedelta;
     97         drawCloud(mat1, NAMED_Tnoise4, 3);
     98     }
     99 
    100     if (mask & 16) {
    101         xshift[4] += 0.00127f * timedelta;
    102         drawCloud(mat1, NAMED_Tnoise5, 4);
    103     }
    104 
    105     // Make sure the texture coordinates don't continuously increase
    106     for(i = 0; i < 5; i++) {
    107         while (xshift[i] >= 1.f) {
    108             xshift[i] -= 1.f;
    109         }
    110     }
    111     // Make sure the rotation angles don't continuously increase
    112     for(i = 0; i < 5; i++) {
    113         while (rotation[i] >= 360.f) {
    114             rotation[i] -= 360.f;
    115         }
    116     }
    117 }
    118 
    119 int premul(int rgb, int a) {
    120     int r = (rgb >> 16) * a + 1;
    121     r = (r + (r >> 8)) >> 8;
    122     int g = ((rgb >> 8) & 0xff) * a + 1;
    123     g = (g + (g >> 8)) >> 8;
    124     int b = (rgb & 0xff) * a + 1;
    125     b = (b + (b >> 8)) >> 8;
    126     return r << 16 | g << 8 | b;
    127 }
    128 
    129 void makeTexture(int *src, int *dst, int rsid) {
    130     
    131     int x;
    132     int y;
    133     int pm = State->mPreMul;
    134 
    135     if (State->mProcessTextureMode == 1) {
    136         int lowcol = State->mLowCol;
    137         int highcol = State->mHighCol;
    138         
    139         for (y=0;y<256;y++) {
    140             for (x=0;x<256;x++) { 
    141                 int pix = src[y*256+x];
    142                 int lum = pix & 0x00ff;
    143                 int newpix;
    144                 if (lum < 128) {
    145                     newpix = lowcol;
    146                     int newalpha = 255 - (lum * 2);
    147                     newalpha /= alphafactor;
    148                     if (pm) newpix = premul(newpix, newalpha);
    149                     newpix = newpix | (newalpha << 24);
    150                 } else {
    151                     newpix = highcol;
    152                     int newalpha = (lum - 128) * 2;
    153                     newalpha /= alphafactor;
    154                     if (pm) newpix = premul(newpix, newalpha);
    155                     newpix = newpix | (newalpha << 24);
    156                 }
    157                 // have ARGB, need ABGR
    158                 newpix = (newpix & 0xff00ff00) | ((newpix & 0xff) << 16) | ((newpix >> 16) & 0xff);
    159                 dst[y*256+x] = newpix;
    160             }
    161         }
    162         alphafactor *= State->mAlphaMul;
    163     } else if (State->mProcessTextureMode == 2) {
    164         int lowcol = State->mLowCol;
    165         int highcol = State->mHighCol;
    166         float scale = 255.f / (255.f - lowcol);
    167         
    168         for (y=0;y<256;y++) {
    169             for (x=0;x<256;x++) { 
    170                 int pix = src[y*256+x];
    171                 int alpha = pix & 0x00ff;
    172                 if (alpha < lowcol) {
    173                     alpha = 0;
    174                 } else {
    175                     alpha = (alpha - lowcol) * scale;
    176                 }
    177                 alpha /= alphafactor;
    178                 int newpix = highcol;
    179                 if (pm) newpix = premul(newpix, alpha);
    180                 newpix = newpix | (alpha << 24);
    181                 // have ARGB, need ABGR
    182                 newpix = (newpix & 0xff00ff00) | ((newpix & 0xff) << 16) | ((newpix >> 16) & 0xff);
    183                 dst[y*256+x] = newpix;
    184             }
    185         }
    186         alphafactor *= State->mAlphaMul;
    187     } else if (State->mProcessTextureMode == 3) {
    188         int lowcol = State->mLowCol;
    189         int highcol = State->mHighCol;
    190         float scale = 255.f / (255.f - lowcol);
    191         
    192         for (y=0;y<256;y++) {
    193             for (x=0;x<256;x++) { 
    194                 int pix = src[y*256+x];
    195                 int lum = pix & 0x00ff;
    196                 int newpix;
    197                 if (lum < 128) lum *= 2;
    198                 else lum = (255 - (lum - 128) * 2);
    199                 if (lum < 128) {
    200                     newpix = lowcol;
    201                     int newalpha = 255 - (lum * 2);
    202                     newalpha /= alphafactor;
    203                     if (pm) newpix = premul(newpix, newalpha);
    204                     newpix = newpix | (newalpha << 24);
    205                 } else {
    206                     newpix = highcol;
    207                     int newalpha = (lum - 128) * 2;
    208                     newalpha /= alphafactor;
    209                     if (pm) newpix = premul(newpix, newalpha);
    210                     newpix = newpix | (newalpha << 24);
    211                 }
    212                 // have ARGB, need ABGR
    213                 newpix = (newpix & 0xff00ff00) | ((newpix & 0xff) << 16) | ((newpix >> 16) & 0xff);
    214                 dst[y*256+x] = newpix;
    215             }
    216         }
    217         alphafactor *= State->mAlphaMul;
    218     } else {
    219 
    220         for (y=0;y<256;y++) {
    221             for (x=0;x<256;x++) {
    222                 int rgb = *src++;
    223                 int a = (rgb >> 24) & 0xff;
    224                 rgb &= 0x00ffffff;
    225                 rgb = premul(rgb, a);
    226                 int newpix = (a << 24) | rgb;
    227                 newpix = (newpix & 0xff00ff00) | ((newpix & 0xff) << 16) | ((newpix >> 16) & 0xff);
    228                 *dst++ = newpix;
    229             }
    230         }
    231     }
    232     uploadToTexture(rsid, 0);
    233 }
    234 
    235 void makeTextures() {
    236     debugI32("makeTextures", State->mPreset);
    237     alphafactor = 1.f;
    238     makeTexture((int*)noisesrc1, (int*)noisedst1, NAMED_Tnoise1);
    239     makeTexture((int*)noisesrc2, (int*)noisedst2, NAMED_Tnoise2);
    240     makeTexture((int*)noisesrc3, (int*)noisedst3, NAMED_Tnoise3);
    241     makeTexture((int*)noisesrc4, (int*)noisedst4, NAMED_Tnoise4);
    242     makeTexture((int*)noisesrc5, (int*)noisedst5, NAMED_Tnoise5);
    243 }
    244 
    245 
    246 
    247 struct color {
    248     float r;
    249     float g;
    250     float b;
    251 };
    252 
    253 void init() {
    254     int i;
    255     for (i=0;i<4;i++) {
    256         xshift[i] = 0.f;
    257         rotation[i] = 360.f * i / 5.f;
    258     }
    259     scale[0] = 4.0f; // changed below based on preset
    260     scale[1] = 3.0f;
    261     scale[2] = 3.4f;
    262     scale[3] = 3.8f;
    263     scale[4] = 4.2f;
    264 
    265     currentpreset = -1;
    266     lastuptime = uptimeMillis();
    267     timedelta = 0;
    268 }
    269 
    270 
    271 int main(int launchID) {
    272 
    273     int i;
    274     float ident[16];
    275     float masterscale = 0.0041f;// / (State->mXOffset * 4.f + 1.f);
    276     matrixLoadIdentity(ident);
    277     matrixTranslate(ident, -State->mXOffset, 0.f, 0.f);
    278     matrixScale(ident, masterscale, masterscale, masterscale);
    279     //matrixRotate(ident, 0.f, 0.f, 0.f, 1.f);
    280     matrixRotate(ident, -State->mTilt, 1.f, 0.f, 0.f);
    281 
    282     if (State->mBlendFunc) {
    283         bindProgramStore(NAMED_PFSBackgroundOne);
    284     } else {
    285         bindProgramStore(NAMED_PFSBackgroundSrc);
    286     }
    287 
    288     int now = uptimeMillis();
    289     timedelta = ((float)(now - lastuptime)) / 44.f;
    290     lastuptime = now;
    291     if (timedelta > 3) {
    292         // Limit the step adjustment factor to 3, so we don't get a sudden jump
    293         // after coming back from sleep.
    294         timedelta = 3;
    295     }
    296 
    297     i = State->mPreset;
    298     if (i != currentpreset) {
    299         currentpreset = i;
    300         int rgb = State->mBackCol;
    301         pfClearColor(
    302             ((float)((rgb >> 16)  & 0xff)) / 255.0f,
    303             ((float)((rgb >> 8)  & 0xff)) / 255.0f,
    304             ((float)(rgb & 0xff)) / 255.0f,
    305             1.0f);
    306         makeTextures();
    307     }
    308 
    309     if (State->mTextureSwap != 0) {
    310         scale[0] = .25f;
    311     } else {
    312         scale[0] = 4.f;
    313     }
    314     drawClouds(ident);
    315 
    316     return 55;
    317 }
    318