- 浏览: 16220 次
void NcLine ( int x0, int y0, int x1, int y1, uint p32BitVram, int pitch, uint color ) { p32BitVram += (x0 << 2) + y0 * pitch; int absX = x1 - x0, absY = y1 - y0, absXTemp = absX >> 31, absYTemp = absY >> 31; int vx_dir = ((absXTemp - ~absXTemp) << 2); pitch = (pitch ^ absYTemp) - absYTemp, absX = (absX ^ absXTemp) - absXTemp, absY = (absY ^ absYTemp) - absYTemp; int rtqX = absX << 1, rtqY = absY << 1; int error, incEx, rtqL_Ex; if (absX > absY) { /* near X */ error = rtqY - absX; incEx = vx_dir + pitch; rtqL_Ex = error - absX; while (--absX) { *cast (uint*) p32BitVram = color; if (error < 0) { p32BitVram += vx_dir; error += rtqY; } else { p32BitVram += incEx; error += rtqL_Ex; } } *cast (uint*) p32BitVram = color; return; } error = rtqX - absY; incEx = vx_dir + pitch; rtqL_Ex = error - absY; while (--absY) { *cast (uint*) p32BitVram = color; if (error < 0) { p32BitVram += pitch; error += rtqX; } else { p32BitVram += incEx; error += rtqL_Ex; } } *cast (uint*) p32BitVram = color; }
void WuLine ( uint * p32bitVram, uint VramPitch, int xPosStart, int yPosStart, int xPosEnd, int yPosEnd, uint clrLine ){ int XDir, DeltaX, DeltaY; uint grayl, grayb, ErrorAdj, ErrorAcc, Weighting, ErrorAccTemp; uint* LastEndWriteAddr = p32bitVram; ubyte Mix[4]; ubyte Line[4]; ubyte Bg[4]; double WeightingShrink; VramPitch >>= 2; if (yPosStart > yPosEnd) { int Temp = yPosEnd; yPosEnd = yPosStart; yPosStart = Temp; Temp = xPosStart; xPosStart = xPosEnd; xPosEnd = Temp; } *( p32bitVram += xPosStart + yPosStart * VramPitch ) = clrLine; if ( ( DeltaX = xPosEnd - xPosStart ) >= 0 ) XDir = 1; else XDir = -1, DeltaX = -DeltaX; if ( ( DeltaY = yPosEnd - yPosStart ) == 0 ) { /* Horizontal line */ if ( XDir > 0 ) { while (--DeltaX != 0) *(++p32bitVram) = clrLine; *(++p32bitVram) = clrLine; } else { while (--DeltaX != 0) *(--p32bitVram) = clrLine; *(--p32bitVram) = clrLine; } return; } else if ( DeltaX == 0 ) { /* Vertical line */ do { *(p32bitVram += VramPitch) = clrLine; } while (--DeltaY != 0); return; } else if ( DeltaX == DeltaY ) { /* Diagonal line */ if ( XDir > 0 ) { do { *(++p32bitVram += VramPitch) = clrLine; } while (--DeltaY != 0); } else /* Diagonal line Dec */ { do { *(--p32bitVram += VramPitch) = clrLine; } while (--DeltaY != 0); } return; } *cast (uint*) Line = clrLine, ErrorAcc = 0; grayl = ( ( cast(uint) Line[2] << 2 ) + cast(uint) Line[1] * 5 + cast(uint) Line[0]); if (DeltaY > DeltaX) { ErrorAdj = cast(uint) ( ( cast(ulong) DeltaX << 32) / cast(ulong) DeltaY ); while (--DeltaY) { ErrorAccTemp = ErrorAcc; * cast (uint*) Bg = ((ErrorAcc += ErrorAdj) <= ErrorAccTemp ? * ( p32bitVram += VramPitch + XDir ) : * ( p32bitVram += VramPitch ) ); Weighting = ErrorAcc >> 24; grayb = ( ( cast(uint) Bg[2] << 2 ) + cast(uint) Bg[1] * 5 + cast(uint) Bg[0] ); WeightingShrink = (grayl >= grayb ? Weighting ^ 0xFF : Weighting) / 255.0; Mix[2] = ( Bg[2] > Line[2] ? ( cast(ubyte)( WeightingShrink * ( Bg[2] - Line[2] ) + Line[2] ) ) : ( cast(ubyte)( WeightingShrink * ( Line[2] - Bg[2] ) + Bg[2] ) ) ); Mix[1] = ( Bg[1] > Line[1] ? ( cast(ubyte)( WeightingShrink * ( Bg[1] - Line[1] ) + Line[1] ) ) : ( cast(ubyte)( WeightingShrink * ( Line[1] - Bg[1] ) + Bg[1] ) ) ); Mix[0] = ( Bg[0] > Line[0] ? ( cast(ubyte)( WeightingShrink * ( Bg[0] - Line[0] ) + Line[0] ) ) : ( cast(ubyte)( WeightingShrink * ( Line[0] - Bg[0] ) + Bg[0] ) ) ); *( p32bitVram ) = *cast(uint*) Mix; *cast(uint*) Bg = *( p32bitVram + XDir ); grayb = ( (cast(uint) Bg[2] << 2) + cast(uint) Bg[1] * 5 +cast(uint) Bg[0] ); WeightingShrink = (grayl < grayb ? Weighting ^ 0xFF : Weighting) / 255.0; Mix[2] = ( Bg[2] > Line[2] ? ( cast(ubyte)( WeightingShrink * ( Bg[2] - Line[2] ) + Line[2] ) ) : ( cast(ubyte)( WeightingShrink * ( Line[2] - Bg[2] ) + Bg[2] ) ) ); Mix[1] = ( Bg[1] > Line[1] ? ( cast(ubyte)( WeightingShrink * ( Bg[1] - Line[1] ) + Line[1] ) ) : ( cast(ubyte)( WeightingShrink * ( Line[1] - Bg[1] ) + Bg[1] ) ) ); Mix[0] = ( Bg[0] > Line[0] ? ( cast(ubyte)( WeightingShrink * ( Bg[0] - Line[0] ) + Line[0] ) ) : ( cast(ubyte)( WeightingShrink * ( Line[0] - Bg[0] ) + Bg[0] ) ) ); *( p32bitVram + XDir ) = *cast(uint*) Mix; } *( LastEndWriteAddr + xPosEnd + yPosEnd * VramPitch ) = clrLine; return; } ErrorAdj = cast(uint) ( (cast(ulong) DeltaY << 32) / cast(ulong) DeltaX); while (--DeltaX) { ErrorAccTemp = ErrorAcc; *cast(uint*) Bg = ((ErrorAcc += ErrorAdj) <= ErrorAccTemp ? * ( p32bitVram += XDir + VramPitch ) : * ( p32bitVram += XDir ) ); Weighting = ErrorAcc >> 24; grayb = ( (cast(uint) Bg[2] << 2) + cast(uint) Bg[1] * 5 +cast(uint) Bg[0] ); WeightingShrink = (grayl >= grayb ? Weighting ^ 0xFF : Weighting) / 255.0; Mix[2] = ( Bg[2] > Line[2] ? ( cast(ubyte)( WeightingShrink * ( Bg[2] - Line[2] ) + Line[2] ) ) : ( cast(ubyte)( WeightingShrink * ( Line[2] - Bg[2] ) + Bg[2] ) ) ); Mix[1] = ( Bg[1] > Line[1] ? ( cast(ubyte)( WeightingShrink * ( Bg[1] - Line[1] ) + Line[1] ) ) : ( cast(ubyte)( WeightingShrink * ( Line[1] - Bg[1] ) + Bg[1] ) ) ); Mix[0] = ( Bg[0] > Line[0] ? ( cast(ubyte)( WeightingShrink * ( Bg[0] - Line[0] ) + Line[0] ) ) : ( cast(ubyte)( WeightingShrink * ( Line[0] - Bg[0] ) + Bg[0] ) ) ); *( p32bitVram ) = *cast(uint*) Mix; *cast(uint*) Bg = *( p32bitVram + VramPitch ); grayb = ( ( cast(uint) Bg[2] << 2 ) + cast(uint) Bg[1] * 5 + cast(uint) Bg[0] ); WeightingShrink = cast (double)(grayl < grayb ? Weighting ^ 0xFF : Weighting) / 255.0; Mix[2] = ( Bg[2] > Line[2] ? ( cast(ubyte)( WeightingShrink * ( Bg[2] - Line[2] ) + Line[2] ) ) : ( cast(ubyte)( WeightingShrink * ( Line[2] - Bg[2] ) + Bg[2] ) ) ); Mix[1] = ( Bg[1] > Line[1] ? ( cast(ubyte)( WeightingShrink * ( Bg[1] - Line[1] ) + Line[1] ) ) : ( cast(ubyte)( WeightingShrink * ( Line[1] - Bg[1] ) + Bg[1] ) ) ); Mix[0] = ( Bg[0] > Line[0] ? ( cast(ubyte)( WeightingShrink * ( Bg[0] - Line[0] ) + Line[0] ) ) : ( cast(ubyte)( WeightingShrink * ( Line[0] - Bg[0] ) + Bg[0] ) ) ); *( p32bitVram + VramPitch ) = *cast(uint*) Mix; } *( LastEndWriteAddr + xPosEnd + yPosEnd * VramPitch ) = clrLine; }
BR直线汇编代码
void _NcLine ( int x0, int y0, int x1, int y1, uint p32BitVram, int pitch, uint color ) { asm { naked ; // use naked asm mode pushad ; // save old frame mov ECX, 36[ESP] ; // ECX <- x0 mov EDX, 40[ESP] ; // EDX <- y0 mov EDI, 44[ESP] ; // EDI <- x1 mov ESI, 48[ESP] ; // ESI <- y1 cmp ECX, EDI ; // x0 < x1 ? setl AL ; // Y ? AL = 1 : AL = 0 shl EAX, 31 ; // left shift save old flags cmp EDX, ESI ; // y0 < y1 ? setl AL ; // Y ? AL = 1 : AL = 0 rol EAX, 1 ; // bit0: X bit1: Y lea EAX, gtIndex[EAX*8] ; jmp EAX ; align 16 ; gtIndex: xchg EDI, ECX ; xchg ESI, EDX ; jmp R2 ; xor EAX, EAX ; xchg EDI, ECX ; xchg ESI, EDX ; jmp tempTable ; xor EAX, EAX ; tempTable: jmp R1 ; xchg EDI, ECX ; inc EAX ; R2: // x0 < x1/y0 < y0 sub EDI, ECX ; // RV - X sub ESI, EDX ; // RV - Y xor EAX, EAX ; // clear cmp ESI, EDI ; // RV - Y > RV - X ? seta AL ; // is > 0 ? AL = 1 : AL = 0 ror EAX, 1 ; // save old frame ror op not affect z bit setz AL ; // is Equal ? lea EAX, R2gtIndex[EAX*8] ; // table jmp EAX ; align 16 ; R2gtIndex: /// r2 TABLE jmp R2NearX ; jmp R2NearY ; inc EDX ; jmp R2NearY ; imul ECX, EAX ; R2Align: // 45 du ^ mov EAX, 56[ESP] ; //pitch imul ECX, EAX ; //- N pitch * tStartY add EAX, 4 ;// ouy lea ECX, [ECX+EDX*4] ; //init pVram comp mov EDX, 60[ESP] ; //EDX = color add ECX, 52[ESP] ; //pVram Pos + RVA imul EDI, EAX ; //- N rv - y * ouy = start to end 's RVA total ... neg EDI; //- N neg opr sub ECX, EDI ; //init first write ... align 16 ; R2Align_main_loop: mov [ECX+EDI], EDX ; //maybe have agi clash lea ESP, [ESP] ; add EDI, EAX ; // emmm ... maybe this is not fast :( jne R2Align_main_loop ; // when write vram finish EDI is zero mov [ECX+EDI], EDX ; // last write vram popad ; ret ; R2NearX: movd XMM7, ESP ; mov EAX, 56[ESP] ; neg EDI ; // dx imul EDX, EAX ; // lea EBX, [EDX+ECX*4] ; // RVA Vram Pos add ESI, ESI ; add EBX, 52[ESP] ; // p32BitVram + RVA Vram Pos lea EDX, 4[EAX] ; // lea ECX, [ESI+EDI] ; // ECX = error mov ESP, 60[ESP] ; // ESP = color lea EBP, [ECX+EDI] ; // test ECX, ECX ; jge R2NearX_Ex ; align 16 ; R2NearX_main_loop: mov [EBX], ESP ; jc R2NearX_RP ; add EBX, 4 ; add ECX, ESI ; inc EDI ; jne R2NearX_main_loop ; jmp R2NearXRet ; R2NearX_RP: add EBX, EDX ; add ECX, EBP ; inc EDI ; jne R2NearX_main_loop ; R2NearXRet: mov [EBX], ESP ; movd ESP, XMM7 ; popad ; ret ; R2NearX_Ex: mov [EBX], ESP ; add EBX, EDX ; add ECX, EBP ; inc EDI ; jne R2NearX_main_loop ; jmp R2NearXRet ; R2NearY: movd XMM0, ESP ; mov EAX, 56[ESP] ; // pitch neg ESI ; // dy imul EDX, EAX ; // - N pitch * tStartY ( EDX ) lea EBX, [EDX+ECX*4] ; // init pVram comp add EDI, EDI ; // dx2 add EBX, 52[ESP] ; // pVram Pos + RVA lea EDX, 4[EAX] ; // EBP = ruy lea ECX, [EDI+ESI] ; // error mov ESP, 60[ESP] ; lea EBP, [ECX+ESI] ; // EBP = ogh test ECX, ECX ; jge R2NearY_RP_Ex ; align 16 ; /* R2NearY_main_loop: mov [EBX], ESP ; // - U jc R2NearY_RP ; // - V add EBX, EAX ; // - U add ECX, EDI ; // - V inc ESI ; // - U jne R2NearY_main_loop ; // - V mov [EBX], ESP ; // - U jmp R2NearY_ret ; // - V R2NearY_RP: add EBX, EDX ; // add ECX, EBP ; inc ESI ; jne R2NearY_main_loop ; */ R2NearY_main_loop: mov [EBX], ESP ; // - U jnc R2NearY_no_repair ; // - V R2NearY_RP: add EBX, EDX ; // add ECX, EBP ; // inc ESI ; // jne R2NearY_main_loop ; // jmp R2NearY_ret ; // - V R2NearY_no_repair: add EBX, EAX ; // - U add ECX, EDI ; // - V inc ESI ; // - U jne R2NearY_main_loop ; // - V R2NearY_ret: mov [EBX], ESP ; movd ESP, XMM7 ; popad ; ret ; R2NearY_RP_Ex: mov [EBX], ESP ; add EBX, EDX ; add ECX, EBP ; inc ESI ; jne R2NearY_main_loop ; jmp R2NearY_ret; R1:// ----- x0 > x1/y0 <= y1 sub ECX, EDI ; //--- RV - X sub ESI, EDX ; // RV - Y xor EAX, EAX ; // cmp ECX, ESI ; // RV - Y > RV - X ? setl AL ; // 1 > 0 <= ror EAX, 1 ; setz AL ; rol EAX, 1 ; lea EAX, R1gtIndex[EAX*8]; jmp EAX ; align 16 ; R1gtIndex: /// r1 TABLE jmp R1NearX; // 1 jmp R1NearY; inc EDX; jmp R1NearY; // 2 imul ECX, EAX; R1Align: mov EAX, 56[ESP] ; //pitch add EDX, ESI ; imul EDI, EAX ; //- N pitch * tStartY sub EAX, 4 ; //ouy lea EDI, [EDI+EDX*4] ; //init pVram comp mov EDX, 60[ESP] ; //EDX = color add EDI, 52[ESP] ; //pVram Pos + RVA imul ESI, EAX ; //- N rv - y * ouy = start to end 's RVA total ... neg ESI; //- N neg opr sub EDI, ESI ;// init first write ... align 16 ; R1Align_main_loop: mov [EDI+ESI], EDX ; // maybe have agi clash lea ESP, [ESP] ; add ESI, EAX ; // emmm ... maybe this is not fast :( jne R1Align_main_loop ; // when write vram finish EDI is zero popad ; ret ; R1NearX: movd XMM7, ESP ; mov EAX, 56[ESP] ; // pitch add EDI, ECX ; imul EDX, EAX ; //- N pitch * tStartY ( EDX ) neg ECX ; // dx lea EBX, [EDX+EDI*4] ; //init pVram comp add ESI, ESI ;// dy2 add EBX, 52[ESP] ; //pVram Pos + RVA lea EDI, [EAX-4] ; //EDI = ruy lea EBP, [ESI+ECX] ; //error mov ESP, 60[ESP] ; lea EDX, [EBP+ECX] ; //EDX = ogh test EBP, EBP ; jge R1NearX_RP_Ex ; align 16 ; R1NearX_main_loop: mov [EBX], ESP; jc R1NearX_repair; sub EBX, 4; add EBP, ESI; inc ECX; jne R1NearX_main_loop; jmp R1NearX_ret; R1NearX_repair: add EBX, EDI; add EBP, EDX; inc ECX ; jne R1NearX_main_loop ; R1NearX_ret: mov [EBX], ESP; movd ESP, XMM7 ; popad ; ret ; R1NearX_RP_Ex: mov [EBX], ESP; add EBX, EDI; add EBP, EDX; inc ECX ; jne R1NearX_main_loop; jmp R1NearX_ret ; R1NearY: movd XMM7, ESP; mov EAX, 56[ESP] ; //pitch neg ESI ;// dy . imul EDX, EAX ; //- N pitch * tStartY ( EDX ) add EDI, ECX; lea EBX, [EDX+EDI*4] ; //init pVram comp add ECX, ECX ; //dx2 add EBX, 52[ESP] ; //pVram Pos + RVA lea EDI, [EAX-4] ; //EDI = ruy lea EBP, [ESI+ECX] ; //error mov ESP, 60[ESP] ; //color lea EDX, [EBP+ESI] ; //EDX = ogh test EBP, EBP; jge R1NearY_RP_Ex ; align 16 ; R1NearY_main_loop: mov [EBX], ESP; jc R1NearY_repair; add EBX, EAX; add EBP, ECX; inc ESI; jne R1NearY_main_loop; jmp R1NearY_ret; R1NearY_repair: add EBX, EDI; add EBP, EDX; inc ESI ; jne R1NearY_main_loop; R1NearY_ret: mov [EBX], ESP; movd ESP, XMM7 ; popad ; ret ; R1NearY_RP_Ex: mov [EBX], ESP; add EBX, EDI; add EBP, EDX; inc ESI ; jne R1NearY_main_loop ; } }
相关推荐
《基于VC6.0的Bresenham直线算法详解》 在计算机图形学领域,Bresenham直线算法是一项至关重要的技术,它被广泛应用于2D图形绘制,尤其是在低分辨率的屏幕上快速绘制像素精确的直线。这个算法由John E. Bresenham于...
Bresenham直线算法是一种在计算机图形学中用于绘制像素化的直线的高效算法,由Jack Bresenham在1965年提出。这个算法基于错误修正的思想,它避免了浮点运算,使得在硬件资源有限的环境下也能快速地生成接近理想的...
计算机图形学-写出Bresenham直线扫描算法,算法能绘制任意方向的直线。 环境:vs2017 使用OpenGL,练习Bresenham直线扫描算法,算法能绘制任意方向的直线。
### Bresenham直线算法与画圆算法 #### 一、Bresenham直线算法 Bresenham直线算法是一种高效的计算机图形算法,用于在二维光栅显示器上绘制直线。该算法通过仅使用整数运算(加法、减法和位移操作),能够在不使用...
在linux下面写的,WIN下面用的话把 typedef int32_t int32; typedef uint32_t uint32; 改成 typedef __int32 int32; typedef unsigned __int32 uint32;
### Bresenham直线生成算法 Bresenham直线生成算法是一种用于绘制二维空间中整数坐标点上近似直线段的算法。该算法由杰克·B·布雷斯哈姆(Jack Elton Bresenham)在1962年提出,并广泛应用于计算机图形学领域,...
提到的源程序案例5-直线反走样Wu算法,指的是吴(Wu)氏反走样算法,也称为Bresenham-Wu算法,是由Bresenham算法扩展而来的。Bresenham算法是一种快速近似算法,主要用于绘制点在像素中心的直线。然而,对于反走样...
本文将深入探讨三种常见的直线绘制算法:DDA(Digital Differential Analyzer)算法、中点Bresenham算法以及Bresenham算法,并结合MFC(Microsoft Foundation Classes)框架进行实现。这些算法在二维图形的渲染和...
中点圆算法与Bresenham直线算法是计算机图形学中的两种重要算法,它们主要用于高效地在像素化平面上绘制几何形状,特别是直线和圆形。这两种算法基于离散的像素网格,通过避免浮点运算来提高计算速度,适用于低级...
在画直线时,传统的Bresenham算法或DDA(Digital Differentiation Algorithm)可能会导致像素化的边缘,而反走样则会考虑像素部分覆盖的情况,对这些像素进行适当的色彩混合。 在MFC环境中,我们可以使用CDC...
在OpenGL中,Bresenham直线算法是一个重要的概念,它用于高效地在屏幕上绘制离散像素构成的近似直线。Bresenham算法是基于错误检测和纠正的算法,特别适合于硬件加速的图形系统,因为它只需要少量的计算和内存访问。...
这里我们关注的是三种在MATLAB环境中实现直线画法的算法:DDA(Digital Differential Analyzer),中点算法,以及Bresenham算法。这些算法都是为了在像素化环境中高效、精确地绘制直线。 1. **DDA算法**: DDA算法...
### Bresenham画直线算法详解 #### 一、引言 Bresenham画直线算法是一种用于在离散坐标系上绘制直线的算法。它由Jack E. Bresenham于1962年发明,并因其高效性而被广泛应用于计算机图形学中。与早期的画线算法相比...
特别地,Bresenham直线算法和Bresenham画圆算法分别解决了如何在二维像素屏幕上绘制直线和圆的难题,它们的核心思想在于仅使用整数运算来确定最接近理想直线或圆的像素点位置。 Bresenham直线算法专注于解决在一个...
Bresenham直线算法是一种在计算机图形学中广泛使用的算法,用于高效地在像素网格上绘制从一个点到另一个点的直线。这个算法由Jack E. Bresenham于1965年提出,它的核心思想是通过迭代计算来决定应该在哪个像素位置...
**布雷森汉姆(Bresenham)直线算法**是一种在数字图像处理和计算机图形学中用于绘制从一个像素到另一个像素精确直线的高效算法。由英国工程师约翰·布雷森汉姆(John W. Bresenham)在1965年提出,这个算法特别适用...
1. 通过实验,进一步理解直线段扫描转换的DDA算法、中点bresenham算法及bresenham算法的基本原理; 2. 掌握以上算法生成直线段的基本过程; 3. 通过编程,会在C/C++环境下完成用DDA算法、中点bresenham算法及...
"Bresenham算法-直线光栅化算法" Bresenham算法是计算机图形学中典型的直线光栅化算法,能够减少乘除法和浮点数的使用,大大加快画图速度,不管是在计算机上自己实现画图还是在单片机上实现都是很有用的。 ...
在MFC中,你可以自定义一个类,包含起点和终点坐标,然后重载OnDraw成员函数来实现Bresenham直线算法的绘制。 Bresenham的画圆算法则利用了中心增量法,通过对半径和偏移量的迭代,决定当前像素是否应该被绘制。与...