⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 triangle.notc

📁 可配置的vga显示控制器
💻 NOTC
字号:
#include "triangle.h"
#include "vga_controller.h"


/******************************************************************
*  Function: min3
*
*  Purpose:  Returns the minimum value of 3 parameters
*
******************************************************************/
inline int max3( int a, int b, int c )
{
  if( a < b )
    a = b;
  if( a < c )
    a = c;
  
  return a;
}

/******************************************************************
*  Function: min3
*
*  Purpose:  Returns the minimum value of 3 parameters
*
******************************************************************/
inline int min3( int a, int b, int c )
{
  if( a > b )
    a = b;
  if( a > c )
    a = c;
  
  return a;
}

/******************************************************************
*  Function: max_diff3
*
*  Purpose:  Returns the positive max difference between 3 
*            parameters.
*
******************************************************************/
int max_diff3(int a, int b, int c)
{
  int max, min;
    
  max = max3( a, b, c );
  min = min3( a, b, c );
  return (max - min);
}

/******************************************************************
*  Function: vga_put_pixel_in_span_map
*
*  Purpose:  This function places a pixel into either the max or
*            min value of an element that represents a span, 
*            essentially just a horizontal line used to fill shapes.
*
******************************************************************/
inline void vga_put_pixel_in_span_map( int x, int y, int *span_array )
{
  if (span_array[y*2] == -1)
  {
    span_array[y*2] = x;
    span_array[(y*2)+1] = x;
  }
  else if( span_array[y*2] > x )
    span_array[y*2] = x;
  else if( span_array[(y*2)+1] < x )
    span_array[(y*2)+1] = x;
}

/******************************************************************
*  Function: vga_bres_scan_edges
*
*  Purpose:  This function uses Bresenham's algorithm to scan a line
*            and determine whether it's the left(min) or right(max)
*            edge of a horizontal span.  This is useful for drawing
*            filled shapes where you fill by drawing successive
*            horizontal lines.
*
******************************************************************/
void vga_bres_scan_edges( int x1, int y1, int x2, int y2, int *span_array) 
{

  int x_incr, y_incr;
  int y_delta, x_delta;

  // Assure we always draw left to right
  if( x1 > x2 )
  {
    int tempx = x2;
    x2 = x1;
    x1 = tempx;
    int tempy = y2;
    y2 = y1;
    y1 = tempy;
  }
  
  // Find the vertical and horizontal distance between the two points
  y_delta = abs(y1-y2);
  x_delta = (x2-x1);

  // Find out what direction we are going
  if (y1 > y2) { y_incr=-1; } else { y_incr=1; }
  x_incr=1;

  // Find out which axis is always incremented when drawing the line
  // If it's the horizontal axis
  if (x_delta >= y_delta) {
    int dPr   = y_delta<<1;
    int dPru  = dPr - (x_delta<<1);
    int P     = dPr - x_delta;

    // Process the line, one horizontal point at at time
    for (; x_delta >= 0; x_delta--) {
      // map the pixel
      vga_put_pixel_in_span_map(x1, y1, span_array);
      // If we're moving along both axis
      if (P > 0) {
        x1+=x_incr;
        y1+=y_incr;
        P+=dPru;
      } else {
        x1+=x_incr;
        P+=dPr;
      }
    }
  }
  else // If it's the vertical axis
  {
    int dPr   = x_delta<<1;
    int dPru  = dPr - (y_delta<<1);
    int P     = dPr - y_delta;

    // Process the line, one vertical point at at time
    for (; y_delta>=0; y_delta--) {
      // plot the pixel
      vga_put_pixel_in_span_map(x1, y1, span_array);
      // If we're moving along both axis
      if (P > 0) {
        x1+=x_incr;
        y1+=y_incr;
        P+=dPru;
      } else {
        y1+=y_incr;
        P+=dPr;
      }
    }
  }
}

/******************************************************************
*  Function: vga_draw_triangle
*
*  Purpose:  This function draws a triangle on the screen between
*            three points defined by the structure tri.
*
******************************************************************/
void vga_draw_triangle(triangle_struct* tri, vga_frame_buffer_struct* vga_frame_buffer)
{
  int i, j;
  
  tri->top_y = min3(tri->ay, tri->by, tri->cy);
  tri->bottom_y = max3(tri->ay, tri->by, tri->cy);
  tri->spans_needed = max_diff3(tri->ay, tri->by, tri->cy);
  tri->max_span = max_diff3(tri->ax, tri->bx, tri->cx);
  tri->span_array = malloc(vga_frame_buffer->height * 4 * 2);

  //init the span array
  for( i = tri->top_y; i <= tri->bottom_y; i++)
  {
    tri->span_array[i*2] = -1;
    tri->span_array[(i*2) + 1] = -1;
  }
    
  // Scan-convert the triangle  
  vga_bres_scan_edges( tri->ax, tri->ay, 
                       tri->bx, tri->by, tri->span_array);
  vga_bres_scan_edges( tri->bx, tri->by, 
                       tri->cx, tri->cy, tri->span_array);
  vga_bres_scan_edges( tri->cx, tri->cy, 
                       tri->ax, tri->ay, tri->span_array);
  
  // Render the polygon
  for( i = tri->top_y; i <= tri->bottom_y; i++ )
  {
    vga_draw_horiz_line (tri->span_array[i*2], tri->span_array[(i*2)+1], i, tri->col, vga_frame_buffer);
  }
  free(tri->span_array);

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -