Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.02.04;
Скачать: CL | DM;

Вниз

Как вклеить текстуру на текстуру, чтобы края плавно переходили из   Найти похожие ветки 

 
Марс   (2007-01-16 04:31) [0]

одной в другую?

CopyRect - просто копирует картинку на картинку. Поэтому переход между ними слишком заметен. А надо как-то так, чтобы переход был плавным. Какое-то комбинирование пикселей что-ли. Или что-то типа этого. Немного поэксперементировал, но получается плохо.

Может у кого есть такая функция? Или кто-нибудь знает как правильно решать эту проблему?

Текстуры более менее похожи. Там земля-трава, и т. п.


 
ors_archangel ©   (2007-01-16 05:37) [1]

AlphaBlend(destDC, dx,dy, w,h, srcDC, sx,sy, w,h, blend); // Win98/2k
где blend: TBlendFunction, код вызова примерно такой может быть

   blend.BlendOp := AC_SRC_OVER;
   blend.BlendFlags := 0;
   blend.SourceConstantAlpha := alpha;
   blend.AlphaFormat := 0;
   AlphaBlend(destDC, dx,dy, w,h, srcDC, sx,sy, w,h, blend);


 
Марс   (2007-01-16 06:09) [2]


> ors_archangel ©   (16.01.07 05:37) [1]
>
> AlphaBlend(destDC, dx,dy, w,h, srcDC, sx,sy, w,h, blend);
>  // Win98/2k


Надо чтобы на 98 работала! Жертвовать совместимостью из-за такой фигни нельзя!


 
ors_archangel ©   (2007-01-16 06:12) [3]

Млин, я же пишу Win98/2k - то бишь  Included in Windows 98 and later :)


 
Марс   (2007-01-16 06:45) [4]

А как использовать то с TBitMap ?
Чёто я не найду эту функцию в справке.


 
antonn ©   (2007-01-16 14:06) [5]

procedure CopyBitmapAlfa32to24(var _B_in,_B_out:Tbitmap; _x,_y:integer);
const
 MaxPixelCountA = MaxInt div SizeOf(TRGBQuad);
 MaxPixelCount = MaxInt div SizeOf(TRGBTriple);
type
 PRGBArray = ^TRGBArray;
 TRGBArray = array[0..MaxPixelCount-1] of TRGBTriple;
 PRGBAArray = ^TRGBAArray;
 TRGBAArray = array[0..MaxPixelCountA-1] of TRGBQuad;
var x, y: Integer; _r,_b,_g:integer;
   w_in,h_in,w_out,h_out,tmp,x_cor,y_cor,x_corS,y_corS: Integer;
   RowOut:PRGBArray; RowIn:PRGBAArray;
   _d,_dd:double;
begin
w_in:=_B_in.Width;
h_in:=_B_in.Height;
w_out:=_B_out.Width;
h_out:=_B_out.Height;
if (_x)>w_out-1 then exit; if (_x+w_out)<0 then exit;
if (_y)>h_out-1 then exit; if (_y+h_out)<0 then exit;

if _x<0 then x_corS:=abs(_x) else x_corS:=0;
if _y<0 then y_corS:=abs(_y) else y_corS:=0;
if (_x+w_in)>w_out then x_cor:=_x+w_in-w_out else x_cor:=0;
if (_y+h_in)>h_out then y_cor:=_y+h_in-h_out else y_cor:=0;

 y_cor:=h_in-1-y_cor;
 tmp:=w_in-1-x_cor; _dd:=(100/255)/100;
 for y:=y_corS to y_cor do begin
    RowOut:= _B_out.ScanLine[y+_y];
    RowIn:= _B_in.ScanLine[y];
   for x:=x_corS to tmp do begin
        _d:=RowIn[x].rgbReserved*_dd;

         _r:= trunc(RowOut[x+_x].rgbtRed+(RowIn[x].rgbRed-RowOut[x+_x].rgbtRed)*_d);
        if _r>255 then _r:=255 else if _r<0 then _r:=0;

        _g:= trunc(RowOut[x+_x].rgbtGreen+(RowIn[x].rgbGreen-RowOut[x+_x].rgbtGreen)*_d);
        if _g>255 then _g:=255 else if _g<0 then _g:=0;

        _b:= trunc(RowOut[x+_x].rgbtBlue+(RowIn[x].rgbBlue-RowOut[x+_x].rgbtBlue)*_d);
        if _b>255 then _b:=255 else if _b<0 then _b:=0;

         RowOut[x+_x].rgbtRed:=_r;
         RowOut[x+_x].rgbtGreen:=_g;
         RowOut[x+_x].rgbtBlue:=_b;
 end; end;
end;


_B_in - 32х битный битмап с альфаканалом
_B_out - обычный 24х битный битмап, на него выводится
_x,_y - координаты вывода


 
ors_archangel ©   (2007-01-16 14:08) [6]

Ты ж ищи не в Delphi Help, а в Windows SDK (пункт чуть ниже первого), - там все APIшные функции описаны.
Про как использовать с VCL:
Если в VCL ты рисуешь на Canvas, то в API - на DC (Device Context - контекст устройства называется). Например,

 Canvas.Pixels[10,10] := clBlack;

- рисует чёрную точку по координатам (10;10), этот код на API:

 SetPixel(dc, 10,10, 0);

dc - это идентификатор контекста устройства, его можно мыслить как идентификатор на Canvas, который мы передаём, когда хотим рисовать на Canvas. Чтобы использовать функцию AlphaBlt, ей нужно передать dc = Canvas.Handle:

 AlphaBlend(targetBitmap.Canvas.Handle, dx,dy, w,h, textureBitmap.Canvas.Handle, sx,sy, w,h, blend);

- подробнее см. справку по Win32 API :)
Чтобы сдлетаь плавный переход, нужно часть текстуры нарисовать обычным копированием CopyRect, а оставшиеся границы AlphaBlt"ом, т.е. минимум 4 прямоугольника (полосы), но лучше разделить эти полосы линейно менять интенсивность одной текстуры по отношению к другой (alpha 1 и alpha 2), чтобы получился действительно плавный переход, т.к. AlphaBlt по всей области рисования использует фиксированное значение alpha (правда его ещё можно хранить в самих битмапах, но это тебе будет, наверно, неудобно).
Вот, попробуй попременять AlphaBlend - он быстро работает, но в принципе можно код плавного перехода написать и полностью на VCL в худшем случае через свойство Pixels - будет катастрофически медленно, либо через свойство ScanLine - это хороший вариант, пример - выше ([5]).



Страницы: 1 вся ветка

Текущий архив: 2007.02.04;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.034 c
2-1167199008
Sw
2006-12-27 08:56
2007.02.04
Индексы


1-1165827510
Asail
2006-12-11 11:58
2007.02.04
Как убрать заголовок в TPageControl?


2-1169033082
vajo
2007-01-17 14:24
2007.02.04
BDS 2006 - Delphi for .NET - ASP.NET Web Application.


15-1168582732
NLex
2007-01-12 09:18
2007.02.04
Развитие в области...


2-1168983706
Vovan #2
2007-01-17 00:41
2007.02.04
Туплю с GlobalAlloc