<legend id='8cscB'><style id='8cscB'><dir id='8cscB'><q id='8cscB'></q></dir></style></legend>

  • <small id='8cscB'></small><noframes id='8cscB'>

      <i id='8cscB'><tr id='8cscB'><dt id='8cscB'><q id='8cscB'><span id='8cscB'><b id='8cscB'><form id='8cscB'><ins id='8cscB'></ins><ul id='8cscB'></ul><sub id='8cscB'></sub></form><legend id='8cscB'></legend><bdo id='8cscB'><pre id='8cscB'><center id='8cscB'></center></pre></bdo></b><th id='8cscB'></th></span></q></dt></tr></i><div id='8cscB'><tfoot id='8cscB'></tfoot><dl id='8cscB'><fieldset id='8cscB'></fieldset></dl></div>

        • <bdo id='8cscB'></bdo><ul id='8cscB'></ul>

      1. <tfoot id='8cscB'></tfoot>

        C++三角形光栅化

        时间:2023-09-27
        <i id='1aiKU'><tr id='1aiKU'><dt id='1aiKU'><q id='1aiKU'><span id='1aiKU'><b id='1aiKU'><form id='1aiKU'><ins id='1aiKU'></ins><ul id='1aiKU'></ul><sub id='1aiKU'></sub></form><legend id='1aiKU'></legend><bdo id='1aiKU'><pre id='1aiKU'><center id='1aiKU'></center></pre></bdo></b><th id='1aiKU'></th></span></q></dt></tr></i><div id='1aiKU'><tfoot id='1aiKU'></tfoot><dl id='1aiKU'><fieldset id='1aiKU'></fieldset></dl></div>

          1. <small id='1aiKU'></small><noframes id='1aiKU'>

                <tbody id='1aiKU'></tbody>
              1. <tfoot id='1aiKU'></tfoot><legend id='1aiKU'><style id='1aiKU'><dir id='1aiKU'><q id='1aiKU'></q></dir></style></legend>
                • <bdo id='1aiKU'></bdo><ul id='1aiKU'></ul>
                  本文介绍了C++三角形光栅化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在尝试修复此三角形光栅化器,但无法使其正常工作.出于某种原因,它只绘制了一半的三角形.

                  I'm trying to fix this triangle rasterizer, but cannot make it work correctly. For some reason it only draws half of the triangles.

                  void DrawTriangle(Point2D p0, Point2D p1, Point2D p2)
                  {
                      Point2D Top, Middle, Bottom;
                      bool MiddleIsLeft;
                  
                      if (p0.y < p1.y)                    // case: 1, 2, 5
                      {
                          if (p0.y < p2.y)                // case: 1, 2
                          {
                              if (p1.y < p2.y)            // case: 1
                              {
                                  Top = p0;
                                  Middle = p1;
                                  Bottom = p2;
                                  MiddleIsLeft = true;
                              }
                              else                        // case: 2
                              {
                                  Top = p0;
                                  Middle = p2;
                                  Bottom = p1;
                                  MiddleIsLeft = false;
                              }
                          }
                          else                            // case: 5
                          {
                              Top = p2;
                              Middle = p0;
                              Bottom = p1;
                              MiddleIsLeft = true;                
                          }
                      }
                      else                        // case: 3, 4, 6
                      {
                          if (p0.y < p2.y)        // case: 4
                          {
                              Top = p1;
                              Middle = p0;
                              Bottom = p2;
                              MiddleIsLeft = false;
                          }
                          else                    // case: 3, 6
                          {
                              if (p1.y < p2.y)    // case: 3
                              {
                                  Top = p1;
                                  Middle = p2;
                                  Bottom = p0;
                                  MiddleIsLeft = true;
                              }
                              else                // case 6
                              {
                                  Top = p2;
                                  Middle = p1;
                                  Bottom = p0;
                                  MiddleIsLeft = false;
                              }
                          }
                      }
                  
                      float xLeft, xRight;
                      xLeft = xRight = Top.x;
                      float mLeft, mRight;
                      // Region 1
                      if(MiddleIsLeft)
                      {
                          mLeft = (Top.x - Middle.x) / (Top.y - Middle.y);
                          mRight = (Top.x - Bottom.x) / (Top.y - Bottom.y);
                      }
                      else
                      {
                          mLeft = (Top.x - Bottom.x) / (Top.y - Bottom.y);
                          mRight = (Middle.x - Top.x) / (Middle.y - Top.y);
                      }
                      int finalY;
                      float Tleft, Tright;
                      for (int y = ceil(Top.y); y < (int)Middle.y; y++)
                      {        
                          Tleft=float(Top.y-y)/(Top.y-Middle.y);
                          Tright=float(Top.y-y)/(Top.y-Bottom.y);
                          for (int x = ceil(xLeft); x <= ceil(xRight) - 1 ; x++)
                          {
                              FrameBuffer::SetPixel(x, y, p0.r,p0.g,p0.b);
                  
                          }  
                          xLeft += mLeft;
                          xRight += mRight;
                          finalY = y;
                      }
                  
                      // Region 2 
                      if (MiddleIsLeft)
                      {
                          mLeft = (Bottom.x - Middle.x) / (Bottom.y - Middle.y);
                      }
                      else
                      {
                          mRight = (Middle.x - Bottom.x) / (Middle.y - Bottom.y);
                      }
                  
                      for (int y = Middle.y; y <= ceil(Bottom.y) - 1; y++)
                      {
                          Tleft=float(Bottom.y-y)/(Bottom.y-Middle.y);
                          Tright=float(Top.y-y)/(Top.y-Bottom.y);
                          for (int x = ceil(xLeft); x <= ceil(xRight) - 1; x++)
                          {
                              FrameBuffer::SetPixel(x, y, p0.r,p0.g,p0.b);
                          }
                          xLeft += mLeft;
                          xRight += mRight; 
                  
                      }
                  }
                  

                  这是我使用它绘制形状时发生的情况.

                  Here is what happens when I use it to draw shapes.

                  当我禁用第二个区域时,所有那些奇怪的三角形都消失了.

                  When I disable the second region, all those weird triangles disappear.

                  线框模式完美运行,因此消除了除三角形光栅化器之外的所有其他可能性.

                  The wireframe mode works perfect, so this eliminates all the other possibilities other than the triangle rasterizer.

                  推荐答案

                  我有点迷失在你的实现中,但这就是我所做的(我有一个稍微复杂的任意凸多边形版本,而不仅仅是三角形)并且我想想除了 Bresenham 的算法之外,它非常简单(实际上算法也很简单):

                  I kind of got lost in your implementation, but here's what I do (I have a slightly more complex version for arbitrary convex polygons, not just triangles) and I think apart from the Bresenham's algorithm it's very simple (actually the algorithm is simple too):

                  #include <stddef.h>
                  #include <limits.h>
                  #include <stdlib.h>
                  #include <stdio.h>
                  #include <string.h>
                  #include <time.h>
                  
                  #define SCREEN_HEIGHT 22
                  #define SCREEN_WIDTH  78
                  
                  // Simulated frame buffer
                  char Screen[SCREEN_HEIGHT][SCREEN_WIDTH];
                  
                  void SetPixel(long x, long y, char color)
                  {
                    if ((x < 0) || (x >= SCREEN_WIDTH) ||
                        (y < 0) || (y >= SCREEN_HEIGHT))
                    {
                      return;
                    }
                  
                    Screen[y][x] = color;
                  }
                  
                  void Visualize(void)
                  {
                    long x, y;
                  
                    for (y = 0; y < SCREEN_HEIGHT; y++)
                    {
                      for (x = 0; x < SCREEN_WIDTH; x++)
                      {
                        printf("%c", Screen[y][x]);
                      }
                  
                      printf("
                  ");
                    }
                  }
                  
                  typedef struct
                  {
                    long x, y;
                    unsigned char color;
                  } Point2D;
                  
                  
                  // min X and max X for every horizontal line within the triangle
                  long ContourX[SCREEN_HEIGHT][2];
                  
                  #define ABS(x) ((x >= 0) ? x : -x)
                  
                  // Scans a side of a triangle setting min X and max X in ContourX[][]
                  // (using the Bresenham's line drawing algorithm).
                  void ScanLine(long x1, long y1, long x2, long y2)
                  {
                    long sx, sy, dx1, dy1, dx2, dy2, x, y, m, n, k, cnt;
                  
                    sx = x2 - x1;
                    sy = y2 - y1;
                  
                    if (sx > 0) dx1 = 1;
                    else if (sx < 0) dx1 = -1;
                    else dx1 = 0;
                  
                    if (sy > 0) dy1 = 1;
                    else if (sy < 0) dy1 = -1;
                    else dy1 = 0;
                  
                    m = ABS(sx);
                    n = ABS(sy);
                    dx2 = dx1;
                    dy2 = 0;
                  
                    if (m < n)
                    {
                      m = ABS(sy);
                      n = ABS(sx);
                      dx2 = 0;
                      dy2 = dy1;
                    }
                  
                    x = x1; y = y1;
                    cnt = m + 1;
                    k = n / 2;
                  
                    while (cnt--)
                    {
                      if ((y >= 0) && (y < SCREEN_HEIGHT))
                      {
                        if (x < ContourX[y][0]) ContourX[y][0] = x;
                        if (x > ContourX[y][1]) ContourX[y][1] = x;
                      }
                  
                      k += n;
                      if (k < m)
                      {
                        x += dx2;
                        y += dy2;
                      }
                      else
                      {
                        k -= m;
                        x += dx1;
                        y += dy1;
                      }
                    }
                  }
                  
                  void DrawTriangle(Point2D p0, Point2D p1, Point2D p2)
                  {
                    int y;
                  
                    for (y = 0; y < SCREEN_HEIGHT; y++)
                    {
                      ContourX[y][0] = LONG_MAX; // min X
                      ContourX[y][1] = LONG_MIN; // max X
                    }
                  
                    ScanLine(p0.x, p0.y, p1.x, p1.y);
                    ScanLine(p1.x, p1.y, p2.x, p2.y);
                    ScanLine(p2.x, p2.y, p0.x, p0.y);
                  
                    for (y = 0; y < SCREEN_HEIGHT; y++)
                    {
                      if (ContourX[y][1] >= ContourX[y][0])
                      {
                        long x = ContourX[y][0];
                        long len = 1 + ContourX[y][1] - ContourX[y][0];
                  
                        // Can draw a horizontal line instead of individual pixels here
                        while (len--)
                        {
                          SetPixel(x++, y, p0.color);
                        }
                      }
                    }
                  }
                  
                  int main(void)
                  {
                    Point2D p0, p1, p2;
                  
                    // clear the screen
                    memset(Screen, ' ', sizeof(Screen));
                  
                    // generate random triangle coordinates
                    srand((unsigned)time(NULL));
                  
                    p0.x = rand() % SCREEN_WIDTH;
                    p0.y = rand() % SCREEN_HEIGHT;
                  
                    p1.x = rand() % SCREEN_WIDTH;
                    p1.y = rand() % SCREEN_HEIGHT;
                  
                    p2.x = rand() % SCREEN_WIDTH;
                    p2.y = rand() % SCREEN_HEIGHT;
                  
                    // draw the triangle
                    p0.color = '1';
                    DrawTriangle(p0, p1, p2);
                  
                    // also draw the triangle's vertices
                    SetPixel(p0.x, p0.y, '*');
                    SetPixel(p1.x, p1.y, '*');
                    SetPixel(p2.x, p2.y, '*');
                  
                    Visualize();
                  
                    return 0;
                  }
                  

                  输出:

                     *111111
                      1111111111111
                        111111111111111111
                           1111111111111111111111
                             111111111111111111111111111
                               11111111111111111111111111111111
                                  111111111111111111111111111111111111
                                    11111111111111111111111111111111111111111
                                      111111111111111111111111111111111111111*
                                         11111111111111111111111111111111111
                                           1111111111111111111111111111111
                                              111111111111111111111111111
                                                11111111111111111111111
                                                  1111111111111111111
                                                     11111111111111
                                                       11111111111
                                                         1111111
                                                            1*
                  

                  这篇关于C++三角形光栅化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:DirectX 11 帧缓冲区捕获(C++,无 Win32 或 D3DX) 下一篇:光栅化二维多边形

                  相关文章

                • <legend id='WhyXi'><style id='WhyXi'><dir id='WhyXi'><q id='WhyXi'></q></dir></style></legend>

                  <small id='WhyXi'></small><noframes id='WhyXi'>

                  <i id='WhyXi'><tr id='WhyXi'><dt id='WhyXi'><q id='WhyXi'><span id='WhyXi'><b id='WhyXi'><form id='WhyXi'><ins id='WhyXi'></ins><ul id='WhyXi'></ul><sub id='WhyXi'></sub></form><legend id='WhyXi'></legend><bdo id='WhyXi'><pre id='WhyXi'><center id='WhyXi'></center></pre></bdo></b><th id='WhyXi'></th></span></q></dt></tr></i><div id='WhyXi'><tfoot id='WhyXi'></tfoot><dl id='WhyXi'><fieldset id='WhyXi'></fieldset></dl></div>

                  1. <tfoot id='WhyXi'></tfoot>

                        <bdo id='WhyXi'></bdo><ul id='WhyXi'></ul>