Home | History | Annotate | Download | only in miscsamples
      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 
     17 #pragma rs java_package_name(com.example.android.rs.miscsamples)
     18 
     19 #include "rs_graphics.rsh"
     20 #include "shader_def.rsh"
     21 
     22 const int gMaxModes = 11;
     23 
     24 rs_program_vertex gProgVertex;
     25 rs_program_fragment gProgFragmentColor;
     26 rs_program_fragment gProgFragmentTexture;
     27 
     28 rs_program_store gProgStoreBlendNoneDepth;
     29 rs_program_store gProgStoreBlendNone;
     30 rs_program_store gProgStoreBlendAlpha;
     31 rs_program_store gProgStoreBlendAdd;
     32 
     33 rs_allocation gTexOpaque;
     34 rs_allocation gTexTorus;
     35 rs_allocation gTexTransparent;
     36 rs_allocation gTexChecker;
     37 rs_allocation gTexCube;
     38 
     39 rs_mesh gMbyNMesh;
     40 rs_mesh gTorusMesh;
     41 
     42 rs_font gFontSans;
     43 rs_font gFontSerif;
     44 rs_font gFontSerifBold;
     45 rs_font gFontSerifItalic;
     46 rs_font gFontSerifBoldItalic;
     47 rs_font gFontMono;
     48 rs_allocation gTextAlloc;
     49 
     50 int gDisplayMode;
     51 
     52 rs_sampler gLinearClamp;
     53 rs_sampler gLinearWrap;
     54 rs_sampler gMipLinearWrap;
     55 rs_sampler gMipLinearAniso8;
     56 rs_sampler gMipLinearAniso15;
     57 rs_sampler gNearestClamp;
     58 
     59 rs_program_raster gCullBack;
     60 rs_program_raster gCullFront;
     61 rs_program_raster gCullNone;
     62 
     63 // Custom vertex shader compunents
     64 VertexShaderConstants *gVSConstants;
     65 VertexShaderConstants2 *gVSConstants2;
     66 FragentShaderConstants *gFSConstants;
     67 FragentShaderConstants2 *gFSConstants2;
     68 // Export these out to easily set the inputs to shader
     69 VertexShaderInputs *gVSInputs;
     70 // Custom shaders we use for lighting
     71 rs_program_vertex gProgVertexCustom;
     72 rs_program_fragment gProgFragmentCustom;
     73 rs_program_vertex gProgVertexCustom2;
     74 rs_program_fragment gProgFragmentCustom2;
     75 rs_program_vertex gProgVertexCube;
     76 rs_program_fragment gProgFragmentCube;
     77 rs_program_fragment gProgFragmentMultitex;
     78 
     79 float gDt = 0;
     80 
     81 void init() {
     82 }
     83 
     84 static void displayFontSamples() {
     85     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
     86     int yPos = 100;
     87     rsgBindFont(gFontSans);
     88     rsgDrawText("Sans font sample", 30, yPos);
     89     yPos += 30;
     90     rsgFontColor(0.5f, 0.9f, 0.5f, 1.0f);
     91     rsgBindFont(gFontSerif);
     92     rsgDrawText("Serif font sample", 30, yPos);
     93     yPos += 30;
     94     rsgFontColor(0.7f, 0.7f, 0.7f, 1.0f);
     95     rsgBindFont(gFontSerifBold);
     96     rsgDrawText("Serif Bold font sample", 30, yPos);
     97     yPos += 30;
     98     rsgFontColor(0.5f, 0.5f, 0.9f, 1.0f);
     99     rsgBindFont(gFontSerifItalic);
    100     rsgDrawText("Serif Italic font sample", 30, yPos);
    101     yPos += 30;
    102     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
    103     rsgBindFont(gFontSerifBoldItalic);
    104     rsgDrawText("Serif Bold Italic font sample", 30, yPos);
    105     yPos += 30;
    106     rsgBindFont(gFontMono);
    107     rsgDrawText("Monospace font sample", 30, yPos);
    108     yPos += 50;
    109 
    110     // Now use text metrics to center the text
    111     uint width = rsgGetWidth();
    112     uint height = rsgGetHeight();
    113     int left = 0, right = 0, top = 0, bottom = 0;
    114 
    115     rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
    116     rsgBindFont(gFontSerifBoldItalic);
    117 
    118     rsgMeasureText(gTextAlloc, &left, &right, &top, &bottom);
    119     int centeredPos = width / 2 - (right - left) / 2;
    120     rsgDrawText(gTextAlloc, centeredPos, yPos);
    121     yPos += 30;
    122 
    123     const char* text = "Centered Text Sample";
    124     rsgMeasureText(text, &left, &right, &top, &bottom);
    125     centeredPos = width / 2 - (right - left) / 2;
    126     rsgDrawText(text, centeredPos, yPos);
    127     yPos += 30;
    128 
    129     rsgBindFont(gFontSans);
    130     text = "More Centered Text Samples";
    131     rsgMeasureText(text, &left, &right, &top, &bottom);
    132     centeredPos = width / 2 - (right - left) / 2;
    133     rsgDrawText(text, centeredPos, yPos);
    134     yPos += 30;
    135 
    136     // Now draw bottom and top right aligned text
    137     text = "Top-right aligned text";
    138     rsgMeasureText(text, &left, &right, &top, &bottom);
    139     rsgDrawText(text, width - right, top);
    140 
    141     text = "Top-left";
    142     rsgMeasureText(text, &left, &right, &top, &bottom);
    143     rsgDrawText(text, -left, top);
    144 
    145     text = "Bottom-right aligned text";
    146     rsgMeasureText(text, &left, &right, &top, &bottom);
    147     rsgDrawText(text, width - right, height + bottom);
    148 
    149 }
    150 
    151 static void bindProgramVertexOrtho() {
    152     // Default vertex sahder
    153     rsgBindProgramVertex(gProgVertex);
    154     // Setup the projectioni matrix
    155     rs_matrix4x4 proj;
    156     rsMatrixLoadOrtho(&proj, 0, rsgGetWidth(), rsgGetHeight(), 0, -500, 500);
    157     rsgProgramVertexLoadProjectionMatrix(&proj);
    158 }
    159 
    160 static void displayShaderSamples() {
    161     bindProgramVertexOrtho();
    162     rs_matrix4x4 matrix;
    163     rsMatrixLoadIdentity(&matrix);
    164     rsgProgramVertexLoadModelMatrix(&matrix);
    165 
    166     // Fragment shader with texture
    167     rsgBindProgramStore(gProgStoreBlendNone);
    168     rsgBindProgramFragment(gProgFragmentTexture);
    169     rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
    170     rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
    171 
    172     float startX = 0, startY = 0;
    173     float width = 256, height = 256;
    174     rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
    175                          startX, startY + height, 0, 0, 1,
    176                          startX + width, startY + height, 0, 1, 1,
    177                          startX + width, startY, 0, 1, 0);
    178 
    179     startX = 200; startY = 0;
    180     width = 128; height = 128;
    181     rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
    182                          startX, startY + height, 0, 0, 1,
    183                          startX + width, startY + height, 0, 1, 1,
    184                          startX + width, startY, 0, 1, 0);
    185 
    186     rsgBindProgramStore(gProgStoreBlendAlpha);
    187     rsgBindTexture(gProgFragmentTexture, 0, gTexTransparent);
    188     startX = 0; startY = 200;
    189     width = 128; height = 128;
    190     rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
    191                          startX, startY + height, 0, 0, 1,
    192                          startX + width, startY + height, 0, 1, 1,
    193                          startX + width, startY, 0, 1, 0);
    194 
    195     // Fragment program with simple color
    196     rsgBindProgramFragment(gProgFragmentColor);
    197     rsgProgramFragmentConstantColor(gProgFragmentColor, 0.9, 0.3, 0.3, 1);
    198     rsgDrawRect(200, 300, 350, 450, 0);
    199     rsgProgramFragmentConstantColor(gProgFragmentColor, 0.3, 0.9, 0.3, 1);
    200     rsgDrawRect(50, 400, 400, 600, 0);
    201 
    202     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
    203     rsgBindFont(gFontMono);
    204     rsgDrawText("Texture shader", 10, 50);
    205     rsgDrawText("Alpha-blended texture shader", 10, 280);
    206     rsgDrawText("Flat color shader", 100, 450);
    207 }
    208 
    209 static void displayBlendingSamples() {
    210     int i;
    211 
    212     bindProgramVertexOrtho();
    213     rs_matrix4x4 matrix;
    214     rsMatrixLoadIdentity(&matrix);
    215     rsgProgramVertexLoadModelMatrix(&matrix);
    216 
    217     rsgBindProgramFragment(gProgFragmentColor);
    218 
    219     rsgBindProgramStore(gProgStoreBlendNone);
    220     for (i = 0; i < 3; i ++) {
    221         float iPlusOne = (float)(i + 1);
    222         rsgProgramFragmentConstantColor(gProgFragmentColor,
    223                                         0.1f*iPlusOne, 0.2f*iPlusOne, 0.3f*iPlusOne, 1);
    224         float yPos = 150 * (float)i;
    225         rsgDrawRect(0, yPos, 200, yPos + 200, 0);
    226     }
    227 
    228     rsgBindProgramStore(gProgStoreBlendAlpha);
    229     for (i = 0; i < 3; i ++) {
    230         float iPlusOne = (float)(i + 1);
    231         rsgProgramFragmentConstantColor(gProgFragmentColor,
    232                                         0.2f*iPlusOne, 0.3f*iPlusOne, 0.1f*iPlusOne, 0.5);
    233         float yPos = 150 * (float)i;
    234         rsgDrawRect(150, yPos, 350, yPos + 200, 0);
    235     }
    236 
    237     rsgBindProgramStore(gProgStoreBlendAdd);
    238     for (i = 0; i < 3; i ++) {
    239         float iPlusOne = (float)(i + 1);
    240         rsgProgramFragmentConstantColor(gProgFragmentColor,
    241                                         0.3f*iPlusOne, 0.1f*iPlusOne, 0.2f*iPlusOne, 0.5);
    242         float yPos = 150 * (float)i;
    243         rsgDrawRect(300, yPos, 500, yPos + 200, 0);
    244     }
    245 
    246 
    247     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
    248     rsgBindFont(gFontMono);
    249     rsgDrawText("No Blending", 10, 50);
    250     rsgDrawText("Alpha Blending", 160, 150);
    251     rsgDrawText("Additive Blending", 320, 250);
    252 
    253 }
    254 
    255 static void displayMeshSamples() {
    256 
    257     bindProgramVertexOrtho();
    258     rs_matrix4x4 matrix;
    259     rsMatrixLoadTranslate(&matrix, 128, 128, 0);
    260     rsgProgramVertexLoadModelMatrix(&matrix);
    261 
    262     // Fragment shader with texture
    263     rsgBindProgramStore(gProgStoreBlendNone);
    264     rsgBindProgramFragment(gProgFragmentTexture);
    265     rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
    266     rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
    267 
    268     rsgDrawMesh(gMbyNMesh);
    269 
    270     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
    271     rsgBindFont(gFontMono);
    272     rsgDrawText("User gen 10 by 10 grid mesh", 10, 250);
    273 }
    274 
    275 static void displayTextureSamplers() {
    276 
    277     bindProgramVertexOrtho();
    278     rs_matrix4x4 matrix;
    279     rsMatrixLoadIdentity(&matrix);
    280     rsgProgramVertexLoadModelMatrix(&matrix);
    281 
    282     // Fragment shader with texture
    283     rsgBindProgramStore(gProgStoreBlendNone);
    284     rsgBindProgramFragment(gProgFragmentTexture);
    285     rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
    286 
    287     // Linear clamp
    288     rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
    289     float startX = 0, startY = 0;
    290     float width = 300, height = 300;
    291     rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
    292                          startX, startY + height, 0, 0, 1.1,
    293                          startX + width, startY + height, 0, 1.1, 1.1,
    294                          startX + width, startY, 0, 1.1, 0);
    295 
    296     // Linear Wrap
    297     rsgBindSampler(gProgFragmentTexture, 0, gLinearWrap);
    298     startX = 0; startY = 300;
    299     width = 300; height = 300;
    300     rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
    301                          startX, startY + height, 0, 0, 1.1,
    302                          startX + width, startY + height, 0, 1.1, 1.1,
    303                          startX + width, startY, 0, 1.1, 0);
    304 
    305     // Nearest
    306     rsgBindSampler(gProgFragmentTexture, 0, gNearestClamp);
    307     startX = 300; startY = 0;
    308     width = 300; height = 300;
    309     rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
    310                          startX, startY + height, 0, 0, 1.1,
    311                          startX + width, startY + height, 0, 1.1, 1.1,
    312                          startX + width, startY, 0, 1.1, 0);
    313 
    314     rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
    315     startX = 300; startY = 300;
    316     width = 300; height = 300;
    317     rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
    318                          startX, startY + height, 0, 0, 1.5,
    319                          startX + width, startY + height, 0, 1.5, 1.5,
    320                          startX + width, startY, 0, 1.5, 0);
    321 
    322     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
    323     rsgBindFont(gFontMono);
    324     rsgDrawText("Filtering: linear clamp", 10, 290);
    325     rsgDrawText("Filtering: linear wrap", 10, 590);
    326     rsgDrawText("Filtering: nearest clamp", 310, 290);
    327     rsgDrawText("Filtering: miplinear wrap", 310, 590);
    328 }
    329 
    330 static float gTorusRotation = 0;
    331 
    332 static void displayCullingSamples() {
    333     rsgBindProgramVertex(gProgVertex);
    334     // Setup the projectioni matrix with 60 degree field of view
    335     rs_matrix4x4 proj;
    336     float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
    337     rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
    338     rsgProgramVertexLoadProjectionMatrix(&proj);
    339 
    340     // Fragment shader with texture
    341     rsgBindProgramStore(gProgStoreBlendNoneDepth);
    342     rsgBindProgramFragment(gProgFragmentTexture);
    343     rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
    344     rsgBindTexture(gProgFragmentTexture, 0, gTexTorus);
    345 
    346     // Aplly a rotation to our mesh
    347     gTorusRotation += 50.0f * gDt;
    348     if (gTorusRotation > 360.0f) {
    349         gTorusRotation -= 360.0f;
    350     }
    351 
    352     rs_matrix4x4 matrix;
    353     // Position our model on the screen
    354     rsMatrixLoadTranslate(&matrix, -2.0f, 0.0f, -10.0f);
    355     rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
    356     rsgProgramVertexLoadModelMatrix(&matrix);
    357     // Use front face culling
    358     rsgBindProgramRaster(gCullFront);
    359     rsgDrawMesh(gTorusMesh);
    360 
    361     rsMatrixLoadTranslate(&matrix, 2.0f, 0.0f, -10.0f);
    362     rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
    363     rsgProgramVertexLoadModelMatrix(&matrix);
    364     // Use back face culling
    365     rsgBindProgramRaster(gCullBack);
    366     rsgDrawMesh(gTorusMesh);
    367 
    368     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
    369     rsgBindFont(gFontMono);
    370     rsgDrawText("Displaying mesh front/back face culling", 10, rsgGetHeight() - 10);
    371 }
    372 
    373 static float gLight0Rotation = 0;
    374 static float gLight1Rotation = 0;
    375 
    376 static void setupCustomShaderLights() {
    377     float4 light0Pos = {-5.0f, 5.0f, -10.0f, 1.0f};
    378     float4 light1Pos = {2.0f, 5.0f, 15.0f, 1.0f};
    379     float4 light0DiffCol = {0.9f, 0.7f, 0.7f, 1.0f};
    380     float4 light0SpecCol = {0.9f, 0.6f, 0.6f, 1.0f};
    381     float4 light1DiffCol = {0.5f, 0.5f, 0.9f, 1.0f};
    382     float4 light1SpecCol = {0.5f, 0.5f, 0.9f, 1.0f};
    383 
    384     gLight0Rotation += 50.0f * gDt;
    385     if (gLight0Rotation > 360.0f) {
    386         gLight0Rotation -= 360.0f;
    387     }
    388     gLight1Rotation -= 50.0f * gDt;
    389     if (gLight1Rotation > 360.0f) {
    390         gLight1Rotation -= 360.0f;
    391     }
    392 
    393     rs_matrix4x4 l0Mat;
    394     rsMatrixLoadRotate(&l0Mat, gLight0Rotation, 1.0f, 0.0f, 0.0f);
    395     light0Pos = rsMatrixMultiply(&l0Mat, light0Pos);
    396     rs_matrix4x4 l1Mat;
    397     rsMatrixLoadRotate(&l1Mat, gLight1Rotation, 0.0f, 0.0f, 1.0f);
    398     light1Pos = rsMatrixMultiply(&l1Mat, light1Pos);
    399 
    400     // Set light 0 properties
    401     gVSConstants->light0_Posision = light0Pos;
    402     gVSConstants->light0_Diffuse = 1.0f;
    403     gVSConstants->light0_Specular = 0.5f;
    404     gVSConstants->light0_CosinePower = 10.0f;
    405     // Set light 1 properties
    406     gVSConstants->light1_Posision = light1Pos;
    407     gVSConstants->light1_Diffuse = 1.0f;
    408     gVSConstants->light1_Specular = 0.7f;
    409     gVSConstants->light1_CosinePower = 25.0f;
    410     rsgAllocationSyncAll(rsGetAllocation(gVSConstants));
    411 
    412     gVSConstants2->light_Posision[0] = light0Pos;
    413     gVSConstants2->light_Diffuse[0] = 1.0f;
    414     gVSConstants2->light_Specular[0] = 0.5f;
    415     gVSConstants2->light_CosinePower[0] = 10.0f;
    416     gVSConstants2->light_Posision[1] = light1Pos;
    417     gVSConstants2->light_Diffuse[1] = 1.0f;
    418     gVSConstants2->light_Specular[1] = 0.7f;
    419     gVSConstants2->light_CosinePower[1] = 25.0f;
    420     rsgAllocationSyncAll(rsGetAllocation(gVSConstants2));
    421 
    422     // Update fragmetn shader constants
    423     // Set light 0 colors
    424     gFSConstants->light0_DiffuseColor = light0DiffCol;
    425     gFSConstants->light0_SpecularColor = light0SpecCol;
    426     // Set light 1 colors
    427     gFSConstants->light1_DiffuseColor = light1DiffCol;
    428     gFSConstants->light1_SpecularColor = light1SpecCol;
    429     rsgAllocationSyncAll(rsGetAllocation(gFSConstants));
    430 
    431     gFSConstants2->light_DiffuseColor[0] = light0DiffCol;
    432     gFSConstants2->light_SpecularColor[0] = light0SpecCol;
    433     // Set light 1 colors
    434     gFSConstants2->light_DiffuseColor[1] = light1DiffCol;
    435     gFSConstants2->light_SpecularColor[1] = light1SpecCol;
    436     rsgAllocationSyncAll(rsGetAllocation(gFSConstants2));
    437 }
    438 
    439 static void displayCustomShaderSamples() {
    440 
    441     // Update vertex shader constants
    442     // Load model matrix
    443     // Aplly a rotation to our mesh
    444     gTorusRotation += 50.0f * gDt;
    445     if (gTorusRotation > 360.0f) {
    446         gTorusRotation -= 360.0f;
    447     }
    448 
    449     // Position our model on the screen
    450     rsMatrixLoadTranslate(&gVSConstants->model, 0.0f, 0.0f, -10.0f);
    451     rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
    452     rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
    453     // Setup the projectioni matrix
    454     float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
    455     rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f);
    456     setupCustomShaderLights();
    457 
    458     rsgBindProgramVertex(gProgVertexCustom);
    459 
    460     // Fragment shader with texture
    461     rsgBindProgramStore(gProgStoreBlendNoneDepth);
    462     rsgBindProgramFragment(gProgFragmentCustom);
    463     rsgBindSampler(gProgFragmentCustom, 0, gLinearClamp);
    464     rsgBindTexture(gProgFragmentCustom, 0, gTexTorus);
    465 
    466     // Use back face culling
    467     rsgBindProgramRaster(gCullBack);
    468     rsgDrawMesh(gTorusMesh);
    469 
    470     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
    471     rsgBindFont(gFontMono);
    472     rsgDrawText("Custom shader sample", 10, rsgGetHeight() - 10);
    473 }
    474 
    475 static void displayCustomShaderSamples2() {
    476 
    477     // Update vertex shader constants
    478     // Load model matrix
    479     // Aplly a rotation to our mesh
    480     gTorusRotation += 50.0f * gDt;
    481     if (gTorusRotation > 360.0f) {
    482         gTorusRotation -= 360.0f;
    483     }
    484 
    485     // Position our model on the screen
    486     rsMatrixLoadTranslate(&gVSConstants2->model[1], 0.0f, 0.0f, -10.0f);
    487     rsMatrixLoadIdentity(&gVSConstants2->model[0]);
    488     rsMatrixRotate(&gVSConstants2->model[0], gTorusRotation, 1.0f, 0.0f, 0.0f);
    489     rsMatrixRotate(&gVSConstants2->model[0], gTorusRotation, 0.0f, 0.0f, 1.0f);
    490     // Setup the projectioni matrix
    491     float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
    492     rsMatrixLoadPerspective(&gVSConstants2->proj, 30.0f, aspect, 0.1f, 100.0f);
    493     setupCustomShaderLights();
    494 
    495     rsgBindProgramVertex(gProgVertexCustom2);
    496 
    497     // Fragment shader with texture
    498     rsgBindProgramStore(gProgStoreBlendNoneDepth);
    499     rsgBindProgramFragment(gProgFragmentCustom2);
    500     rsgBindSampler(gProgFragmentCustom2, 0, gLinearClamp);
    501     rsgBindTexture(gProgFragmentCustom2, 0, gTexTorus);
    502 
    503     // Use back face culling
    504     rsgBindProgramRaster(gCullBack);
    505     rsgDrawMesh(gTorusMesh);
    506 
    507     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
    508     rsgBindFont(gFontMono);
    509     rsgDrawText("Custom shader sample with array uniforms", 10, rsgGetHeight() - 10);
    510 }
    511 
    512 static void displayCubemapShaderSample() {
    513     // Update vertex shader constants
    514     // Load model matrix
    515     // Aplly a rotation to our mesh
    516     gTorusRotation += 50.0f * gDt;
    517     if (gTorusRotation > 360.0f) {
    518         gTorusRotation -= 360.0f;
    519     }
    520 
    521     // Position our model on the screen
    522     // Position our model on the screen
    523     rsMatrixLoadTranslate(&gVSConstants->model, 0.0f, 0.0f, -10.0f);
    524     rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
    525     rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
    526     // Setup the projectioni matrix
    527     float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
    528     rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f);
    529     rsgAllocationSyncAll(rsGetAllocation(gFSConstants));
    530 
    531     rsgBindProgramVertex(gProgVertexCube);
    532 
    533     // Fragment shader with texture
    534     rsgBindProgramStore(gProgStoreBlendNoneDepth);
    535     rsgBindProgramFragment(gProgFragmentCube);
    536     rsgBindSampler(gProgFragmentCube, 0, gLinearClamp);
    537     rsgBindTexture(gProgFragmentCube, 0, gTexCube);
    538 
    539     // Use back face culling
    540     rsgBindProgramRaster(gCullBack);
    541     rsgDrawMesh(gTorusMesh);
    542 
    543     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
    544     rsgBindFont(gFontMono);
    545     rsgDrawText("Cubemap shader sample", 10, rsgGetHeight() - 10);
    546 }
    547 
    548 static void displayMultitextureSample() {
    549     bindProgramVertexOrtho();
    550     rs_matrix4x4 matrix;
    551     rsMatrixLoadIdentity(&matrix);
    552     rsgProgramVertexLoadModelMatrix(&matrix);
    553 
    554     // Fragment shader with texture
    555     rsgBindProgramStore(gProgStoreBlendNone);
    556     rsgBindProgramFragment(gProgFragmentMultitex);
    557     rsgBindSampler(gProgFragmentMultitex, 0, gLinearClamp);
    558     rsgBindSampler(gProgFragmentMultitex, 1, gLinearWrap);
    559     rsgBindSampler(gProgFragmentMultitex, 2, gLinearClamp);
    560     rsgBindTexture(gProgFragmentMultitex, 0, gTexChecker);
    561     rsgBindTexture(gProgFragmentMultitex, 1, gTexTorus);
    562     rsgBindTexture(gProgFragmentMultitex, 2, gTexTransparent);
    563 
    564     float startX = 0, startY = 0;
    565     float width = 256, height = 256;
    566     rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
    567                          startX, startY + height, 0, 0, 1,
    568                          startX + width, startY + height, 0, 1, 1,
    569                          startX + width, startY, 0, 1, 0);
    570 
    571     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
    572     rsgBindFont(gFontMono);
    573     rsgDrawText("Custom shader with multitexturing", 10, 280);
    574 }
    575 
    576 static float gAnisoTime = 0.0f;
    577 static uint anisoMode = 0;
    578 static void displayAnisoSample() {
    579 
    580     gAnisoTime += gDt;
    581 
    582     rsgBindProgramVertex(gProgVertex);
    583     float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
    584     rs_matrix4x4 proj;
    585     rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
    586     rsgProgramVertexLoadProjectionMatrix(&proj);
    587 
    588     rs_matrix4x4 matrix;
    589     // Fragment shader with texture
    590     rsgBindProgramStore(gProgStoreBlendNone);
    591     rsgBindProgramFragment(gProgFragmentTexture);
    592     rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, -10.0f);
    593     rsMatrixRotate(&matrix, -80, 1.0f, 0.0f, 0.0f);
    594     rsgProgramVertexLoadModelMatrix(&matrix);
    595 
    596     rsgBindProgramRaster(gCullNone);
    597 
    598     rsgBindTexture(gProgFragmentTexture, 0, gTexChecker);
    599 
    600     if (gAnisoTime >= 5.0f) {
    601         gAnisoTime = 0.0f;
    602         anisoMode ++;
    603         anisoMode = anisoMode % 3;
    604     }
    605 
    606     if (anisoMode == 0) {
    607         rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso8);
    608     } else if (anisoMode == 1) {
    609         rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso15);
    610     } else {
    611         rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
    612     }
    613 
    614     float startX = -15;
    615     float startY = -15;
    616     float width = 30;
    617     float height = 30;
    618     rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
    619                          startX, startY + height, 0, 0, 10,
    620                          startX + width, startY + height, 0, 10, 10,
    621                          startX + width, startY, 0, 10, 0);
    622 
    623     rsgBindProgramRaster(gCullBack);
    624 
    625     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
    626     rsgBindFont(gFontMono);
    627     if (anisoMode == 0) {
    628         rsgDrawText("Anisotropic filtering 8", 10, 40);
    629     } else if (anisoMode == 1) {
    630         rsgDrawText("Anisotropic filtering 15", 10, 40);
    631     } else {
    632         rsgDrawText("Miplinear filtering", 10, 40);
    633     }
    634 }
    635 
    636 int root(void) {
    637 
    638     gDt = rsGetDt();
    639 
    640     rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
    641     rsgClearDepth(1.0f);
    642 
    643     switch (gDisplayMode) {
    644     case 0:
    645         displayFontSamples();
    646         break;
    647     case 1:
    648         displayShaderSamples();
    649         break;
    650     case 2:
    651         displayBlendingSamples();
    652         break;
    653     case 3:
    654         displayMeshSamples();
    655         break;
    656     case 4:
    657         displayTextureSamplers();
    658         break;
    659     case 5:
    660         displayCullingSamples();
    661         break;
    662     case 6:
    663         displayCustomShaderSamples();
    664         break;
    665     case 7:
    666         displayMultitextureSample();
    667         break;
    668     case 8:
    669         displayAnisoSample();
    670         break;
    671     case 9:
    672         displayCustomShaderSamples2();
    673         break;
    674     case 10:
    675         displayCubemapShaderSample();
    676         break;
    677     }
    678 
    679     return 10;
    680 }
    681