Advertisement
D3ad

Untitled

May 3rd, 2015
292
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.38 KB | None | 0 0
  1. void studrenDrawTriangle(S_Renderer *pRenderer,
  2.     S_Coords *v1, S_Coords *v2, S_Coords *v3,
  3.     S_Coords *n1, S_Coords *n2, S_Coords *n3,
  4.     int x1, int y1,
  5.     int x2, int y2,
  6.     int x3, int y3
  7.     )
  8. {
  9.     /* zaklad fce zkopirujte z render.c */
  10.  
  11.     int         minx, miny, maxx, maxy;
  12.     int         a1, a2, a3, b1, b2, b3, c1, c2, c3;
  13.     int         /*s1,*/ s2, s3;
  14.     int         x, y, e1, e2, e3;
  15.     double      alpha, beta, w1, w2, w3, z;
  16.     S_RGBA      col1, col2, col3, color;
  17.  
  18.     IZG_ASSERT(pRenderer && v1 && v2 && v3 && n1 && n2 && n3);
  19.  
  20.     /* vypocet barev ve vrcholech */
  21.     col1 = pRenderer->calcReflectanceFunc(pRenderer, v1, n1);
  22.     col2 = pRenderer->calcReflectanceFunc(pRenderer, v2, n2);
  23.     col3 = pRenderer->calcReflectanceFunc(pRenderer, v3, n3);
  24.  
  25.     /* obalka trojuhleniku */
  26.     minx = MIN(x1, MIN(x2, x3));
  27.     maxx = MAX(x1, MAX(x2, x3));
  28.     miny = MIN(y1, MIN(y2, y3));
  29.     maxy = MAX(y1, MAX(y2, y3));
  30.  
  31.     /* oriznuti podle rozmeru okna */
  32.     miny = MAX(miny, 0);
  33.     maxy = MIN(maxy, pRenderer->frame_h - 1);
  34.     minx = MAX(minx, 0);
  35.     maxx = MIN(maxx, pRenderer->frame_w - 1);
  36.  
  37.     /* vektory urcene vrcholy 1-2 a 1-3 */
  38.     a1 = x2 - x1;
  39.     a3 = x3 - x1;
  40.     b1 = y2 - y1;
  41.     b3 = y3 - y1;
  42.  
  43.     /* overeni counterclockwise orientace troj. pomoci vektoroveho soucinu */
  44.     if ((a1 * b3 - b1 * a3) < 0)
  45.     {
  46.         /* spatna orientace -> prohodime vrcholy 2 a 3 */
  47.         SWAP(x2, x3);
  48.         SWAP(y2, y3);
  49.  
  50.         /* a take barvy vrcholu */
  51.         SWAP(col2.red, col3.red);
  52.         SWAP(col2.green, col3.green);
  53.         SWAP(col2.blue, col3.blue);
  54.         SWAP(col2.alpha, col3.alpha);
  55.     }
  56.  
  57.     /* Pineduv alg. rasterizace troj.
  58.     hranova fce je obecna rovnice primky Ax + By + C = 0
  59.     primku prochazejici body (x1, y1) a (x2, y2) urcime jako
  60.     (y1 - y2)x + (x2 - x1)y + x1y2 - x2y1 = 0 */
  61.  
  62.     /* normala primek - vektor kolmy k vektoru mezi dvema vrcholy, tedy (-dy, dx) */
  63.     a1 = y1 - y2;
  64.     a2 = y2 - y3;
  65.     a3 = y3 - y1;
  66.     b1 = x2 - x1;
  67.     b2 = x3 - x2;
  68.     b3 = x1 - x3;
  69.  
  70.     /* koeficient C */
  71.     c1 = x1 * y2 - x2 * y1;
  72.     c2 = x2 * y3 - x3 * y2;
  73.     c3 = x3 * y1 - x1 * y3;
  74.  
  75.     /* vypocet hranove fce (vzdalenost od primky) pro protejsi body */
  76.     /*s1 = a1 * x3 + b1 * y3 + c1;*/
  77.     s2 = a2 * x1 + b2 * y1 + c2;
  78.     s3 = a3 * x2 + b3 * y2 + c3;
  79.  
  80.     /* uprava koeficientu C pro korektni vyplnovani, viz "OpenGL top-left rule" */
  81.     /* https://books.google.cz/books?id=3ljRBQAAQBAJ&pg=PA73 */
  82.     if ((y1 == y2 && x2 > x1) || y2 < y1)
  83.     {
  84.         c1 -= 1;
  85.     }
  86.     if ((y2 == y3 && x3 > x2) || y3 < y2)
  87.     {
  88.         c2 -= 1;
  89.     }
  90.     if ((y3 == y1 && x1 > x3) || y1 < y3)
  91.     {
  92.         c3 -= 1;
  93.     }
  94.  
  95.     /* koeficienty pro barycentricke souradnice */
  96.     alpha = 1.0 / (ABS(s2) + 1);
  97.     beta = 1.0 / (ABS(s3) + 1);
  98.  
  99.     /* vyplnovani... */
  100.     for (y = miny; y <= maxy; ++y)
  101.     {
  102.         /* inicilizace hranove fce v bode (minx, y) */
  103.         e1 = a1 * minx + b1 * y + c1;
  104.         e2 = a2 * minx + b2 * y + c2;
  105.         e3 = a3 * minx + b3 * y + c3;
  106.  
  107.         for (x = minx; x <= maxx; ++x)
  108.         {
  109.             if (e1 >= 0 && e2 >= 0 && e3 >= 0)
  110.             {
  111.                 /* interpolace pomoci barycentrickych souradnic
  112.                 e1, e2, e3 je aktualni vzdalenost bodu (x, y) od primek */
  113.                 w1 = alpha * e2;
  114.                 w2 = beta * e3;
  115.                 w3 = 1.0 - w1 - w2;
  116.  
  117.                 /* interpolace z-souradnice */
  118.                 z = w1 * v1->z + w2 * v2->z + w3 * v3->z;
  119.  
  120.                 /* interpolace barvy */
  121.                 color.red = ROUND2BYTE(w1 * col1.red + w2 * col2.red + w3 * col3.red);
  122.                 color.green = ROUND2BYTE(w1 * col1.green + w2 * col2.green + w3 * col3.green);
  123.                 color.blue = ROUND2BYTE(w1 * col1.blue + w2 * col2.blue + w3 * col3.blue);
  124.                 color.alpha = ROUND2BYTE(w1 * col1.alpha + w2 * col2.alpha + w3 * col3.alpha);
  125.  
  126.                 /* ukazatel na studentsky renderer */
  127.                 S_StudentRenderer   * renderer;
  128.                 renderer = (S_StudentRenderer *)pRenderer;
  129.  
  130.                 /* index pixelu */
  131.                 int pixelIndex = x + y * pRenderer->frame_w;
  132.  
  133.                 /* hodnota pixelu na danem indexu */
  134.                 int pixelValue = ivecGet(renderer->buffer1, pixelIndex);
  135.  
  136.                 /* pokud je hodnota pixelu -1, tak vytvorim fragment a nenastavuji naslednika
  137.                 a nasledne index vytvoreneho fragmentu ulozim do HEAD_POINT_BUFFERU
  138.                 */
  139.                 if (pixelValue == -1)
  140.                 {
  141.                     S_Frag fragment = makeFrag((S_RGBA){ color.red, color.green, color.blue, color.alpha }, z, -1);
  142.                     int nextIndex = fragvecPushBack(renderer->buffer2, fragment);
  143.                     ivecSet(renderer->buffer1, pixelIndex, nextIndex);
  144.                 }
  145.                 /* pokud je hodnota jina nez -1 tak vytvorim fragment a jako naslednika dam nasledujici pixel
  146.                 nasledne ulozim index vytvoreneho fragmentu do HEAD_POINT_BUFFERU
  147.                 */
  148.                 else
  149.                 {
  150.                     int pixelValue = ivecGet(renderer->buffer1, pixelIndex);
  151.                     S_Frag fragment = makeFrag((S_RGBA){ color.red, color.green, color.blue, color.alpha }, z, pixelValue);
  152.                     int nextIndex = fragvecPushBack(renderer->buffer2, fragment);
  153.                     ivecSet(renderer->buffer1, pixelIndex, nextIndex);
  154.                 }
  155.             }
  156.  
  157.             /* hranova fce o pixel vedle */
  158.             e1 += a1;
  159.             e2 += a2;
  160.             e3 += a3;
  161.         }
  162.     }
  163. }
  164.  
  165. void studrenProjectTriangle(S_Renderer *pRenderer, S_Model *pModel, int i)
  166. {
  167.     /* zaklad fce zkopirujte z render.c */
  168.     /* ??? */
  169.     S_Coords    aa, bb, cc;             /* souradnice vrcholu po transformaci */
  170.     S_Coords    naa, nbb, ncc;          /* normaly ve vrcholech po transformaci */
  171.     S_Coords    nn;                     /* normala trojuhelniku po transformaci */
  172.     int         u1, v1, u2, v2, u3, v3; /* souradnice vrcholu po projekci do roviny obrazovky */
  173.     S_Triangle  * triangle;
  174.  
  175.     IZG_ASSERT(pRenderer && pModel && i >= 0 && i < trivecSize(pModel->triangles));
  176.  
  177.     /* z modelu si vytahneme trojuhelnik */
  178.     triangle = trivecGetPtr(pModel->triangles, i);
  179.  
  180.     /* transformace vrcholu matici model */
  181.     trTransformVertex(&aa, cvecGetPtr(pModel->vertices, triangle->v[0]));
  182.     trTransformVertex(&bb, cvecGetPtr(pModel->vertices, triangle->v[1]));
  183.     trTransformVertex(&cc, cvecGetPtr(pModel->vertices, triangle->v[2]));
  184.  
  185.     /* promitneme vrcholy trojuhelniku na obrazovku */
  186.     trProjectVertex(&u1, &v1, &aa);
  187.     trProjectVertex(&u2, &v2, &bb);
  188.     trProjectVertex(&u3, &v3, &cc);
  189.  
  190.     /* pro osvetlovaci model transformujeme take normaly ve vrcholech */
  191.     trTransformVector(&naa, cvecGetPtr(pModel->normals, triangle->v[0]));
  192.     trTransformVector(&nbb, cvecGetPtr(pModel->normals, triangle->v[1]));
  193.     trTransformVector(&ncc, cvecGetPtr(pModel->normals, triangle->v[2]));
  194.  
  195.     /* normalizace normal */
  196.     coordsNormalize(&naa);
  197.     coordsNormalize(&nbb);
  198.     coordsNormalize(&ncc);
  199.  
  200.     /* transformace normaly trojuhelniku matici model */
  201.     trTransformVector(&nn, cvecGetPtr(pModel->trinormals, triangle->n));
  202.  
  203.     /* normalizace normaly */
  204.     coordsNormalize(&nn);
  205.  
  206.  
  207.     /* rasterizace trojuhelniku - zavolam svou funci*/
  208.     studrenDrawTriangle(pRenderer,
  209.         &aa, &bb, &cc,
  210.         &naa, &nbb, &ncc,
  211.         u1, v1, u2, v2, u3, v3
  212.         );
  213. }
  214.  
  215. void renderStudentScene(S_Renderer *pRenderer, S_Model *pModel)
  216. {
  217.     S_Matrix backup;
  218.     /*####################################################################
  219.     ######################################################################
  220.     cerveny kralik
  221.     ######################################################################
  222.     ####################################################################*/
  223.     /* test existence frame bufferu a modelu */
  224.     IZG_ASSERT(pModel && pRenderer);
  225.  
  226.     /* nastavit projekcni matici */
  227.     trProjectionPerspective(pRenderer->camera_dist, pRenderer->frame_w, pRenderer->frame_h);
  228.  
  229.     /* vycistit model matici */
  230.     trLoadIdentity();
  231.     trGetMatrix(&backup);
  232.     /* nejprve nastavime posuv cele sceny od/ke kamere */
  233.  
  234.     trTranslate(0.0, 0.0, pRenderer->scene_move_z);
  235.  
  236.     /* nejprve nastavime posuv cele sceny v rovine XY */
  237.     trTranslate(pRenderer->scene_move_x, pRenderer->scene_move_y, 0.0);
  238.  
  239.     /* natoceni cele sceny - jen ve dvou smerech - mys je jen 2D... :( */
  240.     trRotateX(pRenderer->scene_rot_x);
  241.     trRotateY(pRenderer->scene_rot_y);
  242.  
  243.  
  244.  
  245.     trTranslate(pRenderer->scene_move_x - 1.3, 0.0, 0.0);
  246.     /* nastavime material */
  247.     renMatAmbient(pRenderer, &MAT_RED_AMBIENT);
  248.     renMatDiffuse(pRenderer, &MAT_RED_DIFFUSE);
  249.     renMatSpecular(pRenderer, &MAT_RED_SPECULAR);
  250.  
  251.     /* a vykreslime nas model */
  252.     renderModel(pRenderer, pModel);
  253.  
  254.     /*####################################################################
  255.     ######################################################################
  256.     zeleny kralik
  257.     ######################################################################
  258.     ####################################################################*/
  259.  
  260.  
  261.     /* nejprve nastavime posuv cele sceny od/ke kamere */
  262.  
  263.     trSetMatrix(&backup);
  264.     trTranslate(0.0, 0.0, pRenderer->scene_move_z);
  265.  
  266.     /* nejprve nastavime posuv cele sceny v rovine XY */
  267.     trTranslate(pRenderer->scene_move_x, pRenderer->scene_move_y, 0.0);
  268.  
  269.     /* natoceni cele sceny - jen ve dvou smerech - mys je jen 2D... :( */
  270.     trRotateX(pRenderer->scene_rot_x);
  271.     trRotateY(pRenderer->scene_rot_y);
  272.  
  273.  
  274.  
  275.     trTranslate(pRenderer->scene_move_x + 1.3, 0.0, 0.0);
  276.     /* nastavime material */
  277.     renMatAmbient(pRenderer, &MAT_STUD_AMBIENT);
  278.     renMatDiffuse(pRenderer, &MAT_STUD_DIFFUSE);
  279.     renMatSpecular(pRenderer, &MAT_STUD_SPECULAR);
  280.  
  281.     /* a vykreslime nas model */
  282.     renderModel(pRenderer, pModel);
  283.    
  284.     S_StudentRenderer   * renderer;
  285.     renderer = (S_StudentRenderer *)pRenderer;
  286.     S_RGBA dst;
  287.     dst.red = 0;
  288.     dst.green = 0;
  289.     dst.blue = 0;
  290.     dst.alpha = 0;
  291.  
  292.     for (int i = 0; i < fragvecSize(renderer->buffer1); i++){
  293.         S_RGBA src = fragvecGetPtr(renderer->buffer1, i)->color;
  294.  
  295.         float Asrc = src.alpha / 255.0;
  296.        
  297.         dst.red += src.alpha*src.red;
  298.         dst.green += src.alpha*src.green;
  299.         dst.blue += src.alpha*src.blue;
  300.         dst.alpha *= 1 - Asrc;
  301.        
  302.     }
  303.     renderModel(renderer, pModel);
  304. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement