Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. #include "rsgentex.h"
  2.  
  3. #ifdef RS_USE_C_LIBS
  4.     #include <math.h>
  5.     #include <stdlib.h>
  6. #endif
  7.  
  8. #include "rsnoise.h"
  9.  
  10. #include "rs/rsplatform.h"
  11. #include "rs/rsmx.h"
  12.  
  13. /*
  14.  
  15.     Procedural Texture Generator
  16.     by Roman Shuvalov
  17.  
  18.  
  19. */
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27. rs_gen_reg_t rs_gen_reg;
  28.  
  29.  
  30.  
  31.  
  32.  
  33. void rs_gen_func_mult_add_value(int dest, int src, float val_mult, float val_add) {
  34.     int i;
  35.     for (i = 0; i < rs_gen_reg.tex_length; i++ ) {
  36.         rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i] = rs_gen_reg.tex[src*rs_gen_reg.tex_length + i] * val_mult + val_add;
  37.     };
  38. };
  39.  
  40. void rs_gen_func_perlin(int dest, float freq, int octaves, float persistence, float seed) {
  41.     rs_perlin_configure(freq, octaves, persistence, seed, rs_gen_reg.tex_size);
  42.     int i, j;
  43.     for (i = 0; i < rs_gen_reg.tex_size; i++) {
  44.         for (j = 0; j < rs_gen_reg.tex_size; j++) {
  45.             rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = 0.5 + 0.5*rs_perlin(i, j); // rs_perlin(i, j);
  46.         };
  47.     };
  48. };
  49.  
  50. void rs_gen_func_quads(int dest, float freq, int octaves, float persistence, float seed) {
  51.     rs_perlin_configure(freq, octaves, persistence, seed, rs_gen_reg.tex_size);
  52.     int i, j;
  53.     for (i = 0; i < rs_gen_reg.tex_size; i++) {
  54.         for (j = 0; j < rs_gen_reg.tex_size; j++) {
  55.             rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = 0.5 + 0.5*rs_quad_noise(i, j); // rs_perlin(i, j);
  56.         };
  57.     };
  58. };
  59.  
  60. void rs_gen_func_cell(int dest, int seed, int num_points, signed short* p_arr, float k1, float pow1, float k2, float pow2, float k3, float pow3) {
  61.  
  62.  
  63.     int x[num_points];
  64.     int y[num_points];
  65.  
  66.     int i, j, p, dx, dy;
  67.  
  68.     int ts = rs_gen_reg.tex_size;
  69.  
  70.     float mindist, mindist2, mindist3;
  71.     float dist;
  72.  
  73.     if (p_arr == NULL) {
  74.         for (p = 0; p < num_points; p++) {
  75.                 x[p] = (0.5 + 0.5*rs_noise(p, seed)) * ts;
  76.                 y[p] = (0.5 + 0.5*rs_noise(p, seed+100)) * ts;
  77.         //        x[p] = (p * 18 ) % ts;
  78.         //        y[p] = (p * 33 ) % ts;
  79.         }
  80.     }
  81.     else {
  82.         for (p = 0; p < num_points; p++) {
  83.                 x[p] = rs_gen_reg.cell_scale * p_arr[p*2 + 0];
  84.                 y[p] = rs_gen_reg.cell_scale * p_arr[p*2 + 1];
  85.         //        x[p] = (p * 18 ) % ts;
  86.         //        y[p] = (p * 33 ) % ts;
  87.         }
  88.     };
  89.  
  90.     int cyclic = ((p_arr!=NULL) && (seed!=0)) ? 0 : 1;
  91.  
  92.  
  93. //    float maxdist = 0.0;
  94. //    float mindx, mindy, maxdx, maxdy;
  95.  
  96.     int ind_index = 0;
  97.     int ind_index2 = 0;
  98.  
  99.     for (i = 0; i < ts; i++) {
  100.         for (j = 0; j < ts; j++) {
  101.  
  102.             // distance to near point
  103.             mindist = ts;
  104.             for (p = 0; p < num_points; p++) {
  105.                 dx = (ts/2 - abs( abs(j-x[p]) - ts/2))*cyclic + ( abs(j-x[p]) )*(1-cyclic);
  106.                 dy = (ts/2 - abs( abs(i-y[p]) - ts/2))*cyclic + ( abs(i-y[p]) )*(1-cyclic);
  107.                 dist = sqrtf( RS_SQR(dx) + RS_SQR(dy) );
  108.                 if (dist < mindist) {
  109.                     mindist = dist;
  110.                     ind_index = p;
  111.                 };
  112.             };
  113.  
  114.             mindist2 = ts;
  115.             for (p = 0; p < num_points; p++) {
  116.                 if (p == ind_index) {
  117.                     continue;
  118.                 };
  119.                 dx = (ts/2 - abs( abs(j-x[p]) - ts/2))*cyclic + ( abs(j-x[p]) )*(1-cyclic);
  120.                 dy = (ts/2 - abs( abs(i-y[p]) - ts/2))*cyclic + ( abs(i-y[p]) )*(1-cyclic);
  121.                 dist = sqrtf( RS_SQR(dx) + RS_SQR(dy) );
  122.                 if (dist < mindist2) {
  123.                     mindist2 = dist;
  124.                     ind_index2 = p;
  125.                 };
  126.             };
  127.  
  128.             mindist3 = ts;
  129.             for (p = 0; p < num_points; p++) {
  130.                 if ( (p == ind_index) || (p == ind_index2) ) {
  131.                     continue;
  132.                 };
  133.                 dx = (ts/2 - abs( abs(j-x[p]) - ts/2))*cyclic + ( abs(j-x[p]) )*(1-cyclic);
  134.                 dy = (ts/2 - abs( abs(i-y[p]) - ts/2))*cyclic + ( abs(i-y[p]) )*(1-cyclic);
  135.                 dist = sqrtf( RS_SQR(dx) + RS_SQR(dy) );
  136.                 if (dist < mindist3) {
  137.                     mindist3 = dist;
  138.                 };
  139.             };
  140.  
  141.             rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] =
  142.                 k1*rs_pow(mindist,pow1) + k2*rs_pow(mindist2,pow2) + k3*rs_pow(mindist3,pow3);
  143.             // mindist2 * mindist3 + mindist;
  144.         };
  145.     };
  146.  
  147. };
  148.  
  149. void rs_gen_func_adr(int dest, int src, int adr_x, int adr_y, float src_factor, float adr_factor) {
  150.     int i, j;
  151.     for (i = 0; i < rs_gen_reg.tex_size; i++) {
  152.         for (j = 0; j < rs_gen_reg.tex_size; j++) {
  153.             unsigned short u = src_factor*j + adr_factor*(rs_gen_reg.tex[adr_x*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] - 0.5) * rs_gen_reg.tex_size;
  154.             unsigned short v = src_factor*i + adr_factor*(rs_gen_reg.tex[adr_y*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] - 0.5) * rs_gen_reg.tex_size;
  155.  
  156.             u %= rs_gen_reg.tex_size;
  157.             v %= rs_gen_reg.tex_size;
  158.  
  159.             rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] =
  160.                 rs_gen_reg.tex[src*rs_gen_reg.tex_length + v*rs_gen_reg.tex_size + u];
  161.         };
  162.     };
  163. };
  164.  
  165. void rs_gen_func_normalmap(int dest_r, int dest_g, int dest_b, int src, float k) {
  166.     int i, j;
  167.     float max_val = -111111.0;
  168.     float min_val = 100000.0;
  169.     for (i = 0; i < rs_gen_reg.tex_size; i++) {
  170.         for (j = 0; j < rs_gen_reg.tex_size; j++) {
  171.             unsigned short um = rs_gen_reg.tex_size + j-2;
  172.             unsigned short vm = rs_gen_reg.tex_size + i-2;
  173.  
  174.             unsigned short u = j;
  175.             unsigned short v = i;
  176.  
  177.             unsigned short up = j+2;
  178.             unsigned short vp = i+2;
  179.  
  180.             um  %= rs_gen_reg.tex_size;
  181.             vm  %= rs_gen_reg.tex_size;
  182.             up %= rs_gen_reg.tex_size;
  183.             vp %= rs_gen_reg.tex_size;
  184.  
  185. //            float val1 = rs_gen_reg.tex[src*rs_gen_reg.tex_length + v*rs_gen_reg.tex_size + u];
  186.  
  187.             float val_xp = 2.0 * rs_gen_reg.tex[src*rs_gen_reg.tex_length +  v*rs_gen_reg.tex_size + up]
  188.                 + rs_gen_reg.tex[src*rs_gen_reg.tex_length +  vm*rs_gen_reg.tex_size + up]
  189.                 + rs_gen_reg.tex[src*rs_gen_reg.tex_length +  vp*rs_gen_reg.tex_size + up];
  190.  
  191.             float val_xm = 2.0 * rs_gen_reg.tex[src*rs_gen_reg.tex_length +  v*rs_gen_reg.tex_size + um]
  192.                 + rs_gen_reg.tex[src*rs_gen_reg.tex_length +  vm*rs_gen_reg.tex_size + um]
  193.                 + rs_gen_reg.tex[src*rs_gen_reg.tex_length +  vp*rs_gen_reg.tex_size + um];
  194.  
  195.             float val_yp = 2.0 * rs_gen_reg.tex[src*rs_gen_reg.tex_length +  vp*rs_gen_reg.tex_size + u]
  196.                 + rs_gen_reg.tex[src*rs_gen_reg.tex_length +  vp*rs_gen_reg.tex_size + um]
  197.                 + rs_gen_reg.tex[src*rs_gen_reg.tex_length +  vp*rs_gen_reg.tex_size + up];
  198.  
  199.             float val_ym = 2.0 * rs_gen_reg.tex[src*rs_gen_reg.tex_length +  vm*rs_gen_reg.tex_size + u]
  200.                 + rs_gen_reg.tex[src*rs_gen_reg.tex_length +  vm*rs_gen_reg.tex_size + um]
  201.                 + rs_gen_reg.tex[src*rs_gen_reg.tex_length +  vm*rs_gen_reg.tex_size + up];
  202.  
  203. //            float val_dx = rs_gen_reg.tex[src*rs_gen_reg.tex_length +  v*rs_gen_reg.tex_size + u2] - val1;
  204. //            float val_dy = rs_gen_reg.tex[src*rs_gen_reg.tex_length + v2*rs_gen_reg.tex_size +  u] - val1;
  205.  
  206.             float val_dx = val_xp - val_xm;
  207.             float val_dy = val_yp - val_ym;
  208.  
  209.  
  210.  
  211. //            val_dx = val_dx;
  212. //            val_dy = -val_dy;
  213.  
  214. //            val_dx = atan(val_dx * rs_gen_reg.tex_size ) / (M_PI/2);
  215. //            val_dy = atan(val_dy * rs_gen_reg.tex_size ) / (M_PI/2);
  216.  
  217.             float bump_scale = 128.0 / rs_gen_reg.tex_size / k;
  218.  
  219.             rs_vec3_t bump = rs_vec3_cross( rs_vec3_normalize(rs_vec3(bump_scale, 0.0, val_dy)),
  220.                 rs_vec3_normalize(rs_vec3(0.0, bump_scale, -val_dx)));
  221.  
  222.  
  223.  
  224.             float val_dz = sqrtf( 1.0 - (RS_SQR(k*val_dx) + RS_SQR(k*val_dy)) );
  225. //            val_dz = val_dz;
  226.  
  227. //            val_dz = 1.0 / 2.0;
  228.  
  229.             val_dx = 0.5 + 0.5*val_dx;
  230.             val_dy = 0.5 + 0.5*val_dy;
  231.             val_dz = 0.5 + 0.5*val_dz;
  232.  
  233.             max_val = rs_max(max_val, fabs(val_dx) );
  234. //            max_val = rs_max(max_val, fabs(val_dy) );
  235.             min_val = rs_min(min_val, val_dx);
  236. //            min_val = rs_min(min_val, val_dy);
  237.  
  238. //            rs_gen_reg.tex[dest_r*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = val_dy;
  239. //            rs_gen_reg.tex[dest_g*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = val_dx;
  240. //            rs_gen_reg.tex[dest_b*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = val_dz;
  241.  
  242.             rs_gen_reg.tex[dest_r*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = 0.5 + 0.5*bump.x;
  243.             rs_gen_reg.tex[dest_g*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = 0.5 + 0.5*bump.y;
  244.             rs_gen_reg.tex[dest_b*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = 0.5 + 0.5*bump.z;
  245.  
  246.         };
  247.     };
  248.  
  249. //////    if (max_val < 0.001) {
  250. //////        DEBUG10f("WARNING, max_val of normalmap is too low (%.9f) \n", max_val);
  251. //////        max_val = 0.001;
  252. //////    };
  253. //////
  254. //////    max_val *= 1.0;
  255. //////
  256. //////    for (i = 0; i < rs_gen_reg.tex_size; i++) {
  257. //////        for (j = 0; j < rs_gen_reg.tex_size; j++) {
  258. //////
  259. //////            rs_gen_reg.tex[dest_r*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] /= max_val;
  260. //////            rs_gen_reg.tex[dest_g*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] /= max_val;
  261. //////
  262. //////            rs_gen_reg.tex[dest_b*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] =
  263. //////                sqrtf( 1.0 - (RS_SQR(rs_gen_reg.tex[dest_r*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j])
  264. //////                    + RS_SQR(rs_gen_reg.tex[dest_g*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j])) );
  265. //////
  266. //////
  267. //////            rs_gen_reg.tex[dest_r*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] =
  268. //////                0.5 + 0.5*rs_gen_reg.tex[dest_r*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j];
  269. //////            rs_gen_reg.tex[dest_g*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] =
  270. //////                0.5 + 0.5*rs_gen_reg.tex[dest_g*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j];
  271. //////
  272. //////
  273. ////////            float val_dx = rs_gen_reg.tex[dest_r*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j];
  274. ////////            float val_dy = rs_gen_reg.tex[dest_g*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j];
  275. ////////
  276. ////////            float val_dz = sqrtf( 1.0 - (RS_SQR(k*val_dx) + RS_SQR(k*val_dy)) );
  277. //////
  278. ////////            val_dx = 0.5 + 0.5*k*val_dx;
  279. ////////            val_dy = 0.5 + 0.5*k*val_dy;
  280. ////////            val_dz = 0.5 + 0.5*val_dz;
  281. //////
  282. //////
  283. //////            //rs_gen_reg.tex[dest_b*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = val_dz;
  284. //////
  285. //////        };
  286. //////    };
  287.  
  288.     DEBUG10f("\n\nmax val %.3f \nmin %.3f \n", max_val, min_val);
  289.  
  290. };
  291.  
  292. void rs_gen_func_radial(int dest, float x, float y, float radius, float v, float power) {
  293.     x *= rs_gen_reg.tex_size;
  294.     y *= rs_gen_reg.tex_size;
  295.     radius *= rs_gen_reg.tex_size;
  296.     float val;
  297.     int i, j;
  298.     for (i = 0; i < rs_gen_reg.tex_size; i++) {
  299.         for (j = 0; j < rs_gen_reg.tex_size; j++) {
  300.             val = rs_clamp(sqrt(RS_SQR(j-x) + RS_SQR(i-y)) / radius, 0.0, 1.0);
  301.             val = pow(val, power);
  302.             rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] =
  303.                 rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j]*val + v*(1.0-val); // 0.5 + 0.5*rs_quad_noise(i, j); // rs_perlin(i, j);
  304.         };
  305.     };
  306. };
  307.  
  308. void rs_gen_func_gradient_v(int dest, float v, float power) {
  309.     float val;
  310.     int i, j;
  311.     for (i = 0; i < rs_gen_reg.tex_size; i++) {
  312.         val = rs_clamp( (float) (i) / rs_gen_reg.tex_size, 0.0, 1.0);
  313.         val = pow(val, power);
  314.         for (j = 0; j < rs_gen_reg.tex_size; j++) {
  315.             rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] =
  316.                 rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j]*val + v*(1.0-val); // 0.5 + 0.5*rs_quad_noise(i, j); // rs_perlin(i, j);
  317.         };
  318.     };
  319. };
  320.  
  321. void rs_gen_func_normalize(int dest, float vmin, float vmax) {
  322.  
  323.  
  324.         // LAGGY !!!!!!!!!!!!!
  325.  
  326.     float val_min = rs_gen_reg.tex[dest*rs_gen_reg.tex_length];
  327.     float val_max = rs_gen_reg.tex[dest*rs_gen_reg.tex_length];
  328.     float f;
  329.  
  330.     int i, j;
  331.  
  332.     for (i = 0; i < rs_gen_reg.tex_size; i++) {
  333.         for (j = 0; j < rs_gen_reg.tex_size; j++) {
  334.             f = rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] ;
  335.             val_max = rs_max(val_max, f);
  336.             val_min = rs_min(val_min, f);
  337.         };
  338.     };
  339.  
  340.     float val_scale = (vmax - vmin) / (val_max - val_min) - vmin;
  341.  
  342.     for (i = 0; i < rs_gen_reg.tex_size; i++) {
  343.         for (j = 0; j < rs_gen_reg.tex_size; j++) {
  344.             rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] =
  345.                 vmin + val_scale * ( rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] - val_min);
  346.         };
  347.     };
  348. };
  349.  
  350.  
  351. void rs_gen_func_clamp(int dest, float vmin, float vmax) {
  352.  
  353.     float val;
  354.     int i, j;
  355.     for (i = 0; i < rs_gen_reg.tex_size; i++) {
  356.         for (j = 0; j < rs_gen_reg.tex_size; j++) {
  357.             val = rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j];
  358.             rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] =
  359.                 rs_clamp(val, vmin, vmax);
  360.         };
  361.     };
  362. };
  363.  
  364.  
  365. void rs_gen_func_set(int dest, float val) {
  366.     int i, j;
  367.     for (i = 0; i < rs_gen_reg.tex_size; i++) {
  368.         for (j = 0; j < rs_gen_reg.tex_size; j++) {
  369.             rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = val;
  370.         };
  371.     };
  372. };
  373.  
  374. void rs_gen_func_noise(int dest, int seed) {
  375.     int i, j;
  376.     for (i = 0; i < rs_gen_reg.tex_size; i++) {
  377.         for (j = 0; j < rs_gen_reg.tex_size; j++) {
  378.             rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] = rs_noise(i+seed, j+seed/100);
  379.         };
  380.     };
  381. };
  382.  
  383. void rs_gen_func_add(int dest, int src1, int src2, float k1, float k2) {
  384.     int i;
  385.     for (i = 0; i < rs_gen_reg.tex_length; i++ ) {
  386.         rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i] =
  387.             rs_gen_reg.tex[src1*rs_gen_reg.tex_length + i] * k1
  388.             + rs_gen_reg.tex[src2*rs_gen_reg.tex_length + i] * k2;
  389.     };
  390. };
  391.  
  392. void rs_gen_func_add_lerped(int dest, int src1, int src2, float k1, float k2) {
  393.     int i;
  394.     for (i = 0; i < rs_gen_reg.tex_length; i++ ) {
  395.         rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i] =
  396.             rs_gen_reg.tex[src1*rs_gen_reg.tex_length + i] * (1.0 - 0.5*rs_gen_reg.tex[src2*rs_gen_reg.tex_length + i])
  397.             + (1.0 - 0.5*rs_gen_reg.tex[src1*rs_gen_reg.tex_length + i]) * rs_gen_reg.tex[src2*rs_gen_reg.tex_length + i];
  398.     };
  399. };
  400.  
  401. void rs_gen_func_lerp_parametric(int dest, int src1, int src2, int param) {
  402.     int i;
  403.     for (i = 0; i < rs_gen_reg.tex_length; i++ ) {
  404.         rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i] =
  405.             rs_gen_reg.tex[src1*rs_gen_reg.tex_length + i] * rs_gen_reg.tex[param*rs_gen_reg.tex_length + i]
  406.             + rs_gen_reg.tex[src2*rs_gen_reg.tex_length + i] * (1.0 - rs_gen_reg.tex[param*rs_gen_reg.tex_length + i]);
  407.     };
  408. };
  409.  
  410. void rs_gen_func_mult(int dest, int src1, int src2) {
  411.     int i;
  412.     for (i = 0; i < rs_gen_reg.tex_length; i++ ) {
  413.         rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i] =
  414.             rs_gen_reg.tex[src1*rs_gen_reg.tex_length + i] * rs_gen_reg.tex[src2*rs_gen_reg.tex_length + i];
  415.     };
  416. };
  417.  
  418.  
  419.  
  420.  
  421. void rs_gen_init(int tex_count, int tex_size) {
  422.     rs_gen_reg.tex_count = tex_count;
  423.     rs_gen_reg.tex_size = tex_size;
  424.     rs_gen_reg.tex_length = tex_size*tex_size;
  425.     rs_gen_reg.tex = malloc(tex_count * tex_size * tex_size * 4); // float
  426.     rs_gen_reg.tex_out = malloc(tex_size * tex_size * 4); // unsigned char RGBA, RGB
  427.     rs_gen_tex_out_rgba_set(0.0, 0.0, 0.0, 0.0);
  428. };
  429.  
  430. void rs_gen_term() {
  431.     free(rs_gen_reg.tex);
  432.     free(rs_gen_reg.tex_out);
  433. };
  434.  
  435. void rs_gen_tex_out(int tex, int bpp) {
  436.     int i;
  437.     int j;
  438.     for (i = 0; i < rs_gen_reg.tex_length; i++) {
  439.         for (j = 0; j < bpp; j++) {
  440.             rs_gen_reg.tex_out[i*bpp + j] = 255*rs_gen_reg.tex[tex*rs_gen_reg.tex_length + i];
  441.         };
  442.     };
  443. };
  444.  
  445. void rs_gen_tex_out_rgb(int tex_r, int tex_g, int tex_b, float kr, float kg, float kb) {
  446.     int bpp = 3;
  447.     int i;
  448.     for (i = 0; i < rs_gen_reg.tex_length; i++) {
  449.         rs_gen_reg.tex_out[i*bpp + 0] += 255*kr*rs_gen_reg.tex[tex_r*rs_gen_reg.tex_length + i];
  450.         rs_gen_reg.tex_out[i*bpp + 1] += 255*kg*rs_gen_reg.tex[tex_g*rs_gen_reg.tex_length + i];
  451.         rs_gen_reg.tex_out[i*bpp + 2] += 255*kb*rs_gen_reg.tex[tex_b*rs_gen_reg.tex_length + i];
  452.     };
  453. };
  454.  
  455. void rs_gen_tex_out_rgb_set(float r, float g, float b) {
  456.     int bpp = 3;
  457.     int i;
  458.     for (i = 0; i < rs_gen_reg.tex_length; i++) {
  459.         rs_gen_reg.tex_out[i*bpp + 0] = 255*r;
  460.         rs_gen_reg.tex_out[i*bpp + 1] = 255*g;
  461.         rs_gen_reg.tex_out[i*bpp + 2] = 255*b;
  462.     };
  463. };
  464.  
  465. void rs_gen_tex_out_rgba(int tex_r, int tex_g, int tex_b, int tex_a, float kr, float kg, float kb, float ka) {
  466.     int bpp = 4;
  467.     int i;
  468.     for (i = 0; i < rs_gen_reg.tex_length; i++) {
  469.         rs_gen_reg.tex_out[i*bpp + 0] += 255*kr*rs_gen_reg.tex[tex_r*rs_gen_reg.tex_length + i];
  470.         rs_gen_reg.tex_out[i*bpp + 1] += 255*kg*rs_gen_reg.tex[tex_g*rs_gen_reg.tex_length + i];
  471.         rs_gen_reg.tex_out[i*bpp + 2] += 255*kb*rs_gen_reg.tex[tex_b*rs_gen_reg.tex_length + i];
  472.         rs_gen_reg.tex_out[i*bpp + 3] += (tex_a<0) ? 255 : 255*ka*rs_gen_reg.tex[tex_a*rs_gen_reg.tex_length + i]; // <---- -1 for alpha=1, for KolibriOS
  473.     };
  474. };
  475.  
  476. void rs_gen_tex_out_rgba_set(float r, float g, float b, float a) {
  477.     int bpp = 4;
  478.     int i;
  479.     for (i = 0; i < rs_gen_reg.tex_length; i++) {
  480.         rs_gen_reg.tex_out[i*bpp + 0] = 255*r;
  481.         rs_gen_reg.tex_out[i*bpp + 1] = 255*g;
  482.         rs_gen_reg.tex_out[i*bpp + 2] = 255*b;
  483.         rs_gen_reg.tex_out[i*bpp + 3] = 255*a;
  484.     };
  485. };
  486.  
  487.  
  488. void rs_gen_func_apply_mask(int dest, unsigned char *mask_data) {
  489.    
  490.     int i, j;
  491.     for (i = 0; i < rs_gen_reg.tex_size; i++) {
  492.         for (j = 0; j < rs_gen_reg.tex_size; j++) {
  493.             rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i*rs_gen_reg.tex_size + j] *=
  494.                 (mask_data[ j*rs_gen_reg.tex_size/8 + i/8] & (1 << (7 - (i%8)) ) ) ? 1.0 : 0.0;
  495.         };
  496.     };
  497.    
  498. };
  499.  
  500. void rs_gen_func_posterize(int dest, int colors_count) {
  501.     int i;
  502.     float f;
  503.     for (i = 0; i < rs_gen_reg.tex_length; i++ ) {
  504.         f = rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i];
  505.         f *= (254.0/255.0 + colors_count);
  506.         f = floor(f);
  507.         f /= colors_count;
  508.         rs_gen_reg.tex[dest*rs_gen_reg.tex_length + i] = f;
  509.     };
  510. };
  511.