Модераторы: Snowy, Alexeis, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Draw a polygon with Gouraud shading? 
:(
    Опции темы
Poseidon
Дата 19.5.2005, 01:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: нет
Всего: 133



Код
uses 
  Graphics, Dialogs; 

TRGBFloat = record 
  R : single; 
  G : single; 
  B : single; 
end; 

TPointColor = record 
  X : integer; 
  Y : integer; 
  RGB : TRGBFloat; 
end; 

TPointColorTriangle = array[0..2] of TPointColor; 

{This procedure draws a triangular polygon using Gouraud shading.  
 You specify the position and colour of the 3 corners and it will 
 draw a filled triangle with the colours smoothed out over the  
 surface of the polygon. This is used a lot in 3D graphics for 
 improved rendering of curved surfaces. The procedure is very fast  
 and can be used for realtime 3D animation.} 

// fill a traingular polygon using Gouraud shading 
procedure T3DModel.GouraudPoly(var ABitmap : TBitmap; V : TPointColorTriangle); 
Var 
  LX, RX, Ldx, Rdx : Single; 
  Dif1, Dif2 : Single; 
  LRGB, RRGB, RGB, RGBdx, LRGBdy, RRGBdy : TRGBFloat; 
  RGBT : RGBTriple;                       
  Scan : PRGBTripleArray; 
  y, x, ScanStart, ScanEnd : integer; 
  Vmax : byte; 
  Right : boolean; 
  Temp : TPointColor; 
begin 
  try 

    // sort vertices by Y 
    Vmax := 0; 
    if V[1].Y > V[0].Y then Vmax := 1; 
    if V[2].Y > V[Vmax].Y then Vmax := 2; 
    if Vmax <> 2 then begin 
      Temp := V[2]; 
      V[2] := V[Vmax]; 
      V[Vmax] := Temp; 
    end; 
    if V[1].Y > V[0].Y then Vmax := 1  
                       else Vmax := 0; 
    if Vmax = 0 then begin 
      Temp := V[1]; 
      V[1] := V[0]; 
      V[0] := Temp; 
    end; 

    Dif1 := V[2].Y - V[0].Y; 
    if Dif1 = 0 then Dif1 := 0.001; // prevent EZeroDivide 
    Dif2 := V[1].Y - V[0].Y; 
    if Dif2 = 0 then Dif2 := 0.001; 

    { work out if middle point is to the left or right of the line 
      connecting upper and lower points } 
    if V[1].X > (V[2].X - V[0].X) * Dif2 / Dif1 + V[0].X then Right := True 
                                                         else Right := False; 

    // calculate increments in x and colour for stepping through the lines 
    if Right then begin 
      Ldx := (V[2].X - V[0].X) / Dif1; 
      Rdx := (V[1].X - V[0].X) / Dif2; 
      LRGBdy.B := (V[2].RGB.B - V[0].RGB.B) / Dif1; 
      LRGBdy.G := (V[2].RGB.G - V[0].RGB.G) / Dif1; 
      LRGBdy.R := (V[2].RGB.R - V[0].RGB.R) / Dif1; 
      RRGBdy.B := (V[1].RGB.B - V[0].RGB.B) / Dif2; 
      RRGBdy.G := (V[1].RGB.G - V[0].RGB.G) / Dif2; 
      RRGBdy.R := (V[1].RGB.R - V[0].RGB.R) / Dif2; 
    end else begin 
      Ldx := (V[1].X - V[0].X) / Dif2; 
      Rdx := (V[2].X - V[0].X) / Dif1; 
      RRGBdy.B := (V[2].RGB.B - V[0].RGB.B) / Dif1; 
      RRGBdy.G := (V[2].RGB.G - V[0].RGB.G) / Dif1; 
      RRGBdy.R := (V[2].RGB.R - V[0].RGB.R) / Dif1; 
      LRGBdy.B := (V[1].RGB.B - V[0].RGB.B) / Dif2; 
      LRGBdy.G := (V[1].RGB.G - V[0].RGB.G) / Dif2; 
      LRGBdy.R := (V[1].RGB.R - V[0].RGB.R) / Dif2; 
    end; 

    LRGB := V[0].RGB; 
    RRGB := LRGB; 

    LX := V[0].X; 
    RX := V[0].X; 

    // fill region 1 
    for y := V[0].Y to V[1].Y - 1 do begin 

      // y clipping 
      if y > ABitmap.Height - 1 then Break; 
      if y < 0 then begin 
        LX := LX + Ldx; 
        RX := RX + Rdx; 
        LRGB.B := LRGB.B + LRGBdy.B; 
        LRGB.G := LRGB.G + LRGBdy.G; 
        LRGB.R := LRGB.R + LRGBdy.R; 
        RRGB.B := RRGB.B + RRGBdy.B; 
        RRGB.G := RRGB.G + RRGBdy.G; 
        RRGB.R := RRGB.R + RRGBdy.R; 
        Continue; 
      end; 

      Scan := ABitmap.ScanLine[y]; 

      // calculate increments in color for stepping through pixels 
      Dif1 := RX - LX + 1; 
      if Dif1 = 0 then Dif1 := 0.001; 
      RGBdx.B := (RRGB.B - LRGB.B) / Dif1; 
      RGBdx.G := (RRGB.G - LRGB.G) / Dif1; 
      RGBdx.R := (RRGB.R - LRGB.R) / Dif1; 

      // x clipping 
      if LX < 0 then begin 
        ScanStart := 0; 
        RGB.B := LRGB.B + (RGBdx.B * abs(LX)); 
        RGB.G := LRGB.G + (RGBdx.G * abs(LX)); 
        RGB.R := LRGB.R + (RGBdx.R * abs(LX)); 
      end else begin 
        RGB := LRGB; 
        ScanStart := round(LX); 
      end; 
      if RX - 1 > ABitmap.Width - 1 then ScanEnd := ABitmap.Width - 1 
                                    else ScanEnd := round(RX) - 1; 

      // scan the line 
      for x := ScanStart to ScanEnd do begin 
        RGBT.rgbtBlue := trunc(RGB.B); 
        RGBT.rgbtGreen := trunc(RGB.G); 
        RGBT.rgbtRed := trunc(RGB.R); 
        Scan[x] := RGBT; 
        RGB.B := RGB.B + RGBdx.B; 
        RGB.G := RGB.G + RGBdx.G; 
        RGB.R := RGB.R + RGBdx.R; 
      end; 
      // increment edge x positions 
      LX := LX + Ldx; 
      RX := RX + Rdx; 

      // increment edge colours by the y colour increments 
      LRGB.B := LRGB.B + LRGBdy.B; 
      LRGB.G := LRGB.G + LRGBdy.G; 
      LRGB.R := LRGB.R + LRGBdy.R; 
      RRGB.B := RRGB.B + RRGBdy.B; 
      RRGB.G := RRGB.G + RRGBdy.G; 
      RRGB.R := RRGB.R + RRGBdy.R; 
    end; 

    Dif1 := V[2].Y - V[1].Y; 
    if Dif1 = 0 then Dif1 := 0.001; 
    // calculate new increments for region 2 
    if Right then begin 
      Rdx := (V[2].X - V[1].X) / Dif1; 
      RX := V[1].X; 
      RRGBdy.B := (V[2].RGB.B - V[1].RGB.B) / Dif1; 
      RRGBdy.G := (V[2].RGB.G - V[1].RGB.G) / Dif1; 
      RRGBdy.R := (V[2].RGB.R - V[1].RGB.R) / Dif1; 
      RRGB := V[1].RGB; 
    end else begin 
      Ldx := (V[2].X - V[1].X) / Dif1; 
      LX := V[1].X; 
      LRGBdy.B := (V[2].RGB.B - V[1].RGB.B) / Dif1; 
      LRGBdy.G := (V[2].RGB.G - V[1].RGB.G) / Dif1; 
      LRGBdy.R := (V[2].RGB.R - V[1].RGB.R) / Dif1; 
      LRGB := V[1].RGB; 
    end; 

    // fill region 2 
    for y := V[1].Y to V[2].Y - 1 do begin 

      // y clipping 
      if y > ABitmap.Height - 1 then Break; 
      if y < 0 then begin 
        LX := LX + Ldx; 
        RX := RX + Rdx; 
        LRGB.B := LRGB.B + LRGBdy.B; 
        LRGB.G := LRGB.G + LRGBdy.G; 
        LRGB.R := LRGB.R + LRGBdy.R; 
        RRGB.B := RRGB.B + RRGBdy.B; 
        RRGB.G := RRGB.G + RRGBdy.G; 
        RRGB.R := RRGB.R + RRGBdy.R; 
        Continue; 
      end; 

      Scan := ABitmap.ScanLine[y]; 

      Dif1 := RX - LX + 1; 
      if Dif1 = 0 then Dif1 := 0.001; 
      RGBdx.B := (RRGB.B - LRGB.B) / Dif1; 
      RGBdx.G := (RRGB.G - LRGB.G) / Dif1; 
      RGBdx.R := (RRGB.R - LRGB.R) / Dif1; 

      // x clipping 
      if LX < 0 then begin 
        ScanStart := 0; 
        RGB.B := LRGB.B + (RGBdx.B * abs(LX)); 
        RGB.G := LRGB.G + (RGBdx.G * abs(LX)); 
        RGB.R := LRGB.R + (RGBdx.R * abs(LX)); 
      end else begin 
        RGB := LRGB; 
        ScanStart := round(LX); 
      end; 
      if RX - 1 > ABitmap.Width - 1 then ScanEnd := ABitmap.Width - 1 
                                    else ScanEnd := round(RX) - 1; 

      // scan the line 
      for x := ScanStart to ScanEnd do begin 
        RGBT.rgbtBlue := trunc(RGB.B); 
        RGBT.rgbtGreen := trunc(RGB.G); 
        RGBT.rgbtRed := trunc(RGB.R); 
        Scan[x] := RGBT; 
        RGB.B := RGB.B + RGBdx.B; 
        RGB.G := RGB.G + RGBdx.G; 
        RGB.R := RGB.R + RGBdx.R; 
      end; 

      LX := LX + Ldx; 
      RX := RX + Rdx; 

      LRGB.B := LRGB.B + LRGBdy.B; 
      LRGB.G := LRGB.G + LRGBdy.G; 
      LRGB.R := LRGB.R + LRGBdy.R; 
      RRGB.B := RRGB.B + RRGBdy.B; 
      RRGB.G := RRGB.G + RRGBdy.G; 
      RRGB.R := RRGB.R + RRGBdy.R; 
    end; 

  except 
    ShowMessage('Exception in GouraudPoly Method'); 
  end; 
end; 



--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Звук, графика и видео"
Girder
Snowy
Alexeis

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • По вопросам разработки игр стоит заглянуть сюда

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Girder, Snowy.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Звук, графика и видео | Следующая тема »


 




[ Время генерации скрипта: 0.0823 ]   [ Использовано запросов: 23 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.